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>
This commit is contained in:
Greenlamp2 2024-05-23 17:03:10 +02:00 committed by GitHub
parent 2240e09406
commit bac6c22973
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
319 changed files with 41425 additions and 40246 deletions

7
.eslintignore Normal file
View File

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

View File

@ -1,17 +1,29 @@
{ {
"env": { "parser": "@typescript-eslint/parser", // Specifies the ESLint parser for TypeScript
"browser": true, "plugins": ["@typescript-eslint", "import"], // Includes TypeScript and import plugins
"es2021": true "overrides": [
}, {
"parserOptions": { "files": ["src/**/*.{ts,tsx,js,jsx}"], // Applies these rules to all TypeScript and JavaScript files in the src directory
"ecmaVersion": "latest", "rules": {
"sourceType": "module" // General rules that apply to all files
}, "eqeqeq": ["error", "always"], // Enforces the use of === and !== instead of == and !=
"overrides": [ "indent": ["error", 2], // Enforces a 2-space indentation
{ "quotes": ["error", "double"], // Enforces the use of double quotes for strings
"files": ["src/**/*.ts"], "no-var": "error", // Disallows the use of var, enforcing let or const instead
"extends": "eslint:recommended" "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", {
"rules": {} "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"]
}
}
]
} }

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

6529
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ import { GameMode } from "./game-mode";
import { BattleSpec } from "./enums/battle-spec"; import { BattleSpec } from "./enums/battle-spec";
import { PlayerGender } from "./system/game-data"; import { PlayerGender } from "./system/game-data";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { MoneyAchv } from "./system/achv";
import { PokeballType } from "./data/pokeball"; import { PokeballType } from "./data/pokeball";
export enum BattleType { export enum BattleType {
@ -34,268 +33,284 @@ export interface TurnCommand {
targets?: BattlerIndex[]; targets?: BattlerIndex[];
skip?: boolean; skip?: boolean;
args?: any[]; args?: any[];
}; }
interface TurnCommands { interface TurnCommands {
[key: integer]: TurnCommand [key: integer]: TurnCommand
} }
export default class Battle { export default class Battle {
protected gameMode: GameMode; protected gameMode: GameMode;
public waveIndex: integer; public waveIndex: integer;
public battleType: BattleType; public battleType: BattleType;
public battleSpec: BattleSpec; public battleSpec: BattleSpec;
public trainer: Trainer; public trainer: Trainer;
public enemyLevels: integer[]; public enemyLevels: integer[];
public enemyParty: EnemyPokemon[]; public enemyParty: EnemyPokemon[];
public seenEnemyPartyMemberIds: Set<integer>; public seenEnemyPartyMemberIds: Set<integer>;
public double: boolean; public double: boolean;
public started: boolean; public started: boolean;
public enemySwitchCounter: integer; public enemySwitchCounter: integer;
public turn: integer; public turn: integer;
public turnCommands: TurnCommands; public turnCommands: TurnCommands;
public playerParticipantIds: Set<integer>; public playerParticipantIds: Set<integer>;
public battleScore: integer; public battleScore: integer;
public postBattleLoot: PokemonHeldItemModifier[]; public postBattleLoot: PokemonHeldItemModifier[];
public escapeAttempts: integer; public escapeAttempts: integer;
public lastMove: Moves; public lastMove: Moves;
public battleSeed: string; public battleSeed: string;
private battleSeedState: string; private battleSeedState: string;
public moneyScattered: number; public moneyScattered: number;
public lastUsedPokeball: PokeballType; public lastUsedPokeball: PokeballType;
private rngCounter: integer = 0; private rngCounter: integer = 0;
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) { constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) {
this.gameMode = gameMode; this.gameMode = gameMode;
this.waveIndex = waveIndex; this.waveIndex = waveIndex;
this.battleType = battleType; this.battleType = battleType;
this.trainer = trainer; this.trainer = trainer;
this.initBattleSpec(); this.initBattleSpec();
this.enemyLevels = battleType !== BattleType.TRAINER this.enemyLevels = battleType !== BattleType.TRAINER
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave()) ? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer.getPartyLevels(this.waveIndex); : trainer.getPartyLevels(this.waveIndex);
this.enemyParty = []; this.enemyParty = [];
this.seenEnemyPartyMemberIds = new Set<integer>(); this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = double; this.double = double;
this.enemySwitchCounter = 0; this.enemySwitchCounter = 0;
this.turn = 0; this.turn = 0;
this.playerParticipantIds = new Set<integer>(); this.playerParticipantIds = new Set<integer>();
this.battleScore = 0; this.battleScore = 0;
this.postBattleLoot = []; this.postBattleLoot = [];
this.escapeAttempts = 0; this.escapeAttempts = 0;
this.started = false; this.started = false;
this.battleSeed = Utils.randomString(16, true); this.battleSeed = Utils.randomString(16, true);
this.battleSeedState = null; this.battleSeedState = null;
this.moneyScattered = 0; this.moneyScattered = 0;
this.lastUsedPokeball = null; this.lastUsedPokeball = null;
}
private initBattleSpec(): void {
let spec = BattleSpec.DEFAULT;
if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) {
spec = BattleSpec.FINAL_BOSS;
}
this.battleSpec = spec;
}
private getLevelForWave(): integer {
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const bossMultiplier = 1.2;
if (this.gameMode.isBoss(this.waveIndex)) {
const ret = Math.floor(baseLevel * bossMultiplier);
if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) {
return Math.ceil(ret / 25) * 25;
}
let levelOffset = 0;
if (!this.gameMode.isWaveFinal(this.waveIndex)) {
levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10));
}
return ret + levelOffset;
} }
private initBattleSpec(): void { let levelOffset = 0;
let spec = BattleSpec.DEFAULT;
if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic) const deviation = 10 / levelWaveIndex;
spec = BattleSpec.FINAL_BOSS; levelOffset = Math.abs(this.randSeedGaussForLevel(deviation));
this.battleSpec = spec;
return Math.max(Math.round(baseLevel + levelOffset), 1);
}
randSeedGaussForLevel(value: number): number {
let rand = 0;
for (let i = value; i > 0; i--) {
rand += Phaser.Math.RND.realInRange(0, 1);
} }
return rand / value;
}
private getLevelForWave(): integer { getBattlerCount(): integer {
let levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex); return this.double ? 2 : 1;
let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); }
const bossMultiplier = 1.2;
if (this.gameMode.isBoss(this.waveIndex)) { incrementTurn(scene: BattleScene): void {
const ret = Math.floor(baseLevel * bossMultiplier); this.turn++;
if (this.battleSpec === BattleSpec.FINAL_BOSS || !(this.waveIndex % 250)) this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
return Math.ceil(ret / 25) * 25; this.battleSeedState = null;
let levelOffset = 0; }
if (!this.gameMode.isWaveFinal(this.waveIndex))
levelOffset = Math.round(Phaser.Math.RND.realInRange(-1, 1) * Math.floor(levelWaveIndex / 10)); addParticipant(playerPokemon: PlayerPokemon): void {
return ret + levelOffset; this.playerParticipantIds.add(playerPokemon.id);
}
removeFaintedParticipant(playerPokemon: PlayerPokemon): void {
this.playerParticipantIds.delete(playerPokemon.id);
}
addPostBattleLoot(enemyPokemon: EnemyPokemon): void {
this.postBattleLoot.push(...enemyPokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.getTransferrable(false), false).map(i => {
const ret = i as PokemonHeldItemModifier;
ret.pokemonId = null;
return ret;
}));
}
pickUpScatteredMoney(scene: BattleScene): void {
const moneyAmount = new Utils.IntegerHolder(scene.currentBattle.moneyScattered);
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
scene.addMoney(moneyAmount.value);
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) {
partyMemberTurnMultiplier /= 1.5;
}
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 finalBattleScore = Math.ceil(this.battleScore * turnMultiplier);
scene.score += finalBattleScore;
console.log(`Battle Score: ${finalBattleScore} (${this.turn - 1} Turns x${Math.floor(turnMultiplier * 100) / 100})`);
console.log(`Total Score: ${scene.score}`);
scene.updateScoreText();
}
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) {
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 (const pokemon of battlers) {
if (this.battleSpec === BattleSpec.FINAL_BOSS) {
if (pokemon.formIndex) {
return "battle_final";
} }
return "battle_final_encounter";
let levelOffset = 0; }
if (pokemon.species.legendary || pokemon.species.subLegendary || pokemon.species.mythical) {
const deviation = 10 / levelWaveIndex; 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) {
levelOffset = Math.abs(this.randSeedGaussForLevel(deviation)); return "battle_legendary_regis";
return Math.max(Math.round(baseLevel + levelOffset), 1);
}
randSeedGaussForLevel(value: number): number {
let rand = 0;
for (let i = value; i > 0; i--)
rand += Phaser.Math.RND.realInRange(0, 1);
return rand / value;
}
getBattlerCount(): integer {
return this.double ? 2 : 1;
}
incrementTurn(scene: BattleScene): void {
this.turn++;
this.turnCommands = Object.fromEntries(Utils.getEnumValues(BattlerIndex).map(bt => [ bt, null ]));
this.battleSeedState = null;
}
addParticipant(playerPokemon: PlayerPokemon): void {
this.playerParticipantIds.add(playerPokemon.id);
}
removeFaintedParticipant(playerPokemon: PlayerPokemon): void {
this.playerParticipantIds.delete(playerPokemon.id);
}
addPostBattleLoot(enemyPokemon: EnemyPokemon): void {
this.postBattleLoot.push(...enemyPokemon.scene.findModifiers(m => m instanceof PokemonHeldItemModifier && m.pokemonId === enemyPokemon.id && m.getTransferrable(false), false).map(i => {
const ret = i as PokemonHeldItemModifier;
ret.pokemonId = null;
return ret;
}));
}
pickUpScatteredMoney(scene: BattleScene): void {
const moneyAmount = new Utils.IntegerHolder(scene.currentBattle.moneyScattered);
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
scene.addMoney(moneyAmount.value);
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)
partyMemberTurnMultiplier /= 1.5;
for (let 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)); 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) {
const finalBattleScore = Math.ceil(this.battleScore * turnMultiplier); return "battle_legendary_unova";
scene.score += finalBattleScore;
console.log(`Battle Score: ${finalBattleScore} (${this.turn - 1} Turns x${Math.floor(turnMultiplier * 100) / 100})`);
console.log(`Total Score: ${scene.score}`);
scene.updateScoreText();
}
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)
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) {
if (this.battleSpec === BattleSpec.FINAL_BOSS) {
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.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM) {
if (scene.gameMode.isClassic && this.waveIndex <= 4) return "battle_legendary_res_zek";
return 'battle_wild';
return null;
}
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
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)
Phaser.Math.RND.state(this.battleSeedState);
else {
Phaser.Math.RND.sow([ Utils.shiftCharCodes(this.battleSeed, this.turn << 6) ]);
console.log('Battle Seed:', this.battleSeed);
} }
scene.rngCounter = this.rngCounter++; if (pokemon.species.speciesId === Species.KYUREM) {
scene.rngSeedOverride = this.battleSeed; return "battle_legendary_kyurem";
ret = Utils.randSeedInt(range, min); }
this.battleSeedState = Phaser.Math.RND.state(); if (pokemon.species.legendary) {
Phaser.Math.RND.state(state); return "battle_legendary_res_zek";
scene.rngCounter = tempRngCounter; }
scene.rngSeedOverride = tempSeedOverride; return "battle_legendary_unova";
return ret; }
} }
if (scene.gameMode.isClassic && this.waveIndex <= 4) {
return "battle_wild";
}
return null;
}
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
if (range <= 1) {
return min;
}
const tempRngCounter = scene.rngCounter;
const tempSeedOverride = scene.rngSeedOverride;
const state = Phaser.Math.RND.state();
if (this.battleSeedState) {
Phaser.Math.RND.state(this.battleSeedState);
} else {
Phaser.Math.RND.sow([ Utils.shiftCharCodes(this.battleSeed, this.turn << 6) ]);
console.log("Battle Seed:", this.battleSeed);
}
scene.rngCounter = this.rngCounter++;
scene.rngSeedOverride = this.battleSeed;
const ret = Utils.randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state);
scene.rngCounter = tempRngCounter;
scene.rngSeedOverride = tempSeedOverride;
return ret;
}
} }
export class FixedBattle extends Battle { export class FixedBattle extends Battle {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) { constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double); super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double);
if (config.getEnemyParty) if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty(scene); this.enemyParty = config.getEnemyParty(scene);
} }
}
} }
type GetTrainerFunc = (scene: BattleScene) => Trainer; type GetTrainerFunc = (scene: BattleScene) => Trainer;
type GetEnemyPartyFunc = (scene: BattleScene) => EnemyPokemon[]; type GetEnemyPartyFunc = (scene: BattleScene) => EnemyPokemon[];
export class FixedBattleConfig { export class FixedBattleConfig {
public battleType: BattleType; public battleType: BattleType;
public double: boolean; public double: boolean;
public getTrainer: GetTrainerFunc; public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc; public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: integer; public seedOffsetWaveIndex: integer;
setBattleType(battleType: BattleType): FixedBattleConfig { setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType; this.battleType = battleType;
return this; return this;
} }
setDouble(double: boolean): FixedBattleConfig { setDouble(double: boolean): FixedBattleConfig {
this.double = double; this.double = double;
return this; return this;
} }
setGetTrainerFunc(getTrainerFunc: GetTrainerFunc): FixedBattleConfig { setGetTrainerFunc(getTrainerFunc: GetTrainerFunc): FixedBattleConfig {
this.getTrainer = getTrainerFunc; this.getTrainer = getTrainerFunc;
return this; return this;
} }
setGetEnemyPartyFunc(getEnemyPartyFunc: GetEnemyPartyFunc): FixedBattleConfig { setGetEnemyPartyFunc(getEnemyPartyFunc: GetEnemyPartyFunc): FixedBattleConfig {
this.getEnemyParty = getEnemyPartyFunc; this.getEnemyParty = getEnemyPartyFunc;
return this; return this;
} }
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig { setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex; this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this; return this;
} }
} }
function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): GetTrainerFunc { function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): GetTrainerFunc {
return (scene: BattleScene) => { return (scene: BattleScene) => {
const rand = Utils.randSeedInt(trainerPool.length); const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = []; const trainerTypes: TrainerType[] = [];
for (let trainerPoolEntry of trainerPool) { for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry) const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry) ? Utils.randSeedItem(trainerPoolEntry)
: trainerPoolEntry; : trainerPoolEntry;
trainerTypes.push(trainerType); trainerTypes.push(trainerType);
} }
return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT); return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT);
}; };
} }
interface FixedBattleConfigs { interface FixedBattleConfigs {
@ -303,28 +318,28 @@ interface FixedBattleConfigs {
} }
export const fixedBattles: FixedBattleConfigs = { export const fixedBattles: FixedBattleConfigs = {
[5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)), .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.RIKA, TrainerType.CRISPIN ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.RIKA, TrainerType.CRISPIN ])),
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.POPPY, TrainerType.AMARYS ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.POPPY, TrainerType.AMARYS ])),
[186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, TrainerType.LARRY_ELITE, TrainerType.LACEY ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, TrainerType.LARRY_ELITE, TrainerType.LACEY ])),
[188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.HASSEL, TrainerType.DRAYTON ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.HASSEL, TrainerType.DRAYTON ])),
[190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182) [190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN, TrainerType.LEON ])), .setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN, TrainerType.LEON ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER) [195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)) .setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
}; };

View File

@ -2,28 +2,28 @@
* Dualshock mapping * Dualshock mapping
*/ */
const pad_dualshock = { const pad_dualshock = {
padID: 'Dualshock', padID: "Dualshock",
padType: 'Sony', padType: "Sony",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,
RC_W: 2, RC_W: 2,
RC_N: 3, RC_N: 3,
START: 9, // Options START: 9, // Options
SELECT: 8, // Share SELECT: 8, // Share
LB: 4, LB: 4,
RB: 5, RB: 5,
LT: 6, LT: 6,
RT: 7, RT: 7,
LS: 10, LS: 10,
RS: 11, RS: 11,
LC_N: 12, LC_N: 12,
LC_S: 13, LC_S: 13,
LC_W: 14, LC_W: 14,
LC_E: 15, LC_E: 15,
MENU: 16, MENU: 16,
TOUCH: 17 TOUCH: 17
}, },
}; };
export default pad_dualshock; export default pad_dualshock;

View File

@ -2,26 +2,26 @@
* Generic pad mapping * Generic pad mapping
*/ */
const pad_generic = { const pad_generic = {
padID: 'Generic', padID: "Generic",
padType: 'generic', padType: "generic",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,
RC_W: 2, RC_W: 2,
RC_N: 3, RC_N: 3,
START: 9, START: 9,
SELECT: 8, SELECT: 8,
LB: 4, LB: 4,
RB: 5, RB: 5,
LT: 6, LT: 6,
RT: 7, RT: 7,
LS: 10, LS: 10,
RS: 11, RS: 11,
LC_N: 12, LC_N: 12,
LC_S: 13, LC_S: 13,
LC_W: 14, LC_W: 14,
LC_E: 15 LC_E: 15
}, },
}; };
export default pad_generic; export default pad_generic;

View File

@ -2,22 +2,22 @@
* 081f-e401 - UnlicensedSNES * 081f-e401 - UnlicensedSNES
*/ */
const pad_unlicensedSNES = { const pad_unlicensedSNES = {
padID: '081f-e401', padID: "081f-e401",
padType: 'snes', padType: "snes",
gamepadMapping : { gamepadMapping : {
RC_S: 2, RC_S: 2,
RC_E: 1, RC_E: 1,
RC_W: 3, RC_W: 3,
RC_N: 0, RC_N: 0,
START: 9, START: 9,
SELECT: 8, SELECT: 8,
LB: 4, LB: 4,
RB: 5, RB: 5,
LC_N: 12, LC_N: 12,
LC_S: 13, LC_S: 13,
LC_W: 14, LC_W: 14,
LC_E: 15 LC_E: 15
} }
}; };
export default pad_unlicensedSNES; export default pad_unlicensedSNES;

View File

@ -2,27 +2,27 @@
* Generic pad mapping * Generic pad mapping
*/ */
const pad_xbox360 = { const pad_xbox360 = {
padID: 'Xbox 360 controller (XInput STANDARD GAMEPAD)', padID: "Xbox 360 controller (XInput STANDARD GAMEPAD)",
padType: 'xbox', padType: "xbox",
gamepadMapping: { gamepadMapping: {
RC_S: 0, RC_S: 0,
RC_E: 1, RC_E: 1,
RC_W: 2, RC_W: 2,
RC_N: 3, RC_N: 3,
START: 9, START: 9,
SELECT: 8, SELECT: 8,
LB: 4, LB: 4,
RB: 5, RB: 5,
LT: 6, LT: 6,
RT: 7, RT: 7,
LS: 10, LS: 10,
RS: 11, RS: 11,
LC_N: 12, LC_N: 12,
LC_S: 13, LC_S: 13,
LC_W: 14, LC_W: 14,
LC_E: 15, LC_E: 15,
MENU: 16 MENU: 16
}, },
}; };
export default pad_xbox360; export default pad_xbox360;

View File

@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect";
import { Gender } from "./gender"; import { Gender } from "./gender";
import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move"; import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove, VariablePowerAttr, applyMoveAttrs, IncrementMovePriorityAttr } from "./move";
import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag";
import { ArenaTagType } from "./enums/arena-tag-type"; import { ArenaTagType } from "./enums/arena-tag-type";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
@ -20,9 +20,7 @@ import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import i18next, { Localizable } from "#app/plugins/i18n.js"; import i18next, { Localizable } from "#app/plugins/i18n.js";
import { Command } from "../ui/command-ui-handler"; import { Command } from "../ui/command-ui-handler";
import Battle from "#app/battle.js"; import { getPokeballName } from "./pokeball";
import { ability } from "#app/locales/en/ability.js";
import { PokeballType, getPokeballName } from "./pokeball";
import { BerryModifierType } from "#app/modifier/modifier-type"; import { BerryModifierType } from "#app/modifier/modifier-type";
export class Ability implements Localizable { export class Ability implements Localizable {
@ -40,7 +38,7 @@ export class Ability implements Localizable {
constructor(id: Abilities, generation: integer) { constructor(id: Abilities, generation: integer) {
this.id = id; this.id = id;
this.nameAppend = ''; this.nameAppend = "";
this.generation = generation; this.generation = generation;
this.attrs = []; this.attrs = [];
this.conditions = []; this.conditions = [];
@ -49,10 +47,10 @@ export class Ability implements Localizable {
} }
localize(): void { localize(): void {
const i18nKey = Abilities[this.id].split('_').filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join('') as string; const i18nKey = Abilities[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as string;
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : ''; this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : "";
this.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : ''; this.description = this.id ? i18next.t(`ability:${i18nKey}.description`) as string : "";
} }
getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] { getAttrs(attrType: { new(...args: any[]): AbAttr }): AbAttr[] {
@ -95,12 +93,12 @@ export class Ability implements Localizable {
} }
partial(): this { partial(): this {
this.nameAppend += ' (P)'; this.nameAppend += " (P)";
return this; return this;
} }
unimplemented(): this { unimplemented(): this {
this.nameAppend += ' (N)'; this.nameAppend += " (N)";
return this; return this;
} }
} }
@ -146,7 +144,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
return i18next.t('abilityTriggers:blockRecoilDamage', {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName}); return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: `${getPokemonPrefix(pokemon)}${pokemon.name}`, abilityName: abilityName});
} }
} }
@ -179,8 +177,9 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon); const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false; return false;
} }
@ -194,7 +193,7 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) { constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean) {
super(); super();
this.stats = typeof(stats) === 'number' this.stats = typeof(stats) === "number"
? [ stats as BattleStat ] ? [ stats as BattleStat ]
: stats as BattleStat[]; : stats as BattleStat[];
this.levels = levels; this.levels = levels;
@ -204,18 +203,20 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const statChangePhases: StatChangePhase[] = []; const statChangePhases: StatChangePhase[] = [];
if (this.selfTarget) if (this.selfTarget) {
statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels)); statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
else { } else {
for (let opponent of pokemon.getOpponents()) for (const opponent of pokemon.getOpponents()) {
statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels)); statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels));
}
} }
for (let statChangePhase of statChangePhases) { for (const statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData) if (!this.selfTarget && !statChangePhase.getPokemon().summonData) {
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time pokemon.scene.pushPhase(statChangePhase);
else } else { // TODO: This causes the ability bar to be shown at the wrong time
pokemon.scene.unshiftPhase(statChangePhase); pokemon.scene.unshiftPhase(statChangePhase);
}
} }
return true; return true;
@ -257,7 +258,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
return pokemon.addTag(BattlerTagType.STURDY, 1); return pokemon.addTag(BattlerTagType.STURDY, 1);
} }
return false return false;
} }
} }
@ -392,8 +393,9 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true;
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
if (!simulated) if (!simulated) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
}
} }
return ret; return ret;
@ -417,8 +419,9 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
if (ret) { if (ret) {
cancelled.value = true; cancelled.value = true;
const simulated = args.length > 1 && args[1]; const simulated = args.length > 1 && args[1];
if (!simulated) if (!simulated) {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id); pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
}
} }
return ret; return ret;
@ -454,14 +457,15 @@ export class PostDefendAbAttr extends AbAttr {
export class PostDefendDisguiseAbAttr extends PostDefendAbAttr { export class PostDefendDisguiseAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon.formIndex == 0 && pokemon.battleData.hitCount != 0 && (move.getMove().category == MoveCategory.SPECIAL || move.getMove().category == MoveCategory.PHYSICAL)) { if (pokemon.formIndex === 0 && pokemon.battleData.hitCount !== 0 && (move.getMove().category === MoveCategory.SPECIAL || move.getMove().category === MoveCategory.PHYSICAL)) {
const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt); const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt);
if (!recoilDamage) if (!recoilDamage) {
return false; return false;
}
pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER); pokemon.damageAndUpdate(recoilDamage, HitResult.OTHER);
pokemon.turnData.damageTaken += recoilDamage; pokemon.turnData.damageTaken += recoilDamage;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s disguise was busted!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s disguise was busted!"));
return true; return true;
} }
@ -491,18 +495,18 @@ export class PostDefendFormChangeAbAttr extends PostDefendAbAttr {
export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr { export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr {
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const attackPriority = new Utils.IntegerHolder(move.getMove().priority); const attackPriority = new Utils.IntegerHolder(move.getMove().priority);
applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority); applyMoveAttrs(IncrementMovePriorityAttr,attacker,null,move.getMove(),attackPriority);
applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority); applyAbAttrs(IncrementMovePriorityAbAttr, attacker, null, move.getMove(), attackPriority);
if(move.getMove().moveTarget===MoveTarget.USER) { if(move.getMove().moveTarget===MoveTarget.USER) {
return false; return false;
} }
if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) { if(attackPriority.value > 0 && !move.getMove().isMultiTarget()) {
cancelled.value = true; cancelled.value = true;
return true; return true;
} }
return false; return false;
} }
@ -548,7 +552,7 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
} }
applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args) const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args);
if (ret) { if (ret) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
@ -560,7 +564,7 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr {
export class ReverseDrainAbAttr extends PostDefendAbAttr { export class ReverseDrainAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!!move.getMove().getAttrs(HitHealAttr).length || !!move.getMove().getAttrs(StrengthSapHealAttr).length ) { if (!!move.getMove().getAttrs(HitHealAttr).length || !!move.getMove().getAttrs(StrengthSapHealAttr).length ) {
pokemon.scene.queueMessage(getPokemonMessage(attacker, ` sucked up the liquid ooze!`)); pokemon.scene.queueMessage(getPokemonMessage(attacker, " sucked up the liquid ooze!"));
return true; return true;
} }
return false; return false;
@ -587,8 +591,8 @@ export class PostDefendStatChangeAbAttr extends PostDefendAbAttr {
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (this.condition(pokemon, attacker, move.getMove())) { if (this.condition(pokemon, attacker, move.getMove())) {
if (this.allOthers) { if (this.allOthers) {
let otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents(); const otherPokemon = pokemon.getAlly() ? pokemon.getOpponents().concat([ pokemon.getAlly() ]) : pokemon.getOpponents();
for (let other of otherPokemon) { for (const other of otherPokemon) {
other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels)); other.scene.unshiftPhase(new StatChangePhase(other.scene, (other).getBattlerIndex(), false, [ this.stat ], this.levels));
} }
return true; return true;
@ -619,8 +623,8 @@ export class PostDefendHpGatedStatChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate) const hpGateFlat: integer = Math.ceil(pokemon.getMaxHp() * this.hpGate);
const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1] const lastAttackReceived = pokemon.turnData.attacksReceived[pokemon.turnData.attacksReceived.length - 1];
if (this.condition(pokemon, attacker, move.getMove()) && (pokemon.hp <= hpGateFlat && (pokemon.hp + lastAttackReceived.damage) > hpGateFlat)) { if (this.condition(pokemon, attacker, move.getMove()) && (pokemon.hp <= hpGateFlat && (pokemon.hp + lastAttackReceived.damage) > hpGateFlat)) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, (this.selfTarget ? pokemon : attacker).getBattlerIndex(), true, this.stats, this.levels));
return true; return true;
@ -701,8 +705,9 @@ export class PostDefendTerrainChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (hitResult < HitResult.NO_EFFECT) if (hitResult < HitResult.NO_EFFECT) {
return pokemon.scene.arena.trySetTerrain(this.terrainType, true); return pokemon.scene.arena.trySetTerrain(this.terrainType, true);
}
return false; return false;
} }
@ -756,8 +761,9 @@ export class PostDefendContactApplyTagChanceAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && pokemon.randSeedInt(100) < this.chance) {
return attacker.addTag(this.tagType, this.turnCount, move.moveId, attacker.id); return attacker.addTag(this.tagType, this.turnCount, move.moveId, attacker.id);
}
return false; return false;
} }
@ -819,8 +825,9 @@ export class PostDefendWeatherChangeAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -843,7 +850,7 @@ export class PostDefendAbilitySwapAbAttr extends PostDefendAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, ` swapped\nabilities with its target!`); return getPokemonMessage(pokemon, " swapped\nabilities with its target!");
} }
} }
@ -957,7 +964,7 @@ export class MoveTypeChangePowerMultiplierAbAttr extends VariableMoveTypeAbAttr
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const type = (args[0] as Utils.IntegerHolder); const type = (args[0] as Utils.IntegerHolder);
if (type.value == this.matchType) { if (type.value === this.matchType) {
type.value = this.newType; type.value = this.newType;
(args[1] as Utils.NumberHolder).value *= this.powerMultiplier; (args[1] as Utils.NumberHolder).value *= this.powerMultiplier;
return true; return true;
@ -1027,10 +1034,10 @@ export class DamageBoostAbAttr extends PreAttackAbAttr {
if (this.condition(pokemon, defender, move.getMove())) { if (this.condition(pokemon, defender, move.getMove())) {
const power = args[0] as Utils.NumberHolder; const power = args[0] as Utils.NumberHolder;
power.value = Math.floor(power.value * this.damageMultiplier); power.value = Math.floor(power.value * this.damageMultiplier);
return true; return true;
} }
return false; return false;
} }
} }
@ -1119,7 +1126,7 @@ export class BattleStatMultiplierAbAttr extends AbAttr {
} }
applyBattleStat(pokemon: Pokemon, passive: boolean, battleStat: BattleStat, statValue: Utils.NumberHolder, args: any[]): boolean | Promise<boolean> { applyBattleStat(pokemon: Pokemon, passive: boolean, battleStat: BattleStat, statValue: Utils.NumberHolder, args: any[]): boolean | Promise<boolean> {
const move = (args[0] as Move); const move = (args[0] as Move);
if (battleStat === this.battleStat && (!this.condition || this.condition(pokemon, null, move))) { if (battleStat === this.battleStat && (!this.condition || this.condition(pokemon, null, move))) {
statValue.value *= this.multiplier; statValue.value *= this.multiplier;
return true; return true;
@ -1151,8 +1158,9 @@ export class PostAttackStealHeldItemAbAttr extends PostAttackAbAttr {
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
if (success) if (success) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${defender.name}'s ${stolenItem.type.name}!`));
}
resolve(success); resolve(success);
}); });
return; return;
@ -1182,7 +1190,7 @@ export class PostAttackApplyStatusEffectAbAttr extends PostAttackAbAttr {
} }
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon != attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) { if (pokemon !== attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
return attacker.trySetStatus(effect, true, pokemon); return attacker.trySetStatus(effect, true, pokemon);
} }
@ -1212,7 +1220,7 @@ export class PostAttackApplyBattlerTagAbAttr extends PostAttackAbAttr {
} }
applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostAttack(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (pokemon != attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) { if (pokemon !== attacker && (!this.contactRequired || move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) && pokemon.randSeedInt(100) < this.chance(attacker, pokemon, move) && !pokemon.status) {
const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)]; const effect = this.effects.length === 1 ? this.effects[0] : this.effects[pokemon.randSeedInt(this.effects.length)];
@ -1239,8 +1247,9 @@ export class PostDefendStealHeldItemAbAttr extends PostDefendAbAttr {
if (heldItems.length) { if (heldItems.length) {
const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)]; const stolenItem = heldItems[pokemon.randSeedInt(heldItems.length)];
pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => { pokemon.scene.tryTransferHeldItemModifier(stolenItem, pokemon, false, false).then(success => {
if (success) if (success) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` stole\n${attacker.name}'s ${stolenItem.type.name}!`));
}
resolve(success); resolve(success);
}); });
return; return;
@ -1274,7 +1283,7 @@ class PostVictoryStatChangeAbAttr extends PostVictoryAbAttr {
} }
applyPostVictory(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> { applyPostVictory(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
const stat = typeof this.stat === 'function' const stat = typeof this.stat === "function"
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
@ -1321,7 +1330,7 @@ export class PostKnockOutStatChangeAbAttr extends PostKnockOutAbAttr {
} }
applyPostKnockOut(pokemon: Pokemon, passive: boolean, knockedOut: Pokemon, args: any[]): boolean | Promise<boolean> { applyPostKnockOut(pokemon: Pokemon, passive: boolean, knockedOut: Pokemon, args: any[]): boolean | Promise<boolean> {
const stat = typeof this.stat === 'function' const stat = typeof this.stat === "function"
? this.stat(pokemon) ? this.stat(pokemon)
: this.stat; : this.stat;
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], this.levels));
@ -1401,10 +1410,10 @@ export class PostIntimidateStatChangeAbAttr extends AbAttr {
private overwrites: boolean; private overwrites: boolean;
constructor(stats: BattleStat[], levels: integer, overwrites?: boolean) { constructor(stats: BattleStat[], levels: integer, overwrites?: boolean) {
super(true) super(true);
this.stats = stats this.stats = stats;
this.levels = levels this.levels = levels;
this.overwrites = !!overwrites this.overwrites = !!overwrites;
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
@ -1478,7 +1487,7 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean, intimidate?: boolean) { constructor(stats: BattleStat | BattleStat[], levels: integer, selfTarget?: boolean, intimidate?: boolean) {
super(false); super(false);
this.stats = typeof(stats) === 'number' this.stats = typeof(stats) === "number"
? [ stats as BattleStat ] ? [ stats as BattleStat ]
: stats as BattleStat[]; : stats as BattleStat[];
this.levels = levels; this.levels = levels;
@ -1492,8 +1501,8 @@ export class PostSummonStatChangeAbAttr extends PostSummonAbAttr {
pokemon.scene.pushPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels)); pokemon.scene.pushPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
return true; return true;
} }
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
const cancelled = new Utils.BooleanHolder(false) const cancelled = new Utils.BooleanHolder(false);
if (this.intimidate) { if (this.intimidate) {
applyAbAttrs(IntimidateImmunityAbAttr, opponent, cancelled); applyAbAttrs(IntimidateImmunityAbAttr, opponent, cancelled);
applyAbAttrs(PostIntimidateStatChangeAbAttr, opponent, cancelled); applyAbAttrs(PostIntimidateStatChangeAbAttr, opponent, cancelled);
@ -1546,10 +1555,11 @@ export class PostSummonClearAllyStatsAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const target = pokemon.getAlly(); const target = pokemon.getAlly();
if (target?.isActive(true)) { if (target?.isActive(true)) {
for (let s = 0; s < target.summonData.battleStats.length; s++) for (let s = 0; s < target.summonData.battleStats.length; s++) {
target.summonData.battleStats[s] = 0; target.summonData.battleStats[s] = 0;
}
target.scene.queueMessage(getPokemonMessage(target, `'s stat changes\nwere removed!`)); target.scene.queueMessage(getPokemonMessage(target, "'s stat changes\nwere removed!"));
return true; return true;
} }
@ -1567,15 +1577,16 @@ export class DownloadAbAttr extends PostSummonAbAttr {
this.enemyDef = 0; this.enemyDef = 0;
this.enemySpDef = 0; this.enemySpDef = 0;
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
this.enemyDef += opponent.stats[BattleStat.DEF]; this.enemyDef += opponent.stats[BattleStat.DEF];
this.enemySpDef += opponent.stats[BattleStat.SPDEF]; this.enemySpDef += opponent.stats[BattleStat.SPDEF];
} }
if (this.enemyDef < this.enemySpDef) if (this.enemyDef < this.enemySpDef) {
this.stats = [BattleStat.ATK]; this.stats = [BattleStat.ATK];
else } else {
this.stats = [BattleStat.SPATK]; this.stats = [BattleStat.SPATK];
}
if (this.enemyDef > 0 && this.enemySpDef > 0) { // only activate if there's actually an enemy to download from if (this.enemyDef > 0 && this.enemySpDef > 0) { // only activate if there's actually an enemy to download from
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, this.stats, 1));
@ -1596,8 +1607,9 @@ export class PostSummonWeatherChangeAbAttr extends PostSummonAbAttr {
} }
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -1628,8 +1640,9 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const formIndex = this.formFunc(pokemon); const formIndex = this.formFunc(pokemon);
if (formIndex !== pokemon.formIndex) if (formIndex !== pokemon.formIndex) {
return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); return pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
}
return false; return false;
} }
@ -1638,18 +1651,21 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
export class TraceAbAttr extends PostSummonAbAttr { export class TraceAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents(); const targets = pokemon.getOpponents();
if (!targets.length) if (!targets.length) {
return false; return false;
}
let target: Pokemon; let target: Pokemon;
if (targets.length > 1) if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else } else {
target = targets[0]; target = targets[0];
}
// Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it // Wonder Guard is normally uncopiable so has the attribute, but trace specifically can copy it
if (target.getAbility().hasAttr(UncopiableAbilityAbAttr) && target.getAbility().id !== Abilities.WONDER_GUARD) if (target.getAbility().hasAttr(UncopiableAbilityAbAttr) && target.getAbility().id !== Abilities.WONDER_GUARD) {
return false; return false;
}
pokemon.summonData.ability = target.getAbility().id; pokemon.summonData.ability = target.getAbility().id;
@ -1666,14 +1682,16 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const targets = pokemon.getOpponents(); const targets = pokemon.getOpponents();
if (!targets.length) if (!targets.length) {
return false; return false;
}
let target: Pokemon; let target: Pokemon;
if (targets.length > 1) if (targets.length > 1) {
pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex); pokemon.scene.executeWithSeedOffset(() => target = Utils.randSeedItem(targets), pokemon.scene.currentBattle.waveIndex);
else } else {
target = targets[0]; target = targets[0];
}
pokemon.summonData.speciesForm = target.getSpeciesForm(); pokemon.summonData.speciesForm = target.getSpeciesForm();
pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm(); pokemon.summonData.fusionSpeciesForm = target.getFusionSpeciesForm();
@ -1685,7 +1703,7 @@ export class PostSummonTransformAbAttr extends PostSummonAbAttr {
pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp)); pokemon.summonData.moveset = target.getMoveset().map(m => new PokemonMove(m.moveId, m.ppUsed, m.ppUp));
pokemon.summonData.types = target.getTypes(); pokemon.summonData.types = target.getTypes();
pokemon.scene.playSound('PRSFX- Transform'); pokemon.scene.playSound("PRSFX- Transform");
pokemon.loadAssets(false).then(() => pokemon.playAnim()); pokemon.loadAssets(false).then(() => pokemon.playAnim());
@ -1755,7 +1773,7 @@ export class ProtectStatAbAttr extends PreStatChangeAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents lowering its ${this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : 'stats'}!`); return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents lowering its ${this.protectedStat !== undefined ? getBattleStatName(this.protectedStat) : "stats"}!`);
} }
} }
@ -1784,7 +1802,7 @@ export class StatusEffectImmunityAbAttr extends PreSetStatusAbAttr {
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string { getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents ${this.immuneEffects.length ? getStatusEffectDescriptor(args[0] as StatusEffect) : 'status problems'}!`); return getPokemonMessage(pokemon, `'s ${abilityName}\nprevents ${this.immuneEffects.length ? getStatusEffectDescriptor(args[0] as StatusEffect) : "status problems"}!`);
} }
} }
@ -1874,8 +1892,9 @@ export class ConditionalCritAbAttr extends AbAttr {
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
const target = (args[1] as Pokemon); const target = (args[1] as Pokemon);
const move = (args[2] as Move); const move = (args[2] as Move);
if(!this.condition(pokemon,target,move)) if(!this.condition(pokemon,target,move)) {
return false; return false;
}
(args[0] as Utils.BooleanHolder).value = true; (args[0] as Utils.BooleanHolder).value = true;
return true; return true;
@ -1908,8 +1927,9 @@ export class IncrementMovePriorityAbAttr extends AbAttr {
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.moveIncrementFunc(pokemon, args[0] as Move)) if (!this.moveIncrementFunc(pokemon, args[0] as Move)) {
return false; return false;
}
(args[1] as Utils.IntegerHolder).value += this.increaseAmount; (args[1] as Utils.IntegerHolder).value += this.increaseAmount;
return true; return true;
@ -1936,8 +1956,9 @@ export class BlockWeatherDamageAttr extends PreWeatherDamageAbAttr {
} }
applyPreWeatherEffect(pokemon: Pokemon, passive: boolean, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreWeatherEffect(pokemon: Pokemon, passive: boolean, weather: Weather, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!this.weatherTypes.length || this.weatherTypes.indexOf(weather?.weatherType) > -1) if (!this.weatherTypes.length || this.weatherTypes.indexOf(weather?.weatherType) > -1) {
cancelled.value = true; cancelled.value = true;
}
return true; return true;
} }
@ -1964,8 +1985,9 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition { function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) if (pokemon.scene.arena.weather?.isEffectSuppressed(pokemon.scene)) {
return false; return false;
}
const weatherType = pokemon.scene.arena.weather?.weatherType; const weatherType = pokemon.scene.arena.weather?.weatherType;
return weatherType && weatherTypes.indexOf(weatherType) > -1; return weatherType && weatherTypes.indexOf(weatherType) > -1;
}; };
@ -1973,36 +1995,36 @@ function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
function getAnticipationCondition(): AbAttrCondition { function getAnticipationCondition(): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) { for (const move of opponent.moveset) {
// move is super effective // move is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) { if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) {
return true; return true;
} }
// move is a OHKO // move is a OHKO
if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) { if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) {
return true; return true;
} }
// edge case for hidden power, type is computed // edge case for hidden power, type is computed
if (move.getMove().id === Moves.HIDDEN_POWER) { if (move.getMove().id === Moves.HIDDEN_POWER) {
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1) const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
+(opponent.ivs[Stat.ATK] & 1) * 2 +(opponent.ivs[Stat.ATK] & 1) * 2
+(opponent.ivs[Stat.DEF] & 1) * 4 +(opponent.ivs[Stat.DEF] & 1) * 4
+(opponent.ivs[Stat.SPD] & 1) * 8 +(opponent.ivs[Stat.SPD] & 1) * 8
+(opponent.ivs[Stat.SPATK] & 1) * 16 +(opponent.ivs[Stat.SPATK] & 1) * 16
+(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63); +(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
const type = [ const type = [
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND, Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL, Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC, Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val]; Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val];
if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) { if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) {
return true; return true;
}
} }
} }
}
} }
return false; return false;
}; };
@ -2018,7 +2040,7 @@ function getAnticipationCondition(): AbAttrCondition {
function getOncePerBattleCondition(ability: Abilities): AbAttrCondition { function getOncePerBattleCondition(ability: Abilities): AbAttrCondition {
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
return !pokemon.battleData?.abilitiesApplied.includes(ability); return !pokemon.battleData?.abilitiesApplied.includes(ability);
} };
} }
export class ForewarnAbAttr extends PostSummonAbAttr { export class ForewarnAbAttr extends PostSummonAbAttr {
@ -2030,8 +2052,8 @@ export class ForewarnAbAttr extends PostSummonAbAttr {
let maxPowerSeen = 0; let maxPowerSeen = 0;
let maxMove = ""; let maxMove = "";
let movePower = 0; let movePower = 0;
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) { for (const move of opponent.moveset) {
if (move.getMove() instanceof StatusMove) { if (move.getMove() instanceof StatusMove) {
movePower = 1; movePower = 1;
} else if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) { } else if (move.getMove().findAttr(attr => attr instanceof OneHitKOAttr)) {
@ -2061,8 +2083,8 @@ export class FriskAbAttr extends PostSummonAbAttr {
} }
applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
for (let opponent of pokemon.getOpponents()) { for (const opponent of pokemon.getOpponents()) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "\'s " + opponent.getAbility().name + "!")); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "'s " + opponent.getAbility().name + "!"));
} }
return true; return true;
} }
@ -2089,8 +2111,9 @@ export class PostWeatherChangeAddBattlerTagAttr extends PostWeatherChangeAbAttr
applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean { applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean {
console.log(this.weatherTypes.find(w => weather === w), WeatherType[weather]); console.log(this.weatherTypes.find(w => weather === w), WeatherType[weather]);
if (!this.weatherTypes.find(w => weather === w)) if (!this.weatherTypes.find(w => weather === w)) {
return false; return false;
}
return pokemon.addTag(this.tagType, this.turnCount); return pokemon.addTag(this.tagType, this.turnCount);
} }
@ -2178,8 +2201,9 @@ export class PostTerrainChangeAddBattlerTagAttr extends PostTerrainChangeAbAttr
} }
applyPostTerrainChange(pokemon: Pokemon, passive: boolean, terrain: TerrainType, args: any[]): boolean { applyPostTerrainChange(pokemon: Pokemon, passive: boolean, terrain: TerrainType, args: any[]): boolean {
if (!this.terrainTypes.find(t => t === terrain)) if (!this.terrainTypes.find(t => t === terrain)) {
return false; return false;
}
return pokemon.addTag(this.tagType, this.turnCount); return pokemon.addTag(this.tagType, this.turnCount);
} }
@ -2273,9 +2297,9 @@ export class PostTurnLootAbAttr extends PostTurnAbAttr {
} }
const randomIdx = Utils.randSeedInt(berriesEaten.length); const randomIdx = Utils.randSeedInt(berriesEaten.length);
const chosenBerryType = berriesEaten[randomIdx] const chosenBerryType = berriesEaten[randomIdx];
const chosenBerry = new BerryModifierType(chosenBerryType); const chosenBerry = new BerryModifierType(chosenBerryType);
berriesEaten.splice(randomIdx) // Remove berry from memory berriesEaten.splice(randomIdx); // Remove berry from memory
const berryModifier = pokemon.scene.findModifier( const berryModifier = pokemon.scene.findModifier(
(m) => m instanceof BerryModifier && m.berryType === chosenBerryType, (m) => m instanceof BerryModifier && m.berryType === chosenBerryType,
@ -2301,17 +2325,17 @@ export class MoodyAbAttr extends PostTurnAbAttr {
} }
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD]; const selectableStats = [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD];
let increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6); const increaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] < 6);
let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6); let decreaseStatArray = selectableStats.filter(s => pokemon.summonData.battleStats[s] > -6);
if (increaseStatArray.length > 0) { if (increaseStatArray.length > 0) {
let increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)]; const increaseStat = increaseStatArray[Utils.randInt(increaseStatArray.length)];
decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat); decreaseStatArray = decreaseStatArray.filter(s => s !== increaseStat);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [increaseStat], 2));
} }
if (decreaseStatArray.length > 0) { if (decreaseStatArray.length > 0) {
let decreaseStat = selectableStats[Utils.randInt(selectableStats.length)]; const decreaseStat = selectableStats[Utils.randInt(selectableStats.length)];
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1)); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [decreaseStat], -1));
} }
return true; return true;
@ -2386,10 +2410,10 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
*/ */
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean | Promise<boolean> {
let hadEffect: boolean = false; let hadEffect: boolean = false;
for(let opp of pokemon.getOpponents()) { for(const opp of pokemon.getOpponents()) {
if(opp.status !== undefined && opp.status.effect === StatusEffect.SLEEP) { if(opp.status !== undefined && opp.status.effect === StatusEffect.SLEEP) {
opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER); opp.damageAndUpdate(Math.floor(Math.max(1, opp.getMaxHp() / 8)), HitResult.OTHER);
pokemon.scene.queueMessage(i18next.t('abilityTriggers:badDreams', {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`})); pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: `${getPokemonPrefix(opp)}${opp.name}`}));
hadEffect = true; hadEffect = true;
} }
@ -2415,8 +2439,8 @@ export class FetchBallAbAttr extends PostTurnAbAttr {
* @returns true if player has used a pokeball and this pokemon is owned by the player * @returns true if player has used a pokeball and this pokemon is owned by the player
*/ */
applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean { applyPostTurn(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
let lastUsed = pokemon.scene.currentBattle.lastUsedPokeball; const lastUsed = pokemon.scene.currentBattle.lastUsedPokeball;
if(lastUsed != null && pokemon.isPlayer) { if(lastUsed !== null && pokemon.isPlayer) {
pokemon.scene.pokeballCounts[lastUsed]++; pokemon.scene.pokeballCounts[lastUsed]++;
pokemon.scene.currentBattle.lastUsedPokeball = null; pokemon.scene.currentBattle.lastUsedPokeball = null;
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` found a\n${getPokeballName(lastUsed)}!`));
@ -2438,8 +2462,9 @@ export class PostBiomeChangeWeatherChangeAbAttr extends PostBiomeChangeAbAttr {
} }
apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean { apply(pokemon: Pokemon, passive: boolean, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (!pokemon.scene.arena.weather?.isImmutable()) if (!pokemon.scene.arena.weather?.isImmutable()) {
return pokemon.scene.arena.trySetWeather(this.weatherType, true); return pokemon.scene.arena.trySetWeather(this.weatherType, true);
}
return false; return false;
} }
@ -2615,7 +2640,7 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { applyPostFaint(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean {
if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) { if (move.getMove().checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon)) {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled)) pokemon.scene.getField(true).map(p=>applyAbAttrs(FieldPreventExplosiveMovesAbAttr, p, cancelled));
if (cancelled) { if (cancelled) {
return false; return false;
} }
@ -2897,10 +2922,11 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> { pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => { return new Promise(resolve => {
if (!pokemon.canApplyAbility(passive)) { if (!pokemon.canApplyAbility(passive)) {
if (!passive) if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else } else {
return resolve(); return resolve();
}
} }
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()); const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility());
@ -2908,51 +2934,58 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any
const clearSpliceQueueAndResolve = () => { const clearSpliceQueueAndResolve = () => {
pokemon.scene.clearPhaseQueueSplice(); pokemon.scene.clearPhaseQueueSplice();
if (!passive) if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve()); return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else } else {
return resolve(); return resolve();
}
}; };
const applyNextAbAttr = () => { const applyNextAbAttr = () => {
if (attrs.length) if (attrs.length) {
applyAbAttr(attrs.shift()); applyAbAttr(attrs.shift());
else } else {
clearSpliceQueueAndResolve(); clearSpliceQueueAndResolve();
}
}; };
const applyAbAttr = (attr: TAttr) => { const applyAbAttr = (attr: TAttr) => {
if (!canApplyAttr(pokemon, attr)) if (!canApplyAttr(pokemon, attr)) {
return applyNextAbAttr(); return applyNextAbAttr();
}
pokemon.scene.setPhaseQueueSplice(); pokemon.scene.setPhaseQueueSplice();
const onApplySuccess = () => { const onApplySuccess = () => {
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) { if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id); pokemon.battleData.abilitiesApplied.push(ability.id);
} }
if (attr.showAbility && !quiet) { if (attr.showAbility && !quiet) {
if (showAbilityInstant) if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive); pokemon.scene.abilityBar.showAbility(pokemon, passive);
else } else {
queueShowAbility(pokemon, passive); queueShowAbility(pokemon, passive);
}
} }
if (!quiet) { if (!quiet) {
const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args); const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args);
if (message) { if (message) {
if (isAsync) if (isAsync) {
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true); pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
else } else {
pokemon.scene.queueMessage(message); pokemon.scene.queueMessage(message);
}
} }
} }
}; };
const result = applyFunc(attr, passive); const result = applyFunc(attr, passive);
if (result instanceof Promise) { if (result instanceof Promise) {
result.then(success => { result.then(success => {
if (success) if (success) {
onApplySuccess(); onApplySuccess();
}
applyNextAbAttr(); applyNextAbAttr();
}); });
} else { } else {
if (result) if (result) {
onApplySuccess(); onApplySuccess();
}
applyNextAbAttr(); applyNextAbAttr();
} }
}; };
@ -3227,7 +3260,7 @@ export function initAbilities() {
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM), .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SANDSTORM),
new Ability(Abilities.PRESSURE, 3) new Ability(Abilities.PRESSURE, 3)
.attr(IncreasePpAbAttr) .attr(IncreasePpAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is exerting its Pressure!')), .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is exerting its Pressure!")),
new Ability(Abilities.THICK_FAT, 3) new Ability(Abilities.THICK_FAT, 3)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.FIRE, 0.5)
.attr(ReceivedTypeDamageMultiplierAbAttr, Type.ICE, 0.5) .attr(ReceivedTypeDamageMultiplierAbAttr, Type.ICE, 0.5)
@ -3250,8 +3283,8 @@ export function initAbilities() {
new Ability(Abilities.TRUANT, 3) new Ability(Abilities.TRUANT, 3)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false), .attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.TRUANT, 1, false),
new Ability(Abilities.HUSTLE, 3) new Ability(Abilities.HUSTLE, 3)
.attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5, (user, target, move) => move.category == MoveCategory.PHYSICAL) .attr(BattleStatMultiplierAbAttr, BattleStat.ATK, 1.5, (user, target, move) => move.category === MoveCategory.PHYSICAL)
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8, (user, target, move) => move.category == MoveCategory.PHYSICAL), .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 0.8, (user, target, move) => move.category === MoveCategory.PHYSICAL),
new Ability(Abilities.CUTE_CHARM, 3) new Ability(Abilities.CUTE_CHARM, 3)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED), .attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3) new Ability(Abilities.PLUS, 3)
@ -3377,7 +3410,7 @@ export function initAbilities() {
.attr(MovePowerBoostAbAttr, (user, target, move) => { .attr(MovePowerBoostAbAttr, (user, target, move) => {
const power = new Utils.NumberHolder(move.power); const power = new Utils.NumberHolder(move.power);
applyMoveAttrs(VariablePowerAttr, user, target, move, power); applyMoveAttrs(VariablePowerAttr, user, target, move, power);
return power.value <= 60 return power.value <= 60;
}, 1.5), }, 1.5),
new Ability(Abilities.LEAF_GUARD, 4) new Ability(Abilities.LEAF_GUARD, 4)
.attr(StatusEffectImmunityAbAttr) .attr(StatusEffectImmunityAbAttr)
@ -3386,7 +3419,7 @@ export function initAbilities() {
new Ability(Abilities.KLUTZ, 4) new Ability(Abilities.KLUTZ, 4)
.unimplemented(), .unimplemented(),
new Ability(Abilities.MOLD_BREAKER, 4) new Ability(Abilities.MOLD_BREAKER, 4)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' breaks the mold!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " breaks the mold!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.SUPER_LUCK, 4) new Ability(Abilities.SUPER_LUCK, 4)
.attr(BonusCritAbAttr) .attr(BonusCritAbAttr)
@ -3395,7 +3428,7 @@ export function initAbilities() {
.attr(PostFaintContactDamageAbAttr,4) .attr(PostFaintContactDamageAbAttr,4)
.bypassFaint(), .bypassFaint(),
new Ability(Abilities.ANTICIPATION, 4) new Ability(Abilities.ANTICIPATION, 4)
.conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' shuddered!')), .conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " shuddered!")),
new Ability(Abilities.FOREWARN, 4) new Ability(Abilities.FOREWARN, 4)
.attr(ForewarnAbAttr), .attr(ForewarnAbAttr),
new Ability(Abilities.UNAWARE, 4) new Ability(Abilities.UNAWARE, 4)
@ -3504,7 +3537,7 @@ export function initAbilities() {
new Ability(Abilities.POISON_TOUCH, 5) new Ability(Abilities.POISON_TOUCH, 5)
.attr(PostAttackContactApplyStatusEffectAbAttr, 30, StatusEffect.POISON), .attr(PostAttackContactApplyStatusEffectAbAttr, 30, StatusEffect.POISON),
new Ability(Abilities.REGENERATOR, 5) new Ability(Abilities.REGENERATOR, 5)
.attr(PreSwitchOutHealAbAttr), .attr(PreSwitchOutHealAbAttr),
new Ability(Abilities.BIG_PECKS, 5) new Ability(Abilities.BIG_PECKS, 5)
.attr(ProtectStatAbAttr, BattleStat.DEF) .attr(ProtectStatAbAttr, BattleStat.DEF)
.ignorable(), .ignorable(),
@ -3566,10 +3599,10 @@ export function initAbilities() {
.attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 1.1) .attr(BattleStatMultiplierAbAttr, BattleStat.ACC, 1.1)
.partial(), .partial(),
new Ability(Abilities.TURBOBLAZE, 5) new Ability(Abilities.TURBOBLAZE, 5)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a blazing aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a blazing aura!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.TERAVOLT, 5) new Ability(Abilities.TERAVOLT, 5)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a bursting aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a bursting aura!"))
.attr(MoveAbilityBypassAbAttr), .attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.AROMA_VEIL, 6) new Ability(Abilities.AROMA_VEIL, 6)
.ignorable() .ignorable()
@ -3625,10 +3658,10 @@ export function initAbilities() {
new Ability(Abilities.PARENTAL_BOND, 6) new Ability(Abilities.PARENTAL_BOND, 6)
.unimplemented(), .unimplemented(),
new Ability(Abilities.DARK_AURA, 6) new Ability(Abilities.DARK_AURA, 6)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Dark Aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a Dark Aura!"))
.attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3), .attr(FieldMoveTypePowerBoostAbAttr, Type.DARK, 4 / 3),
new Ability(Abilities.FAIRY_AURA, 6) new Ability(Abilities.FAIRY_AURA, 6)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' is radiating a Fairy Aura!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, " is radiating a Fairy Aura!"))
.attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3), .attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3),
new Ability(Abilities.AURA_BREAK, 6) new Ability(Abilities.AURA_BREAK, 6)
.ignorable() .ignorable()
@ -3694,7 +3727,7 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr), .attr(NoFusionAbilityAbAttr),
new Ability(Abilities.DISGUISE, 7) new Ability(Abilities.DISGUISE, 7)
.attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type, user) > 0) .attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex === 0 && target.getAttackTypeEffectiveness(move.type, user) > 0)
.attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
.attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
.attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1)
@ -3714,9 +3747,9 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr), .attr(NoFusionAbilityAbAttr),
new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly new Ability(Abilities.POWER_CONSTRUCT, 7) // TODO: 10% Power Construct Zygarde isn't accounted for yet. If changed, update Zygarde's getSpeciesFormIndex entry accordingly
.attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostBattleInitFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostSummonFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === 'complete' ? 4 : 2) .attr(PostTurnFormChangeAbAttr, p => p.getHpRatio() <= 0.5 || p.getFormKey() === "complete" ? 4 : 2)
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
@ -3865,7 +3898,7 @@ export function initAbilities() {
.attr(UncopiableAbilityAbAttr) .attr(UncopiableAbilityAbAttr)
.attr(UnswappableAbilityAbAttr) .attr(UnswappableAbilityAbAttr)
.attr(NoTransformAbilityAbAttr) .attr(NoTransformAbilityAbAttr)
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, '\'s Neutralizing Gas filled the area!')) .attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, "'s Neutralizing Gas filled the area!"))
.partial(), .partial(),
new Ability(Abilities.PASTEL_VEIL, 8) new Ability(Abilities.PASTEL_VEIL, 8)
.attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC) .attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -56,7 +56,7 @@ export class BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return ''; return "";
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -97,13 +97,13 @@ export class RechargingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] }) pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] });
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' must\nrecharge!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " must\nrecharge!"));
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.getMoveQueue().shift(); pokemon.getMoveQueue().shift();
@ -136,7 +136,7 @@ export class TrappedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'trapping'; return "trapping";
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -144,7 +144,7 @@ export class TrappedTag extends BattlerTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' can no\nlonger escape!'); return getPokemonMessage(pokemon, " can no\nlonger escape!");
} }
} }
@ -167,36 +167,36 @@ export class FlinchedTag extends BattlerTag {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' flinched!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " flinched!"));
return true; return true;
} }
getDescriptor(): string { getDescriptor(): string {
return 'flinching'; return "flinching";
} }
} }
export class InterruptedTag extends BattlerTag { export class InterruptedTag extends BattlerTag {
constructor(sourceMove: Moves){ constructor(sourceMove: Moves){
super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove) super(BattlerTagType.INTERRUPTED, BattlerTagLapseType.PRE_MOVE, 0, sourceMove);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
return !!pokemon.getTag(BattlerTagType.FLYING) return !!pokemon.getTag(BattlerTagType.FLYING);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.getMoveQueue().shift() pokemon.getMoveQueue().shift();
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER}) pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER});
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
super.lapse(pokemon, lapseType); super.lapse(pokemon, lapseType);
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
return true return true;
} }
} }
@ -213,33 +213,33 @@ export class ConfusedTag extends BattlerTag {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' became\nconfused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " became\nconfused!"));
} }
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' snapped\nout of confusion!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " snapped\nout of confusion!"));
} }
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready confused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready confused!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM && super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nconfused!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nconfused!"));
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CONFUSION));
if (pokemon.randSeedInt(3)) { if (pokemon.randSeedInt(3)) {
const atk = pokemon.getBattleStat(Stat.ATK); const atk = pokemon.getBattleStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF); const def = pokemon.getBattleStat(Stat.DEF);
const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); const damage = Math.ceil(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
pokemon.scene.queueMessage('It hurt itself in its\nconfusion!'); pokemon.scene.queueMessage("It hurt itself in its\nconfusion!");
pokemon.damageAndUpdate(damage); pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++; pokemon.battleData.hitCount++;
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
@ -250,7 +250,7 @@ export class ConfusedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'confusion'; return "confusion";
} }
} }
@ -272,7 +272,7 @@ export class InfatuatedTag extends BattlerTag {
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready in love!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready in love!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -283,7 +283,7 @@ export class InfatuatedTag extends BattlerTag {
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT)); pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.ATTRACT));
if (pokemon.randSeedInt(2)) { if (pokemon.randSeedInt(2)) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nimmobilized by love!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nimmobilized by love!"));
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
} }
} }
@ -294,7 +294,7 @@ export class InfatuatedTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' got over\nits infatuation.')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got over\nits infatuation."));
} }
isSourceLinked(): boolean { isSourceLinked(): boolean {
@ -302,7 +302,7 @@ export class InfatuatedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'infatuation'; return "infatuation";
} }
} }
@ -329,7 +329,7 @@ export class SeedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' was seeded!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " was seeded!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
@ -349,7 +349,7 @@ export class SeedTag extends BattlerTag {
const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr); const reverseDrain = pokemon.hasAbilityWithAttr(ReverseDrainAbAttr);
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, source.getBattlerIndex(),
!reverseDrain ? damage : damage * -1, !reverseDrain ? damage : damage * -1,
!reverseDrain ? getPokemonMessage(pokemon, '\'s health is\nsapped by Leech Seed!') : getPokemonMessage(source, '\'s Leech Seed\nsucked up the liquid ooze!'), !reverseDrain ? getPokemonMessage(pokemon, "'s health is\nsapped by Leech Seed!") : getPokemonMessage(source, "'s Leech Seed\nsucked up the liquid ooze!"),
false, true)); false, true));
} }
} }
@ -359,7 +359,7 @@ export class SeedTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'seeding'; return "seeding";
} }
} }
@ -371,34 +371,35 @@ export class NightmareTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' began\nhaving a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " began\nhaving a Nightmare!"));
} }
onOverlap(pokemon: Pokemon): void { onOverlap(pokemon: Pokemon): void {
super.onOverlap(pokemon); super.onOverlap(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nalready locked in a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nalready locked in a Nightmare!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) { if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is locked\nin a Nightmare!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is locked\nin a Nightmare!"));
pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type pokemon.scene.unshiftPhase(new CommonAnimPhase(pokemon.scene, pokemon.getBattlerIndex(), undefined, CommonAnim.CURSE)); // TODO: Update animation type
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 4)); pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 4));
}
} }
return ret; return ret;
} }
getDescriptor(): string { getDescriptor(): string {
return 'nightmares'; return "nightmares";
} }
} }
@ -437,31 +438,35 @@ export class EncoreTag extends BattlerTag {
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
if (pokemon.isMax()) if (pokemon.isMax()) {
return false; return false;
}
const lastMoves = pokemon.getLastXMoves(1); const lastMoves = pokemon.getLastXMoves(1);
if (!lastMoves.length) if (!lastMoves.length) {
return false; return false;
}
const repeatableMove = lastMoves[0]; const repeatableMove = lastMoves[0];
if (!repeatableMove.move || repeatableMove.virtual) if (!repeatableMove.move || repeatableMove.virtual) {
return false; return false;
switch (repeatableMove.move) {
case Moves.MIMIC:
case Moves.MIRROR_MOVE:
case Moves.TRANSFORM:
case Moves.STRUGGLE:
case Moves.SKETCH:
case Moves.SLEEP_TALK:
case Moves.ENCORE:
return false;
} }
if (allMoves[repeatableMove.move].getAttrs(ChargeAttr).length && repeatableMove.result === MoveResult.OTHER) switch (repeatableMove.move) {
case Moves.MIMIC:
case Moves.MIRROR_MOVE:
case Moves.TRANSFORM:
case Moves.STRUGGLE:
case Moves.SKETCH:
case Moves.SLEEP_TALK:
case Moves.ENCORE:
return false; return false;
}
if (allMoves[repeatableMove.move].getAttrs(ChargeAttr).length && repeatableMove.result === MoveResult.OTHER) {
return false;
}
this.moveId = repeatableMove.move; this.moveId = repeatableMove.move;
@ -471,7 +476,7 @@ export class EncoreTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' got\nan Encore!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " got\nan Encore!"));
const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon); const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
if (movePhase) { if (movePhase) {
@ -487,7 +492,7 @@ export class EncoreTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\'s Encore\nended!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "'s Encore\nended!"));
} }
} }
@ -524,19 +529,20 @@ export class IngrainTag extends TrappedTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), Math.floor(pokemon.getMaxHp() / 16), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), Math.floor(pokemon.getMaxHp() / 16),
getPokemonMessage(pokemon, ` absorbed\nnutrients with its roots!`), true)); getPokemonMessage(pokemon, " absorbed\nnutrients with its roots!"), true));
}
return ret; return ret;
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' planted its roots!'); return getPokemonMessage(pokemon, " planted its roots!");
} }
getDescriptor(): string { getDescriptor(): string {
return 'roots'; return "roots";
} }
} }
@ -548,15 +554,16 @@ export class AquaRingTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' surrounded\nitself with a veil of water!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " surrounded\nitself with a veil of water!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const ret = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true)); Math.floor(pokemon.getMaxHp() / 16), `${this.getMoveName()} restored\n${pokemon.name}\'s HP!`, true));
}
return ret; return ret;
} }
@ -579,7 +586,7 @@ export class MinimizeTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
//If a pokemon dynamaxes they lose minimized status //If a pokemon dynamaxes they lose minimized status
if(pokemon.isMax()){ if(pokemon.isMax()){
return false return false;
} }
return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); return lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
} }
@ -601,7 +608,7 @@ export class DrowsyTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' grew drowsy!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " grew drowsy!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -614,7 +621,7 @@ export class DrowsyTag extends BattlerTag {
} }
getDescriptor(): string { getDescriptor(): string {
return 'drowsiness'; return "drowsiness";
} }
} }
@ -650,8 +657,9 @@ export abstract class DamagingTrapTag extends TrappedTag {
const cancelled = new Utils.BooleanHolder(false); const cancelled = new Utils.BooleanHolder(false);
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled); applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
if (!cancelled.value) if (!cancelled.value) {
pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8)) pokemon.damageAndUpdate(Math.ceil(pokemon.getMaxHp() / 8));
}
} }
return ret; return ret;
@ -684,7 +692,7 @@ export abstract class VortexTrapTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ' was trapped\nin the vortex!'); return getPokemonMessage(pokemon, " was trapped\nin the vortex!");
} }
} }
@ -726,7 +734,7 @@ export class MagmaStormTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` became trapped\nby swirling magma!`); return getPokemonMessage(pokemon, " became trapped\nby swirling magma!");
} }
} }
@ -736,7 +744,7 @@ export class SnapTrapTag extends DamagingTrapTag {
} }
getTrapMessage(pokemon: Pokemon): string { getTrapMessage(pokemon: Pokemon): string {
return getPokemonMessage(pokemon, ` got trapped\nby a snap trap!`); return getPokemonMessage(pokemon, " got trapped\nby a snap trap!");
} }
} }
@ -769,13 +777,13 @@ export class ProtectedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene); new CommonBattleAnim(CommonAnim.PROTECT, pokemon).play(pokemon.scene);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, '\nprotected itself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, "\nprotected itself!"));
return true; return true;
} }
@ -900,12 +908,12 @@ export class EnduringTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' braced\nitself!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " braced\nitself!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true; return true;
} }
@ -920,7 +928,7 @@ export class SturdyTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.CUSTOM) { if (lapseType === BattlerTagLapseType.CUSTOM) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' endured\nthe hit!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " endured\nthe hit!"));
return true; return true;
} }
@ -940,10 +948,11 @@ export class PerishSongTag extends BattlerTag {
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
const ret = super.lapse(pokemon, lapseType); const ret = super.lapse(pokemon, lapseType);
if (ret) if (ret) {
pokemon.scene.queueMessage(getPokemonMessage(pokemon, `\'s perish count fell to ${this.turnCount}.`)); pokemon.scene.queueMessage(getPokemonMessage(pokemon, `\'s perish count fell to ${this.turnCount}.`));
else } else {
pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true); pokemon.damageAndUpdate(pokemon.hp, HitResult.ONE_HIT_KO, false, true, true);
}
return ret; return ret;
} }
@ -974,8 +983,9 @@ export class TruantTag extends AbilityBattlerTag {
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (!pokemon.hasAbility(Abilities.TRUANT)) if (!pokemon.hasAbility(Abilities.TRUANT)) {
return super.lapse(pokemon, lapseType); return super.lapse(pokemon, lapseType);
}
const passive = pokemon.getAbility().id !== Abilities.TRUANT; const passive = pokemon.getAbility().id !== Abilities.TRUANT;
const lastMove = pokemon.getLastXMoves().find(() => true); const lastMove = pokemon.getLastXMoves().find(() => true);
@ -983,7 +993,7 @@ export class TruantTag extends AbilityBattlerTag {
if (lastMove && lastMove.move !== Moves.NONE) { if (lastMove && lastMove.move !== Moves.NONE) {
(pokemon.scene.getCurrentPhase() as MovePhase).cancel(); (pokemon.scene.getCurrentPhase() as MovePhase).cancel();
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive)); pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.id, passive));
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is\nloafing around!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is\nloafing around!"));
} }
return true; return true;
@ -998,12 +1008,13 @@ export class SlowStartTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' can\'t\nget it going!'), null, false, null, true); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " can't\nget it going!"), null, false, null, true);
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (!pokemon.hasAbility(this.ability)) if (!pokemon.hasAbility(this.ability)) {
this.turnCount = 1; this.turnCount = 1;
}
return super.lapse(pokemon, lapseType); return super.lapse(pokemon, lapseType);
} }
@ -1011,7 +1022,7 @@ export class SlowStartTag extends AbilityBattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' finally\ngot its act together!'), null, false, null); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " finally\ngot its act together!"), null, false, null);
} }
} }
@ -1049,12 +1060,12 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
this.stat = highestStat; this.stat = highestStat;
switch (this.stat) { switch (this.stat) {
case Stat.SPD: case Stat.SPD:
this.multiplier = 1.5; this.multiplier = 1.5;
break; break;
default: default:
this.multiplier = 1.3; this.multiplier = 1.3;
break; break;
} }
pokemon.scene.queueMessage(getPokemonMessage(pokemon, `'s ${getStatName(highestStat)}\nwas heightened!`), null, false, null, true); pokemon.scene.queueMessage(getPokemonMessage(pokemon, `'s ${getStatName(highestStat)}\nwas heightened!`), null, false, null, true);
@ -1182,7 +1193,7 @@ export class CritBoostTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is getting\npumped!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is getting\npumped!"));
} }
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1192,7 +1203,7 @@ export class CritBoostTag extends BattlerTag {
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon); super.onRemove(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' relaxed.')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " relaxed."));
} }
} }
@ -1227,7 +1238,7 @@ export class SaltCuredTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' is being salt cured!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " is being salt cured!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
@ -1271,7 +1282,7 @@ export class CursedTag extends BattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ' has been cursed!')); pokemon.scene.queueMessage(getPokemonMessage(pokemon, " has been cursed!"));
this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex(); this.sourceIndex = pokemon.scene.getPokemonById(this.sourceId).getBattlerIndex();
} }
@ -1296,118 +1307,118 @@ export class CursedTag extends BattlerTag {
export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag { export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourceMove: Moves, sourceId: integer): BattlerTag {
switch (tagType) { switch (tagType) {
case BattlerTagType.RECHARGING: case BattlerTagType.RECHARGING:
return new RechargingTag(sourceMove); return new RechargingTag(sourceMove);
case BattlerTagType.FLINCHED: case BattlerTagType.FLINCHED:
return new FlinchedTag(sourceMove); return new FlinchedTag(sourceMove);
case BattlerTagType.INTERRUPTED: case BattlerTagType.INTERRUPTED:
return new InterruptedTag(sourceMove); return new InterruptedTag(sourceMove);
case BattlerTagType.CONFUSED: case BattlerTagType.CONFUSED:
return new ConfusedTag(turnCount, sourceMove); return new ConfusedTag(turnCount, sourceMove);
case BattlerTagType.INFATUATED: case BattlerTagType.INFATUATED:
return new InfatuatedTag(sourceMove, sourceId); return new InfatuatedTag(sourceMove, sourceId);
case BattlerTagType.SEEDED: case BattlerTagType.SEEDED:
return new SeedTag(sourceId); return new SeedTag(sourceId);
case BattlerTagType.NIGHTMARE: case BattlerTagType.NIGHTMARE:
return new NightmareTag(); return new NightmareTag();
case BattlerTagType.FRENZY: case BattlerTagType.FRENZY:
return new FrenzyTag(sourceMove, sourceId); return new FrenzyTag(sourceMove, sourceId);
case BattlerTagType.CHARGING: case BattlerTagType.CHARGING:
return new ChargingTag(sourceMove, sourceId); return new ChargingTag(sourceMove, sourceId);
case BattlerTagType.ENCORE: case BattlerTagType.ENCORE:
return new EncoreTag(sourceId); return new EncoreTag(sourceId);
case BattlerTagType.HELPING_HAND: case BattlerTagType.HELPING_HAND:
return new HelpingHandTag(sourceId); return new HelpingHandTag(sourceId);
case BattlerTagType.INGRAIN: case BattlerTagType.INGRAIN:
return new IngrainTag(sourceId); return new IngrainTag(sourceId);
case BattlerTagType.AQUA_RING: case BattlerTagType.AQUA_RING:
return new AquaRingTag(); return new AquaRingTag();
case BattlerTagType.DROWSY: case BattlerTagType.DROWSY:
return new DrowsyTag(); return new DrowsyTag();
case BattlerTagType.TRAPPED: case BattlerTagType.TRAPPED:
return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); return new TrappedTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
case BattlerTagType.BIND: case BattlerTagType.BIND:
return new BindTag(turnCount, sourceId); return new BindTag(turnCount, sourceId);
case BattlerTagType.WRAP: case BattlerTagType.WRAP:
return new WrapTag(turnCount, sourceId); return new WrapTag(turnCount, sourceId);
case BattlerTagType.FIRE_SPIN: case BattlerTagType.FIRE_SPIN:
return new FireSpinTag(turnCount, sourceId); return new FireSpinTag(turnCount, sourceId);
case BattlerTagType.WHIRLPOOL: case BattlerTagType.WHIRLPOOL:
return new WhirlpoolTag(turnCount, sourceId); return new WhirlpoolTag(turnCount, sourceId);
case BattlerTagType.CLAMP: case BattlerTagType.CLAMP:
return new ClampTag(turnCount, sourceId); return new ClampTag(turnCount, sourceId);
case BattlerTagType.SAND_TOMB: case BattlerTagType.SAND_TOMB:
return new SandTombTag(turnCount, sourceId); return new SandTombTag(turnCount, sourceId);
case BattlerTagType.MAGMA_STORM: case BattlerTagType.MAGMA_STORM:
return new MagmaStormTag(turnCount, sourceId); return new MagmaStormTag(turnCount, sourceId);
case BattlerTagType.SNAP_TRAP: case BattlerTagType.SNAP_TRAP:
return new SnapTrapTag(turnCount, sourceId); return new SnapTrapTag(turnCount, sourceId);
case BattlerTagType.THUNDER_CAGE: case BattlerTagType.THUNDER_CAGE:
return new ThunderCageTag(turnCount, sourceId); return new ThunderCageTag(turnCount, sourceId);
case BattlerTagType.INFESTATION: case BattlerTagType.INFESTATION:
return new InfestationTag(turnCount, sourceId); return new InfestationTag(turnCount, sourceId);
case BattlerTagType.PROTECTED: case BattlerTagType.PROTECTED:
return new ProtectedTag(sourceMove); return new ProtectedTag(sourceMove);
case BattlerTagType.SPIKY_SHIELD: case BattlerTagType.SPIKY_SHIELD:
return new ContactDamageProtectedTag(sourceMove, 8); return new ContactDamageProtectedTag(sourceMove, 8);
case BattlerTagType.KINGS_SHIELD: case BattlerTagType.KINGS_SHIELD:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.ATK, -1); return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.ATK, -1);
case BattlerTagType.OBSTRUCT: case BattlerTagType.OBSTRUCT:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.DEF, -2); return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.DEF, -2);
case BattlerTagType.SILK_TRAP: case BattlerTagType.SILK_TRAP:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.SPD, -1); return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.SPD, -1);
case BattlerTagType.BANEFUL_BUNKER: case BattlerTagType.BANEFUL_BUNKER:
return new ContactPoisonProtectedTag(sourceMove); return new ContactPoisonProtectedTag(sourceMove);
case BattlerTagType.BURNING_BULWARK: case BattlerTagType.BURNING_BULWARK:
return new ContactBurnProtectedTag(sourceMove); return new ContactBurnProtectedTag(sourceMove);
case BattlerTagType.ENDURING: case BattlerTagType.ENDURING:
return new EnduringTag(sourceMove); return new EnduringTag(sourceMove);
case BattlerTagType.STURDY: case BattlerTagType.STURDY:
return new SturdyTag(sourceMove); return new SturdyTag(sourceMove);
case BattlerTagType.PERISH_SONG: case BattlerTagType.PERISH_SONG:
return new PerishSongTag(turnCount); return new PerishSongTag(turnCount);
case BattlerTagType.TRUANT: case BattlerTagType.TRUANT:
return new TruantTag(); return new TruantTag();
case BattlerTagType.SLOW_START: case BattlerTagType.SLOW_START:
return new SlowStartTag(); return new SlowStartTag();
case BattlerTagType.PROTOSYNTHESIS: case BattlerTagType.PROTOSYNTHESIS:
return new WeatherHighestStatBoostTag(tagType, Abilities.PROTOSYNTHESIS, WeatherType.SUNNY, WeatherType.HARSH_SUN); return new WeatherHighestStatBoostTag(tagType, Abilities.PROTOSYNTHESIS, WeatherType.SUNNY, WeatherType.HARSH_SUN);
case BattlerTagType.QUARK_DRIVE: case BattlerTagType.QUARK_DRIVE:
return new TerrainHighestStatBoostTag(tagType, Abilities.QUARK_DRIVE, TerrainType.ELECTRIC); return new TerrainHighestStatBoostTag(tagType, Abilities.QUARK_DRIVE, TerrainType.ELECTRIC);
case BattlerTagType.FLYING: case BattlerTagType.FLYING:
case BattlerTagType.UNDERGROUND: case BattlerTagType.UNDERGROUND:
case BattlerTagType.UNDERWATER: case BattlerTagType.UNDERWATER:
case BattlerTagType.HIDDEN: case BattlerTagType.HIDDEN:
return new HideSpriteTag(tagType, turnCount, sourceMove); return new HideSpriteTag(tagType, turnCount, sourceMove);
case BattlerTagType.FIRE_BOOST: case BattlerTagType.FIRE_BOOST:
return new TypeBoostTag(tagType, sourceMove, Type.FIRE, 1.5, false); return new TypeBoostTag(tagType, sourceMove, Type.FIRE, 1.5, false);
case BattlerTagType.CRIT_BOOST: case BattlerTagType.CRIT_BOOST:
return new CritBoostTag(tagType, sourceMove); return new CritBoostTag(tagType, sourceMove);
case BattlerTagType.ALWAYS_CRIT: case BattlerTagType.ALWAYS_CRIT:
return new AlwaysCritTag(sourceMove); return new AlwaysCritTag(sourceMove);
case BattlerTagType.NO_CRIT: case BattlerTagType.NO_CRIT:
return new BattlerTag(tagType, BattlerTagLapseType.AFTER_MOVE, turnCount, sourceMove); return new BattlerTag(tagType, BattlerTagLapseType.AFTER_MOVE, turnCount, sourceMove);
case BattlerTagType.IGNORE_ACCURACY: case BattlerTagType.IGNORE_ACCURACY:
return new IgnoreAccuracyTag(sourceMove); return new IgnoreAccuracyTag(sourceMove);
case BattlerTagType.BYPASS_SLEEP: case BattlerTagType.BYPASS_SLEEP:
return new BattlerTag(BattlerTagType.BYPASS_SLEEP, BattlerTagLapseType.TURN_END, turnCount, sourceMove); return new BattlerTag(BattlerTagType.BYPASS_SLEEP, BattlerTagLapseType.TURN_END, turnCount, sourceMove);
case BattlerTagType.IGNORE_FLYING: case BattlerTagType.IGNORE_FLYING:
return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove); return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount, sourceMove);
case BattlerTagType.GROUNDED: case BattlerTagType.GROUNDED:
return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount - 1, sourceMove); return new BattlerTag(tagType, BattlerTagLapseType.TURN_END, turnCount - 1, sourceMove);
case BattlerTagType.SALT_CURED: case BattlerTagType.SALT_CURED:
return new SaltCuredTag(sourceId); return new SaltCuredTag(sourceId);
case BattlerTagType.CURSED: case BattlerTagType.CURSED:
return new CursedTag(sourceId); return new CursedTag(sourceId);
case BattlerTagType.CHARGED: case BattlerTagType.CHARGED:
return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true);
case BattlerTagType.MAGNET_RISEN: case BattlerTagType.MAGNET_RISEN:
return new MagnetRisenTag(tagType, sourceMove); return new MagnetRisenTag(tagType, sourceMove);
case BattlerTagType.MINIMIZED: case BattlerTagType.MINIMIZED:
return new MinimizeTag(); return new MinimizeTag();
case BattlerTagType.NONE: case BattlerTagType.NONE:
default: default:
return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId);
} }
} }

View File

@ -1,13 +1,12 @@
import { PokemonHealPhase, StatChangePhase } from "../phases"; import { PokemonHealPhase, StatChangePhase } from "../phases";
import { getPokemonMessage } from "../messages"; import { getPokemonMessage } from "../messages";
import Pokemon, { HitResult } from "../field/pokemon"; import Pokemon, { HitResult } from "../field/pokemon";
import { getBattleStatName } from "./battle-stat";
import { BattleStat } from "./battle-stat"; import { BattleStat } from "./battle-stat";
import { BattlerTagType } from "./enums/battler-tag-type"; import { BattlerTagType } from "./enums/battler-tag-type";
import { getStatusEffectHealText } from "./status-effect"; import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability"; import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from '../plugins/i18n'; import i18next from "../plugins/i18n";
export enum BerryType { export enum BerryType {
SITRUS, SITRUS,
@ -35,41 +34,41 @@ export type BerryPredicate = (pokemon: Pokemon) => boolean;
export function getBerryPredicate(berryType: BerryType): BerryPredicate { export function getBerryPredicate(berryType: BerryType): BerryPredicate {
switch (berryType) { switch (berryType) {
case BerryType.SITRUS: case BerryType.SITRUS:
return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5; return (pokemon: Pokemon) => pokemon.getHpRatio() < 0.5;
case BerryType.LUM: case BerryType.LUM:
return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED); return (pokemon: Pokemon) => !!pokemon.status || !!pokemon.getTag(BattlerTagType.CONFUSED);
case BerryType.ENIGMA: case BerryType.ENIGMA:
return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length; return (pokemon: Pokemon) => !!pokemon.turnData.attacksReceived.filter(a => a.result === HitResult.SUPER_EFFECTIVE).length;
case BerryType.LIECHI: case BerryType.LIECHI:
case BerryType.GANLON: case BerryType.GANLON:
case BerryType.PETAYA: case BerryType.PETAYA:
case BerryType.APICOT: case BerryType.APICOT:
case BerryType.SALAC: case BerryType.SALAC:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25); const threshold = new Utils.NumberHolder(0.25);
const battleStat = (berryType - BerryType.LIECHI) as BattleStat; const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6; return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6;
}; };
case BerryType.LANSAT: case BerryType.LANSAT:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25); const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST); return pokemon.getHpRatio() < 0.25 && !pokemon.getTag(BattlerTagType.CRIT_BOOST);
}; };
case BerryType.STARF: case BerryType.STARF:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25); const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return pokemon.getHpRatio() < 0.25; return pokemon.getHpRatio() < 0.25;
}; };
case BerryType.LEPPA: case BerryType.LEPPA:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25); const threshold = new Utils.NumberHolder(0.25);
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, threshold);
return !!pokemon.getMoveset().find(m => !m.getPpRatio()); return !!pokemon.getMoveset().find(m => !m.getPpRatio());
}; };
} }
} }
@ -77,64 +76,71 @@ export type BerryEffectFunc = (pokemon: Pokemon) => void;
export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc { export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
switch (berryType) { switch (berryType) {
case BerryType.SITRUS: case BerryType.SITRUS:
case BerryType.ENIGMA: case BerryType.ENIGMA:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
if (pokemon.battleData) if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4)); }
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed); const hpHealed = new Utils.NumberHolder(Math.floor(pokemon.getMaxHp() / 4));
pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(), applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, hpHealed);
hpHealed.value, getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true)); pokemon.scene.unshiftPhase(new PokemonHealPhase(pokemon.scene, pokemon.getBattlerIndex(),
}; hpHealed.value, getPokemonMessage(pokemon, `'s ${getBerryName(berryType)}\nrestored its HP!`), true));
case BerryType.LUM: };
return (pokemon: Pokemon) => { case BerryType.LUM:
if (pokemon.battleData) return (pokemon: Pokemon) => {
pokemon.battleData.berriesEaten.push(berryType); if (pokemon.battleData) {
if (pokemon.status) { pokemon.battleData.berriesEaten.push(berryType);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect))); }
pokemon.resetStatus(); if (pokemon.status) {
pokemon.updateInfo(); pokemon.scene.queueMessage(getPokemonMessage(pokemon, getStatusEffectHealText(pokemon.status.effect)));
} pokemon.resetStatus();
if (pokemon.getTag(BattlerTagType.CONFUSED)) pokemon.updateInfo();
pokemon.lapseTag(BattlerTagType.CONFUSED); }
}; if (pokemon.getTag(BattlerTagType.CONFUSED)) {
case BerryType.LIECHI: pokemon.lapseTag(BattlerTagType.CONFUSED);
case BerryType.GANLON: }
case BerryType.PETAYA: };
case BerryType.APICOT: case BerryType.LIECHI:
case BerryType.SALAC: case BerryType.GANLON:
return (pokemon: Pokemon) => { case BerryType.PETAYA:
if (pokemon.battleData) case BerryType.APICOT:
pokemon.battleData.berriesEaten.push(berryType); case BerryType.SALAC:
const battleStat = (berryType - BerryType.LIECHI) as BattleStat; return (pokemon: Pokemon) => {
const statLevels = new Utils.NumberHolder(1); if (pokemon.battleData) {
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels); pokemon.battleData.berriesEaten.push(berryType);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value)); }
}; const battleStat = (berryType - BerryType.LIECHI) as BattleStat;
case BerryType.LANSAT: const statLevels = new Utils.NumberHolder(1);
return (pokemon: Pokemon) => { applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
if (pokemon.battleData) pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value));
pokemon.battleData.berriesEaten.push(berryType); };
pokemon.addTag(BattlerTagType.CRIT_BOOST); case BerryType.LANSAT:
}; return (pokemon: Pokemon) => {
case BerryType.STARF: if (pokemon.battleData) {
return (pokemon: Pokemon) => { pokemon.battleData.berriesEaten.push(berryType);
if (pokemon.battleData) }
pokemon.battleData.berriesEaten.push(berryType); pokemon.addTag(BattlerTagType.CRIT_BOOST);
const statLevels = new Utils.NumberHolder(2); };
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels); case BerryType.STARF:
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value)); return (pokemon: Pokemon) => {
}; if (pokemon.battleData) {
case BerryType.LEPPA: pokemon.battleData.berriesEaten.push(berryType);
return (pokemon: Pokemon) => { }
if (pokemon.battleData) const statLevels = new Utils.NumberHolder(2);
pokemon.battleData.berriesEaten.push(berryType); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, statLevels);
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1); pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value));
if(ppRestoreMove !== undefined){ };
ppRestoreMove.ppUsed = Math.max(ppRestoreMove.ppUsed - 10, 0); case BerryType.LEPPA:
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`)); return (pokemon: Pokemon) => {
} 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);
pokemon.scene.queueMessage(getPokemonMessage(pokemon, ` restored PP to its move ${ppRestoreMove.getName()}\nusing its ${getBerryName(berryType)}!`));
}
};
} }
} }

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -576,37 +576,39 @@ export const speciesEggMoves = {
}; };
function parseEggMoves(content: string): void { function parseEggMoves(content: string): void {
let output = ''; let output = "";
const speciesNames = Utils.getEnumKeys(Species); const speciesNames = Utils.getEnumKeys(Species);
const speciesValues = Utils.getEnumValues(Species); const speciesValues = Utils.getEnumValues(Species);
const lines = content.split(/\n/g); const lines = content.split(/\n/g);
lines.forEach((line, l) => { lines.forEach((line, l) => {
const cols = line.split(',').slice(0, 5); const cols = line.split(",").slice(0, 5);
const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, '').toLowerCase()); const moveNames = allMoves.map(m => m.name.replace(/ \([A-Z]\)$/, "").toLowerCase());
const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, '_'); const enumSpeciesName = cols[0].toUpperCase().replace(/[ -]/g, "_");
const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)]; const species = speciesValues[speciesNames.findIndex(s => s === enumSpeciesName)];
let eggMoves: Moves[] = []; const eggMoves: Moves[] = [];
for (let m = 0; m < 4; m++) { for (let m = 0; m < 4; m++) {
const moveName = cols[m + 1].trim(); const moveName = cols[m + 1].trim();
const moveIndex = moveName !== 'N/A' ? moveNames.findIndex(mn => mn === moveName.toLowerCase()) : -1; const moveIndex = moveName !== "N/A" ? moveNames.findIndex(mn => mn === moveName.toLowerCase()) : -1;
eggMoves.push(moveIndex > -1 ? moveIndex as Moves : Moves.NONE); eggMoves.push(moveIndex > -1 ? moveIndex as Moves : Moves.NONE);
if (moveIndex === -1) if (moveIndex === -1) {
console.warn(moveName, 'could not be parsed'); console.warn(moveName, "could not be parsed");
}
} }
if (eggMoves.find(m => m !== Moves.NONE)) if (eggMoves.find(m => m !== Moves.NONE)) {
output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(', ')} ],\n`; output += `[Species.${Species[species]}]: [ ${eggMoves.map(m => `Moves.${Moves[m]}`).join(", ")} ],\n`;
}
}); });
console.log(output); console.log(output);
} }
const eggMovesStr = ``; const eggMovesStr = "";
if (eggMovesStr) { if (eggMovesStr) {
setTimeout(() => { setTimeout(() => {
parseEggMoves(eggMovesStr); parseEggMoves(eggMovesStr);

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@ import { Stat, getStatName } from "./pokemon-stat";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { TextStyle, getBBCodeFrag } from "../ui/text"; import { TextStyle, getBBCodeFrag } from "../ui/text";
import { UiTheme } from "#app/enums/ui-theme"; import { UiTheme } from "#app/enums/ui-theme";
import i18next from 'i18next'; import i18next from "i18next";
export enum Nature { export enum Nature {
HARDY, HARDY,
@ -35,102 +35,104 @@ export enum Nature {
export function getNatureName(nature: Nature, includeStatEffects: boolean = false, forStarterSelect: boolean = false, ignoreBBCode: boolean = false, uiTheme: UiTheme = UiTheme.DEFAULT): string { export function getNatureName(nature: Nature, includeStatEffects: boolean = false, forStarterSelect: boolean = false, ignoreBBCode: boolean = false, uiTheme: UiTheme = UiTheme.DEFAULT): string {
let ret = Utils.toReadableString(Nature[nature]); let ret = Utils.toReadableString(Nature[nature]);
//Translating nature //Translating nature
if(i18next.exists('nature:' + ret)){ if(i18next.exists("nature:" + ret)){
ret = i18next.t('nature:' + ret as any) ret = i18next.t("nature:" + ret as any);
} }
if (includeStatEffects) { if (includeStatEffects) {
const stats = Utils.getEnumValues(Stat).slice(1); const stats = Utils.getEnumValues(Stat).slice(1);
let increasedStat: Stat = null; let increasedStat: Stat = null;
let decreasedStat: Stat = null; let decreasedStat: Stat = null;
for (let stat of stats) { for (const stat of stats) {
const multiplier = getNatureStatMultiplier(nature, stat); const multiplier = getNatureStatMultiplier(nature, stat);
if (multiplier > 1) if (multiplier > 1) {
increasedStat = stat; increasedStat = stat;
else if (multiplier < 1) } else if (multiplier < 1) {
decreasedStat = stat; decreasedStat = stat;
}
} }
const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW; const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW;
const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text; const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text;
if (increasedStat && decreasedStat) if (increasedStat && decreasedStat) {
ret = `${getTextFrag(`${ret}${!forStarterSelect ? '\n' : ' '}(`, textStyle)}${getTextFrag(`+${getStatName(increasedStat, true)}`, TextStyle.SUMMARY_PINK)}${getTextFrag('/', textStyle)}${getTextFrag(`-${getStatName(decreasedStat, true)}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(')', textStyle)}`; ret = `${getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(`, textStyle)}${getTextFrag(`+${getStatName(increasedStat, true)}`, TextStyle.SUMMARY_PINK)}${getTextFrag("/", textStyle)}${getTextFrag(`-${getStatName(decreasedStat, true)}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(")", textStyle)}`;
else } else {
ret = getTextFrag(`${ret}${!forStarterSelect ? '\n' : ' '}(-)`, textStyle); ret = getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(-)`, textStyle);
}
} }
return ret; return ret;
} }
export function getNatureStatMultiplier(nature: Nature, stat: Stat): number { export function getNatureStatMultiplier(nature: Nature, stat: Stat): number {
switch (stat) { switch (stat) {
case Stat.ATK: case Stat.ATK:
switch (nature) { switch (nature) {
case Nature.LONELY: case Nature.LONELY:
case Nature.BRAVE: case Nature.BRAVE:
case Nature.ADAMANT: case Nature.ADAMANT:
case Nature.NAUGHTY: case Nature.NAUGHTY:
return 1.1; return 1.1;
case Nature.BOLD: case Nature.BOLD:
case Nature.TIMID: case Nature.TIMID:
case Nature.MODEST: case Nature.MODEST:
case Nature.CALM: case Nature.CALM:
return 0.9; return 0.9;
} }
break; break;
case Stat.DEF: case Stat.DEF:
switch (nature) { switch (nature) {
case Nature.BOLD: case Nature.BOLD:
case Nature.RELAXED: case Nature.RELAXED:
case Nature.IMPISH: case Nature.IMPISH:
case Nature.LAX: case Nature.LAX:
return 1.1; return 1.1;
case Nature.LONELY: case Nature.LONELY:
case Nature.HASTY: case Nature.HASTY:
case Nature.MILD: case Nature.MILD:
case Nature.GENTLE: case Nature.GENTLE:
return 0.9; return 0.9;
} }
break; break;
case Stat.SPATK: case Stat.SPATK:
switch (nature) { switch (nature) {
case Nature.MODEST: case Nature.MODEST:
case Nature.MILD: case Nature.MILD:
case Nature.QUIET: case Nature.QUIET:
case Nature.RASH: case Nature.RASH:
return 1.1; return 1.1;
case Nature.ADAMANT: case Nature.ADAMANT:
case Nature.IMPISH: case Nature.IMPISH:
case Nature.JOLLY: case Nature.JOLLY:
case Nature.CAREFUL: case Nature.CAREFUL:
return 0.9; return 0.9;
} }
break; break;
case Stat.SPDEF: case Stat.SPDEF:
switch (nature) { switch (nature) {
case Nature.CALM: case Nature.CALM:
case Nature.GENTLE: case Nature.GENTLE:
case Nature.SASSY: case Nature.SASSY:
case Nature.CAREFUL: case Nature.CAREFUL:
return 1.1; return 1.1;
case Nature.NAUGHTY: case Nature.NAUGHTY:
case Nature.LAX: case Nature.LAX:
case Nature.NAIVE: case Nature.NAIVE:
case Nature.RASH: case Nature.RASH:
return 0.9; return 0.9;
} }
break; break;
case Stat.SPD: case Stat.SPD:
switch (nature) { switch (nature) {
case Nature.TIMID: case Nature.TIMID:
case Nature.HASTY: case Nature.HASTY:
case Nature.JOLLY: case Nature.JOLLY:
case Nature.NAIVE: case Nature.NAIVE:
return 1.1; return 1.1;
case Nature.BRAVE: case Nature.BRAVE:
case Nature.RELAXED: case Nature.RELAXED:
case Nature.QUIET: case Nature.QUIET:
case Nature.SASSY: case Nature.SASSY:
return 0.9; return 0.9;
} }
break; break;
} }
return 1; return 1;

View File

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

View File

@ -1,5 +1,5 @@
import { Gender } from "./gender"; import { Gender } from "./gender";
import { AttackTypeBoosterModifier, FlinchChanceModifier } from "../modifier/modifier"; import { FlinchChanceModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves"; import { Moves } from "./enums/moves";
import { PokeballType } from "./pokeball"; import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon"; import Pokemon from "../field/pokemon";
@ -185,7 +185,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DUGTRIO, 26, null, null) new SpeciesEvolution(Species.DUGTRIO, 26, null, null)
], ],
[Species.MEOWTH]: [ [Species.MEOWTH]: [
new SpeciesFormEvolution(Species.PERSIAN, '', '', 28, null, null) new SpeciesFormEvolution(Species.PERSIAN, "", "", 28, null, null)
], ],
[Species.PSYDUCK]: [ [Species.PSYDUCK]: [
new SpeciesEvolution(Species.GOLDUCK, 33, null, null) new SpeciesEvolution(Species.GOLDUCK, 33, null, null)
@ -858,8 +858,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!p.scene.getParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.ESPURR]: [ [Species.ESPURR]: [
new SpeciesFormEvolution(Species.MEOWSTIC, '', 'female', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
new SpeciesFormEvolution(Species.MEOWSTIC, '', '', 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
], ],
[Species.HONEDGE]: [ [Species.HONEDGE]: [
new SpeciesEvolution(Species.DOUBLADE, 35, null, null) new SpeciesEvolution(Species.DOUBLADE, 35, null, null)
@ -1049,9 +1049,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null) new SpeciesEvolution(Species.BARRASKEWDA, 26, null, null)
], ],
[Species.TOXEL]: [ [Species.TOXEL]: [
new SpeciesFormEvolution(Species.TOXTRICITY, '', 'lowkey', 30, null, new SpeciesFormEvolution(Species.TOXTRICITY, "", "lowkey", 30, null,
new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)), new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)),
new SpeciesFormEvolution(Species.TOXTRICITY, '', 'amped', 30, null, null) new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null)
], ],
[Species.SIZZLIPEDE]: [ [Species.SIZZLIPEDE]: [
new SpeciesEvolution(Species.CENTISKORCH, 28, null, null) new SpeciesEvolution(Species.CENTISKORCH, 28, null, null)
@ -1130,8 +1130,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null) new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null)
], ],
[Species.LECHONK]: [ [Species.LECHONK]: [
new SpeciesFormEvolution(Species.OINKOLOGNE, '', 'female', 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)), new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
new SpeciesFormEvolution(Species.OINKOLOGNE, '', '', 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)) new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
], ],
[Species.TAROUNTULA]: [ [Species.TAROUNTULA]: [
new SpeciesEvolution(Species.SPIDOPS, 15, null, null) new SpeciesEvolution(Species.SPIDOPS, 15, null, null)
@ -1215,8 +1215,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLODSIRE, 20, null, null) new SpeciesEvolution(Species.CLODSIRE, 20, null, null)
], ],
[Species.PIKACHU]: [ [Species.PIKACHU]: [
new SpeciesFormEvolution(Species.ALOLA_RAICHU, '', '', 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALOLA_RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.RAICHU, '', '', 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.RAICHU, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.NIDORINA]: [ [Species.NIDORINA]: [
new SpeciesEvolution(Species.NIDOQUEEN, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.NIDOQUEEN, 1, EvolutionItem.MOON_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1254,7 +1254,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CLOYSTER, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.EXEGGCUTE]: [ [Species.EXEGGCUTE]: [
new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType == Biome.BEACH), SpeciesWildEvolutionDelay.LONG), new SpeciesEvolution(Species.ALOLA_EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ISLAND || p.scene.arena.biomeType === Biome.BEACH), SpeciesWildEvolutionDelay.LONG),
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.TANGELA]: [ [Species.TANGELA]: [
@ -1267,14 +1267,14 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.EEVEE]: [ [Species.EEVEE]: [
new SpeciesFormEvolution(Species.SYLVEON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ESPEON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.UMBREON, '', '', 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(70, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.VAPOREON, '', '', 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.JOLTEON, '', '', 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.FLAREON, '', '', 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.FLAREON, "", "", 1, EvolutionItem.FIRE_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.LEAFEON, '', '', 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.LEAFEON, "", "", 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.GLACEON, '', '', 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.GLACEON, "", "", 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG),
], ],
[Species.TOGETIC]: [ [Species.TOGETIC]: [
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
@ -1298,10 +1298,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DUNSPARCE]: [ [Species.DUNSPARCE]: [
new SpeciesFormEvolution(Species.DUDUNSPARCE, '', 'three-segment', 32, null, new SpeciesEvolutionCondition(p => { new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
let ret = false; let ret = false;
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) {
p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id); p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
}
return ret; return ret;
}), SpeciesWildEvolutionDelay.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) new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
@ -1363,8 +1364,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.BASCULIN]: [ [Species.BASCULIN]: [
new SpeciesFormEvolution(Species.BASCULEGION, 'white-striped', 'female', 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.BASCULEGION, 'white-striped', 'male', 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.MINCCINO]: [ [Species.MINCCINO]: [
new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1391,9 +1392,9 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.ROCKRUFF]: [ [Species.ROCKRUFF]: [
new SpeciesFormEvolution(Species.LYCANROC, '', 'midday', 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0)), null), new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0)), null),
new SpeciesFormEvolution(Species.LYCANROC, '', 'dusk', 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1), null), new SpeciesFormEvolution(Species.LYCANROC, "", "dusk", 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1), null),
new SpeciesFormEvolution(Species.LYCANROC, '', 'midnight', 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)), null) new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)), null)
], ],
[Species.STEENEE]: [ [Species.STEENEE]: [
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
@ -1416,26 +1417,26 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TAUNT).length > 0), SpeciesWildEvolutionDelay.MEDIUM) new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TAUNT).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
], ],
[Species.SINISTEA]: [ [Species.SINISTEA]: [
new SpeciesFormEvolution(Species.POLTEAGEIST, 'phony', 'phony', 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.POLTEAGEIST, 'antique', 'antique', 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.MILCERY]: [ [Species.MILCERY]: [
new SpeciesFormEvolution(Species.ALCREMIE, '', 'vanilla-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TOWN || p.scene.arena.biomeType === Biome.PLAINS || p.scene.arena.biomeType === Biome.GRASS || p.scene.arena.biomeType === Biome.TALL_GRASS || p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TOWN || p.scene.arena.biomeType === Biome.PLAINS || p.scene.arena.biomeType === Biome.GRASS || p.scene.arena.biomeType === Biome.TALL_GRASS || p.scene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'ruby-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.BADLANDS || p.scene.arena.biomeType === Biome.VOLCANO || p.scene.arena.biomeType === Biome.GRAVEYARD || p.scene.arena.biomeType === Biome.FACTORY || p.scene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.BADLANDS || p.scene.arena.biomeType === Biome.VOLCANO || p.scene.arena.biomeType === Biome.GRAVEYARD || p.scene.arena.biomeType === Biome.FACTORY || p.scene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'matcha-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.FOREST || p.scene.arena.biomeType === Biome.SWAMP || p.scene.arena.biomeType === Biome.MEADOW || p.scene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.FOREST || p.scene.arena.biomeType === Biome.SWAMP || p.scene.arena.biomeType === Biome.MEADOW || p.scene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'mint-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.SEA || p.scene.arena.biomeType === Biome.BEACH || p.scene.arena.biomeType === Biome.LAKE || p.scene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.SEA || p.scene.arena.biomeType === Biome.BEACH || p.scene.arena.biomeType === Biome.LAKE || p.scene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'lemon-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.DESERT || p.scene.arena.biomeType === Biome.POWER_PLANT || p.scene.arena.biomeType === Biome.DOJO || p.scene.arena.biomeType === Biome.RUINS || p.scene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.DESERT || p.scene.arena.biomeType === Biome.POWER_PLANT || p.scene.arena.biomeType === Biome.DOJO || p.scene.arena.biomeType === Biome.RUINS || p.scene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'salted-cream', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.MOUNTAIN || p.scene.arena.biomeType === Biome.CAVE || p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.FAIRY_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.MOUNTAIN || p.scene.arena.biomeType === Biome.CAVE || p.scene.arena.biomeType === Biome.ICE_CAVE || p.scene.arena.biomeType === Biome.FAIRY_CAVE || p.scene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'ruby-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.WASTELAND || p.scene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.WASTELAND || p.scene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'caramel-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TEMPLE || p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.TEMPLE || p.scene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.ALCREMIE, '', 'rainbow-swirl', 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ABYSS || p.scene.arena.biomeType === Biome.SPACE || p.scene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => p.scene.arena.biomeType === Biome.ABYSS || p.scene.arena.biomeType === Biome.SPACE || p.scene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DURALUDON]: [ [Species.DURALUDON]: [
new SpeciesFormEvolution(Species.ARCHALUDON, '', '', 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.KUBFU]: [ [Species.KUBFU]: [
new SpeciesFormEvolution(Species.URSHIFU, '', 'single-strike', 1, EvolutionItem.SCROLL_OF_DARKNESS, null, SpeciesWildEvolutionDelay.VERY_LONG), new SpeciesFormEvolution(Species.URSHIFU, "", "single-strike", 1, EvolutionItem.SCROLL_OF_DARKNESS, null, SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesFormEvolution(Species.URSHIFU, '', 'rapid-strike', 1, EvolutionItem.SCROLL_OF_WATERS, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesFormEvolution(Species.URSHIFU, "", "rapid-strike", 1, EvolutionItem.SCROLL_OF_WATERS, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.GALAR_DARUMAKA]: [ [Species.GALAR_DARUMAKA]: [
new SpeciesEvolution(Species.GALAR_DARMANITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.GALAR_DARMANITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
@ -1466,8 +1467,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.CETITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG) new SpeciesEvolution(Species.CETITAN, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.POLTCHAGEIST]: [ [Species.POLTCHAGEIST]: [
new SpeciesFormEvolution(Species.SINISTCHA, 'counterfeit', 'unremarkable', 1, EvolutionItem.UNREMARKABLE_TEACUP, null, SpeciesWildEvolutionDelay.LONG), new SpeciesFormEvolution(Species.SINISTCHA, "counterfeit", "unremarkable", 1, EvolutionItem.UNREMARKABLE_TEACUP, null, SpeciesWildEvolutionDelay.LONG),
new SpeciesFormEvolution(Species.SINISTCHA, 'artisan', 'masterpiece', 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG) new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
], ],
[Species.DIPPLIN]: [ [Species.DIPPLIN]: [
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
@ -1486,8 +1487,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
], ],
[Species.ONIX]: [ [Species.ONIX]: [
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition( new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0), p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0),
SpeciesWildEvolutionDelay.VERY_LONG) SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.RHYDON]: [ [Species.RHYDON]: [
new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Protector */), SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => true /* Protector */), SpeciesWildEvolutionDelay.VERY_LONG)
@ -1498,7 +1499,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
[Species.SCYTHER]: [ [Species.SCYTHER]: [
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition( new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0), p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0),
SpeciesWildEvolutionDelay.VERY_LONG), SpeciesWildEvolutionDelay.VERY_LONG),
new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG) new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG)
], ],
[Species.ELECTABUZZ]: [ [Species.ELECTABUZZ]: [
@ -1619,13 +1620,14 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {}; export const pokemonPrevolutions: PokemonPrevolutions = {};
{ {
const megaFormKeys = [ SpeciesFormKey.MEGA, '', SpeciesFormKey.MEGA_X, '', SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string); const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const prevolutionKeys = Object.keys(pokemonEvolutions); const prevolutionKeys = Object.keys(pokemonEvolutions);
prevolutionKeys.forEach(pk => { prevolutionKeys.forEach(pk => {
const evolutions = pokemonEvolutions[pk]; const evolutions = pokemonEvolutions[pk];
for (let ev of evolutions) { for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue; continue;
}
pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species; pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species;
} }
}); });

View File

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

View File

@ -1,21 +1,21 @@
import { Abilities } from "./enums/abilities"; import { Abilities } from "./enums/abilities";
import BattleScene, { AnySound } from '../battle-scene'; import BattleScene, { AnySound } from "../battle-scene";
import { Variant, variantColorCache } from './variant'; import { Variant, variantColorCache } from "./variant";
import { variantData } from './variant'; import { variantData } from "./variant";
import { GrowthRate } from './exp'; import { GrowthRate } from "./exp";
import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from './pokemon-evolutions'; import { SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
import { Species } from './enums/species'; import { Species } from "./enums/species";
import { Type } from './type'; import { Type } from "./type";
import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from './pokemon-level-moves'; import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from "./pokemon-level-moves";
import { uncatchableSpecies } from './biomes'; import { uncatchableSpecies } from "./biomes";
import * as Utils from '../utils'; import * as Utils from "../utils";
import { StarterMoveset } from '../system/game-data'; import { StarterMoveset } from "../system/game-data";
import { speciesEggMoves } from './egg-moves'; import { speciesEggMoves } from "./egg-moves";
import { PartyMemberStrength } from "./enums/party-member-strength"; import { PartyMemberStrength } from "./enums/party-member-strength";
import { GameMode } from '../game-mode'; import { GameMode } from "../game-mode";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities"; import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import { VariantSet } from './variant'; import { VariantSet } from "./variant";
import i18next, { Localizable } from '../plugins/i18n'; import i18next, { Localizable } from "../plugins/i18n";
import { Stat } from "./pokemon-stat"; import { Stat } from "./pokemon-stat";
export enum Region { export enum Region {
@ -27,17 +27,19 @@ export enum Region {
} }
export function getPokemonSpecies(species: Species): PokemonSpecies { export function getPokemonSpecies(species: Species): PokemonSpecies {
if (species >= 2000) if (species >= 2000) {
return allSpecies.find(s => s.speciesId === species); return allSpecies.find(s => s.speciesId === species);
}
return allSpecies[species - 1]; return allSpecies[species - 1];
} }
export function getPokemonSpeciesForm(species: Species, formIndex: integer): PokemonSpeciesForm { export function getPokemonSpeciesForm(species: Species, formIndex: integer): PokemonSpeciesForm {
let retSpecies: PokemonSpecies = species >= 2000 const retSpecies: PokemonSpecies = species >= 2000
? allSpecies.find(s => s.speciesId === species) ? allSpecies.find(s => s.speciesId === species)
: allSpecies[species - 1]; : allSpecies[species - 1];
if (formIndex < retSpecies.forms?.length) if (formIndex < retSpecies.forms?.length) {
return retSpecies.forms[formIndex]; return retSpecies.forms[formIndex];
}
return retSpecies; return retSpecies;
} }
@ -46,26 +48,30 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string):
const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-\'])(.*?)$/i; const fragBPattern = /([a-z]{2}.*?[aeiou(?:y$)\-\'])(.*?)$/i;
const [ speciesAPrefixMatch, speciesBPrefixMatch ] = [ speciesAName, speciesBName ].map(n => /^(?:[^ ]+) /.exec(n)); const [ speciesAPrefixMatch, speciesBPrefixMatch ] = [ speciesAName, speciesBName ].map(n => /^(?:[^ ]+) /.exec(n));
const [ speciesAPrefix, speciesBPrefix ] = [ speciesAPrefixMatch, speciesBPrefixMatch ].map(m => m ? m[0] : ''); const [ speciesAPrefix, speciesBPrefix ] = [ speciesAPrefixMatch, speciesBPrefixMatch ].map(m => m ? m[0] : "");
if (speciesAPrefix) if (speciesAPrefix) {
speciesAName = speciesAName.slice(speciesAPrefix.length); speciesAName = speciesAName.slice(speciesAPrefix.length);
if (speciesBPrefix) }
if (speciesBPrefix) {
speciesBName = speciesBName.slice(speciesBPrefix.length); speciesBName = speciesBName.slice(speciesBPrefix.length);
}
const [ speciesASuffixMatch, speciesBSuffixMatch ] = [ speciesAName, speciesBName ].map(n => / (?:[^ ]+)$/.exec(n)); const [ speciesASuffixMatch, speciesBSuffixMatch ] = [ speciesAName, speciesBName ].map(n => / (?:[^ ]+)$/.exec(n));
const [ speciesASuffix, speciesBSuffix ] = [ speciesASuffixMatch, speciesBSuffixMatch ].map(m => m ? m[0] : ''); const [ speciesASuffix, speciesBSuffix ] = [ speciesASuffixMatch, speciesBSuffixMatch ].map(m => m ? m[0] : "");
if (speciesASuffix) if (speciesASuffix) {
speciesAName = speciesAName.slice(0, -speciesASuffix.length); speciesAName = speciesAName.slice(0, -speciesASuffix.length);
if (speciesBSuffix) }
if (speciesBSuffix) {
speciesBName = speciesBName.slice(0, -speciesBSuffix.length); speciesBName = speciesBName.slice(0, -speciesBSuffix.length);
}
const splitNameA = speciesAName.split(/ /g); const splitNameA = speciesAName.split(/ /g);
const splitNameB = speciesBName.split(/ /g); const splitNameB = speciesBName.split(/ /g);
let fragAMatch = fragAPattern.exec(speciesAName); const fragAMatch = fragAPattern.exec(speciesAName);
let fragBMatch = fragBPattern.exec(speciesBName); const fragBMatch = fragBPattern.exec(speciesBName);
let fragA: string; let fragA: string;
let fragB: string; let fragB: string;
@ -78,23 +84,27 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string):
if (fragBMatch) { if (fragBMatch) {
const lastCharA = fragA.slice(fragA.length - 1); const lastCharA = fragA.slice(fragA.length - 1);
const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1); const prevCharB = fragBMatch[1].slice(fragBMatch.length - 1);
fragB = (/[\-']/.test(prevCharB) ? prevCharB : '') + fragBMatch[2] || prevCharB; fragB = (/[\-']/.test(prevCharB) ? prevCharB : "") + fragBMatch[2] || prevCharB;
if (lastCharA === fragB[0]) { if (lastCharA === fragB[0]) {
if (/[aiu]/.test(lastCharA)) if (/[aiu]/.test(lastCharA)) {
fragB = fragB.slice(1); fragB = fragB.slice(1);
else { } else {
const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB); const newCharMatch = new RegExp(`[^${lastCharA}]`).exec(fragB);
if (newCharMatch?.index > 0) if (newCharMatch?.index > 0) {
fragB = fragB.slice(newCharMatch.index); fragB = fragB.slice(newCharMatch.index);
}
} }
} }
} else } else {
fragB = speciesBName; fragB = speciesBName;
} else }
} else {
fragB = splitNameB[splitNameB.length - 1]; fragB = splitNameB[splitNameB.length - 1];
}
if (splitNameA.length > 1) if (splitNameA.length > 1) {
fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(' ')} ${fragA}`; fragA = `${splitNameA.slice(0, splitNameA.length - 1).join(" ")} ${fragA}`;
}
fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`; fragB = `${fragB.slice(0, 1).toLowerCase()}${fragB.slice(1)}`;
@ -124,25 +134,26 @@ export abstract class PokemonSpeciesForm {
constructor(type1: Type, type2: Type, height: number, weight: number, ability1: Abilities, ability2: Abilities, abilityHidden: Abilities, constructor(type1: Type, type2: Type, height: number, weight: number, ability1: Abilities, ability2: Abilities, abilityHidden: Abilities,
baseTotal: integer, baseHp: integer, baseAtk: integer, baseDef: integer, baseSpatk: integer, baseSpdef: integer, baseSpd: integer, baseTotal: integer, baseHp: integer, baseAtk: integer, baseDef: integer, baseSpatk: integer, baseSpdef: integer, baseSpd: integer,
catchRate: integer, baseFriendship: integer, baseExp: integer, genderDiffs: boolean) { catchRate: integer, baseFriendship: integer, baseExp: integer, genderDiffs: boolean) {
this.type1 = type1; this.type1 = type1;
this.type2 = type2; this.type2 = type2;
this.height = height; this.height = height;
this.weight = weight; this.weight = weight;
this.ability1 = ability1; this.ability1 = ability1;
this.ability2 = ability2; this.ability2 = ability2;
this.abilityHidden = abilityHidden; this.abilityHidden = abilityHidden;
this.baseTotal = baseTotal; this.baseTotal = baseTotal;
this.baseStats = [ baseHp, baseAtk, baseDef, baseSpatk, baseSpdef, baseSpd ]; this.baseStats = [ baseHp, baseAtk, baseDef, baseSpatk, baseSpdef, baseSpd ];
this.catchRate = catchRate; this.catchRate = catchRate;
this.baseFriendship = baseFriendship; this.baseFriendship = baseFriendship;
this.baseExp = baseExp; this.baseExp = baseExp;
this.genderDiffs = genderDiffs; this.genderDiffs = genderDiffs;
} }
getRootSpeciesId(forStarter: boolean = false): Species { getRootSpeciesId(forStarter: boolean = false): Species {
let ret = this.speciesId; let ret = this.speciesId;
while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret))) while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret))) {
ret = pokemonPrevolutions[ret]; ret = pokemonPrevolutions[ret];
}
return ret; return ret;
} }
@ -159,8 +170,9 @@ export abstract class PokemonSpeciesForm {
} }
getLevelMoves(): LevelMoves { getLevelMoves(): LevelMoves {
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0); return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0);
}
return pokemonSpeciesLevelMoves[this.speciesId].slice(0); return pokemonSpeciesLevelMoves[this.speciesId].slice(0);
} }
@ -186,8 +198,8 @@ export abstract class PokemonSpeciesForm {
isRareRegional(): boolean { isRareRegional(): boolean {
switch (this.getRegion()) { switch (this.getRegion()) {
case Region.HISUI: case Region.HISUI:
return true; return true;
} }
return false; return false;
@ -199,44 +211,44 @@ export abstract class PokemonSpeciesForm {
* @returns The species' base stat amount. * @returns The species' base stat amount.
*/ */
getBaseStat(stat: Stat): integer { getBaseStat(stat: Stat): integer {
return this.baseStats[stat] return this.baseStats[stat];
} }
getBaseExp(): integer { getBaseExp(): integer {
let ret = this.baseExp; let ret = this.baseExp;
switch (this.getFormSpriteKey()) { switch (this.getFormSpriteKey()) {
case SpeciesFormKey.MEGA: case SpeciesFormKey.MEGA:
case SpeciesFormKey.MEGA_X: case SpeciesFormKey.MEGA_X:
case SpeciesFormKey.MEGA_Y: case SpeciesFormKey.MEGA_Y:
case SpeciesFormKey.PRIMAL: case SpeciesFormKey.PRIMAL:
case SpeciesFormKey.GIGANTAMAX: case SpeciesFormKey.GIGANTAMAX:
case SpeciesFormKey.ETERNAMAX: case SpeciesFormKey.ETERNAMAX:
ret *= 1.5; ret *= 1.5;
break; break;
} }
return ret; return ret;
} }
getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, '/'); const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, "/");
return `${/_[1-3]$/.test(spriteId) ? 'variant/' : ''}${spriteId}`; return `${/_[1-3]$/.test(spriteId) ? "variant/" : ""}${spriteId}`;
} }
getSpriteId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer, back?: boolean): string { getSpriteId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer, back?: boolean): string {
if (formIndex === undefined || this instanceof PokemonForm) if (formIndex === undefined || this instanceof PokemonForm) {
formIndex = this.formIndex; formIndex = this.formIndex;
}
const formSpriteKey = this.getFormSpriteKey(formIndex); const formSpriteKey = this.getFormSpriteKey(formIndex);
const showGenderDiffs = this.genderDiffs && female && ![ SpeciesFormKey.MEGA, SpeciesFormKey.GIGANTAMAX ].find(k => formSpriteKey === k); const showGenderDiffs = this.genderDiffs && female && ![ SpeciesFormKey.MEGA, SpeciesFormKey.GIGANTAMAX ].find(k => formSpriteKey === k);
const baseSpriteKey = `${showGenderDiffs ? 'female__' : ''}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ''}`; const baseSpriteKey = `${showGenderDiffs ? "female__" : ""}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ""}`;
let variantSet: VariantSet;
let config = variantData; let config = variantData;
`${back ? 'back__' : ''}${baseSpriteKey}`.split('__').map(p => config ? config = config[p] : null); `${back ? "back__" : ""}${baseSpriteKey}`.split("__").map(p => config ? config = config[p] : null);
variantSet = config as VariantSet; const variantSet = config as VariantSet;
return `${back ? 'back__' : ''}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? 'shiny__' : ''}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ''}`; return `${back ? "back__" : ""}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? "shiny__" : ""}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ""}`;
} }
getSpriteKey(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getSpriteKey(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
@ -247,47 +259,51 @@ export abstract class PokemonSpeciesForm {
getIconAtlasKey(formIndex?: integer, shiny?: boolean, variant?: integer): string { getIconAtlasKey(formIndex?: integer, shiny?: boolean, variant?: integer): string {
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant]; const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
return `pokemon_icons_${this.generation}${isVariant ? 'v' : ''}`; return `pokemon_icons_${this.generation}${isVariant ? "v" : ""}`;
} }
getIconId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string { getIconId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
if (formIndex === undefined) if (formIndex === undefined) {
formIndex = this.formIndex; formIndex = this.formIndex;
}
let ret = this.speciesId.toString(); let ret = this.speciesId.toString();
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant]; const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
if (shiny && !isVariant) if (shiny && !isVariant) {
ret += 's'; ret += "s";
}
switch (this.speciesId) { switch (this.speciesId) {
case Species.HIPPOPOTAS: case Species.HIPPOPOTAS:
case Species.HIPPOWDON: case Species.HIPPOWDON:
case Species.UNFEZANT: case Species.UNFEZANT:
case Species.FRILLISH: case Species.FRILLISH:
case Species.JELLICENT: case Species.JELLICENT:
ret += female ? '-f' : ''; ret += female ? "-f" : "";
break; break;
} }
let formSpriteKey = this.getFormSpriteKey(formIndex); let formSpriteKey = this.getFormSpriteKey(formIndex);
if (formSpriteKey) { if (formSpriteKey) {
switch (this.speciesId) { switch (this.speciesId) {
case Species.DUDUNSPARCE: case Species.DUDUNSPARCE:
break; break;
case Species.ZACIAN: case Species.ZACIAN:
case Species.ZAMAZENTA: case Species.ZAMAZENTA:
if (formSpriteKey.startsWith('behemoth')) if (formSpriteKey.startsWith("behemoth")) {
formSpriteKey = 'crowned'; formSpriteKey = "crowned";
default: }
ret += `-${formSpriteKey}`; default:
break; ret += `-${formSpriteKey}`;
break;
} }
} }
if (isVariant) if (isVariant) {
ret += `_${variant + 1}`; ret += `_${variant + 1}`;
}
return ret; return ret;
} }
@ -296,15 +312,15 @@ export abstract class PokemonSpeciesForm {
let speciesId = this.speciesId; let speciesId = this.speciesId;
if (this.speciesId > 2000) { if (this.speciesId > 2000) {
switch (this.speciesId) { switch (this.speciesId) {
case Species.GALAR_SLOWPOKE: case Species.GALAR_SLOWPOKE:
break; break;
case Species.ETERNAL_FLOETTE: case Species.ETERNAL_FLOETTE:
break; break;
case Species.BLOODMOON_URSALUNA: case Species.BLOODMOON_URSALUNA:
break; break;
default: default:
speciesId = speciesId % 2000; speciesId = speciesId % 2000;
break; break;
} }
} }
let ret = speciesId.toString(); let ret = speciesId.toString();
@ -316,41 +332,41 @@ export abstract class PokemonSpeciesForm {
} }
const formKey = forms[formIndex || 0].formKey; const formKey = forms[formIndex || 0].formKey;
switch (formKey) { switch (formKey) {
case SpeciesFormKey.MEGA: case SpeciesFormKey.MEGA:
case SpeciesFormKey.MEGA_X: case SpeciesFormKey.MEGA_X:
case SpeciesFormKey.MEGA_Y: case SpeciesFormKey.MEGA_Y:
case SpeciesFormKey.GIGANTAMAX: case SpeciesFormKey.GIGANTAMAX:
case SpeciesFormKey.GIGANTAMAX_SINGLE: case SpeciesFormKey.GIGANTAMAX_SINGLE:
case SpeciesFormKey.GIGANTAMAX_RAPID: case SpeciesFormKey.GIGANTAMAX_RAPID:
case 'white': case "white":
case 'black': case "black":
case 'therian': case "therian":
case 'sky': case "sky":
case 'gorging': case "gorging":
case 'gulping': case "gulping":
case 'no-ice': case "no-ice":
case 'hangry': case "hangry":
case 'crowned': case "crowned":
case 'eternamax': case "eternamax":
case 'four': case "four":
case 'droopy': case "droopy":
case 'stretchy': case "stretchy":
case 'roaming': case "roaming":
case 'complete': case "complete":
case '10': case "10":
case 'super': case "super":
case 'unbound': case "unbound":
case 'pau': case "pau":
case 'pompom': case "pompom":
case 'sensu': case "sensu":
case 'dusk': case "dusk":
case 'midnight': case "midnight":
case 'school': case "school":
case 'dawn-wings': case "dawn-wings":
case 'dusk-mane': case "dusk-mane":
case 'ultra': case "ultra":
ret += `-${formKey}`; ret += `-${formKey}`;
break; break;
} }
} }
return ret; return ret;
@ -358,17 +374,20 @@ export abstract class PokemonSpeciesForm {
validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean { validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean {
const rootSpeciesId = this.getRootSpeciesId(); const rootSpeciesId = this.getRootSpeciesId();
for (let moveId of moveset) { for (const moveId of moveset) {
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) { if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId); const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) {
continue; continue;
}
} }
if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) { if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId)) if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false; return false;
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId)) }
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false; return false;
}
} }
return true; return true;
@ -391,19 +410,20 @@ export abstract class PokemonSpeciesForm {
frameRate: 12, frameRate: 12,
repeat: -1 repeat: -1
}); });
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace('variant/', '').replace(/_[1-3]$/, ''); let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey); const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);
if (useExpSprite) if (useExpSprite) {
spritePath = `exp/${spritePath}`; spritePath = `exp/${spritePath}`;
let variantSet: VariantSet; }
let config = variantData; let config = variantData;
spritePath.split('/').map(p => config ? config = config[p] : null); spritePath.split("/").map(p => config ? config = config[p] : null);
variantSet = config as VariantSet; const variantSet = config as VariantSet;
if (variantSet && variantSet[variant] === 1) { if (variantSet && variantSet[variant] === 1) {
const populateVariantColors = (key: string): Promise<void> => { const populateVariantColors = (key: string): Promise<void> => {
return new Promise(resolve => { return new Promise(resolve => {
if (variantColorCache.hasOwnProperty(key)) if (variantColorCache.hasOwnProperty(key)) {
return resolve(); return resolve();
}
scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => { scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
variantColorCache[key] = c; variantColorCache[key] = c;
resolve(); resolve();
@ -416,21 +436,25 @@ export abstract class PokemonSpeciesForm {
resolve(); resolve();
}); });
if (startLoad) { if (startLoad) {
if (!scene.load.isLoading()) if (!scene.load.isLoading()) {
scene.load.start(); scene.load.start();
} else }
} else {
resolve(); resolve();
}
}); });
} }
cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound { cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound {
const cryKey = this.getCryKey(this.formIndex); const cryKey = this.getCryKey(this.formIndex);
let cry = scene.sound.get(cryKey) as AnySound; let cry = scene.sound.get(cryKey) as AnySound;
if (cry?.pendingRemove) if (cry?.pendingRemove) {
cry = null; cry = null;
}
cry = scene.playSound(cry || cryKey, soundConfig); cry = scene.playSound(cry || cryKey, soundConfig);
if (ignorePlay) if (ignorePlay) {
cry.stop(); cry.stop();
}
return cry; return cry;
} }
@ -440,11 +464,11 @@ export abstract class PokemonSpeciesForm {
const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame]; const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame];
const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement; const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement;
const canvas = document.createElement('canvas'); const canvas = document.createElement("canvas");
const spriteColors: integer[][] = []; const spriteColors: integer[][] = [];
const context = canvas.getContext('2d'); const context = canvas.getContext("2d");
const frame = sourceFrame; const frame = sourceFrame;
canvas.width = frame.width; canvas.width = frame.width;
canvas.height = frame.height; canvas.height = frame.height;
@ -456,16 +480,18 @@ export abstract class PokemonSpeciesForm {
if (pixelData[i + 3]) { if (pixelData[i + 3]) {
const pixel = pixelData.slice(i, i + 4); const pixel = pixelData.slice(i, i + 4);
const [ r, g, b, a ] = pixel; const [ r, g, b, a ] = pixel;
if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b)) if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b)) {
spriteColors.push([ r, g, b, a ]); spriteColors.push([ r, g, b, a ]);
}
} }
} }
const pixelColors = []; const pixelColors = [];
for (let i = 0; i < pixelData.length; i += 4) { for (let i = 0; i < pixelData.length; i += 4) {
const total = pixelData.slice(i, i + 3).reduce((total: integer, value: integer) => total + value, 0); const total = pixelData.slice(i, i + 3).reduce((total: integer, value: integer) => total + value, 0);
if (!total) if (!total) {
continue; continue;
}
pixelColors.push(argbFromRgba({ r: pixelData[i], g: pixelData[i + 1], b: pixelData[i + 2], a: pixelData[i + 3] })); pixelColors.push(argbFromRgba({ r: pixelData[i], g: pixelData[i + 1], b: pixelData[i + 2], a: pixelData[i + 3] }));
} }
@ -476,7 +502,7 @@ export abstract class PokemonSpeciesForm {
scene.executeWithSeedOffset(() => { scene.executeWithSeedOffset(() => {
paletteColors = QuantizerCelebi.quantize(pixelColors, 2); paletteColors = QuantizerCelebi.quantize(pixelColors, 2);
}, 0, 'This result should not vary'); }, 0, "This result should not vary");
Math.random = originalRandom; Math.random = originalRandom;
@ -529,17 +555,18 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
if (formIndex !== undefined && this.forms.length) { if (formIndex !== undefined && this.forms.length) {
const form = this.forms[formIndex]; const form = this.forms[formIndex];
switch (form.formKey) { switch (form.formKey) {
case SpeciesFormKey.MEGA: case SpeciesFormKey.MEGA:
case SpeciesFormKey.PRIMAL: case SpeciesFormKey.PRIMAL:
case SpeciesFormKey.ETERNAMAX: case SpeciesFormKey.ETERNAMAX:
return `${form.formName} ${this.name}`; return `${form.formName} ${this.name}`;
case SpeciesFormKey.MEGA_X: case SpeciesFormKey.MEGA_X:
return `Mega ${this.name} X`; return `Mega ${this.name} X`;
case SpeciesFormKey.MEGA_Y: case SpeciesFormKey.MEGA_Y:
return `Mega ${this.name} Y`; return `Mega ${this.name} Y`;
default: default:
if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) {
return `G-Max ${this.name}`; return `G-Max ${this.name}`;
}
} }
} }
return this.name; return this.name;
@ -559,18 +586,18 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
private getStrengthLevelDiff(strength: PartyMemberStrength): integer { private getStrengthLevelDiff(strength: PartyMemberStrength): integer {
switch (Math.min(strength, PartyMemberStrength.STRONGER)) { switch (Math.min(strength, PartyMemberStrength.STRONGER)) {
case PartyMemberStrength.WEAKEST: case PartyMemberStrength.WEAKEST:
return 60; return 60;
case PartyMemberStrength.WEAKER: case PartyMemberStrength.WEAKER:
return 40; return 40;
case PartyMemberStrength.WEAK: case PartyMemberStrength.WEAK:
return 20; return 20;
case PartyMemberStrength.AVERAGE: case PartyMemberStrength.AVERAGE:
return 10; return 10;
case PartyMemberStrength.STRONG: case PartyMemberStrength.STRONG:
return 5; return 5;
default: default:
return 0; return 0;
} }
} }
@ -580,52 +607,56 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
if (prevolutionLevels.length) { if (prevolutionLevels.length) {
for (let pl = prevolutionLevels.length - 1; pl >= 0; pl--) { for (let pl = prevolutionLevels.length - 1; pl >= 0; pl--) {
const prevolutionLevel = prevolutionLevels[pl]; const prevolutionLevel = prevolutionLevels[pl];
if (level < prevolutionLevel[1]) if (level < prevolutionLevel[1]) {
return prevolutionLevel[0]; return prevolutionLevel[0];
}
} }
} }
if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId)) if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId)) {
return this.speciesId; return this.speciesId;
}
const evolutions = pokemonEvolutions[this.speciesId]; const evolutions = pokemonEvolutions[this.speciesId];
const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeIn'); const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeIn");
const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeOut'); const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeOut");
const evolutionPool: Map<number, Species> = new Map(); const evolutionPool: Map<number, Species> = new Map();
let totalWeight = 0; let totalWeight = 0;
let noEvolutionChance = 1; let noEvolutionChance = 1;
for (let ev of evolutions) { for (const ev of evolutions) {
if (ev.level > level) if (ev.level > level) {
continue; continue;
}
let evolutionChance: number; let evolutionChance: number;
const evolutionSpecies = getPokemonSpecies(ev.speciesId); const evolutionSpecies = getPokemonSpecies(ev.speciesId);
const isRegionalEvolution = !this.isRegional() && evolutionSpecies.isRegional(); const isRegionalEvolution = !this.isRegional() && evolutionSpecies.isRegional();
if (!forTrainer && isRegionalEvolution) if (!forTrainer && isRegionalEvolution) {
evolutionChance = 0; evolutionChance = 0;
else { } else {
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) { if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
if (strength === PartyMemberStrength.STRONGER) if (strength === PartyMemberStrength.STRONGER) {
evolutionChance = 1; evolutionChance = 1;
else { } else {
const maxLevelDiff = this.getStrengthLevelDiff(strength); const maxLevelDiff = this.getStrengthLevelDiff(strength);
const minChance: number = 0.875 - 0.125 * strength; const minChance: number = 0.875 - 0.125 * strength;
evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1); evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1);
} }
} else { } else {
let preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1); const preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1);
let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1); let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1);
if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) { if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) {
const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(ev => ev.speciesId === this.speciesId).level; const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(ev => ev.speciesId === this.speciesId).level;
if (prevolutionLevel > 1) if (prevolutionLevel > 1) {
evolutionLevel = prevolutionLevel; evolutionLevel = prevolutionLevel;
}
} }
evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1); evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1);
@ -633,26 +664,30 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
} }
if (evolutionChance > 0) { if (evolutionChance > 0) {
if (isRegionalEvolution) if (isRegionalEvolution) {
evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4); evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4);
}
totalWeight += evolutionChance; totalWeight += evolutionChance;
evolutionPool.set(totalWeight, ev.speciesId); evolutionPool.set(totalWeight, ev.speciesId);
if ((1 - evolutionChance) < noEvolutionChance) if ((1 - evolutionChance) < noEvolutionChance) {
noEvolutionChance = 1 - evolutionChance; noEvolutionChance = 1 - evolutionChance;
}
} }
} }
if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) {
return this.speciesId; return this.speciesId;
}
const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight); const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight);
for (let weight of evolutionPool.keys()) { for (const weight of evolutionPool.keys()) {
if (randValue < weight) if (randValue < weight) {
return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength); return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength);
}
} }
return this.speciesId; return this.speciesId;
@ -664,14 +699,15 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
//console.log(Species[this.speciesId], pokemonEvolutions[this.speciesId]) //console.log(Species[this.speciesId], pokemonEvolutions[this.speciesId])
if (pokemonEvolutions.hasOwnProperty(this.speciesId)) { if (pokemonEvolutions.hasOwnProperty(this.speciesId)) {
for (let e of pokemonEvolutions[this.speciesId]) { for (const e of pokemonEvolutions[this.speciesId]) {
const speciesId = e.speciesId; const speciesId = e.speciesId;
const level = e.level; const level = e.level;
evolutionLevels.push([ speciesId, level ]); evolutionLevels.push([ speciesId, level ]);
//console.log(Species[speciesId], getPokemonSpecies(speciesId), getPokemonSpecies(speciesId).getEvolutionLevels()); //console.log(Species[speciesId], getPokemonSpecies(speciesId), getPokemonSpecies(speciesId).getEvolutionLevels());
const nextEvolutionLevels = getPokemonSpecies(speciesId).getEvolutionLevels(); const nextEvolutionLevels = getPokemonSpecies(speciesId).getEvolutionLevels();
for (let npl of nextEvolutionLevels) for (const npl of nextEvolutionLevels) {
evolutionLevels.push(npl); evolutionLevels.push(npl);
}
} }
} }
@ -682,15 +718,16 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
const prevolutionLevels = []; const prevolutionLevels = [];
const allEvolvingPokemon = Object.keys(pokemonEvolutions); const allEvolvingPokemon = Object.keys(pokemonEvolutions);
for (let p of allEvolvingPokemon) { for (const p of allEvolvingPokemon) {
for (let e of pokemonEvolutions[p]) { for (const e of pokemonEvolutions[p]) {
if (e.speciesId === this.speciesId && (!this.forms.length || !e.evoFormKey || e.evoFormKey === this.forms[this.formIndex].formKey)) { if (e.speciesId === this.speciesId && (!this.forms.length || !e.evoFormKey || e.evoFormKey === this.forms[this.formIndex].formKey)) {
const speciesId = parseInt(p) as Species; const speciesId = parseInt(p) as Species;
let level = e.level; const level = e.level;
prevolutionLevels.push([ speciesId, level ]); prevolutionLevels.push([ speciesId, level ]);
const subPrevolutionLevels = getPokemonSpecies(speciesId).getPrevolutionLevels(); const subPrevolutionLevels = getPokemonSpecies(speciesId).getPrevolutionLevels();
for (let spl of subPrevolutionLevels) for (const spl of subPrevolutionLevels) {
prevolutionLevels.push(spl); prevolutionLevels.push(spl);
}
} }
} }
} }
@ -747,7 +784,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
} }
return this.forms?.length return this.forms?.length
? this.forms[formIndex || 0].getFormSpriteKey() ? this.forms[formIndex || 0].getFormSpriteKey()
: ''; : "";
} }
} }
@ -788,7 +825,7 @@ export enum SpeciesFormKey {
export const allSpecies: PokemonSpecies[] = []; export const allSpecies: PokemonSpecies[] = [];
export function initSpecies() { export function initSpecies() {
allSpecies.push( allSpecies.push(
new PokemonSpecies(Species.BULBASAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 0.7, 6.9, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 318, 45, 49, 49, 65, 65, 45, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.BULBASAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 0.7, 6.9, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 318, 45, 49, 49, 65, 65, 45, 45, 50, 64, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.IVYSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 1, 13, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 405, 60, 62, 63, 80, 80, 60, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false), new PokemonSpecies(Species.IVYSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 1, 13, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 405, 60, 62, 63, 80, 80, 60, 45, 50, 142, GrowthRate.MEDIUM_SLOW, 87.5, false),
new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true, new PokemonSpecies(Species.VENUSAUR, 1, false, false, false, "Seed Pokémon", Type.GRASS, Type.POISON, 2, 100, Abilities.OVERGROW, Abilities.NONE, Abilities.CHLOROPHYLL, 525, 80, 82, 83, 100, 100, 80, 45, 50, 263, GrowthRate.MEDIUM_SLOW, 87.5, true, true,
@ -3168,25 +3205,25 @@ export const noStarterFormKeys: string[] = [
export function getStarterValueFriendshipCap(value: integer): integer { export function getStarterValueFriendshipCap(value: integer): integer {
switch (value) { switch (value) {
case 1: case 1:
return 20; return 20;
case 2: case 2:
return 40; return 40;
case 3: case 3:
return 60; return 60;
case 4: case 4:
return 100; return 100;
case 5: case 5:
return 140; return 140;
case 6: case 6:
return 200; return 200;
case 7: case 7:
return 280; return 280;
case 8: case 8:
case 9: case 9:
return 450; return 450;
default: default:
return 600; return 600;
} }
} }
@ -3765,7 +3802,7 @@ export const starterPassiveAbilities = {
// TODO: Remove // TODO: Remove
{ {
//setTimeout(() => { //setTimeout(() => {
/*for (let tc of Object.keys(trainerConfigs)) { /*for (let tc of Object.keys(trainerConfigs)) {
console.log(TrainerType[tc], !trainerConfigs[tc].speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(trainerConfigs[tc].speciesFilter).map(s => { console.log(TrainerType[tc], !trainerConfigs[tc].speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(trainerConfigs[tc].speciesFilter).map(s => {
while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) while (pokemonPrevolutions.hasOwnProperty(s.speciesId))
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]); s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);

View File

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

View File

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

View File

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

View File

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

View File

@ -24,26 +24,30 @@ export class Terrain {
} }
lapse(): boolean { lapse(): boolean {
if (this.turnsLeft) if (this.turnsLeft) {
return !!--this.turnsLeft; return !!--this.turnsLeft;
}
return true; return true;
} }
getAttackTypeMultiplier(attackType: Type): number { getAttackTypeMultiplier(attackType: Type): number {
switch (this.terrainType) { switch (this.terrainType) {
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
if (attackType === Type.ELECTRIC) if (attackType === Type.ELECTRIC) {
return 1.3; return 1.3;
break; }
case TerrainType.GRASSY: break;
if (attackType === Type.GRASS) case TerrainType.GRASSY:
return 1.3; if (attackType === Type.GRASS) {
break; return 1.3;
case TerrainType.PSYCHIC: }
if (attackType === Type.PSYCHIC) break;
return 1.3; case TerrainType.PSYCHIC:
break; if (attackType === Type.PSYCHIC) {
return 1.3;
}
break;
} }
return 1; return 1;
@ -51,12 +55,12 @@ export class Terrain {
isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean { isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean {
switch (this.terrainType) { switch (this.terrainType) {
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
if (!move.getAttrs(ProtectAttr).length) { if (!move.getAttrs(ProtectAttr).length) {
const priority = new Utils.IntegerHolder(move.priority); const priority = new Utils.IntegerHolder(move.priority);
applyAbAttrs(IncrementMovePriorityAbAttr, user, null, move, priority); applyAbAttrs(IncrementMovePriorityAbAttr, user, null, move, priority);
return priority.value > 0 && user.getOpponents().filter(o => targets.includes(o.getBattlerIndex())).length > 0; return priority.value > 0 && user.getOpponents().filter(o => targets.includes(o.getBattlerIndex())).length > 0;
} }
} }
return false; return false;
@ -65,14 +69,14 @@ export class Terrain {
export function getTerrainColor(terrainType: TerrainType): [ integer, integer, integer ] { export function getTerrainColor(terrainType: TerrainType): [ integer, integer, integer ] {
switch (terrainType) { switch (terrainType) {
case TerrainType.MISTY: case TerrainType.MISTY:
return [ 232, 136, 200 ]; return [ 232, 136, 200 ];
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
return [ 248, 248, 120 ]; return [ 248, 248, 120 ];
case TerrainType.GRASSY: case TerrainType.GRASSY:
return [ 120, 200, 80 ]; return [ 120, 200, 80 ];
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
return [ 160, 64, 160 ]; return [ 160, 64, 160 ];
} }
return [ 0, 0, 0 ]; return [ 0, 0, 0 ];

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ class TrainerNameConfig {
public femaleUrls: string[]; public femaleUrls: string[];
constructor(type: TrainerType, ...urls: string[]) { constructor(type: TrainerType, ...urls: string[]) {
this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, '_') ]; this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, "_") ];
} }
hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig { hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig {
@ -19,6 +19,8 @@ interface TrainerNameConfigs {
[key: integer]: TrainerNameConfig [key: integer]: TrainerNameConfig
} }
// used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const trainerNameConfigs: TrainerNameConfigs = { const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER), [TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER),
[TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST), [TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST),
@ -27,13 +29,13 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER), [TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER),
[TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY), [TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY),
[TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER), [TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant('Battle_Girl'), [TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant("Battle_Girl"),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, 'Pokémon_Breeder'), [TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, "Pokémon_Breeder"),
[TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK), [TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK),
[TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST), [TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST),
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER), [TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
[TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT), [TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT),
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant('Nurse'), [TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant("Nurse"),
[TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN), [TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN),
[TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST), [TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN), [TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
@ -50,113 +52,118 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER), [TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER),
[TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY), [TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY),
[TrainerType.PILOT]: new TrainerNameConfig(TrainerType.PILOT), [TrainerType.PILOT]: new TrainerNameConfig(TrainerType.PILOT),
[TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, 'Poké_Fan'), [TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, "Poké_Fan"),
[TrainerType.PRESCHOOLER]: new TrainerNameConfig(TrainerType.PRESCHOOLER), [TrainerType.PRESCHOOLER]: new TrainerNameConfig(TrainerType.PRESCHOOLER),
[TrainerType.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC), [TrainerType.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC),
[TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER), [TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, 'Gentleman').hasGenderVariant('Madame'), [TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, "Gentleman").hasGenderVariant("Madame"),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, 'Rich_Boy').hasGenderVariant('Lady'), [TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, "Rich_Boy").hasGenderVariant("Lady"),
[TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK), [TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK),
[TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST), [TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST),
[TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER), [TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER),
[TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, 'Worker'), [TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, "Worker"),
[TrainerType.STRIKER]: new TrainerNameConfig(TrainerType.STRIKER), [TrainerType.STRIKER]: new TrainerNameConfig(TrainerType.STRIKER),
[TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, 'School_Kid'), [TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, "School_Kid"),
[TrainerType.SWIMMER]: new TrainerNameConfig(TrainerType.SWIMMER), [TrainerType.SWIMMER]: new TrainerNameConfig(TrainerType.SWIMMER),
[TrainerType.TWINS]: new TrainerNameConfig(TrainerType.TWINS), [TrainerType.TWINS]: new TrainerNameConfig(TrainerType.TWINS),
[TrainerType.VETERAN]: new TrainerNameConfig(TrainerType.VETERAN), [TrainerType.VETERAN]: new TrainerNameConfig(TrainerType.VETERAN),
[TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant('Waitress'), [TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant("Waitress"),
[TrainerType.WORKER]: new TrainerNameConfig(TrainerType.WORKER), [TrainerType.WORKER]: new TrainerNameConfig(TrainerType.WORKER),
[TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant('Lass') [TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant("Lass")
}; };
export const trainerNamePools = { export const trainerNamePools = {
[TrainerType.ACE_TRAINER]: [["Aaron","Allen","Blake","Brian","Gaven","Jake","Kevin","Mike","Nick","Paul","Ryan","Sean","Darin","Albert","Berke","Clyde","Edgar","George","Leroy","Owen","Parker","Randall","Ruben","Samuel","Vincent","Warren","Wilton","Zane","Alfred","Braxton","Felix","Gerald","Jonathan","Leonel","Marcel","Mitchell","Quincy","Roderick","Colby","Rolando","Yuji","Abel","Anton","Arthur","Cesar","Dalton","Dennis","Ernest","Garrett","Graham","Henry","Isaiah","Jonah","Jose","Keenan","Micah","Omar","Quinn","Rodolfo","Saul","Sergio","Skylar","Stefan","Zachery","Alton","Arabella","Bonita","Cal","Cody","French","Kobe","Paulo","Shaye","Austin","Beckett","Charlie","Corky","David","Dwayne","Elmer","Jesse","Jared","Johan","Jordan","Kipp","Lou","Terry","Tom","Webster","Billy","Doyle","Enzio","Geoff","Grant","Kelsey","Miguel","Pierce","Ray","Santino","Shel","Adelbert","Bence","Emil","Evan","Mathis","Maxim","Neil","Rico","Robbie","Theo","Viktor","Benedict","Cornelius","Hisato","Leopold","Neville","Vito","Chase","Cole","Hiroshi","Jackson","Jim","Kekoa","Makana","Yuki","Elwood","Seth","Alvin","Arjun","Arnold","Cameron","Carl","Carlton","Christopher","Dave","Dax","Dominic","Edmund","Finn","Fred","Garret","Grayson","Jace","Jaxson","Jay","Jirard","Johnson","Kayden","Kite","Louis","Mac","Marty","Percy","Raymond","Ronnie","Satch","Tim","Zach","Conner","Vince","Bedro","Boda","Botan","Daras","Dury","Herton","Rewn","Stum","Tock","Trilo","Berki","Cruik","Dazon","Desid","Dillot","Farfin","Forgon","Hebel","Morfon","Moril","Shadd","Vanhub","Bardo","Carben","Degin","Gorps","Klept","Lask","Malex","Mopar","Niled","Noxon","Teslor","Tetil"],["Beth","Carol","Cybil","Emma","Fran","Gwen","Irene","Jenn","Joyce","Kate","Kelly","Lois","Lola","Megan","Quinn","Reena","Cara","Alexa","Brooke","Caroline","Elaine","Hope","Jennifer","Jody","Julie","Lori","Mary","Michelle","Shannon","Wendy","Alexia","Alicia","Athena","Carolina","Cristin","Darcy","Dianne","Halle","Jazmyn","Katelynn","Keira","Marley","Allyson","Kathleen","Naomi","Alyssa","Ariana","Brandi","Breanna","Brenda","Brenna","Catherine","Clarice","Dana","Deanna","Destiny","Jamie","Jasmin","Kassandra","Laura","Maria","Mariah","Maya","Meagan","Mikayla","Monique","Natasha","Olivia","Sandra","Savannah","Sydney","Moira","Piper","Salma","Allison","Beverly","Cathy","Cheyenne","Clara","Dara","Eileen","Glinda","Junko","Lena","Lucille","Mariana","Olwen","Shanta","Stella","Angi","Belle","Chandra","Cora","Eve","Jacqueline","Jeanne","Juliet","Kathrine","Layla","Lucca","Melina","Miki","Nina","Sable","Shelly","Summer","Trish","Vicki","Alanza","Cordelia","Hilde","Imelda","Michele","Mireille","Claudia","Constance","Harriet","Honor","Melba","Portia","Alexis","Angela","Karla","Lindsey","Tori","Sheri","Jada","Kailee","Amanda","Annie","Kindra","Kyla","Sofia","Yvette","Becky","Flora","Gloria","Buna","Ferda","Lehan","Liqui","Lomen","Neira","Atilo","Detta","Gilly","Gosney","Levens","Moden","Rask","Rateis","Rosno","Tynan","Veron","Zoel","Cida","Dibsin","Dodin","Ebson","Equin","Flostin","Gabsen","Halsion","Hileon","Quelor","Rapeel","Roze","Tensin"]], [TrainerType.ACE_TRAINER]: [["Aaron","Allen","Blake","Brian","Gaven","Jake","Kevin","Mike","Nick","Paul","Ryan","Sean","Darin","Albert","Berke","Clyde","Edgar","George","Leroy","Owen","Parker","Randall","Ruben","Samuel","Vincent","Warren","Wilton","Zane","Alfred","Braxton","Felix","Gerald","Jonathan","Leonel","Marcel","Mitchell","Quincy","Roderick","Colby","Rolando","Yuji","Abel","Anton","Arthur","Cesar","Dalton","Dennis","Ernest","Garrett","Graham","Henry","Isaiah","Jonah","Jose","Keenan","Micah","Omar","Quinn","Rodolfo","Saul","Sergio","Skylar","Stefan","Zachery","Alton","Arabella","Bonita","Cal","Cody","French","Kobe","Paulo","Shaye","Austin","Beckett","Charlie","Corky","David","Dwayne","Elmer","Jesse","Jared","Johan","Jordan","Kipp","Lou","Terry","Tom","Webster","Billy","Doyle","Enzio","Geoff","Grant","Kelsey","Miguel","Pierce","Ray","Santino","Shel","Adelbert","Bence","Emil","Evan","Mathis","Maxim","Neil","Rico","Robbie","Theo","Viktor","Benedict","Cornelius","Hisato","Leopold","Neville","Vito","Chase","Cole","Hiroshi","Jackson","Jim","Kekoa","Makana","Yuki","Elwood","Seth","Alvin","Arjun","Arnold","Cameron","Carl","Carlton","Christopher","Dave","Dax","Dominic","Edmund","Finn","Fred","Garret","Grayson","Jace","Jaxson","Jay","Jirard","Johnson","Kayden","Kite","Louis","Mac","Marty","Percy","Raymond","Ronnie","Satch","Tim","Zach","Conner","Vince","Bedro","Boda","Botan","Daras","Dury","Herton","Rewn","Stum","Tock","Trilo","Berki","Cruik","Dazon","Desid","Dillot","Farfin","Forgon","Hebel","Morfon","Moril","Shadd","Vanhub","Bardo","Carben","Degin","Gorps","Klept","Lask","Malex","Mopar","Niled","Noxon","Teslor","Tetil"],["Beth","Carol","Cybil","Emma","Fran","Gwen","Irene","Jenn","Joyce","Kate","Kelly","Lois","Lola","Megan","Quinn","Reena","Cara","Alexa","Brooke","Caroline","Elaine","Hope","Jennifer","Jody","Julie","Lori","Mary","Michelle","Shannon","Wendy","Alexia","Alicia","Athena","Carolina","Cristin","Darcy","Dianne","Halle","Jazmyn","Katelynn","Keira","Marley","Allyson","Kathleen","Naomi","Alyssa","Ariana","Brandi","Breanna","Brenda","Brenna","Catherine","Clarice","Dana","Deanna","Destiny","Jamie","Jasmin","Kassandra","Laura","Maria","Mariah","Maya","Meagan","Mikayla","Monique","Natasha","Olivia","Sandra","Savannah","Sydney","Moira","Piper","Salma","Allison","Beverly","Cathy","Cheyenne","Clara","Dara","Eileen","Glinda","Junko","Lena","Lucille","Mariana","Olwen","Shanta","Stella","Angi","Belle","Chandra","Cora","Eve","Jacqueline","Jeanne","Juliet","Kathrine","Layla","Lucca","Melina","Miki","Nina","Sable","Shelly","Summer","Trish","Vicki","Alanza","Cordelia","Hilde","Imelda","Michele","Mireille","Claudia","Constance","Harriet","Honor","Melba","Portia","Alexis","Angela","Karla","Lindsey","Tori","Sheri","Jada","Kailee","Amanda","Annie","Kindra","Kyla","Sofia","Yvette","Becky","Flora","Gloria","Buna","Ferda","Lehan","Liqui","Lomen","Neira","Atilo","Detta","Gilly","Gosney","Levens","Moden","Rask","Rateis","Rosno","Tynan","Veron","Zoel","Cida","Dibsin","Dodin","Ebson","Equin","Flostin","Gabsen","Halsion","Hileon","Quelor","Rapeel","Roze","Tensin"]],
[TrainerType.ARTIST]: [["Ismael","William","Horton","Pierre","Zach","Gough","Salvador","Vincent","Duncan"],["Georgia"]], [TrainerType.ARTIST]: [["Ismael","William","Horton","Pierre","Zach","Gough","Salvador","Vincent","Duncan"],["Georgia"]],
[TrainerType.BACKERS]: [["Alf & Fred","Hawk & Dar","Joe & Ross","Les & Web","Masa & Yas","Stu & Art"],["Ai & Ciel","Ami & Eira","Cam & Abby","Fey & Sue","Kat & Phae","Kay & Ali","Ava & Aya","Cleo & Rio","May & Mal"]], [TrainerType.BACKERS]: [["Alf & Fred","Hawk & Dar","Joe & Ross","Les & Web","Masa & Yas","Stu & Art"],["Ai & Ciel","Ami & Eira","Cam & Abby","Fey & Sue","Kat & Phae","Kay & Ali","Ava & Aya","Cleo & Rio","May & Mal"]],
[TrainerType.BACKPACKER]: [["Alexander","Carlos","Herman","Jerome","Keane","Kelsey","Kiyo","Michael","Nate","Peter","Sam","Stephen","Talon","Terrance","Toru","Waylon","Boone","Clifford","Ivan","Kendall","Lowell","Randall","Reece","Roland","Shane","Walt","Farid","Heike","Joren","Lane","Roderick","Darnell","Deon","Emory","Graeme","Grayson","Ashley","Mikiko","Kiana","Perdy","Maria","Yuho","Peren","Barbara","Diane","Ruth","Aitor","Alex","Arturo","Asier","Jaime","Jonathan","Julio","Kevin","Kosuke","Lander","Markel","Mateo","Nil","Pau","Samuel"],["Anna","Corin","Elaine","Emi","Jill","Kumiko","Liz","Lois","Lora","Molly","Patty","Ruth","Vicki","Annie","Blossom","Clara","Eileen","Mae","Myra","Rachel","Tami"]], [TrainerType.BACKPACKER]: [["Alexander","Carlos","Herman","Jerome","Keane","Kelsey","Kiyo","Michael","Nate","Peter","Sam","Stephen","Talon","Terrance","Toru","Waylon","Boone","Clifford","Ivan","Kendall","Lowell","Randall","Reece","Roland","Shane","Walt","Farid","Heike","Joren","Lane","Roderick","Darnell","Deon","Emory","Graeme","Grayson","Ashley","Mikiko","Kiana","Perdy","Maria","Yuho","Peren","Barbara","Diane","Ruth","Aitor","Alex","Arturo","Asier","Jaime","Jonathan","Julio","Kevin","Kosuke","Lander","Markel","Mateo","Nil","Pau","Samuel"],["Anna","Corin","Elaine","Emi","Jill","Kumiko","Liz","Lois","Lora","Molly","Patty","Ruth","Vicki","Annie","Blossom","Clara","Eileen","Mae","Myra","Rachel","Tami"]],
[TrainerType.BAKER]: ["Chris","Jenn","Lilly"], [TrainerType.BAKER]: ["Chris","Jenn","Lilly"],
[TrainerType.BEAUTY]: ["Cassie","Julia","Olivia","Samantha","Valerie","Victoria","Bridget","Connie","Jessica","Johanna","Melissa","Sheila","Shirley","Tiffany","Namiko","Thalia","Grace","Lola","Lori","Maura","Tamia","Cyndy","Devon","Gabriella","Harley","Lindsay","Nicola","Callie","Charlotte","Kassandra","December","Fleming","Nikola","Aimee","Anais","Brigitte","Cassandra","Andrea","Brittney","Carolyn","Krystal","Alexis","Alice","Aina","Anya","Arianna","Aubrey","Beverly","Camille","Beauty","Evette","Hansol","Haruka","Jill","Jo","Lana","Lois","Lucy","Mai","Nickie","Nicole","Prita","Rose","Shelly","Suzy","Tessa","Anita","Alissa","Rita","Cudsy","Eloff","Miru","Minot","Nevah","Niven","Ogoin"], [TrainerType.BEAUTY]: ["Cassie","Julia","Olivia","Samantha","Valerie","Victoria","Bridget","Connie","Jessica","Johanna","Melissa","Sheila","Shirley","Tiffany","Namiko","Thalia","Grace","Lola","Lori","Maura","Tamia","Cyndy","Devon","Gabriella","Harley","Lindsay","Nicola","Callie","Charlotte","Kassandra","December","Fleming","Nikola","Aimee","Anais","Brigitte","Cassandra","Andrea","Brittney","Carolyn","Krystal","Alexis","Alice","Aina","Anya","Arianna","Aubrey","Beverly","Camille","Beauty","Evette","Hansol","Haruka","Jill","Jo","Lana","Lois","Lucy","Mai","Nickie","Nicole","Prita","Rose","Shelly","Suzy","Tessa","Anita","Alissa","Rita","Cudsy","Eloff","Miru","Minot","Nevah","Niven","Ogoin"],
[TrainerType.BIKER]: ["Charles","Dwayne","Glenn","Harris","Joel","Riley","Zeke","Alex","Billy","Ernest","Gerald","Hideo","Isaac","Jared","Jaren","Jaxon","Jordy","Lao","Lukas","Malik","Nikolas","Ricardo","Ruben","Virgil","William","Aiden","Dale","Dan","Jacob","Markey","Reese","Teddy","Theron","Jeremy","Morgann","Phillip","Philip","Stanley","Dillon"], [TrainerType.BIKER]: ["Charles","Dwayne","Glenn","Harris","Joel","Riley","Zeke","Alex","Billy","Ernest","Gerald","Hideo","Isaac","Jared","Jaren","Jaxon","Jordy","Lao","Lukas","Malik","Nikolas","Ricardo","Ruben","Virgil","William","Aiden","Dale","Dan","Jacob","Markey","Reese","Teddy","Theron","Jeremy","Morgann","Phillip","Philip","Stanley","Dillon"],
[TrainerType.BLACK_BELT]: [["Kenji","Lao","Lung","Nob","Wai","Yoshi","Atsushi","Daisuke","Hideki","Hitoshi","Kiyo","Koichi","Koji","Yuji","Cristian","Rhett","Takao","Theodore","Zander","Aaron","Hugh","Mike","Nicolas","Shea","Takashi","Adam","Carl","Colby","Darren","David","Davon","Derek","Eddie","Gregory","Griffin","Jarrett","Jeffery","Kendal","Kyle","Luke","Miles","Nathaniel","Philip","Rafael","Ray","Ricky","Sean","Willie","Ander","Manford","Benjamin","Corey","Edward","Grant","Jay","Kendrew","Kentaro","Ryder","Teppei","Thomas","Tyrone","Andrey","Donny","Drago","Gordon","Grigor","Jeriel","Kenneth","Martell","Mathis","Rich","Rocky","Rodrigo","Wesley","Zachery","Alonzo","Cadoc","Gunnar","Igor","Killian","Markus","Ricardo","Yanis","Banting","Clayton","Duane","Earl","Greg","Roy","Terry","Tracy","Walter","Alvaro","Curtis","Francis","Ross","Brice","Cheng","Dudley","Eric","Kano","Masahiro","Randy","Ryuji","Steve","Tadashi","Wong","Yuen","Brian","Carter","Reece","Nick","Yang"],["Cora","Cyndy","Jill","Laura","Sadie","Tessa","Vivian","Aisha","Callie","Danielle","Helene","Jocelyn","Lilith","Paula","Reyna","Helen","Kelsey","Tyler","Amy","Chandra","Hillary","Janie","Lee","Maggie","Mikiko","Miriam","Sharon","Susie","Xiao","Alize","Azra","Brenda","Chalina","Chan","Glinda","Maki","Tia","Tiffany","Wendy","Andrea","Gabrielle","Gerardine","Hailey","Hedvig","Justine","Kinsey","Sigrid","Veronique","Tess"]], [TrainerType.BLACK_BELT]: [["Kenji","Lao","Lung","Nob","Wai","Yoshi","Atsushi","Daisuke","Hideki","Hitoshi","Kiyo","Koichi","Koji","Yuji","Cristian","Rhett","Takao","Theodore","Zander","Aaron","Hugh","Mike","Nicolas","Shea","Takashi","Adam","Carl","Colby","Darren","David","Davon","Derek","Eddie","Gregory","Griffin","Jarrett","Jeffery","Kendal","Kyle","Luke","Miles","Nathaniel","Philip","Rafael","Ray","Ricky","Sean","Willie","Ander","Manford","Benjamin","Corey","Edward","Grant","Jay","Kendrew","Kentaro","Ryder","Teppei","Thomas","Tyrone","Andrey","Donny","Drago","Gordon","Grigor","Jeriel","Kenneth","Martell","Mathis","Rich","Rocky","Rodrigo","Wesley","Zachery","Alonzo","Cadoc","Gunnar","Igor","Killian","Markus","Ricardo","Yanis","Banting","Clayton","Duane","Earl","Greg","Roy","Terry","Tracy","Walter","Alvaro","Curtis","Francis","Ross","Brice","Cheng","Dudley","Eric","Kano","Masahiro","Randy","Ryuji","Steve","Tadashi","Wong","Yuen","Brian","Carter","Reece","Nick","Yang"],["Cora","Cyndy","Jill","Laura","Sadie","Tessa","Vivian","Aisha","Callie","Danielle","Helene","Jocelyn","Lilith","Paula","Reyna","Helen","Kelsey","Tyler","Amy","Chandra","Hillary","Janie","Lee","Maggie","Mikiko","Miriam","Sharon","Susie","Xiao","Alize","Azra","Brenda","Chalina","Chan","Glinda","Maki","Tia","Tiffany","Wendy","Andrea","Gabrielle","Gerardine","Hailey","Hedvig","Justine","Kinsey","Sigrid","Veronique","Tess"]],
[TrainerType.BREEDER]: [["Isaac","Myles","Salvadore","Albert","Kahlil","Eustace","Galen","Owen","Addison","Marcus","Foster","Cory","Glenn","Jay","Wesley","William","Adrian","Bradley","Jaime"],["Allison","Alize","Bethany","Lily","Lydia","Gabrielle","Jayden","Pat","Veronica","Amber","Jennifer","Kaylee","Adelaide","Brooke","Ethel","April","Irene","Magnolia","Amala","Mercy","Amanda","Ikue","Savannah","Yuka","Chloe","Debra","Denise","Elena"]], [TrainerType.BREEDER]: [["Isaac","Myles","Salvadore","Albert","Kahlil","Eustace","Galen","Owen","Addison","Marcus","Foster","Cory","Glenn","Jay","Wesley","William","Adrian","Bradley","Jaime"],["Allison","Alize","Bethany","Lily","Lydia","Gabrielle","Jayden","Pat","Veronica","Amber","Jennifer","Kaylee","Adelaide","Brooke","Ethel","April","Irene","Magnolia","Amala","Mercy","Amanda","Ikue","Savannah","Yuka","Chloe","Debra","Denise","Elena"]],
[TrainerType.CLERK]: [["Chaz","Clemens","Doug","Fredric","Ivan","Isaac","Nelson","Wade","Warren","Augustin","Gilligan","Cody","Jeremy","Shane","Dugal","Royce","Ronald"],["Alberta","Ingrid","Katie","Piper","Trisha","Wren","Britney","Lana","Jessica","Kristen","Michelle","Gabrielle"]], [TrainerType.CLERK]: [["Chaz","Clemens","Doug","Fredric","Ivan","Isaac","Nelson","Wade","Warren","Augustin","Gilligan","Cody","Jeremy","Shane","Dugal","Royce","Ronald"],["Alberta","Ingrid","Katie","Piper","Trisha","Wren","Britney","Lana","Jessica","Kristen","Michelle","Gabrielle"]],
[TrainerType.CYCLIST]: [["Axel","James","John","Ryan","Hector","Jeremiah"],["Kayla","Megan","Nicole","Rachel","Krissa","Adelaide"]], [TrainerType.CYCLIST]: [["Axel","James","John","Ryan","Hector","Jeremiah"],["Kayla","Megan","Nicole","Rachel","Krissa","Adelaide"]],
[TrainerType.DANCER]: ["Brian","Davey","Dirk","Edmond","Mickey","Raymond","Cara","Julia","Maika","Mireille","Ronda","Zoe"], [TrainerType.DANCER]: ["Brian","Davey","Dirk","Edmond","Mickey","Raymond","Cara","Julia","Maika","Mireille","Ronda","Zoe"],
[TrainerType.DEPOT_AGENT]: ["Josh","Hank","Vincent"], [TrainerType.DEPOT_AGENT]: ["Josh","Hank","Vincent"],
[TrainerType.DOCTOR]: [["Hank","Jerry","Jules","Logan","Wayne","Braid","Derek","Heath","Julius","Kit","Graham"],["Kirsten","Sachiko","Shery","Carol","Dixie","Mariah"]], [TrainerType.DOCTOR]: [["Hank","Jerry","Jules","Logan","Wayne","Braid","Derek","Heath","Julius","Kit","Graham"],["Kirsten","Sachiko","Shery","Carol","Dixie","Mariah"]],
[TrainerType.FISHERMAN]: ["Andre","Arnold","Barney","Chris","Edgar","Henry","Jonah","Justin","Kyle","Martin","Marvin","Ralph","Raymond","Scott","Stephen","Wilton","Tully","Andrew","Barny","Carter","Claude","Dale","Elliot","Eugene","Ivan","Ned","Nolan","Roger","Ronald","Wade","Wayne","Darian","Kai","Chip","Hank","Kaden","Tommy","Tylor","Alec","Brett","Cameron","Cody","Cole","Cory","Erick","George","Joseph","Juan","Kenneth","Luc","Miguel","Travis","Walter","Zachary","Josh","Gideon","Kyler","Liam","Murphy","Bruce","Damon","Devon","Hubert","Jones","Lydon","Mick","Pete","Sean","Sid","Vince","Bucky","Dean","Eustace","Kenzo","Leroy","Mack","Ryder","Ewan","Finn","Murray","Seward","Shad","Wharton","Finley","Fisher","Fisk","River","Sheaffer","Timin","Carl","Ernest","Hal","Herbert","Hisato","Mike","Vernon","Harriet","Marina","Chase"], [TrainerType.FISHERMAN]: ["Andre","Arnold","Barney","Chris","Edgar","Henry","Jonah","Justin","Kyle","Martin","Marvin","Ralph","Raymond","Scott","Stephen","Wilton","Tully","Andrew","Barny","Carter","Claude","Dale","Elliot","Eugene","Ivan","Ned","Nolan","Roger","Ronald","Wade","Wayne","Darian","Kai","Chip","Hank","Kaden","Tommy","Tylor","Alec","Brett","Cameron","Cody","Cole","Cory","Erick","George","Joseph","Juan","Kenneth","Luc","Miguel","Travis","Walter","Zachary","Josh","Gideon","Kyler","Liam","Murphy","Bruce","Damon","Devon","Hubert","Jones","Lydon","Mick","Pete","Sean","Sid","Vince","Bucky","Dean","Eustace","Kenzo","Leroy","Mack","Ryder","Ewan","Finn","Murray","Seward","Shad","Wharton","Finley","Fisher","Fisk","River","Sheaffer","Timin","Carl","Ernest","Hal","Herbert","Hisato","Mike","Vernon","Harriet","Marina","Chase"],
[TrainerType.GUITARIST]: ["Anna","Beverly","January","Tina","Alicia","Claudia","Julia","Lidia","Mireia","Noelia","Sara","Sheila","Tatiana"], [TrainerType.GUITARIST]: ["Anna","Beverly","January","Tina","Alicia","Claudia","Julia","Lidia","Mireia","Noelia","Sara","Sheila","Tatiana"],
[TrainerType.HARLEQUIN]: ["Charley","Ian","Jack","Kerry","Louis","Pat","Paul","Rick","Anders","Clarence","Gary"], [TrainerType.HARLEQUIN]: ["Charley","Ian","Jack","Kerry","Louis","Pat","Paul","Rick","Anders","Clarence","Gary"],
[TrainerType.HIKER]: ["Anthony","Bailey","Benjamin","Daniel","Erik","Jim","Kenny","Leonard","Michael","Parry","Phillip","Russell","Sidney","Tim","Timothy","Alan","Brice","Clark","Eric","Lenny","Lucas","Mike","Trent","Devan","Eli","Marc","Sawyer","Allen","Daryl","Dudley","Earl","Franklin","Jeremy","Marcos","Nob","Oliver","Wayne","Alexander","Damon","Jonathan","Justin","Kevin","Lorenzo","Louis","Maurice","Nicholas","Reginald","Robert","Theodore","Bruce","Clarke","Devin","Dwight","Edwin","Eoin","Noland","Russel","Andy","Bret","Darrell","Gene","Hardy","Hugh","Jebediah","Jeremiah","Kit","Neil","Terrell","Don","Doug","Hunter","Jared","Jerome","Keith","Manuel","Markus","Otto","Shelby","Stephen","Teppei","Tobias","Wade","Zaiem","Aaron","Alain","Bergin","Bernard","Brent","Corwin","Craig","Delmon","Dunstan","Orestes","Ross","Davian","Calhoun","David","Gabriel","Ryan","Thomas","Travis","Zachary","Anuhea","Barnaby","Claus","Collin","Colson","Dexter","Dillan","Eugine","Farkas","Hisato","Julius","Kenji","Irwin","Lionel","Paul","Richter","Valentino","Donald","Douglas","Kevyn","Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira","Chester"], [TrainerType.HIKER]: ["Anthony","Bailey","Benjamin","Daniel","Erik","Jim","Kenny","Leonard","Michael","Parry","Phillip","Russell","Sidney","Tim","Timothy","Alan","Brice","Clark","Eric","Lenny","Lucas","Mike","Trent","Devan","Eli","Marc","Sawyer","Allen","Daryl","Dudley","Earl","Franklin","Jeremy","Marcos","Nob","Oliver","Wayne","Alexander","Damon","Jonathan","Justin","Kevin","Lorenzo","Louis","Maurice","Nicholas","Reginald","Robert","Theodore","Bruce","Clarke","Devin","Dwight","Edwin","Eoin","Noland","Russel","Andy","Bret","Darrell","Gene","Hardy","Hugh","Jebediah","Jeremiah","Kit","Neil","Terrell","Don","Doug","Hunter","Jared","Jerome","Keith","Manuel","Markus","Otto","Shelby","Stephen","Teppei","Tobias","Wade","Zaiem","Aaron","Alain","Bergin","Bernard","Brent","Corwin","Craig","Delmon","Dunstan","Orestes","Ross","Davian","Calhoun","David","Gabriel","Ryan","Thomas","Travis","Zachary","Anuhea","Barnaby","Claus","Collin","Colson","Dexter","Dillan","Eugine","Farkas","Hisato","Julius","Kenji","Irwin","Lionel","Paul","Richter","Valentino","Donald","Douglas","Kevyn","Angela","Carla","Celia","Daniela","Estela","Fatima","Helena","Leire","Lucia","Luna","Manuela","Mar","Marina","Miyu","Nancy","Nerea","Paula","Rocio","Yanira","Chester"],
[TrainerType.HOOLIGANS]: ["Jim & Cas","Rob & Sal"], [TrainerType.HOOLIGANS]: ["Jim & Cas","Rob & Sal"],
[TrainerType.HOOPSTER]: ["Bobby","John","Lamarcus","Derrick","Nicolas"], [TrainerType.HOOPSTER]: ["Bobby","John","Lamarcus","Derrick","Nicolas"],
[TrainerType.INFIELDER]: ["Alex","Connor","Todd"], [TrainerType.INFIELDER]: ["Alex","Connor","Todd"],
[TrainerType.JANITOR]: ["Caleb","Geoff","Brady","Felix","Orville","Melvin","Shawn"], [TrainerType.JANITOR]: ["Caleb","Geoff","Brady","Felix","Orville","Melvin","Shawn"],
[TrainerType.LINEBACKER]: ["Bob","Dan","Jonah"], [TrainerType.LINEBACKER]: ["Bob","Dan","Jonah"],
[TrainerType.MAID]: ["Belinda","Sophie","Emily","Elena","Clare","Alica","Tanya","Tammy"], [TrainerType.MAID]: ["Belinda","Sophie","Emily","Elena","Clare","Alica","Tanya","Tammy"],
[TrainerType.MUSICIAN]: ["Boris","Preston","Charles","Clyde","Vincent","Dalton","Kirk","Shawn","Fabian","Fernando","Joseph","Marcos","Arturo","Jerry","Lonnie","Tony"], [TrainerType.MUSICIAN]: ["Boris","Preston","Charles","Clyde","Vincent","Dalton","Kirk","Shawn","Fabian","Fernando","Joseph","Marcos","Arturo","Jerry","Lonnie","Tony"],
[TrainerType.NURSERY_AIDE]: ["Autumn","Briana","Leah","Miho","Ethel","Hollie","Ilse","June","Kimya","Rosalyn"], [TrainerType.NURSERY_AIDE]: ["Autumn","Briana","Leah","Miho","Ethel","Hollie","Ilse","June","Kimya","Rosalyn"],
[TrainerType.OFFICER]: ["Dirk","Keith","Alex","Bobby","Caleb","Danny","Dylan","Thomas","Daniel","Jeff","Braven","Dell","Neagle","Haruki","Mitchell","Raymond"], [TrainerType.OFFICER]: ["Dirk","Keith","Alex","Bobby","Caleb","Danny","Dylan","Thomas","Daniel","Jeff","Braven","Dell","Neagle","Haruki","Mitchell","Raymond"],
[TrainerType.PARASOL_LADY]: ["Angelica","Clarissa","Madeline","Akari","Annabell","Kayley","Rachel","Alexa","Sabrina","April","Gwyneth","Laura","Lumi","Mariah","Melita","Nicole","Tihana","Ingrid","Tyra"], [TrainerType.PARASOL_LADY]: ["Angelica","Clarissa","Madeline","Akari","Annabell","Kayley","Rachel","Alexa","Sabrina","April","Gwyneth","Laura","Lumi","Mariah","Melita","Nicole","Tihana","Ingrid","Tyra"],
[TrainerType.PILOT]: ["Chase","Leonard","Ted","Elron","Ewing","Flynn","Winslow"], [TrainerType.PILOT]: ["Chase","Leonard","Ted","Elron","Ewing","Flynn","Winslow"],
[TrainerType.POKEFAN]: [["Alex","Allan","Brandon","Carter","Colin","Derek","Jeremy","Joshua","Rex","Robert","Trevor","William","Colton","Miguel","Francisco","Kaleb","Leonard","Boone","Elliot","Jude","Norbert","Corey","Gabe","Baxter"],["Beverly","Georgia","Jaime","Ruth","Isabel","Marissa","Vanessa","Annika","Bethany","Kimberly","Meredith","Rebekah","Eleanor","Darcy","Lydia","Sachiko","Abigail","Agnes","Lydie","Roisin","Tara","Carmen","Janet"]], [TrainerType.POKEFAN]: [["Alex","Allan","Brandon","Carter","Colin","Derek","Jeremy","Joshua","Rex","Robert","Trevor","William","Colton","Miguel","Francisco","Kaleb","Leonard","Boone","Elliot","Jude","Norbert","Corey","Gabe","Baxter"],["Beverly","Georgia","Jaime","Ruth","Isabel","Marissa","Vanessa","Annika","Bethany","Kimberly","Meredith","Rebekah","Eleanor","Darcy","Lydia","Sachiko","Abigail","Agnes","Lydie","Roisin","Tara","Carmen","Janet"]],
[TrainerType.PRESCHOOLER]: [["Billy","Doyle","Evan","Homer","Tully","Albert","Buster","Greg","Ike","Jojo","Tyrone","Adrian","Oliver","Hayden","Hunter","Kaleb","Liam","Dylan"],["Juliet","Mia","Sarah","Wendy","Winter","Chrissy","Eva","Lin","Samantha","Ella","Lily","Natalie","Ailey","Hannah","Malia","Kindra","Nancy"]], [TrainerType.PRESCHOOLER]: [["Billy","Doyle","Evan","Homer","Tully","Albert","Buster","Greg","Ike","Jojo","Tyrone","Adrian","Oliver","Hayden","Hunter","Kaleb","Liam","Dylan"],["Juliet","Mia","Sarah","Wendy","Winter","Chrissy","Eva","Lin","Samantha","Ella","Lily","Natalie","Ailey","Hannah","Malia","Kindra","Nancy"]],
[TrainerType.PSYCHIC]: [["Fidel","Franklin","Gilbert","Greg","Herman","Jared","Mark","Nathan","Norman","Phil","Richard","Rodney","Cameron","Edward","Fritz","Joshua","Preston","Virgil","William","Alvaro","Blake","Cedric","Keenan","Nicholas","Dario","Johan","Lorenzo","Tyron","Bryce","Corbin","Deandre","Elijah","Kody","Landon","Maxwell","Mitchell","Sterling","Eli","Nelson","Vernon","Gaven","Gerard","Low","Micki","Perry","Rudolf","Tommy","Al","Nandor","Tully","Arthur","Emanuel","Franz","Harry","Paschal","Robert","Sayid","Angelo","Anton","Arin","Avery","Danny","Frasier","Harrison","Jaime","Ross","Rui","Vlad","Mason"],["Alexis","Hannah","Jacki","Jaclyn","Kayla","Maura","Samantha","Alix","Brandi","Edie","Macey","Mariella","Marlene","Laura","Rodette","Abigail","Brittney","Chelsey","Daisy","Desiree","Kendra","Lindsey","Rachael","Valencia","Belle","Cybil","Doreen","Dua","Future","Lin","Madhu","Alia","Ena","Joyce","Lynette","Olesia","Sarah"]], [TrainerType.PSYCHIC]: [["Fidel","Franklin","Gilbert","Greg","Herman","Jared","Mark","Nathan","Norman","Phil","Richard","Rodney","Cameron","Edward","Fritz","Joshua","Preston","Virgil","William","Alvaro","Blake","Cedric","Keenan","Nicholas","Dario","Johan","Lorenzo","Tyron","Bryce","Corbin","Deandre","Elijah","Kody","Landon","Maxwell","Mitchell","Sterling","Eli","Nelson","Vernon","Gaven","Gerard","Low","Micki","Perry","Rudolf","Tommy","Al","Nandor","Tully","Arthur","Emanuel","Franz","Harry","Paschal","Robert","Sayid","Angelo","Anton","Arin","Avery","Danny","Frasier","Harrison","Jaime","Ross","Rui","Vlad","Mason"],["Alexis","Hannah","Jacki","Jaclyn","Kayla","Maura","Samantha","Alix","Brandi","Edie","Macey","Mariella","Marlene","Laura","Rodette","Abigail","Brittney","Chelsey","Daisy","Desiree","Kendra","Lindsey","Rachael","Valencia","Belle","Cybil","Doreen","Dua","Future","Lin","Madhu","Alia","Ena","Joyce","Lynette","Olesia","Sarah"]],
[TrainerType.RANGER]: [["Carlos","Jackson","Sebastian","Gav","Lorenzo","Logan","Nicolas","Trenton","Deshawn","Dwayne","Jeffery","Kyler","Taylor","Alain","Claude","Crofton","Forrest","Harry","Jaden","Keith","Lewis","Miguel","Pedro","Ralph","Richard","Bret","Daryl","Eddie","Johan","Leaf","Louis","Maxwell","Parker","Rick","Steve","Bjorn","Chaise","Dean","Lee","Maurice","Nash","Ralf","Reed","Shinobu","Silas"],["Catherine","Jenna","Sophia","Merdith","Nora","Beth","Chelsea","Katelyn","Madeline","Allison","Ashlee","Felicia","Krista","Annie","Audra","Brenda","Chloris","Eliza","Heidi","Irene","Mary","Mylene","Shanti","Shelly","Thalia","Anja","Briana","Dianna","Elaine","Elle","Hillary","Katie","Lena","Lois","Malory","Melita","Mikiko","Naoko","Serenity","Ambre","Brooke","Clementine","Melina","Petra","Twiggy"]], [TrainerType.RANGER]: [["Carlos","Jackson","Sebastian","Gav","Lorenzo","Logan","Nicolas","Trenton","Deshawn","Dwayne","Jeffery","Kyler","Taylor","Alain","Claude","Crofton","Forrest","Harry","Jaden","Keith","Lewis","Miguel","Pedro","Ralph","Richard","Bret","Daryl","Eddie","Johan","Leaf","Louis","Maxwell","Parker","Rick","Steve","Bjorn","Chaise","Dean","Lee","Maurice","Nash","Ralf","Reed","Shinobu","Silas"],["Catherine","Jenna","Sophia","Merdith","Nora","Beth","Chelsea","Katelyn","Madeline","Allison","Ashlee","Felicia","Krista","Annie","Audra","Brenda","Chloris","Eliza","Heidi","Irene","Mary","Mylene","Shanti","Shelly","Thalia","Anja","Briana","Dianna","Elaine","Elle","Hillary","Katie","Lena","Lois","Malory","Melita","Mikiko","Naoko","Serenity","Ambre","Brooke","Clementine","Melina","Petra","Twiggy"]],
[TrainerType.RICH]: [["Alfred","Edward","Gregory","Preston","Thomas","Tucker","Walter","Clifford","Everett","Micah","Nate","Pierre","Terrance","Arthur","Brooks","Emanuel","Lamar","Jeremy","Leonardo","Milton","Frederic","Renaud","Robert","Yan","Daniel","Sheldon","Stonewall","Gerald","Ronald","Smith","Stanley","Reginald","Orson","Wilco","Caden","Glenn"],["Rebecca","Reina","Cassandra","Emilia","Grace","Marian","Elizabeth","Kathleen","Sayuri","Caroline","Judy"]], [TrainerType.RICH]: [["Alfred","Edward","Gregory","Preston","Thomas","Tucker","Walter","Clifford","Everett","Micah","Nate","Pierre","Terrance","Arthur","Brooks","Emanuel","Lamar","Jeremy","Leonardo","Milton","Frederic","Renaud","Robert","Yan","Daniel","Sheldon","Stonewall","Gerald","Ronald","Smith","Stanley","Reginald","Orson","Wilco","Caden","Glenn"],["Rebecca","Reina","Cassandra","Emilia","Grace","Marian","Elizabeth","Kathleen","Sayuri","Caroline","Judy"]],
[TrainerType.RICH_KID]: [["Garret","Winston","Dawson","Enrique","Jason","Roman","Trey","Liam","Anthony","Brad","Cody","Manuel","Martin","Pierce","Rolan","Keenan","Filbert","Antoin","Cyus","Diek","Dugo","Flitz","Jurek","Lond","Perd","Quint","Basto","Benit","Brot","Denc","Guyit","Marcon","Perc","Puros","Roex","Sainz","Symin","Tark","Venak"],["Anette","Brianna","Cindy","Colleen","Daphne","Elizabeth","Naomi","Sarah","Charlotte","Gillian","Jacki","Lady","Melissa","Celeste","Colette","Elizandra","Isabel","Lynette","Magnolia","Sophie","Lina","Dulcie","Auro","Brin","Caril","Eloos","Gwin","Illa","Kowly","Rima","Ristin","Vesey","Brena","Deasy","Denslon","Kylet","Nemi","Rene","Sanol","Stouner","Sturk","Talmen","Zoila"]], [TrainerType.RICH_KID]: [["Garret","Winston","Dawson","Enrique","Jason","Roman","Trey","Liam","Anthony","Brad","Cody","Manuel","Martin","Pierce","Rolan","Keenan","Filbert","Antoin","Cyus","Diek","Dugo","Flitz","Jurek","Lond","Perd","Quint","Basto","Benit","Brot","Denc","Guyit","Marcon","Perc","Puros","Roex","Sainz","Symin","Tark","Venak"],["Anette","Brianna","Cindy","Colleen","Daphne","Elizabeth","Naomi","Sarah","Charlotte","Gillian","Jacki","Lady","Melissa","Celeste","Colette","Elizandra","Isabel","Lynette","Magnolia","Sophie","Lina","Dulcie","Auro","Brin","Caril","Eloos","Gwin","Illa","Kowly","Rima","Ristin","Vesey","Brena","Deasy","Denslon","Kylet","Nemi","Rene","Sanol","Stouner","Sturk","Talmen","Zoila"]],
[TrainerType.ROUGHNECK]: ["Camron","Corey","Gabriel","Isaiah","Jamal","Koji","Luke","Paxton","Raul","Zeek","Kirby","Chance","Dave","Fletcher","Johnny","Reese","Joey","Ricky","Silvester","Martin"], [TrainerType.ROUGHNECK]: ["Camron","Corey","Gabriel","Isaiah","Jamal","Koji","Luke","Paxton","Raul","Zeek","Kirby","Chance","Dave","Fletcher","Johnny","Reese","Joey","Ricky","Silvester","Martin"],
[TrainerType.SCIENTIST]: [["Jed","Marc","Mitch","Rich","Ross","Beau","Braydon","Connor","Ed","Ivan","Jerry","Jose","Joshua","Parker","Rodney","Taylor","Ted","Travis","Zackery","Darrius","Emilio","Fredrick","Shaun","Stefano","Travon","Daniel","Garett","Gregg","Linden","Lowell","Trenton","Dudley","Luke","Markus","Nathan","Orville","Randall","Ron","Ronald","Simon","Steve","William","Franklin","Clarke","Jacques","Terrance","Ernst","Justus","Ikaika","Jayson","Kyle","Reid","Tyrone","Adam","Albert","Alphonse","Cory","Donnie","Elton","Francis","Gordon","Herbert","Humphrey","Jordan","Julian","Keaton","Levi","Melvin","Murray","West","Craig","Coren","Dubik","Kotan","Lethco","Mante","Mort","Myron","Odlow","Ribek","Roeck","Vogi","Vonder","Zogo","Doimo","Doton","Durel","Hildon","Kukla","Messa","Nanot","Platen","Raburn","Reman","Acrod","Coffy","Elrok","Foss","Hardig","Hombol","Hospel","Kaller","Klots","Krilok","Limar","Loket","Mesak","Morbit","Newin","Orill","Tabor","Tekot"],["Blythe","Chan","Kathrine","Marie","Maria","Naoko","Samantha","Satomi","Shannon","Athena","Caroline","Lumi","Lumina","Marissa","Sonia"]], [TrainerType.SCIENTIST]: [["Jed","Marc","Mitch","Rich","Ross","Beau","Braydon","Connor","Ed","Ivan","Jerry","Jose","Joshua","Parker","Rodney","Taylor","Ted","Travis","Zackery","Darrius","Emilio","Fredrick","Shaun","Stefano","Travon","Daniel","Garett","Gregg","Linden","Lowell","Trenton","Dudley","Luke","Markus","Nathan","Orville","Randall","Ron","Ronald","Simon","Steve","William","Franklin","Clarke","Jacques","Terrance","Ernst","Justus","Ikaika","Jayson","Kyle","Reid","Tyrone","Adam","Albert","Alphonse","Cory","Donnie","Elton","Francis","Gordon","Herbert","Humphrey","Jordan","Julian","Keaton","Levi","Melvin","Murray","West","Craig","Coren","Dubik","Kotan","Lethco","Mante","Mort","Myron","Odlow","Ribek","Roeck","Vogi","Vonder","Zogo","Doimo","Doton","Durel","Hildon","Kukla","Messa","Nanot","Platen","Raburn","Reman","Acrod","Coffy","Elrok","Foss","Hardig","Hombol","Hospel","Kaller","Klots","Krilok","Limar","Loket","Mesak","Morbit","Newin","Orill","Tabor","Tekot"],["Blythe","Chan","Kathrine","Marie","Maria","Naoko","Samantha","Satomi","Shannon","Athena","Caroline","Lumi","Lumina","Marissa","Sonia"]],
[TrainerType.SMASHER]: ["Aspen","Elena","Mari","Amy","Lizzy"], [TrainerType.SMASHER]: ["Aspen","Elena","Mari","Amy","Lizzy"],
[TrainerType.SNOW_WORKER]: [["Braden","Brendon","Colin","Conrad","Dillan","Gary","Gerardo","Holden","Jackson","Mason","Quentin","Willy","Noel","Arnold","Brady","Brand","Cairn","Cliff","Don","Eddie","Felix","Filipe","Glenn","Gus","Heath","Matthew","Patton","Rich","Rob","Ryan","Scott","Shelby","Sterling","Tyler","Victor","Zack","Friedrich","Herman","Isaac","Leo","Maynard","Mitchell","Morgann","Nathan","Niel","Pasqual","Paul","Tavarius","Tibor","Dimitri","Narek","Yusif","Frank","Jeff","Vaclav","Ovid","Francis","Keith","Russel","Sangon","Toway","Bomber","Chean","Demit","Hubor","Kebile","Laber","Ordo","Retay","Ronix","Wagel","Dobit","Kaster","Lobel","Releo","Saken","Rustix"],["Georgia","Sandra","Yvonne"]], [TrainerType.SNOW_WORKER]: [["Braden","Brendon","Colin","Conrad","Dillan","Gary","Gerardo","Holden","Jackson","Mason","Quentin","Willy","Noel","Arnold","Brady","Brand","Cairn","Cliff","Don","Eddie","Felix","Filipe","Glenn","Gus","Heath","Matthew","Patton","Rich","Rob","Ryan","Scott","Shelby","Sterling","Tyler","Victor","Zack","Friedrich","Herman","Isaac","Leo","Maynard","Mitchell","Morgann","Nathan","Niel","Pasqual","Paul","Tavarius","Tibor","Dimitri","Narek","Yusif","Frank","Jeff","Vaclav","Ovid","Francis","Keith","Russel","Sangon","Toway","Bomber","Chean","Demit","Hubor","Kebile","Laber","Ordo","Retay","Ronix","Wagel","Dobit","Kaster","Lobel","Releo","Saken","Rustix"],["Georgia","Sandra","Yvonne"]],
[TrainerType.STRIKER]: ["Marco","Roberto","Tony"], [TrainerType.STRIKER]: ["Marco","Roberto","Tony"],
[TrainerType.SCHOOL_KID]: [["Alan","Billy","Chad","Danny","Dudley","Jack","Joe","Johnny","Kipp","Nate","Ricky","Tommy","Jerry","Paul","Ted","Chance","Esteban","Forrest","Harrison","Connor","Sherman","Torin","Travis","Al","Carter","Edgar","Jem","Sammy","Shane","Shayne","Alvin","Keston","Neil","Seymour","William","Carson","Clark","Nolan"],["Georgia","Karen","Meiko","Christine","Mackenzie","Tiera","Ann","Gina","Lydia","Marsha","Millie","Sally","Serena","Silvia","Alberta","Cassie","Mara","Rita","Georgie","Meena","Nitzel"]], [TrainerType.SCHOOL_KID]: [["Alan","Billy","Chad","Danny","Dudley","Jack","Joe","Johnny","Kipp","Nate","Ricky","Tommy","Jerry","Paul","Ted","Chance","Esteban","Forrest","Harrison","Connor","Sherman","Torin","Travis","Al","Carter","Edgar","Jem","Sammy","Shane","Shayne","Alvin","Keston","Neil","Seymour","William","Carson","Clark","Nolan"],["Georgia","Karen","Meiko","Christine","Mackenzie","Tiera","Ann","Gina","Lydia","Marsha","Millie","Sally","Serena","Silvia","Alberta","Cassie","Mara","Rita","Georgie","Meena","Nitzel"]],
[TrainerType.SWIMMER]: [["Berke","Cameron","Charlie","George","Harold","Jerome","Kirk","Mathew","Parker","Randall","Seth","Simon","Tucker","Austin","Barry","Chad","Cody","Darrin","David","Dean","Douglas","Franklin","Gilbert","Herman","Jack","Luis","Matthew","Reed","Richard","Rodney","Roland","Spencer","Stan","Tony","Clarence","Declan","Dominik","Harrison","Kevin","Leonardo","Nolen","Pete","Santiago","Axle","Braden","Finn","Garrett","Mymo","Reece","Samir","Toby","Adrian","Colton","Dillon","Erik","Evan","Francisco","Glenn","Kurt","Oscar","Ricardo","Sam","Sheltin","Troy","Vincent","Wade","Wesley","Duane","Elmo","Esteban","Frankie","Ronald","Tyson","Bart","Matt","Tim","Wright","Jeffery","Kyle","Alessandro","Estaban","Kieran","Ramses","Casey","Dakota","Jared","Kalani","Keoni","Lawrence","Logan","Robert","Roddy","Yasu","Derek","Jacob","Bruce","Clayton"],["Briana","Dawn","Denise","Diana","Elaine","Kara","Kaylee","Lori","Nicole","Nikki","Paula","Susie","Wendy","Alice","Beth","Beverly","Brenda","Dana","Debra","Grace","Jenny","Katie","Laurel","Linda","Missy","Sharon","Tanya","Tara","Tisha","Carlee","Imani","Isabelle","Kyla","Sienna","Abigail","Amara","Anya","Connie","Maria","Melissa","Nora","Shirley","Shania","Tiffany","Aubree","Cassandra","Claire","Crystal","Erica","Gabrielle","Haley","Jessica","Joanna","Lydia","Mallory","Mary","Miranda","Paige","Sophia","Vanessa","Chelan","Debbie","Joy","Kendra","Leona","Mina","Caroline","Joyce","Larissa","Rebecca","Tyra","Dara","Desiree","Kaoru","Ruth","Coral","Genevieve","Isla","Marissa","Romy","Sheryl","Alexandria","Alicia","Chelsea","Jade","Kelsie","Laura","Portia","Shelby","Sara","Tiare","Kyra","Natasha","Layla","Scarlett","Cora"]], [TrainerType.SWIMMER]: [["Berke","Cameron","Charlie","George","Harold","Jerome","Kirk","Mathew","Parker","Randall","Seth","Simon","Tucker","Austin","Barry","Chad","Cody","Darrin","David","Dean","Douglas","Franklin","Gilbert","Herman","Jack","Luis","Matthew","Reed","Richard","Rodney","Roland","Spencer","Stan","Tony","Clarence","Declan","Dominik","Harrison","Kevin","Leonardo","Nolen","Pete","Santiago","Axle","Braden","Finn","Garrett","Mymo","Reece","Samir","Toby","Adrian","Colton","Dillon","Erik","Evan","Francisco","Glenn","Kurt","Oscar","Ricardo","Sam","Sheltin","Troy","Vincent","Wade","Wesley","Duane","Elmo","Esteban","Frankie","Ronald","Tyson","Bart","Matt","Tim","Wright","Jeffery","Kyle","Alessandro","Estaban","Kieran","Ramses","Casey","Dakota","Jared","Kalani","Keoni","Lawrence","Logan","Robert","Roddy","Yasu","Derek","Jacob","Bruce","Clayton"],["Briana","Dawn","Denise","Diana","Elaine","Kara","Kaylee","Lori","Nicole","Nikki","Paula","Susie","Wendy","Alice","Beth","Beverly","Brenda","Dana","Debra","Grace","Jenny","Katie","Laurel","Linda","Missy","Sharon","Tanya","Tara","Tisha","Carlee","Imani","Isabelle","Kyla","Sienna","Abigail","Amara","Anya","Connie","Maria","Melissa","Nora","Shirley","Shania","Tiffany","Aubree","Cassandra","Claire","Crystal","Erica","Gabrielle","Haley","Jessica","Joanna","Lydia","Mallory","Mary","Miranda","Paige","Sophia","Vanessa","Chelan","Debbie","Joy","Kendra","Leona","Mina","Caroline","Joyce","Larissa","Rebecca","Tyra","Dara","Desiree","Kaoru","Ruth","Coral","Genevieve","Isla","Marissa","Romy","Sheryl","Alexandria","Alicia","Chelsea","Jade","Kelsie","Laura","Portia","Shelby","Sara","Tiare","Kyra","Natasha","Layla","Scarlett","Cora"]],
[TrainerType.TWINS]: ["Amy & May","Jo & Zoe","Meg & Peg","Ann & Anne","Lea & Pia","Amy & Liv","Gina & Mia","Miu & Yuki","Tori & Tia","Eli & Anne","Jen & Kira","Joy & Meg","Kiri & Jan","Miu & Mia","Emma & Lil","Liv & Liz","Teri & Tia","Amy & Mimi","Clea & Gil","Day & Dani","Kay & Tia","Tori & Til","Saya & Aya","Emy & Lin","Kumi & Amy","Mayo & May","Ally & Amy","Lia & Lily","Rae & Ula","Sola & Ana","Tara & Val","Faith & Joy","Nana & Nina"], [TrainerType.TWINS]: ["Amy & May","Jo & Zoe","Meg & Peg","Ann & Anne","Lea & Pia","Amy & Liv","Gina & Mia","Miu & Yuki","Tori & Tia","Eli & Anne","Jen & Kira","Joy & Meg","Kiri & Jan","Miu & Mia","Emma & Lil","Liv & Liz","Teri & Tia","Amy & Mimi","Clea & Gil","Day & Dani","Kay & Tia","Tori & Til","Saya & Aya","Emy & Lin","Kumi & Amy","Mayo & May","Ally & Amy","Lia & Lily","Rae & Ula","Sola & Ana","Tara & Val","Faith & Joy","Nana & Nina"],
[TrainerType.VETERAN]: [["Armando","Brenden","Brian","Clayton","Edgar","Emanuel","Grant","Harlan","Terrell","Arlen","Chester","Hugo","Martell","Ray","Shaun","Abraham","Carter","Claude","Jerry","Lucius","Murphy","Rayne","Ron","Sinan","Sterling","Vincent","Zach","Gerard","Gilles","Louis","Timeo","Akira","Don","Eric","Harry","Leon","Roger","Angus","Aristo","Brone","Johnny"],["Julia","Karla","Kim","Sayuri","Tiffany","Cathy","Cecile","Chloris","Denae","Gina","Maya","Oriana","Portia","Rhona","Rosaline","Catrina","Inga","Trisha","Heather","Lynn","Sheri","Alonsa","Ella","Leticia","Kiara"]], [TrainerType.VETERAN]: [["Armando","Brenden","Brian","Clayton","Edgar","Emanuel","Grant","Harlan","Terrell","Arlen","Chester","Hugo","Martell","Ray","Shaun","Abraham","Carter","Claude","Jerry","Lucius","Murphy","Rayne","Ron","Sinan","Sterling","Vincent","Zach","Gerard","Gilles","Louis","Timeo","Akira","Don","Eric","Harry","Leon","Roger","Angus","Aristo","Brone","Johnny"],["Julia","Karla","Kim","Sayuri","Tiffany","Cathy","Cecile","Chloris","Denae","Gina","Maya","Oriana","Portia","Rhona","Rosaline","Catrina","Inga","Trisha","Heather","Lynn","Sheri","Alonsa","Ella","Leticia","Kiara"]],
[TrainerType.WAITER]: [["Bert","Clint","Maxwell","Lou"],["Kati","Aurora","Bonita","Flo","Tia","Jan","Olwen","Paget","Paula","Talia"]], [TrainerType.WAITER]: [["Bert","Clint","Maxwell","Lou"],["Kati","Aurora","Bonita","Flo","Tia","Jan","Olwen","Paget","Paula","Talia"]],
[TrainerType.WORKER]: [["Braden","Brendon","Colin","Conrad","Dillan","Gary","Gerardo","Holden","Jackson","Mason","Quentin","Willy","Noel","Arnold","Brady","Brand","Cairn","Cliff","Don","Eddie","Felix","Filipe","Glenn","Gus","Heath","Matthew","Patton","Rich","Rob","Ryan","Scott","Shelby","Sterling","Tyler","Victor","Zack","Friedrich","Herman","Isaac","Leo","Maynard","Mitchell","Morgann","Nathan","Niel","Pasqual","Paul","Tavarius","Tibor","Dimitri","Narek","Yusif","Frank","Jeff","Vaclav","Ovid","Francis","Keith","Russel","Sangon","Toway","Bomber","Chean","Demit","Hubor","Kebile","Laber","Ordo","Retay","Ronix","Wagel","Dobit","Kaster","Lobel","Releo","Saken","Rustix"],["Georgia","Sandra","Yvonne"]], [TrainerType.WORKER]: [["Braden","Brendon","Colin","Conrad","Dillan","Gary","Gerardo","Holden","Jackson","Mason","Quentin","Willy","Noel","Arnold","Brady","Brand","Cairn","Cliff","Don","Eddie","Felix","Filipe","Glenn","Gus","Heath","Matthew","Patton","Rich","Rob","Ryan","Scott","Shelby","Sterling","Tyler","Victor","Zack","Friedrich","Herman","Isaac","Leo","Maynard","Mitchell","Morgann","Nathan","Niel","Pasqual","Paul","Tavarius","Tibor","Dimitri","Narek","Yusif","Frank","Jeff","Vaclav","Ovid","Francis","Keith","Russel","Sangon","Toway","Bomber","Chean","Demit","Hubor","Kebile","Laber","Ordo","Retay","Ronix","Wagel","Dobit","Kaster","Lobel","Releo","Saken","Rustix"],["Georgia","Sandra","Yvonne"]],
[TrainerType.YOUNGSTER]: [["Albert","Gordon","Ian","Jason","Jimmy","Mikey","Owen","Samuel","Warren","Allen","Ben","Billy","Calvin","Dillion","Eddie","Joey","Josh","Neal","Timmy","Tommy","Breyden","Deandre","Demetrius","Dillon","Jaylen","Johnson","Shigenobu","Chad","Cole","Cordell","Dan","Dave","Destin","Nash","Tyler","Yasu","Austin","Dallas","Darius","Donny","Jonathon","Logan","Michael","Oliver","Sebastian","Tristan","Wayne","Norman","Roland","Regis","Abe","Astor","Keita","Kenneth","Kevin","Kyle","Lester","Masao","Nicholas","Parker","Wes","Zachary","Cody","Henley","Jaye","Karl","Kenny","Masahiro","Pedro","Petey","Sinclair","Terrell","Waylon","Aidan","Anthony","David","Jacob","Jayden","Cutler","Ham","Caleb","Kai","Honus","Kenway","Bret","Chris","Cid","Dennis","Easton","Ken","Robby","Ronny","Shawn","Benjamin","Jake","Travis","Adan","Aday","Beltran","Elian","Hernan","Julen","Luka","Roi","Bernie","Dustin","Jonathan","Wyatt"],["Alice","Bridget","Carrie","Connie","Dana","Ellen","Krise","Laura","Linda","Michelle","Shannon","Andrea","Crissy","Janice","Robin","Sally","Tiana","Haley","Ali","Ann","Dalia","Dawn","Iris","Joana","Julia","Kay","Lisa","Megan","Mikaela","Miriam","Paige","Reli","Blythe","Briana","Caroline","Cassidy","Kaitlin","Madeline","Molly","Natalie","Samantha","Sarah","Cathy","Dye","Eri","Eva","Fey","Kara","Lurleen","Maki","Mali","Maya","Miki","Sibyl","Daya","Diana","Flo","Helia","Henrietta","Isabel","Mai","Persephone","Serena","Anna","Charlotte","Elin","Elsa","Lise","Sara","Suzette","Audrey","Emmy","Isabella","Madison","Rika","Rylee","Salla","Ellie","Alexandra","Amy","Lass","Brittany","Chel","Cindy","Dianne","Emily","Emma","Evelyn","Hana","Harleen","Hazel","Jocelyn","Katrina","Kimberly","Lina","Marge","Mila","Mizuki","Rena","Sal","Satoko","Summer","Tomoe","Vicky","Yue","Yumi","Lauren","Rei","Riley","Lois","Nancy","Tammy","Terry"]], [TrainerType.YOUNGSTER]: [["Albert","Gordon","Ian","Jason","Jimmy","Mikey","Owen","Samuel","Warren","Allen","Ben","Billy","Calvin","Dillion","Eddie","Joey","Josh","Neal","Timmy","Tommy","Breyden","Deandre","Demetrius","Dillon","Jaylen","Johnson","Shigenobu","Chad","Cole","Cordell","Dan","Dave","Destin","Nash","Tyler","Yasu","Austin","Dallas","Darius","Donny","Jonathon","Logan","Michael","Oliver","Sebastian","Tristan","Wayne","Norman","Roland","Regis","Abe","Astor","Keita","Kenneth","Kevin","Kyle","Lester","Masao","Nicholas","Parker","Wes","Zachary","Cody","Henley","Jaye","Karl","Kenny","Masahiro","Pedro","Petey","Sinclair","Terrell","Waylon","Aidan","Anthony","David","Jacob","Jayden","Cutler","Ham","Caleb","Kai","Honus","Kenway","Bret","Chris","Cid","Dennis","Easton","Ken","Robby","Ronny","Shawn","Benjamin","Jake","Travis","Adan","Aday","Beltran","Elian","Hernan","Julen","Luka","Roi","Bernie","Dustin","Jonathan","Wyatt"],["Alice","Bridget","Carrie","Connie","Dana","Ellen","Krise","Laura","Linda","Michelle","Shannon","Andrea","Crissy","Janice","Robin","Sally","Tiana","Haley","Ali","Ann","Dalia","Dawn","Iris","Joana","Julia","Kay","Lisa","Megan","Mikaela","Miriam","Paige","Reli","Blythe","Briana","Caroline","Cassidy","Kaitlin","Madeline","Molly","Natalie","Samantha","Sarah","Cathy","Dye","Eri","Eva","Fey","Kara","Lurleen","Maki","Mali","Maya","Miki","Sibyl","Daya","Diana","Flo","Helia","Henrietta","Isabel","Mai","Persephone","Serena","Anna","Charlotte","Elin","Elsa","Lise","Sara","Suzette","Audrey","Emmy","Isabella","Madison","Rika","Rylee","Salla","Ellie","Alexandra","Amy","Lass","Brittany","Chel","Cindy","Dianne","Emily","Emma","Evelyn","Hana","Harleen","Hazel","Jocelyn","Katrina","Kimberly","Lina","Marge","Mila","Mizuki","Rena","Sal","Satoko","Summer","Tomoe","Vicky","Yue","Yumi","Lauren","Rei","Riley","Lois","Nancy","Tammy","Terry"]],
[TrainerType.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"], [TrainerType.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"],
}; };
// function used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNames: Set<string>, femaleTrainerNames: Set<string>, forceFemale: boolean = false) { function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNames: Set<string>, femaleTrainerNames: Set<string>, forceFemale: boolean = false) {
return new Promise<void>(resolve => { return new Promise<void>(resolve => {
fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`) fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`)
.then(response => response.text()) .then(response => response.text())
.then(html => { .then(html => {
console.log(url); console.log(url);
const htmlDoc = parser.parseFromString(html, 'text/html'); const htmlDoc = parser.parseFromString(html, "text/html");
const trainerListHeader = htmlDoc.querySelector('#Trainer_list').parentElement; const trainerListHeader = htmlDoc.querySelector("#Trainer_list").parentElement;
const elements = [...trainerListHeader.parentElement.childNodes]; const elements = [...trainerListHeader.parentElement.childNodes];
const startChildIndex = elements.indexOf(trainerListHeader); const startChildIndex = elements.indexOf(trainerListHeader);
const endChildIndex = elements.findIndex(h => h.nodeName === 'H2' && elements.indexOf(h) > startChildIndex); const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex);
const tables = elements.filter(t => { const tables = elements.filter(t => {
if (t.nodeName !== 'TABLE' || t['className'] !== 'expandable') if (t.nodeName !== "TABLE" || t["className"] !== "expandable") {
return false; return false;
}
const childIndex = elements.indexOf(t); const childIndex = elements.indexOf(t);
return childIndex > startChildIndex && childIndex < endChildIndex; return childIndex > startChildIndex && childIndex < endChildIndex;
}).map(t => t as Element); }).map(t => t as Element);
console.log(url, tables) console.log(url, tables);
for (let table of tables) { for (const table of tables) {
const trainerRows = [...table.querySelectorAll('tr:not(:first-child)')].filter(r => r.children.length === 9); const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9);
for (let row of trainerRows) { for (const row of trainerRows) {
const nameCell = row.firstElementChild; const nameCell = row.firstElementChild;
const content = nameCell.innerHTML; const content = nameCell.innerHTML;
if (content.indexOf(' <a ') > -1) { if (content.indexOf(" <a ") > -1) {
const female = /♀/.test(content); const female = /♀/.test(content);
if (url === 'Twins') if (url === "Twins") {
console.log(content) console.log(content);
}
const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content); const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content);
if (nameMatch) if (nameMatch) {
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace('&amp;', '&')); (female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace("&amp;", "&"));
}
} }
} }
} }
resolve(); resolve();
}); });
}); });
} }
/*export function scrapeTrainerNames() { /*export function scrapeTrainerNames() {

File diff suppressed because it is too large Load Diff

View File

@ -8,11 +8,11 @@ export const variantColorCache = {};
export function getVariantTint(variant: Variant): integer { export function getVariantTint(variant: Variant): integer {
switch (variant) { switch (variant) {
case 0: case 0:
return 0xf8c020; return 0xf8c020;
case 1: case 1:
return 0x20f8f0; return 0x20f8f0;
case 2: case 2:
return 0xe81048; return 0xe81048;
} }
} }

View File

@ -32,20 +32,22 @@ export class Weather {
} }
lapse(): boolean { lapse(): boolean {
if (this.isImmutable()) if (this.isImmutable()) {
return true; return true;
if (this.turnsLeft) }
if (this.turnsLeft) {
return !!--this.turnsLeft; return !!--this.turnsLeft;
}
return true; return true;
} }
isImmutable(): boolean { isImmutable(): boolean {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return true; return true;
} }
return false; return false;
@ -53,9 +55,9 @@ export class Weather {
isDamaging(): boolean { isDamaging(): boolean {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
case WeatherType.HAIL: case WeatherType.HAIL:
return true; return true;
} }
return false; return false;
@ -63,10 +65,10 @@ export class Weather {
isTypeDamageImmune(type: Type): boolean { isTypeDamageImmune(type: Type): boolean {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return type === Type.GROUND || type === Type.ROCK || type === Type.STEEL; return type === Type.GROUND || type === Type.ROCK || type === Type.STEEL;
case WeatherType.HAIL: case WeatherType.HAIL:
return type === Type.ICE; return type === Type.ICE;
} }
return false; return false;
@ -74,20 +76,24 @@ export class Weather {
getAttackTypeMultiplier(attackType: Type): number { getAttackTypeMultiplier(attackType: Type): number {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
if (attackType === Type.FIRE) if (attackType === Type.FIRE) {
return 1.5; return 1.5;
if (attackType === Type.WATER) }
return 0.5; if (attackType === Type.WATER) {
break; return 0.5;
case WeatherType.RAIN: }
case WeatherType.HEAVY_RAIN: break;
if (attackType === Type.FIRE) case WeatherType.RAIN:
return 0.5; case WeatherType.HEAVY_RAIN:
if (attackType === Type.WATER) if (attackType === Type.FIRE) {
return 1.5; return 0.5;
break; }
if (attackType === Type.WATER) {
return 1.5;
}
break;
} }
return 1; return 1;
@ -95,10 +101,10 @@ export class Weather {
isMoveWeatherCancelled(move: Move): boolean { isMoveWeatherCancelled(move: Move): boolean {
switch (this.weatherType) { switch (this.weatherType) {
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return move instanceof AttackMove && move.type === Type.WATER; return move instanceof AttackMove && move.type === Type.WATER;
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return move instanceof AttackMove && move.type === Type.FIRE; return move instanceof AttackMove && move.type === Type.FIRE;
} }
return false; return false;
@ -107,12 +113,14 @@ export class Weather {
isEffectSuppressed(scene: BattleScene): boolean { isEffectSuppressed(scene: BattleScene): boolean {
const field = scene.getField(true); const field = scene.getField(true);
for (let pokemon of field) { for (const pokemon of field) {
let suppressWeatherEffectAbAttr = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr; let suppressWeatherEffectAbAttr = pokemon.getAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr;
if (!suppressWeatherEffectAbAttr) if (!suppressWeatherEffectAbAttr) {
suppressWeatherEffectAbAttr = pokemon.hasPassive() ? pokemon.getPassiveAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr : null; suppressWeatherEffectAbAttr = pokemon.hasPassive() ? pokemon.getPassiveAbility().getAttrs(SuppressWeatherEffectAbAttr).find(() => true) as SuppressWeatherEffectAbAttr : null;
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable)) }
if (suppressWeatherEffectAbAttr && (!this.isImmutable() || suppressWeatherEffectAbAttr.affectsImmutable)) {
return true; return true;
}
} }
return false; return false;
@ -121,24 +129,24 @@ export class Weather {
export function getWeatherStartMessage(weatherType: WeatherType): string { export function getWeatherStartMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyStartMessage'); return i18next.t("weather:sunnyStartMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainStartMessage'); return i18next.t("weather:rainStartMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormStartMessage'); return i18next.t("weather:sandstormStartMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailStartMessage'); return i18next.t("weather:hailStartMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowStartMessage'); return i18next.t("weather:snowStartMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogStartMessage'); return i18next.t("weather:fogStartMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainStartMessage'); return i18next.t("weather:heavyRainStartMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunStartMessage'); return i18next.t("weather:harshSunStartMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsStartMessage'); return i18next.t("weather:strongWindsStartMessage");
} }
return null; return null;
@ -146,24 +154,24 @@ export function getWeatherStartMessage(weatherType: WeatherType): string {
export function getWeatherLapseMessage(weatherType: WeatherType): string { export function getWeatherLapseMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyLapseMessage'); return i18next.t("weather:sunnyLapseMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainLapseMessage'); return i18next.t("weather:rainLapseMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormLapseMessage'); return i18next.t("weather:sandstormLapseMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailLapseMessage'); return i18next.t("weather:hailLapseMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowLapseMessage'); return i18next.t("weather:snowLapseMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogLapseMessage'); return i18next.t("weather:fogLapseMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainLapseMessage'); return i18next.t("weather:heavyRainLapseMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunLapseMessage'); return i18next.t("weather:harshSunLapseMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsLapseMessage'); return i18next.t("weather:strongWindsLapseMessage");
} }
return null; return null;
@ -171,10 +179,10 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string {
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string { export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormDamageMessage', {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name}); return i18next.t("weather:sandstormDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailDamageMessage', {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name}); return i18next.t("weather:hailDamageMessage", {pokemonPrefix: getPokemonPrefix(pokemon), pokemonName: pokemon.name});
} }
return null; return null;
@ -182,24 +190,24 @@ export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokem
export function getWeatherClearMessage(weatherType: WeatherType): string { export function getWeatherClearMessage(weatherType: WeatherType): string {
switch (weatherType) { switch (weatherType) {
case WeatherType.SUNNY: case WeatherType.SUNNY:
return i18next.t('weather:sunnyClearMessage'); return i18next.t("weather:sunnyClearMessage");
case WeatherType.RAIN: case WeatherType.RAIN:
return i18next.t('weather:rainClearMessage'); return i18next.t("weather:rainClearMessage");
case WeatherType.SANDSTORM: case WeatherType.SANDSTORM:
return i18next.t('weather:sandstormClearMessage'); return i18next.t("weather:sandstormClearMessage");
case WeatherType.HAIL: case WeatherType.HAIL:
return i18next.t('weather:hailClearMessage'); return i18next.t("weather:hailClearMessage");
case WeatherType.SNOW: case WeatherType.SNOW:
return i18next.t('weather:snowClearMessage'); return i18next.t("weather:snowClearMessage");
case WeatherType.FOG: case WeatherType.FOG:
return i18next.t('weather:fogClearMessage'); return i18next.t("weather:fogClearMessage");
case WeatherType.HEAVY_RAIN: case WeatherType.HEAVY_RAIN:
return i18next.t('weather:heavyRainClearMessage'); return i18next.t("weather:heavyRainClearMessage");
case WeatherType.HARSH_SUN: case WeatherType.HARSH_SUN:
return i18next.t('weather:harshSunClearMessage'); return i18next.t("weather:harshSunClearMessage");
case WeatherType.STRONG_WINDS: case WeatherType.STRONG_WINDS:
return i18next.t('weather:strongWindsClearMessage'); return i18next.t("weather:strongWindsClearMessage");
} }
return null; return null;
@ -207,33 +215,34 @@ export function getWeatherClearMessage(weatherType: WeatherType): string {
export function getTerrainStartMessage(terrainType: TerrainType): string { export function getTerrainStartMessage(terrainType: TerrainType): string {
switch (terrainType) { switch (terrainType) {
case TerrainType.MISTY: case TerrainType.MISTY:
return 'Mist swirled around the battlefield!'; return "Mist swirled around the battlefield!";
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
return 'An electric current ran across the battlefield!'; return "An electric current ran across the battlefield!";
case TerrainType.GRASSY: case TerrainType.GRASSY:
return 'Grass grew to cover the battlefield!'; return "Grass grew to cover the battlefield!";
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
return 'The battlefield got weird!'; return "The battlefield got weird!";
} }
} }
export function getTerrainClearMessage(terrainType: TerrainType): string { export function getTerrainClearMessage(terrainType: TerrainType): string {
switch (terrainType) { switch (terrainType) {
case TerrainType.MISTY: case TerrainType.MISTY:
return 'The mist disappeared from the battlefield.'; return "The mist disappeared from the battlefield.";
case TerrainType.ELECTRIC: case TerrainType.ELECTRIC:
return 'The electricity disappeared from the battlefield.'; return "The electricity disappeared from the battlefield.";
case TerrainType.GRASSY: case TerrainType.GRASSY:
return 'The grass disappeared from the battlefield.'; return "The grass disappeared from the battlefield.";
case TerrainType.PSYCHIC: case TerrainType.PSYCHIC:
return 'The weirdness disappeared from the battlefield!'; return "The weirdness disappeared from the battlefield!";
} }
} }
export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string { export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string {
if (terrainType === TerrainType.MISTY) if (terrainType === TerrainType.MISTY) {
return getPokemonMessage(pokemon, ` surrounds itself with a protective mist!`); return getPokemonMessage(pokemon, " surrounds itself with a protective mist!");
}
return getPokemonMessage(pokemon, ` is protected by the ${Utils.toReadableString(TerrainType[terrainType])} Terrain!`); return getPokemonMessage(pokemon, ` is protected by the ${Utils.toReadableString(TerrainType[terrainType])} Terrain!`);
} }
@ -246,119 +255,126 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
let weatherPool: WeatherPoolEntry[] = []; let weatherPool: WeatherPoolEntry[] = [];
const hasSun = arena.getTimeOfDay() < 2; const hasSun = arena.getTimeOfDay() < 2;
switch (arena.biomeType) { switch (arena.biomeType) {
case Biome.GRASS: case Biome.GRASS:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 7 } { weatherType: WeatherType.NONE, weight: 7 }
]; ];
if (hasSun) if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 }); weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 });
break; }
case Biome.TALL_GRASS: break;
weatherPool = [ case Biome.TALL_GRASS:
{ weatherType: WeatherType.NONE, weight: 8 }, weatherPool = [
{ weatherType: WeatherType.RAIN, weight: 5 }, { weatherType: WeatherType.NONE, weight: 8 },
]; { weatherType: WeatherType.RAIN, weight: 5 },
if (hasSun) ];
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 }); if (hasSun) {
break; weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 });
case Biome.FOREST: }
weatherPool = [ break;
{ weatherType: WeatherType.NONE, weight: 8 }, case Biome.FOREST:
{ weatherType: WeatherType.RAIN, weight: 5 } weatherPool = [
]; { weatherType: WeatherType.NONE, weight: 8 },
break; { weatherType: WeatherType.RAIN, weight: 5 }
case Biome.SEA: ];
weatherPool = [ break;
{ weatherType: WeatherType.NONE, weight: 3 }, case Biome.SEA:
{ weatherType: WeatherType.RAIN, weight: 12 } weatherPool = [
]; { weatherType: WeatherType.NONE, weight: 3 },
break; { weatherType: WeatherType.RAIN, weight: 12 }
case Biome.SWAMP: ];
weatherPool = [ break;
{ weatherType: WeatherType.NONE, weight: 3 }, case Biome.SWAMP:
{ weatherType: WeatherType.RAIN, weight: 4 }, weatherPool = [
{ weatherType: WeatherType.FOG, weight: 1 } { weatherType: WeatherType.NONE, weight: 3 },
]; { weatherType: WeatherType.RAIN, weight: 4 },
break; { weatherType: WeatherType.FOG, weight: 1 }
case Biome.BEACH: ];
weatherPool = [ break;
{ weatherType: WeatherType.NONE, weight: 8 }, case Biome.BEACH:
{ weatherType: WeatherType.RAIN, weight: 3 } weatherPool = [
]; { weatherType: WeatherType.NONE, weight: 8 },
if (hasSun) { weatherType: WeatherType.RAIN, weight: 3 }
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); ];
break; if (hasSun) {
case Biome.LAKE: weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
weatherPool = [ }
{ weatherType: WeatherType.NONE, weight: 10 }, break;
{ weatherType: WeatherType.RAIN, weight: 5 }, case Biome.LAKE:
{ weatherType: WeatherType.FOG, weight: 1 } weatherPool = [
]; { weatherType: WeatherType.NONE, weight: 10 },
break; { weatherType: WeatherType.RAIN, weight: 5 },
case Biome.SEABED: { weatherType: WeatherType.FOG, weight: 1 }
weatherPool = [ ];
{ weatherType: WeatherType.RAIN, weight: 1 } break;
]; case Biome.SEABED:
break; weatherPool = [
case Biome.BADLANDS: { weatherType: WeatherType.RAIN, weight: 1 }
weatherPool = [ ];
{ weatherType: WeatherType.NONE, weight: 8 }, break;
{ weatherType: WeatherType.SANDSTORM, weight: 2 } case Biome.BADLANDS:
]; weatherPool = [
if (hasSun) { weatherType: WeatherType.NONE, weight: 8 },
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 }); { weatherType: WeatherType.SANDSTORM, weight: 2 }
break; ];
case Biome.DESERT: if (hasSun) {
weatherPool = [ weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
{ weatherType: WeatherType.SANDSTORM, weight: 2 } }
]; break;
if (hasSun) case Biome.DESERT:
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); weatherPool = [
break; { weatherType: WeatherType.SANDSTORM, weight: 2 }
case Biome.ICE_CAVE: ];
weatherPool = [ if (hasSun) {
{ weatherType: WeatherType.NONE, weight: 3 }, weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
{ weatherType: WeatherType.SNOW, weight: 4 }, }
{ weatherType: WeatherType.HAIL, weight: 1 } break;
]; case Biome.ICE_CAVE:
break; weatherPool = [
case Biome.MEADOW: { weatherType: WeatherType.NONE, weight: 3 },
weatherPool = [ { weatherType: WeatherType.SNOW, weight: 4 },
{ weatherType: WeatherType.NONE, weight: 2 } { weatherType: WeatherType.HAIL, weight: 1 }
]; ];
if (hasSun) break;
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); case Biome.MEADOW:
case Biome.VOLCANO: weatherPool = [
weatherPool = [ { weatherType: WeatherType.NONE, weight: 2 }
{ weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 } ];
]; if (hasSun) {
break; weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
case Biome.GRAVEYARD: }
weatherPool = [ case Biome.VOLCANO:
{ weatherType: WeatherType.NONE, weight: 3 }, weatherPool = [
{ weatherType: WeatherType.FOG, weight: 1 } { weatherType: hasSun ? WeatherType.SUNNY : WeatherType.NONE, weight: 1 }
]; ];
break; break;
case Biome.JUNGLE: case Biome.GRAVEYARD:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 8 }, { weatherType: WeatherType.NONE, weight: 3 },
{ weatherType: WeatherType.RAIN, weight: 2 } { weatherType: WeatherType.FOG, weight: 1 }
]; ];
break; break;
case Biome.SNOWY_FOREST: case Biome.JUNGLE:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.SNOW, weight: 7 }, { weatherType: WeatherType.NONE, weight: 8 },
{ weatherType: WeatherType.HAIL, weight: 1 } { weatherType: WeatherType.RAIN, weight: 2 }
]; ];
break; break;
case Biome.ISLAND: case Biome.SNOWY_FOREST:
weatherPool = [ weatherPool = [
{ weatherType: WeatherType.NONE, weight: 5 }, { weatherType: WeatherType.SNOW, weight: 7 },
{ weatherType: WeatherType.RAIN, weight: 1 }, { weatherType: WeatherType.HAIL, weight: 1 }
]; ];
if (hasSun) break;
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); case Biome.ISLAND:
break; weatherPool = [
{ weatherType: WeatherType.NONE, weight: 5 },
{ weatherType: WeatherType.RAIN, weight: 1 },
];
if (hasSun) {
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
}
break;
} }
if (weatherPool.length > 1) { if (weatherPool.length > 1) {
@ -367,10 +383,11 @@ export function getRandomWeatherType(arena: any /* Importing from arena causes a
const rand = Utils.randSeedInt(totalWeight); const rand = Utils.randSeedInt(totalWeight);
let w = 0; let w = 0;
for (let weather of weatherPool) { for (const weather of weatherPool) {
w += weather.weight; w += weather.weight;
if (rand < w) if (rand < w) {
return weather.weatherType; return weather.weatherType;
}
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ import { TimeOfDay } from "../data/enums/time-of-day";
import { Terrain, TerrainType } from "../data/terrain"; import { Terrain, TerrainType } from "../data/terrain";
import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability"; import { PostTerrainChangeAbAttr, PostWeatherChangeAbAttr, applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs } from "../data/ability";
import Pokemon from "./pokemon"; import Pokemon from "./pokemon";
import * as Overrides from '../overrides'; import * as Overrides from "../overrides";
export class Arena { export class Arena {
public scene: BattleScene; public scene: BattleScene;
@ -58,16 +58,18 @@ export class Arena {
const timeOfDay = this.getTimeOfDay(); const timeOfDay = this.getTimeOfDay();
if (timeOfDay !== this.lastTimeOfDay) { if (timeOfDay !== this.lastTimeOfDay) {
this.pokemonPool = {}; this.pokemonPool = {};
for (let tier of Object.keys(biomePokemonPools[this.biomeType])) for (const tier of Object.keys(biomePokemonPools[this.biomeType])) {
this.pokemonPool[tier] = Object.assign([], biomePokemonPools[this.biomeType][tier][TimeOfDay.ALL]).concat(biomePokemonPools[this.biomeType][tier][timeOfDay]); this.pokemonPool[tier] = Object.assign([], biomePokemonPools[this.biomeType][tier][TimeOfDay.ALL]).concat(biomePokemonPools[this.biomeType][tier][timeOfDay]);
}
this.lastTimeOfDay = timeOfDay; this.lastTimeOfDay = timeOfDay;
} }
} }
randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies { randomSpecies(waveIndex: integer, level: integer, attempt?: integer): PokemonSpecies {
const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex); const overrideSpecies = this.scene.gameMode.getOverrideSpecies(waveIndex);
if (overrideSpecies) if (overrideSpecies) {
return overrideSpecies; return overrideSpecies;
}
const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length const isBoss = !!this.scene.getEncounterBossSegments(waveIndex, level) && !!this.pokemonPool[BiomePoolTier.BOSS].length
&& (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex)); && (this.biomeType !== Biome.END || this.scene.gameMode.isClassic || this.scene.gameMode.isWaveFinal(waveIndex));
const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64);
@ -82,23 +84,24 @@ export class Arena {
const tierPool = this.pokemonPool[tier]; const tierPool = this.pokemonPool[tier];
let ret: PokemonSpecies; let ret: PokemonSpecies;
let regen = false; let regen = false;
if (!tierPool.length) if (!tierPool.length) {
ret = this.scene.randomSpecies(waveIndex, level); ret = this.scene.randomSpecies(waveIndex, level);
else { } else {
const entry = tierPool[Utils.randSeedInt(tierPool.length)]; const entry = tierPool[Utils.randSeedInt(tierPool.length)];
let species: Species; let species: Species;
if (typeof entry === 'number') if (typeof entry === "number") {
species = entry as Species; species = entry as Species;
else { } else {
const levelThresholds = Object.keys(entry); const levelThresholds = Object.keys(entry);
for (let l = levelThresholds.length - 1; l >= 0; l--) { for (let l = levelThresholds.length - 1; l >= 0; l--) {
const levelThreshold = parseInt(levelThresholds[l]); const levelThreshold = parseInt(levelThresholds[l]);
if (level >= levelThreshold) { if (level >= levelThreshold) {
const speciesIds = entry[levelThreshold]; const speciesIds = entry[levelThreshold];
if (speciesIds.length > 1) if (speciesIds.length > 1) {
species = speciesIds[Utils.randSeedInt(speciesIds.length)]; species = speciesIds[Utils.randSeedInt(speciesIds.length)];
else } else {
species = speciesIds[0]; species = speciesIds[0];
}
break; break;
} }
} }
@ -108,30 +111,30 @@ export class Arena {
if (ret.subLegendary || ret.legendary || ret.mythical) { if (ret.subLegendary || ret.legendary || ret.mythical) {
switch (true) { switch (true) {
case (ret.baseTotal >= 720): case (ret.baseTotal >= 720):
regen = level < 90; regen = level < 90;
break; break;
case (ret.baseTotal >= 670): case (ret.baseTotal >= 670):
regen = level < 70; regen = level < 70;
break; break;
case (ret.baseTotal >= 580): case (ret.baseTotal >= 580):
regen = level < 50; regen = level < 50;
break; break;
default: default:
regen = level < 30; regen = level < 30;
break; break;
} }
} }
} }
if (regen && (attempt || 0) < 10) { if (regen && (attempt || 0) < 10) {
console.log('Incompatible level: regenerating...'); console.log("Incompatible level: regenerating...");
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1); return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
} }
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode); const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode);
if (newSpeciesId !== ret.speciesId) { if (newSpeciesId !== ret.speciesId) {
console.log('Replaced', Species[ret.speciesId], 'with', Species[newSpeciesId]); console.log("Replaced", Species[ret.speciesId], "with", Species[newSpeciesId]);
ret = getPokemonSpecies(newSpeciesId); ret = getPokemonSpecies(newSpeciesId);
} }
return ret; return ret;
@ -140,7 +143,7 @@ export class Arena {
randomTrainerType(waveIndex: integer): TrainerType { randomTrainerType(waveIndex: integer): TrainerType {
const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length const isBoss = !!this.trainerPool[BiomePoolTier.BOSS].length
&& this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType, this.scene.offsetGym); && this.scene.gameMode.isTrainerBoss(waveIndex, this.biomeType, this.scene.offsetGym);
console.log(isBoss, this.trainerPool) console.log(isBoss, this.trainerPool);
const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64); const tierValue = Utils.randSeedInt(!isBoss ? 512 : 64);
let tier = !isBoss let tier = !isBoss
? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE ? tierValue >= 156 ? BiomePoolTier.COMMON : tierValue >= 32 ? BiomePoolTier.UNCOMMON : tierValue >= 6 ? BiomePoolTier.RARE : tierValue >= 1 ? BiomePoolTier.SUPER_RARE : BiomePoolTier.ULTRA_RARE
@ -156,41 +159,41 @@ export class Arena {
getSpeciesFormIndex(species: PokemonSpecies): integer { getSpeciesFormIndex(species: PokemonSpecies): integer {
switch (species.speciesId) { switch (species.speciesId) {
case Species.BURMY: case Species.BURMY:
case Species.WORMADAM: case Species.WORMADAM:
switch (this.biomeType) { switch (this.biomeType) {
case Biome.BEACH: case Biome.BEACH:
return 1; return 1;
case Biome.SLUM: case Biome.SLUM:
return 2; return 2;
} }
break; break;
case Species.ROTOM: case Species.ROTOM:
switch (this.biomeType) { switch (this.biomeType) {
case Biome.VOLCANO: case Biome.VOLCANO:
return 1; return 1;
case Biome.SEA: case Biome.SEA:
return 2; return 2;
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
return 3; return 3;
case Biome.MOUNTAIN: case Biome.MOUNTAIN:
return 4; return 4;
case Biome.TALL_GRASS: case Biome.TALL_GRASS:
return 5; return 5;
} }
break; break;
case Species.LYCANROC: case Species.LYCANROC:
const timeOfDay = this.getTimeOfDay(); const timeOfDay = this.getTimeOfDay();
switch (timeOfDay) { switch (timeOfDay) {
case TimeOfDay.DAY: case TimeOfDay.DAY:
case TimeOfDay.DAWN: case TimeOfDay.DAWN:
return 0; return 0;
case TimeOfDay.DUSK: case TimeOfDay.DUSK:
return 2; return 2;
case TimeOfDay.NIGHT: case TimeOfDay.NIGHT:
return 1; return 1;
} }
break; break;
} }
return 0; return 0;
@ -198,70 +201,70 @@ export class Arena {
getTypeForBiome() { getTypeForBiome() {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.TOWN: case Biome.TOWN:
case Biome.PLAINS: case Biome.PLAINS:
case Biome.METROPOLIS: case Biome.METROPOLIS:
return Type.NORMAL; return Type.NORMAL;
case Biome.GRASS: case Biome.GRASS:
case Biome.TALL_GRASS: case Biome.TALL_GRASS:
return Type.GRASS; return Type.GRASS;
case Biome.FOREST: case Biome.FOREST:
case Biome.JUNGLE: case Biome.JUNGLE:
return Type.BUG; return Type.BUG;
case Biome.SLUM: case Biome.SLUM:
case Biome.SWAMP: case Biome.SWAMP:
return Type.POISON; return Type.POISON;
case Biome.SEA: case Biome.SEA:
case Biome.BEACH: case Biome.BEACH:
case Biome.LAKE: case Biome.LAKE:
case Biome.SEABED: case Biome.SEABED:
return Type.WATER; return Type.WATER;
case Biome.MOUNTAIN: case Biome.MOUNTAIN:
return Type.FLYING; return Type.FLYING;
case Biome.BADLANDS: case Biome.BADLANDS:
return Type.GROUND; return Type.GROUND;
case Biome.CAVE: case Biome.CAVE:
case Biome.DESERT: case Biome.DESERT:
return Type.ROCK; return Type.ROCK;
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
case Biome.SNOWY_FOREST: case Biome.SNOWY_FOREST:
return Type.ICE; return Type.ICE;
case Biome.MEADOW: case Biome.MEADOW:
case Biome.FAIRY_CAVE: case Biome.FAIRY_CAVE:
case Biome.ISLAND: case Biome.ISLAND:
return Type.FAIRY; return Type.FAIRY;
case Biome.POWER_PLANT: case Biome.POWER_PLANT:
return Type.ELECTRIC; return Type.ELECTRIC;
case Biome.VOLCANO: case Biome.VOLCANO:
return Type.FIRE; return Type.FIRE;
case Biome.GRAVEYARD: case Biome.GRAVEYARD:
case Biome.TEMPLE: case Biome.TEMPLE:
return Type.GHOST; return Type.GHOST;
case Biome.DOJO: case Biome.DOJO:
case Biome.CONSTRUCTION_SITE: case Biome.CONSTRUCTION_SITE:
return Type.FIGHTING; return Type.FIGHTING;
case Biome.FACTORY: case Biome.FACTORY:
case Biome.LABORATORY: case Biome.LABORATORY:
return Type.STEEL; return Type.STEEL;
case Biome.RUINS: case Biome.RUINS:
case Biome.SPACE: case Biome.SPACE:
return Type.PSYCHIC; return Type.PSYCHIC;
case Biome.WASTELAND: case Biome.WASTELAND:
case Biome.END: case Biome.END:
return Type.DRAGON; return Type.DRAGON;
case Biome.ABYSS: case Biome.ABYSS:
return Type.DARK; return Type.DARK;
default: default:
return Type.UNKNOWN; return Type.UNKNOWN;
} }
} }
getBgTerrainColorRatioForBiome(): number { getBgTerrainColorRatioForBiome(): number {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.SPACE: case Biome.SPACE:
return 1; return 1;
case Biome.END: case Biome.END:
return 0; return 0;
} }
return 131 / 180; return 131 / 180;
@ -276,7 +279,7 @@ export class Arena {
this.weather = new Weather(weather, 0); this.weather = new Weather(weather, 0);
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1))); this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.SUNNY + (weather - 1)));
this.scene.queueMessage(getWeatherStartMessage(weather)); this.scene.queueMessage(getWeatherStartMessage(weather));
return true return true;
} }
/** /**
@ -286,11 +289,13 @@ export class Arena {
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use * @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
*/ */
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean { trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
if (Overrides.WEATHER_OVERRIDE) if (Overrides.WEATHER_OVERRIDE) {
return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE); return this.trySetWeatherOverride(Overrides.WEATHER_OVERRIDE);
}
if (this.weather?.weatherType === (weather || undefined)) if (this.weather?.weatherType === (weather || undefined)) {
return false; return false;
}
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE; const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
@ -306,7 +311,7 @@ export class Arena {
} }
this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => { this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => 'weatherTypes' in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather)); pokemon.findAndRemoveTags(t => "weatherTypes" in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather));
applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather); applyPostWeatherChangeAbAttrs(PostWeatherChangeAbAttr, pokemon, weather);
}); });
@ -314,22 +319,25 @@ export class Arena {
} }
trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim: boolean = false): boolean { trySetTerrain(terrain: TerrainType, hasPokemonSource: boolean, ignoreAnim: boolean = false): boolean {
if (this.terrain?.terrainType === (terrain || undefined)) if (this.terrain?.terrainType === (terrain || undefined)) {
return false; return false;
}
const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE; const oldTerrainType = this.terrain?.terrainType || TerrainType.NONE;
this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null; this.terrain = terrain ? new Terrain(terrain, hasPokemonSource ? 5 : 0) : null;
if (this.terrain) { if (this.terrain) {
if (!ignoreAnim) if (!ignoreAnim) {
this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1))); this.scene.unshiftPhase(new CommonAnimPhase(this.scene, undefined, undefined, CommonAnim.MISTY_TERRAIN + (terrain - 1)));
}
this.scene.queueMessage(getTerrainStartMessage(terrain)); this.scene.queueMessage(getTerrainStartMessage(terrain));
} else } else {
this.scene.queueMessage(getTerrainClearMessage(oldTerrainType)); this.scene.queueMessage(getTerrainClearMessage(oldTerrainType));
}
this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => { this.scene.getField(true).filter(p => p.isOnField()).map(pokemon => {
pokemon.findAndRemoveTags(t => 'terrainTypes' in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain)); pokemon.findAndRemoveTags(t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain));
applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain); applyPostTerrainChangeAbAttrs(PostTerrainChangeAbAttr, pokemon, terrain);
}); });
@ -350,131 +358,138 @@ export class Arena {
getAttackTypeMultiplier(attackType: Type, grounded: boolean): number { getAttackTypeMultiplier(attackType: Type, grounded: boolean): number {
let weatherMultiplier = 1; let weatherMultiplier = 1;
if (this.weather && !this.weather.isEffectSuppressed(this.scene)) if (this.weather && !this.weather.isEffectSuppressed(this.scene)) {
weatherMultiplier = this.weather.getAttackTypeMultiplier(attackType); weatherMultiplier = this.weather.getAttackTypeMultiplier(attackType);
}
let terrainMultiplier = 1; let terrainMultiplier = 1;
if (this.terrain && grounded) if (this.terrain && grounded) {
terrainMultiplier = this.terrain.getAttackTypeMultiplier(attackType); terrainMultiplier = this.terrain.getAttackTypeMultiplier(attackType);
}
return weatherMultiplier * terrainMultiplier; return weatherMultiplier * terrainMultiplier;
} }
getTrainerChance(): integer { getTrainerChance(): integer {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.METROPOLIS: case Biome.METROPOLIS:
return 2; return 2;
case Biome.SLUM: case Biome.SLUM:
case Biome.BEACH: case Biome.BEACH:
case Biome.DOJO: case Biome.DOJO:
case Biome.CONSTRUCTION_SITE: case Biome.CONSTRUCTION_SITE:
return 4; return 4;
case Biome.PLAINS: case Biome.PLAINS:
case Biome.GRASS: case Biome.GRASS:
case Biome.LAKE: case Biome.LAKE:
case Biome.CAVE: case Biome.CAVE:
return 6; return 6;
case Biome.TALL_GRASS: case Biome.TALL_GRASS:
case Biome.FOREST: case Biome.FOREST:
case Biome.SEA: case Biome.SEA:
case Biome.SWAMP: case Biome.SWAMP:
case Biome.MOUNTAIN: case Biome.MOUNTAIN:
case Biome.BADLANDS: case Biome.BADLANDS:
case Biome.DESERT: case Biome.DESERT:
case Biome.MEADOW: case Biome.MEADOW:
case Biome.POWER_PLANT: case Biome.POWER_PLANT:
case Biome.GRAVEYARD: case Biome.GRAVEYARD:
case Biome.FACTORY: case Biome.FACTORY:
case Biome.SNOWY_FOREST: case Biome.SNOWY_FOREST:
return 8; return 8;
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
case Biome.VOLCANO: case Biome.VOLCANO:
case Biome.RUINS: case Biome.RUINS:
case Biome.WASTELAND: case Biome.WASTELAND:
case Biome.JUNGLE: case Biome.JUNGLE:
case Biome.FAIRY_CAVE: case Biome.FAIRY_CAVE:
return 12; return 12;
case Biome.SEABED: case Biome.SEABED:
case Biome.ABYSS: case Biome.ABYSS:
case Biome.SPACE: case Biome.SPACE:
case Biome.TEMPLE: case Biome.TEMPLE:
return 16; return 16;
default: default:
return 0; return 0;
} }
} }
getTimeOfDay(): TimeOfDay { getTimeOfDay(): TimeOfDay {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.ABYSS: case Biome.ABYSS:
return TimeOfDay.NIGHT; return TimeOfDay.NIGHT;
} }
const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40; const waveCycle = ((this.scene.currentBattle?.waveIndex || 0) + this.scene.waveCycleOffset) % 40;
if (waveCycle < 15) if (waveCycle < 15) {
return TimeOfDay.DAY; return TimeOfDay.DAY;
}
if (waveCycle < 20) if (waveCycle < 20) {
return TimeOfDay.DUSK; return TimeOfDay.DUSK;
}
if (waveCycle < 35) if (waveCycle < 35) {
return TimeOfDay.NIGHT; return TimeOfDay.NIGHT;
}
return TimeOfDay.DAWN; return TimeOfDay.DAWN;
} }
isOutside(): boolean { isOutside(): boolean {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.SEABED: case Biome.SEABED:
case Biome.CAVE: case Biome.CAVE:
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
case Biome.POWER_PLANT: case Biome.POWER_PLANT:
case Biome.DOJO: case Biome.DOJO:
case Biome.FACTORY: case Biome.FACTORY:
case Biome.ABYSS: case Biome.ABYSS:
case Biome.FAIRY_CAVE: case Biome.FAIRY_CAVE:
case Biome.TEMPLE: case Biome.TEMPLE:
case Biome.LABORATORY: case Biome.LABORATORY:
return false; return false;
default: default:
return true; return true;
} }
} }
getDayTint(): [integer, integer, integer] { getDayTint(): [integer, integer, integer] {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.ABYSS: case Biome.ABYSS:
return [ 64, 64, 64 ]; return [ 64, 64, 64 ];
default: default:
return [ 128, 128, 128 ]; return [ 128, 128, 128 ];
} }
} }
getDuskTint(): [integer, integer, integer] { getDuskTint(): [integer, integer, integer] {
if (!this.isOutside()) if (!this.isOutside()) {
return [ 0, 0, 0 ]; return [ 0, 0, 0 ];
}
switch (this.biomeType) { switch (this.biomeType) {
default: default:
return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer]; return [ 98, 48, 73 ].map(c => Math.round((c + 128) / 2)) as [integer, integer, integer];
} }
} }
getNightTint(): [integer, integer, integer] { getNightTint(): [integer, integer, integer] {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.ABYSS: case Biome.ABYSS:
case Biome.SPACE: case Biome.SPACE:
case Biome.END: case Biome.END:
return this.getDayTint(); return this.getDayTint();
} }
if (!this.isOutside()) if (!this.isOutside()) {
return [ 64, 64, 64 ]; return [ 64, 64, 64 ];
}
switch (this.biomeType) { switch (this.biomeType) {
default: default:
return [ 48, 48, 98 ]; return [ 48, 48, 98 ];
} }
} }
@ -483,17 +498,18 @@ export class Arena {
} }
applyTagsForSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide, ...args: any[]): void { applyTagsForSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide, ...args: any[]): void {
let tags = typeof tagType === 'string' let tags = typeof tagType === "string"
? this.tags.filter(t => t.tagType === tagType) ? this.tags.filter(t => t.tagType === tagType)
: this.tags.filter(t => t instanceof tagType); : this.tags.filter(t => t instanceof tagType);
if (side !== ArenaTagSide.BOTH) if (side !== ArenaTagSide.BOTH) {
tags = tags.filter(t => t.side === side); tags = tags.filter(t => t.side === side);
}
tags.forEach(t => t.apply(this, args)); tags.forEach(t => t.apply(this, args));
} }
applyTags(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, ...args: any[]): void { applyTags(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, ...args: any[]): void {
this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args);
} }
addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, targetIndex?: BattlerIndex): boolean { addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, targetIndex?: BattlerIndex): boolean {
const existingTag = this.getTagOnSide(tagType, side); const existingTag = this.getTagOnSide(tagType, side);
@ -514,7 +530,7 @@ export class Arena {
} }
getTagOnSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide): ArenaTag { getTagOnSide(tagType: ArenaTagType | { new(...args: any[]): ArenaTag }, side: ArenaTagSide): ArenaTag {
return typeof(tagType) === 'string' return typeof(tagType) === "string"
? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)) ? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side))
: this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); : this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
} }
@ -567,74 +583,74 @@ export class Arena {
getBgmLoopPoint(): number { getBgmLoopPoint(): number {
switch (this.biomeType) { switch (this.biomeType) {
case Biome.TOWN: case Biome.TOWN:
return 7.288; return 7.288;
case Biome.PLAINS: case Biome.PLAINS:
return 7.693; return 7.693;
case Biome.GRASS: case Biome.GRASS:
return 1.995; return 1.995;
case Biome.TALL_GRASS: case Biome.TALL_GRASS:
return 9.608; return 9.608;
case Biome.METROPOLIS: case Biome.METROPOLIS:
return 141.470; return 141.470;
case Biome.FOREST: case Biome.FOREST:
return 4.294; return 4.294;
case Biome.SEA: case Biome.SEA:
return 1.672; return 1.672;
case Biome.SWAMP: case Biome.SWAMP:
return 4.461; return 4.461;
case Biome.BEACH: case Biome.BEACH:
return 3.462; return 3.462;
case Biome.LAKE: case Biome.LAKE:
return 5.350; return 5.350;
case Biome.SEABED: case Biome.SEABED:
return 2.629; return 2.629;
case Biome.MOUNTAIN: case Biome.MOUNTAIN:
return 4.018; return 4.018;
case Biome.BADLANDS: case Biome.BADLANDS:
return 17.790; return 17.790;
case Biome.CAVE: case Biome.CAVE:
return 14.240; return 14.240;
case Biome.DESERT: case Biome.DESERT:
return 1.143; return 1.143;
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
return 15.010; return 15.010;
case Biome.MEADOW: case Biome.MEADOW:
return 3.891; return 3.891;
case Biome.POWER_PLANT: case Biome.POWER_PLANT:
return 2.810; return 2.810;
case Biome.VOLCANO: case Biome.VOLCANO:
return 5.116; return 5.116;
case Biome.GRAVEYARD: case Biome.GRAVEYARD:
return 3.232; return 3.232;
case Biome.DOJO: case Biome.DOJO:
return 6.205; return 6.205;
case Biome.FACTORY: case Biome.FACTORY:
return 4.985; return 4.985;
case Biome.RUINS: case Biome.RUINS:
return 2.270; return 2.270;
case Biome.WASTELAND: case Biome.WASTELAND:
return 6.336; return 6.336;
case Biome.ABYSS: case Biome.ABYSS:
return 5.130; return 5.130;
case Biome.SPACE: case Biome.SPACE:
return 21.347; return 21.347;
case Biome.CONSTRUCTION_SITE: case Biome.CONSTRUCTION_SITE:
return 1.222; return 1.222;
case Biome.JUNGLE: case Biome.JUNGLE:
return 0.000; return 0.000;
case Biome.FAIRY_CAVE: case Biome.FAIRY_CAVE:
return 4.542; return 4.542;
case Biome.TEMPLE: case Biome.TEMPLE:
return 2.547; return 2.547;
case Biome.ISLAND: case Biome.ISLAND:
return 2.751; return 2.751;
case Biome.LABORATORY: case Biome.LABORATORY:
return 114.862; return 114.862;
case Biome.SLUM: case Biome.SLUM:
return 1.221; return 1.221;
case Biome.SNOWY_FOREST: case Biome.SNOWY_FOREST:
return 3.047; return 3.047;
} }
} }
} }
@ -645,32 +661,32 @@ export function getBiomeKey(biome: Biome): string {
export function getBiomeHasProps(biomeType: Biome): boolean { export function getBiomeHasProps(biomeType: Biome): boolean {
switch (biomeType) { switch (biomeType) {
case Biome.METROPOLIS: case Biome.METROPOLIS:
case Biome.BEACH: case Biome.BEACH:
case Biome.LAKE: case Biome.LAKE:
case Biome.SEABED: case Biome.SEABED:
case Biome.MOUNTAIN: case Biome.MOUNTAIN:
case Biome.BADLANDS: case Biome.BADLANDS:
case Biome.CAVE: case Biome.CAVE:
case Biome.DESERT: case Biome.DESERT:
case Biome.ICE_CAVE: case Biome.ICE_CAVE:
case Biome.MEADOW: case Biome.MEADOW:
case Biome.POWER_PLANT: case Biome.POWER_PLANT:
case Biome.VOLCANO: case Biome.VOLCANO:
case Biome.GRAVEYARD: case Biome.GRAVEYARD:
case Biome.FACTORY: case Biome.FACTORY:
case Biome.RUINS: case Biome.RUINS:
case Biome.WASTELAND: case Biome.WASTELAND:
case Biome.ABYSS: case Biome.ABYSS:
case Biome.CONSTRUCTION_SITE: case Biome.CONSTRUCTION_SITE:
case Biome.JUNGLE: case Biome.JUNGLE:
case Biome.FAIRY_CAVE: case Biome.FAIRY_CAVE:
case Biome.TEMPLE: case Biome.TEMPLE:
case Biome.SNOWY_FOREST: case Biome.SNOWY_FOREST:
case Biome.ISLAND: case Biome.ISLAND:
case Biome.LABORATORY: case Biome.LABORATORY:
case Biome.END: case Biome.END:
return true; return true;
} }
return false; return false;
@ -688,12 +704,12 @@ export class ArenaBase extends Phaser.GameObjects.Container {
this.player = player; this.player = player;
this.base = scene.addFieldSprite(0, 0, 'plains_a', null, 1); this.base = scene.addFieldSprite(0, 0, "plains_a", null, 1);
this.base.setOrigin(0, 0); this.base.setOrigin(0, 0);
this.props = !player ? this.props = !player ?
new Array(3).fill(null).map(() => { new Array(3).fill(null).map(() => {
const ret = scene.addFieldSprite(0, 0, 'plains_b', null, 1); const ret = scene.addFieldSprite(0, 0, "plains_b", null, 1);
ret.setOrigin(0, 0); ret.setOrigin(0, 0);
ret.setVisible(false); ret.setVisible(false);
return ret; return ret;
@ -703,7 +719,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
setBiome(biome: Biome, propValue?: integer): void { setBiome(biome: Biome, propValue?: integer): void {
const hasProps = getBiomeHasProps(biome); const hasProps = getBiomeHasProps(biome);
const biomeKey = getBiomeKey(biome); const biomeKey = getBiomeKey(biome);
const baseKey = `${biomeKey}_${this.player ? 'a' : 'b'}`; const baseKey = `${biomeKey}_${this.player ? "a" : "b"}`;
if (biome !== this.biome) { if (biome !== this.biome) {
this.base.setTexture(baseKey); this.base.setTexture(baseKey);
@ -717,8 +733,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1 repeat: -1
}); });
this.base.play(baseKey); this.base.play(baseKey);
} else } else {
this.base.stop(); this.base.stop();
}
this.add(this.base); this.add(this.base);
} }
@ -729,7 +746,7 @@ export class ArenaBase extends Phaser.GameObjects.Container {
? hasProps ? Utils.randSeedInt(8) : 0 ? hasProps ? Utils.randSeedInt(8) : 0
: propValue; : propValue;
this.props.forEach((prop, p) => { this.props.forEach((prop, p) => {
const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ''}`; const propKey = `${biomeKey}_b${hasProps ? `_${p + 1}` : ""}`;
prop.setTexture(propKey); prop.setTexture(propKey);
if (hasProps && prop.texture.frameTotal > 1) { if (hasProps && prop.texture.frameTotal > 1) {
@ -741,8 +758,9 @@ export class ArenaBase extends Phaser.GameObjects.Container {
repeat: -1 repeat: -1
}); });
prop.play(propKey); prop.play(propKey);
} else } else {
prop.stop(); prop.stop();
}
prop.setVisible(hasProps && !!(this.propValue & (1 << p))); prop.setVisible(hasProps && !!(this.propValue & (1 << p)));
this.add(prop); this.add(prop);

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import { Species } from "./data/enums/species";
import PokemonSpecies, { allSpecies } from "./data/pokemon-species"; import PokemonSpecies, { allSpecies } from "./data/pokemon-species";
import { Arena } from "./field/arena"; import { Arena } from "./field/arena";
import * as Utils from "./utils"; import * as Utils from "./utils";
import * as Overrides from './overrides'; import * as Overrides from "./overrides";
export enum GameModes { export enum GameModes {
CLASSIC, CLASSIC,
@ -52,13 +52,14 @@ export class GameMode implements GameModeConfig {
* - 5 for all other modes * - 5 for all other modes
*/ */
getStartingLevel(): integer { getStartingLevel(): integer {
if (Overrides.STARTING_LEVEL_OVERRIDE) if (Overrides.STARTING_LEVEL_OVERRIDE) {
return Overrides.STARTING_LEVEL_OVERRIDE; return Overrides.STARTING_LEVEL_OVERRIDE;
}
switch (this.modeId) { switch (this.modeId) {
case GameModes.DAILY: case GameModes.DAILY:
return 20; return 20;
default: default:
return 5; return 5;
} }
} }
@ -80,46 +81,50 @@ export class GameMode implements GameModeConfig {
*/ */
getStartingBiome(scene: BattleScene): Biome { getStartingBiome(scene: BattleScene): Biome {
switch (this.modeId) { switch (this.modeId) {
case GameModes.DAILY: case GameModes.DAILY:
return scene.generateRandomBiome(this.getWaveForDifficulty(1)); return scene.generateRandomBiome(this.getWaveForDifficulty(1));
default: default:
return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN; return Overrides.STARTING_BIOME_OVERRIDE || Biome.TOWN;
} }
} }
getWaveForDifficulty(waveIndex: integer, ignoreCurveChanges: boolean = false): integer { getWaveForDifficulty(waveIndex: integer, ignoreCurveChanges: boolean = false): integer {
switch (this.modeId) { switch (this.modeId) {
case GameModes.DAILY: case GameModes.DAILY:
return waveIndex + 30 + (!ignoreCurveChanges ? Math.floor(waveIndex / 5) : 0); return waveIndex + 30 + (!ignoreCurveChanges ? Math.floor(waveIndex / 5) : 0);
default: default:
return waveIndex; return waveIndex;
} }
} }
isWaveTrainer(waveIndex: integer, arena: Arena): boolean { isWaveTrainer(waveIndex: integer, arena: Arena): boolean {
if (this.isDaily) if (this.isDaily) {
return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex)); return waveIndex % 10 === 5 || (!(waveIndex % 10) && waveIndex > 10 && !this.isWaveFinal(waveIndex));
if ((waveIndex % 30) === (arena.scene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) }
if ((waveIndex % 30) === (arena.scene.offsetGym ? 0 : 20) && !this.isWaveFinal(waveIndex)) {
return true; return true;
else if (waveIndex % 10 !== 1 && waveIndex % 10) { } else if (waveIndex % 10 !== 1 && waveIndex % 10) {
const trainerChance = arena.getTrainerChance(); const trainerChance = arena.getTrainerChance();
let allowTrainerBattle = true; let allowTrainerBattle = true;
if (trainerChance) { if (trainerChance) {
const waveBase = Math.floor(waveIndex / 10) * 10; const waveBase = Math.floor(waveIndex / 10) * 10;
for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) { for (let w = Math.max(waveIndex - 3, waveBase + 2); w <= Math.min(waveIndex + 3, waveBase + 9); w++) {
if (w === waveIndex) if (w === waveIndex) {
continue; continue;
}
if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || fixedBattles.hasOwnProperty(w)) { if ((w % 30) === (arena.scene.offsetGym ? 0 : 20) || fixedBattles.hasOwnProperty(w)) {
allowTrainerBattle = false; allowTrainerBattle = false;
break; break;
} else if (w < waveIndex) { } else if (w < waveIndex) {
arena.scene.executeWithSeedOffset(() => { arena.scene.executeWithSeedOffset(() => {
const waveTrainerChance = arena.getTrainerChance(); const waveTrainerChance = arena.getTrainerChance();
if (!Utils.randSeedInt(waveTrainerChance)) if (!Utils.randSeedInt(waveTrainerChance)) {
allowTrainerBattle = false; allowTrainerBattle = false;
}
}, w); }, w);
if (!allowTrainerBattle) if (!allowTrainerBattle) {
break; break;
}
} }
} }
} }
@ -130,10 +135,10 @@ export class GameMode implements GameModeConfig {
isTrainerBoss(waveIndex: integer, biomeType: Biome, offsetGym: boolean): boolean { isTrainerBoss(waveIndex: integer, biomeType: Biome, offsetGym: boolean): boolean {
switch (this.modeId) { switch (this.modeId) {
case GameModes.DAILY: case GameModes.DAILY:
return waveIndex > 10 && waveIndex < 50 && !(waveIndex % 10); return waveIndex > 10 && waveIndex < 50 && !(waveIndex % 10);
default: default:
return (waveIndex % 30) === (offsetGym ? 0 : 20) && (biomeType !== Biome.END || this.isClassic || this.isWaveFinal(waveIndex)); return (waveIndex % 30) === (offsetGym ? 0 : 20) && (biomeType !== Biome.END || this.isClassic || this.isWaveFinal(waveIndex));
} }
} }
@ -155,85 +160,85 @@ export class GameMode implements GameModeConfig {
*/ */
isWaveFinal(waveIndex: integer, modeId: GameModes = this.modeId): boolean { isWaveFinal(waveIndex: integer, modeId: GameModes = this.modeId): boolean {
switch (modeId) { switch (modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
return waveIndex === 200; return waveIndex === 200;
case GameModes.ENDLESS: case GameModes.ENDLESS:
case GameModes.SPLICED_ENDLESS: case GameModes.SPLICED_ENDLESS:
return !(waveIndex % 250); return !(waveIndex % 250);
case GameModes.DAILY: case GameModes.DAILY:
return waveIndex === 50; return waveIndex === 50;
} }
} }
/** /**
* Every 10 waves is a boss battle * Every 10 waves is a boss battle
* @returns true if waveIndex is a multiple of 10 * @returns true if waveIndex is a multiple of 10
*/ */
isBoss(waveIndex: integer): boolean { isBoss(waveIndex: integer): boolean {
return waveIndex % 10 === 0; return waveIndex % 10 === 0;
} }
/** /**
* Every 50 waves of an Endless mode is a boss * Every 50 waves of an Endless mode is a boss
* At this time it is paradox pokemon * At this time it is paradox pokemon
* @returns true if waveIndex is a multiple of 50 in Endless * @returns true if waveIndex is a multiple of 50 in Endless
*/ */
isEndlessBoss(waveIndex: integer): boolean { isEndlessBoss(waveIndex: integer): boolean {
return waveIndex % 50 && return waveIndex % 50 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS); (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
} }
/** /**
* Every 250 waves of an Endless mode is a minor boss * Every 250 waves of an Endless mode is a minor boss
* At this time it is Eternatus * At this time it is Eternatus
* @returns true if waveIndex is a multiple of 250 in Endless * @returns true if waveIndex is a multiple of 250 in Endless
*/ */
isEndlessMinorBoss(waveIndex: integer): boolean { isEndlessMinorBoss(waveIndex: integer): boolean {
return waveIndex % 250 === 0 && return waveIndex % 250 === 0 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS); (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
} }
/** /**
* Every 1000 waves of an Endless mode is a major boss * Every 1000 waves of an Endless mode is a major boss
* At this time it is Eternamax Eternatus * At this time it is Eternamax Eternatus
* @returns true if waveIndex is a multiple of 1000 in Endless * @returns true if waveIndex is a multiple of 1000 in Endless
*/ */
isEndlessMajorBoss(waveIndex: integer): boolean { isEndlessMajorBoss(waveIndex: integer): boolean {
return waveIndex % 1000 === 0 && return waveIndex % 1000 === 0 &&
(this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS); (this.modeId === GameModes.ENDLESS || this.modeId === GameModes.SPLICED_ENDLESS);
} }
getClearScoreBonus(): integer { getClearScoreBonus(): integer {
switch (this.modeId) { switch (this.modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
return 5000; return 5000;
case GameModes.DAILY: case GameModes.DAILY:
return 2500; return 2500;
} }
} }
getEnemyModifierChance(isBoss: boolean): integer { getEnemyModifierChance(isBoss: boolean): integer {
switch (this.modeId) { switch (this.modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
case GameModes.DAILY: case GameModes.DAILY:
return !isBoss ? 18 : 6; return !isBoss ? 18 : 6;
case GameModes.ENDLESS: case GameModes.ENDLESS:
case GameModes.SPLICED_ENDLESS: case GameModes.SPLICED_ENDLESS:
return !isBoss ? 12 : 4; return !isBoss ? 12 : 4;
} }
} }
getName(): string { getName(): string {
switch (this.modeId) { switch (this.modeId) {
case GameModes.CLASSIC: case GameModes.CLASSIC:
return 'Classic'; return "Classic";
case GameModes.ENDLESS: case GameModes.ENDLESS:
return 'Endless'; return "Endless";
case GameModes.SPLICED_ENDLESS: case GameModes.SPLICED_ENDLESS:
return 'Endless (Spliced)'; return "Endless (Spliced)";
case GameModes.DAILY: case GameModes.DAILY:
return 'Daily Run'; return "Daily Run";
} }
} }
} }

View File

@ -1,6 +1,6 @@
import Phaser, {Time} from "phaser"; import Phaser, {Time} from "phaser";
import * as Utils from "./utils"; import * as Utils from "./utils";
import {initTouchControls} from './touch-controls'; import {initTouchControls} from "./touch-controls";
import pad_generic from "./configs/pad_generic"; import pad_generic from "./configs/pad_generic";
import pad_unlicensedSNES from "./configs/pad_unlicensedSNES"; import pad_unlicensedSNES from "./configs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/pad_xbox360"; import pad_xbox360 from "./configs/pad_xbox360";
@ -46,19 +46,19 @@ const repeatInputDelayMillis = 250;
* providing a unified interface for all input-related interactions. * providing a unified interface for all input-related interactions.
*/ */
export class InputsController { export class InputsController {
private buttonKeys: Phaser.Input.Keyboard.Key[][]; private buttonKeys: Phaser.Input.Keyboard.Key[][];
private gamepads: Array<string> = new Array(); private gamepads: Array<string> = new Array();
private scene: Phaser.Scene; private scene: Phaser.Scene;
private buttonLock: Button; private buttonLock: Button;
private buttonLock2: Button; private buttonLock2: Button;
private interactions: Map<Button, Map<string, boolean>> = new Map(); private interactions: Map<Button, Map<string, boolean>> = new Map();
private time: Time; private time: Time;
private player: Map<String, GamepadMapping> = new Map(); private player: Map<String, GamepadMapping> = new Map();
private gamepadSupport: boolean = true; private gamepadSupport: boolean = true;
/** /**
* Initializes a new instance of the game control system, setting up initial state and configurations. * Initializes a new instance of the game control system, setting up initial state and configurations.
* *
* @param scene - The Phaser scene associated with this instance. * @param scene - The Phaser scene associated with this instance.
@ -69,25 +69,25 @@ export class InputsController {
* Specific buttons like MENU and STATS are set not to repeat their actions. * Specific buttons like MENU and STATS are set not to repeat their actions.
* It concludes by calling the `init` method to complete the setup. * It concludes by calling the `init` method to complete the setup.
*/ */
constructor(scene: Phaser.Scene) { constructor(scene: Phaser.Scene) {
this.scene = scene; this.scene = scene;
this.time = this.scene.time; this.time = this.scene.time;
this.buttonKeys = []; this.buttonKeys = [];
for (const b of Utils.getEnumValues(Button)) { for (const b of Utils.getEnumValues(Button)) {
this.interactions[b] = { this.interactions[b] = {
pressTime: false, pressTime: false,
isPressed: false, isPressed: false,
source: null, source: null,
} };
}
// We don't want the menu key to be repeated
delete this.interactions[Button.MENU];
delete this.interactions[Button.STATS];
this.init();
} }
// We don't want the menu key to be repeated
delete this.interactions[Button.MENU];
delete this.interactions[Button.STATS];
this.init();
}
/** /**
* Sets up event handlers and initializes gamepad and keyboard controls. * Sets up event handlers and initializes gamepad and keyboard controls.
* *
* @remarks * @remarks
@ -95,46 +95,46 @@ export class InputsController {
* It handles gamepad connections/disconnections and button press events, and ensures keyboard controls are set up. * It handles gamepad connections/disconnections and button press events, and ensures keyboard controls are set up.
* Additionally, it manages the game's behavior when it loses focus to prevent unwanted game actions during this state. * Additionally, it manages the game's behavior when it loses focus to prevent unwanted game actions during this state.
*/ */
init(): void { init(): void {
this.events = new Phaser.Events.EventEmitter(); this.events = new Phaser.Events.EventEmitter();
this.scene.game.events.on(Phaser.Core.Events.BLUR, () => { this.scene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus() this.loseFocus();
}) });
if (typeof this.scene.input.gamepad !== 'undefined') { if (typeof this.scene.input.gamepad !== "undefined") {
this.scene.input.gamepad.on('connected', function (thisGamepad) { this.scene.input.gamepad.on("connected", function (thisGamepad) {
this.refreshGamepads(); this.refreshGamepads();
this.setupGamepad(thisGamepad); this.setupGamepad(thisGamepad);
}, this); }, this);
// Check to see if the gamepad has already been setup by the browser // Check to see if the gamepad has already been setup by the browser
this.scene.input.gamepad.refreshPads(); this.scene.input.gamepad.refreshPads();
if (this.scene.input.gamepad.total) { if (this.scene.input.gamepad.total) {
this.refreshGamepads(); this.refreshGamepads();
for (const thisGamepad of this.gamepads) { for (const thisGamepad of this.gamepads) {
this.scene.input.gamepad.emit('connected', thisGamepad); this.scene.input.gamepad.emit("connected", thisGamepad);
}
}
this.scene.input.gamepad.on('down', this.gamepadButtonDown, this);
this.scene.input.gamepad.on('up', this.gamepadButtonUp, this);
} }
}
// Keyboard this.scene.input.gamepad.on("down", this.gamepadButtonDown, this);
this.setupKeyboardControls(); this.scene.input.gamepad.on("up", this.gamepadButtonUp, this);
} }
/** // Keyboard
this.setupKeyboardControls();
}
/**
* Handles actions to take when the game loses focus, such as deactivating pressed keys. * Handles actions to take when the game loses focus, such as deactivating pressed keys.
* *
* @remarks * @remarks
* This method is triggered when the game or the browser tab loses focus. It ensures that any keys pressed are deactivated to prevent stuck keys affecting gameplay when the game is not active. * This method is triggered when the game or the browser tab loses focus. It ensures that any keys pressed are deactivated to prevent stuck keys affecting gameplay when the game is not active.
*/ */
loseFocus(): void { loseFocus(): void {
this.deactivatePressedKey(); this.deactivatePressedKey();
} }
/** /**
* Enables or disables support for gamepad input. * Enables or disables support for gamepad input.
* *
* @param value - A boolean indicating whether gamepad support should be enabled (true) or disabled (false). * @param value - A boolean indicating whether gamepad support should be enabled (true) or disabled (false).
@ -142,17 +142,17 @@ export class InputsController {
* @remarks * @remarks
* This method toggles gamepad support. If disabled, it also ensures that all currently pressed gamepad buttons are deactivated to avoid stuck inputs. * This method toggles gamepad support. If disabled, it also ensures that all currently pressed gamepad buttons are deactivated to avoid stuck inputs.
*/ */
setGamepadSupport(value: boolean): void { setGamepadSupport(value: boolean): void {
if (value) { if (value) {
this.gamepadSupport = true; this.gamepadSupport = true;
} else { } else {
this.gamepadSupport = false; this.gamepadSupport = false;
// if we disable the gamepad, we want to release every key pressed // if we disable the gamepad, we want to release every key pressed
this.deactivatePressedKey(); this.deactivatePressedKey();
}
} }
}
/** /**
* Updates the interaction handling by processing input states. * Updates the interaction handling by processing input states.
* This method gives priority to certain buttons by reversing the order in which they are checked. * This method gives priority to certain buttons by reversing the order in which they are checked.
* *
@ -165,30 +165,30 @@ export class InputsController {
* Special handling is applied if gamepad support is disabled but a gamepad source is still triggering inputs, * Special handling is applied if gamepad support is disabled but a gamepad source is still triggering inputs,
* preventing potential infinite loops by removing the last processed movement time for the button. * preventing potential infinite loops by removing the last processed movement time for the button.
*/ */
update(): void { update(): void {
for (const b of Utils.getEnumValues(Button).reverse()) { for (const b of Utils.getEnumValues(Button).reverse()) {
if ( if (
this.interactions.hasOwnProperty(b) && this.interactions.hasOwnProperty(b) &&
this.repeatInputDurationJustPassed(b) && this.repeatInputDurationJustPassed(b) &&
this.interactions[b].isPressed this.interactions[b].isPressed
) { ) {
// Prevents repeating button interactions when gamepad support is disabled. // Prevents repeating button interactions when gamepad support is disabled.
if (!this.gamepadSupport && this.interactions[b].source === 'gamepad') { if (!this.gamepadSupport && this.interactions[b].source === "gamepad") {
// Deletes the last interaction for a button if gamepad is disabled. // Deletes the last interaction for a button if gamepad is disabled.
this.delLastProcessedMovementTime(b); this.delLastProcessedMovementTime(b);
return; return;
}
// Emits an event for the button press.
this.events.emit('input_down', {
controller_type: this.interactions[b].source,
button: b,
});
this.setLastProcessedMovementTime(b, this.interactions[b].source);
}
} }
// Emits an event for the button press.
this.events.emit("input_down", {
controller_type: this.interactions[b].source,
button: b,
});
this.setLastProcessedMovementTime(b, this.interactions[b].source);
}
} }
}
/** /**
* Configures a gamepad for use based on its device ID. * Configures a gamepad for use based on its device ID.
* *
* @param thisGamepad - The gamepad to set up. * @param thisGamepad - The gamepad to set up.
@ -198,13 +198,13 @@ export class InputsController {
* It updates the player's gamepad mapping based on the identified configuration, ensuring * It updates the player's gamepad mapping based on the identified configuration, ensuring
* that the gamepad controls are correctly mapped to in-game actions. * that the gamepad controls are correctly mapped to in-game actions.
*/ */
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void { setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
let gamepadID = thisGamepad.id.toLowerCase(); const gamepadID = thisGamepad.id.toLowerCase();
const mappedPad = this.mapGamepad(gamepadID); const mappedPad = this.mapGamepad(gamepadID);
this.player['mapping'] = mappedPad.gamepadMapping; this.player["mapping"] = mappedPad.gamepadMapping;
} }
/** /**
* Refreshes and re-indexes the list of connected gamepads. * Refreshes and re-indexes the list of connected gamepads.
* *
* @remarks * @remarks
@ -212,18 +212,18 @@ export class InputsController {
* It corrects the index of each gamepad to account for any previously undefined entries, * It corrects the index of each gamepad to account for any previously undefined entries,
* ensuring that all gamepads are properly indexed and can be accurately referenced within the game. * ensuring that all gamepads are properly indexed and can be accurately referenced within the game.
*/ */
refreshGamepads(): void { refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason. // Sometimes, gamepads are undefined. For some reason.
this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) { this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) {
return el != null; return el !== null;
}); });
for (const [index, thisGamepad] of this.gamepads.entries()) { for (const [index, thisGamepad] of this.gamepads.entries()) {
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
}
} }
}
/** /**
* Retrieves the current gamepad mapping for in-game actions. * Retrieves the current gamepad mapping for in-game actions.
* *
* @returns An object mapping gamepad buttons to in-game actions based on the player's current gamepad configuration. * @returns An object mapping gamepad buttons to in-game actions based on the player's current gamepad configuration.
@ -234,31 +234,33 @@ export class InputsController {
* The mapping includes directional controls, action buttons, and system commands among others, * The mapping includes directional controls, action buttons, and system commands among others,
* adjusted for any custom settings such as swapped action buttons. * adjusted for any custom settings such as swapped action buttons.
*/ */
getActionGamepadMapping(): ActionGamepadMapping { getActionGamepadMapping(): ActionGamepadMapping {
const gamepadMapping = {}; const gamepadMapping = {};
if (!this.player?.mapping) return gamepadMapping; if (!this.player?.mapping) {
gamepadMapping[this.player.mapping.LC_N] = Button.UP; return gamepadMapping;
gamepadMapping[this.player.mapping.LC_S] = Button.DOWN;
gamepadMapping[this.player.mapping.LC_W] = Button.LEFT;
gamepadMapping[this.player.mapping.LC_E] = Button.RIGHT;
gamepadMapping[this.player.mapping.TOUCH] = Button.SUBMIT;
gamepadMapping[this.player.mapping.RC_S] = this.scene.abSwapped ? Button.CANCEL : Button.ACTION;
gamepadMapping[this.player.mapping.RC_E] = this.scene.abSwapped ? Button.ACTION : Button.CANCEL;
gamepadMapping[this.player.mapping.SELECT] = Button.STATS;
gamepadMapping[this.player.mapping.START] = Button.MENU;
gamepadMapping[this.player.mapping.RB] = Button.CYCLE_SHINY;
gamepadMapping[this.player.mapping.LB] = Button.CYCLE_FORM;
gamepadMapping[this.player.mapping.LT] = Button.CYCLE_GENDER;
gamepadMapping[this.player.mapping.RT] = Button.CYCLE_ABILITY;
gamepadMapping[this.player.mapping.RC_W] = Button.CYCLE_NATURE;
gamepadMapping[this.player.mapping.RC_N] = Button.CYCLE_VARIANT;
gamepadMapping[this.player.mapping.LS] = Button.SPEED_UP;
gamepadMapping[this.player.mapping.RS] = Button.SLOW_DOWN;
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;
gamepadMapping[this.player.mapping.LC_E] = Button.RIGHT;
gamepadMapping[this.player.mapping.TOUCH] = Button.SUBMIT;
gamepadMapping[this.player.mapping.RC_S] = this.scene.abSwapped ? Button.CANCEL : Button.ACTION;
gamepadMapping[this.player.mapping.RC_E] = this.scene.abSwapped ? Button.ACTION : Button.CANCEL;
gamepadMapping[this.player.mapping.SELECT] = Button.STATS;
gamepadMapping[this.player.mapping.START] = Button.MENU;
gamepadMapping[this.player.mapping.RB] = Button.CYCLE_SHINY;
gamepadMapping[this.player.mapping.LB] = Button.CYCLE_FORM;
gamepadMapping[this.player.mapping.LT] = Button.CYCLE_GENDER;
gamepadMapping[this.player.mapping.RT] = Button.CYCLE_ABILITY;
gamepadMapping[this.player.mapping.RC_W] = Button.CYCLE_NATURE;
gamepadMapping[this.player.mapping.RC_N] = Button.CYCLE_VARIANT;
gamepadMapping[this.player.mapping.LS] = Button.SPEED_UP;
gamepadMapping[this.player.mapping.RS] = Button.SLOW_DOWN;
/** return gamepadMapping;
}
/**
* Handles the 'down' event for gamepad buttons, emitting appropriate events and updating the interaction state. * Handles the 'down' event for gamepad buttons, emitting appropriate events and updating the interaction state.
* *
* @param pad - The gamepad on which the button press occurred. * @param pad - The gamepad on which the button press occurred.
@ -271,20 +273,22 @@ export class InputsController {
* - Checks if the pressed button is mapped to a game action. * - Checks if the pressed button is mapped to a game action.
* - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button. * - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button.
*/ */
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return; if (!this.gamepadSupport) {
const actionMapping = this.getActionGamepadMapping(); return;
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonDown !== undefined) {
this.events.emit('input_down', {
controller_type: 'gamepad',
button: buttonDown,
});
this.setLastProcessedMovementTime(buttonDown, 'gamepad');
}
} }
const actionMapping = this.getActionGamepadMapping();
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonDown !== undefined) {
this.events.emit("input_down", {
controller_type: "gamepad",
button: buttonDown,
});
this.setLastProcessedMovementTime(buttonDown, "gamepad");
}
}
/** /**
* Handles the 'up' event for gamepad buttons, emitting appropriate events and clearing the interaction state. * Handles the 'up' event for gamepad buttons, emitting appropriate events and clearing the interaction state.
* *
* @param pad - The gamepad on which the button release occurred. * @param pad - The gamepad on which the button release occurred.
@ -297,20 +301,22 @@ export class InputsController {
* - Checks if the released button is mapped to a game action. * - Checks if the released button is mapped to a game action.
* - If mapped, emits an 'input_up' event with the controller type and button action, and clears the interaction for this button. * - If mapped, emits an 'input_up' event with the controller type and button action, and clears the interaction for this button.
*/ */
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void { gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return; if (!this.gamepadSupport) {
const actionMapping = this.getActionGamepadMapping(); return;
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) {
this.events.emit('input_up', {
controller_type: 'gamepad',
button: buttonUp,
});
this.delLastProcessedMovementTime(buttonUp);
}
} }
const actionMapping = this.getActionGamepadMapping();
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) {
this.events.emit("input_up", {
controller_type: "gamepad",
button: buttonUp,
});
this.delLastProcessedMovementTime(buttonUp);
}
}
/** /**
* Configures keyboard controls for the game, mapping physical keys to game actions. * Configures keyboard controls for the game, mapping physical keys to game actions.
* *
* @remarks * @remarks
@ -328,43 +334,44 @@ export class InputsController {
* Post-setup, it initializes touch controls (if applicable) and starts listening for keyboard inputs using * Post-setup, it initializes touch controls (if applicable) and starts listening for keyboard inputs using
* `listenInputKeyboard`, ensuring that all configured keys are actively monitored for player interactions. * `listenInputKeyboard`, ensuring that all configured keys are actively monitored for player interactions.
*/ */
setupKeyboardControls(): void { setupKeyboardControls(): void {
const keyCodes = Phaser.Input.Keyboard.KeyCodes; const keyCodes = Phaser.Input.Keyboard.KeyCodes;
const keyConfig = { const keyConfig = {
[Button.UP]: [keyCodes.UP, keyCodes.W], [Button.UP]: [keyCodes.UP, keyCodes.W],
[Button.DOWN]: [keyCodes.DOWN, keyCodes.S], [Button.DOWN]: [keyCodes.DOWN, keyCodes.S],
[Button.LEFT]: [keyCodes.LEFT, keyCodes.A], [Button.LEFT]: [keyCodes.LEFT, keyCodes.A],
[Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D], [Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D],
[Button.SUBMIT]: [keyCodes.ENTER], [Button.SUBMIT]: [keyCodes.ENTER],
[Button.ACTION]: [keyCodes.SPACE, keyCodes.Z], [Button.ACTION]: [keyCodes.SPACE, keyCodes.Z],
[Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X], [Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X],
[Button.MENU]: [keyCodes.ESC, keyCodes.M], [Button.MENU]: [keyCodes.ESC, keyCodes.M],
[Button.STATS]: [keyCodes.SHIFT, keyCodes.C], [Button.STATS]: [keyCodes.SHIFT, keyCodes.C],
[Button.CYCLE_SHINY]: [keyCodes.R], [Button.CYCLE_SHINY]: [keyCodes.R],
[Button.CYCLE_FORM]: [keyCodes.F], [Button.CYCLE_FORM]: [keyCodes.F],
[Button.CYCLE_GENDER]: [keyCodes.G], [Button.CYCLE_GENDER]: [keyCodes.G],
[Button.CYCLE_ABILITY]: [keyCodes.E], [Button.CYCLE_ABILITY]: [keyCodes.E],
[Button.CYCLE_NATURE]: [keyCodes.N], [Button.CYCLE_NATURE]: [keyCodes.N],
[Button.CYCLE_VARIANT]: [keyCodes.V], [Button.CYCLE_VARIANT]: [keyCodes.V],
[Button.SPEED_UP]: [keyCodes.PLUS], [Button.SPEED_UP]: [keyCodes.PLUS],
[Button.SLOW_DOWN]: [keyCodes.MINUS] [Button.SLOW_DOWN]: [keyCodes.MINUS]
}; };
const mobileKeyConfig = {}; const mobileKeyConfig = {};
for (const b of Utils.getEnumValues(Button)) { for (const b of Utils.getEnumValues(Button)) {
const keys: Phaser.Input.Keyboard.Key[] = []; const keys: Phaser.Input.Keyboard.Key[] = [];
if (keyConfig.hasOwnProperty(b)) { if (keyConfig.hasOwnProperty(b)) {
for (let k of keyConfig[b]) for (const k of keyConfig[b]) {
keys.push(this.scene.input.keyboard.addKey(k, false)); keys.push(this.scene.input.keyboard.addKey(k, false));
mobileKeyConfig[Button[b]] = keys[0];
}
this.buttonKeys[b] = keys;
} }
mobileKeyConfig[Button[b]] = keys[0];
initTouchControls(mobileKeyConfig); }
this.listenInputKeyboard(); this.buttonKeys[b] = keys;
} }
/** initTouchControls(mobileKeyConfig);
this.listenInputKeyboard();
}
/**
* Sets up event listeners for keyboard inputs on all registered keys. * Sets up event listeners for keyboard inputs on all registered keys.
* *
* @remarks * @remarks
@ -382,28 +389,28 @@ export class InputsController {
* This setup ensures that each key on the keyboard is monitored for press and release events, * This setup ensures that each key on the keyboard is monitored for press and release events,
* and that these events are properly communicated within the system. * and that these events are properly communicated within the system.
*/ */
listenInputKeyboard(): void { listenInputKeyboard(): void {
this.buttonKeys.forEach((row, index) => { this.buttonKeys.forEach((row, index) => {
for (const key of row) { for (const key of row) {
key.on('down', () => { key.on("down", () => {
this.events.emit('input_down', { this.events.emit("input_down", {
controller_type: 'keyboard', controller_type: "keyboard",
button: index, button: index,
}); });
this.setLastProcessedMovementTime(index, 'keyboard'); this.setLastProcessedMovementTime(index, "keyboard");
});
key.on('up', () => {
this.events.emit('input_up', {
controller_type: 'keyboard',
button: index,
});
this.delLastProcessedMovementTime(index);
});
}
}); });
} key.on("up", () => {
this.events.emit("input_up", {
controller_type: "keyboard",
button: index,
});
this.delLastProcessedMovementTime(index);
});
}
});
}
/** /**
* Maps a gamepad ID to a specific gamepad configuration based on the ID's characteristics. * Maps a gamepad ID to a specific gamepad configuration based on the ID's characteristics.
* *
* @param id - The gamepad ID string, typically representing a unique identifier for a gamepad model or make. * @param id - The gamepad ID string, typically representing a unique identifier for a gamepad model or make.
@ -416,33 +423,35 @@ export class InputsController {
* - If the ID contains '054c', it is identified as a DualShock gamepad. * - If the ID contains '054c', it is identified as a DualShock gamepad.
* If no specific identifiers are recognized, a generic gamepad configuration is returned. * If no specific identifiers are recognized, a generic gamepad configuration is returned.
*/ */
mapGamepad(id: string): GamepadConfig { mapGamepad(id: string): GamepadConfig {
id = id.toLowerCase(); id = id.toLowerCase();
if (id.includes('081f') && id.includes('e401')) { if (id.includes("081f") && id.includes("e401")) {
return pad_unlicensedSNES; return pad_unlicensedSNES;
} else if (id.includes('xbox') && id.includes('360')) { } else if (id.includes("xbox") && id.includes("360")) {
return pad_xbox360; return pad_xbox360;
} else if (id.includes('054c')) { } else if (id.includes("054c")) {
return pad_dualshock; return pad_dualshock;
}
return pad_generic;
} }
/** return pad_generic;
}
/**
* repeatInputDurationJustPassed returns true if @param button has been held down long * repeatInputDurationJustPassed returns true if @param button has been held down long
* enough to fire a repeated input. A button must claim the buttonLock before * enough to fire a repeated input. A button must claim the buttonLock before
* firing a repeated input - this is to prevent multiple buttons from firing repeatedly. * firing a repeated input - this is to prevent multiple buttons from firing repeatedly.
*/ */
repeatInputDurationJustPassed(button: Button): boolean { repeatInputDurationJustPassed(button: Button): boolean {
if (!this.isButtonLocked(button)) return false; if (!this.isButtonLocked(button)) {
if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) { return false;
return true;
}
} }
if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) {
return true;
}
}
/** /**
* This method updates the interaction state to reflect that the button is pressed. * This method updates the interaction state to reflect that the button is pressed.
* *
* @param button - The button for which to set the interaction. * @param button - The button for which to set the interaction.
@ -457,15 +466,17 @@ export class InputsController {
* *
* Additionally, this method locks the button (by calling `setButtonLock`) to prevent it from being re-processed until it is released, ensuring that each press is handled distinctly. * Additionally, this method locks the button (by calling `setButtonLock`) to prevent it from being re-processed until it is released, ensuring that each press is handled distinctly.
*/ */
setLastProcessedMovementTime(button: Button, source: String = 'keyboard'): void { setLastProcessedMovementTime(button: Button, source: String = "keyboard"): void {
if (!this.interactions.hasOwnProperty(button)) return; if (!this.interactions.hasOwnProperty(button)) {
this.setButtonLock(button); return;
this.interactions[button].pressTime = this.time.now;
this.interactions[button].isPressed = true;
this.interactions[button].source = source;
} }
this.setButtonLock(button);
this.interactions[button].pressTime = this.time.now;
this.interactions[button].isPressed = true;
this.interactions[button].source = source;
}
/** /**
* Clears the last interaction for a specified button. * Clears the last interaction for a specified button.
* *
* @param button - The button for which to clear the interaction. * @param button - The button for which to clear the interaction.
@ -479,15 +490,17 @@ export class InputsController {
* *
* It releases the button lock, which prevents the button from being processed repeatedly until it's explicitly released. * It releases the button lock, which prevents the button from being processed repeatedly until it's explicitly released.
*/ */
delLastProcessedMovementTime(button: Button): void { delLastProcessedMovementTime(button: Button): void {
if (!this.interactions.hasOwnProperty(button)) return; if (!this.interactions.hasOwnProperty(button)) {
this.releaseButtonLock(button); return;
this.interactions[button].pressTime = null;
this.interactions[button].isPressed = false;
this.interactions[button].source = null;
} }
this.releaseButtonLock(button);
this.interactions[button].pressTime = null;
this.interactions[button].isPressed = false;
this.interactions[button].source = null;
}
/** /**
* Deactivates all currently pressed keys and resets their interaction states. * Deactivates all currently pressed keys and resets their interaction states.
* *
* @remarks * @remarks
@ -505,19 +518,19 @@ export class InputsController {
* *
* This method is typically called when needing to ensure that all inputs are neutralized. * This method is typically called when needing to ensure that all inputs are neutralized.
*/ */
deactivatePressedKey(): void { deactivatePressedKey(): void {
this.releaseButtonLock(this.buttonLock); this.releaseButtonLock(this.buttonLock);
this.releaseButtonLock(this.buttonLock2); this.releaseButtonLock(this.buttonLock2);
for (const b of Utils.getEnumValues(Button)) { for (const b of Utils.getEnumValues(Button)) {
if (this.interactions.hasOwnProperty(b)) { if (this.interactions.hasOwnProperty(b)) {
this.interactions[b].pressTime = null; this.interactions[b].pressTime = null;
this.interactions[b].isPressed = false; this.interactions[b].isPressed = false;
this.interactions[b].source = null; this.interactions[b].source = null;
} }
}
} }
}
/** /**
* Checks if a specific button is currently locked. * Checks if a specific button is currently locked.
* *
* @param button - The button to check for a lock status. * @param button - The button to check for a lock status.
@ -527,11 +540,11 @@ export class InputsController {
* This method is used to determine if a given button is currently prevented from being processed due to a lock. * This method is used to determine if a given button is currently prevented from being processed due to a lock.
* It checks against two separate lock variables, allowing for up to two buttons to be locked simultaneously. * It checks against two separate lock variables, allowing for up to two buttons to be locked simultaneously.
*/ */
isButtonLocked(button: Button): boolean { isButtonLocked(button: Button): boolean {
return (this.buttonLock === button || this.buttonLock2 === button); return (this.buttonLock === button || this.buttonLock2 === button);
} }
/** /**
* Sets a lock on a given button if it is not already locked. * Sets a lock on a given button if it is not already locked.
* *
* @param button - The button to lock. * @param button - The button to lock.
@ -542,15 +555,22 @@ export class InputsController {
* If not, it locks the button using the first available lock variable. * If not, it locks the button using the first available lock variable.
* This mechanism allows for up to two buttons to be locked at the same time. * This mechanism allows for up to two buttons to be locked at the same time.
*/ */
setButtonLock(button: Button): void { setButtonLock(button: Button): void {
if (this.buttonLock === button || this.buttonLock2 === button) return; if (this.buttonLock === button || this.buttonLock2 === button) {
if (this.buttonLock === button) this.buttonLock2 = button; return;
else if (this.buttonLock2 === button) this.buttonLock = button;
else if (!!this.buttonLock) this.buttonLock2 = button;
else this.buttonLock = button;
} }
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;
}
}
/** /**
* Releases a lock on a specific button, allowing it to be processed again. * Releases a lock on a specific button, allowing it to be processed again.
* *
* @param button - The button whose lock is to be released. * @param button - The button whose lock is to be released.
@ -560,8 +580,11 @@ export class InputsController {
* If either lock matches the specified button, that lock is cleared. * If either lock matches the specified button, that lock is cleared.
* This action frees the button to be processed again, ensuring it can respond to new inputs. * This action frees the button to be processed again, ensuring it can respond to new inputs.
*/ */
releaseButtonLock(button: Button): void { releaseButtonLock(button: Button): void {
if (this.buttonLock === button) this.buttonLock = null; if (this.buttonLock === button) {
else if (this.buttonLock2 === button) this.buttonLock2 = null; this.buttonLock = null;
} else if (this.buttonLock2 === button) {
this.buttonLock2 = null;
} }
}
} }

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const commandUiHandler: SimpleTranslationEntries = { export const commandUiHandler: SimpleTranslationEntries = {
"fight": "Kampf", "fight": "Kampf",
"ball": "Ball", "ball": "Ball",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"run": "Fliehen", "run": "Fliehen",
"actionMessage": "Was soll\n{{pokemonName}} tun?", "actionMessage": "Was soll\n{{pokemonName}} tun?",
} as const; } as const;

View File

@ -23,29 +23,29 @@ import { berry } from "./berry";
import { voucher } from "./voucher"; import { voucher } from "./voucher";
export const deConfig = { export const deConfig = {
ability: ability, ability: ability,
abilityTriggers: abilityTriggers, abilityTriggers: abilityTriggers,
battle: battle, battle: battle,
commandUiHandler: commandUiHandler, commandUiHandler: commandUiHandler,
egg: egg, egg: egg,
fightUiHandler: fightUiHandler, fightUiHandler: fightUiHandler,
growth: growth, growth: growth,
menu: menu, menu: menu,
menuUiHandler: menuUiHandler, menuUiHandler: menuUiHandler,
modifierType: modifierType, modifierType: modifierType,
move: move, move: move,
nature: nature, nature: nature,
pokeball: pokeball, pokeball: pokeball,
pokemon: pokemon, pokemon: pokemon,
pokemonInfo: pokemonInfo, pokemonInfo: pokemonInfo,
splashMessages: splashMessages, splashMessages: splashMessages,
starterSelectUiHandler: starterSelectUiHandler, starterSelectUiHandler: starterSelectUiHandler,
titles: titles, titles: titles,
trainerClasses: trainerClasses, trainerClasses: trainerClasses,
trainerNames: trainerNames, trainerNames: trainerNames,
tutorial: tutorial, tutorial: tutorial,
weather: weather, weather: weather,
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "AP", "pp": "AP",
"power": "Stärke", "power": "Stärke",
"accuracy": "Genauigkeit", "accuracy": "Genauigkeit",
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const growth: SimpleTranslationEntries = { export const growth: SimpleTranslationEntries = {
"Erratic": "Unregelmäßig", "Erratic": "Unregelmäßig",
"Fast": "Schnell", "Fast": "Schnell",
"Medium_Fast": "Schneller", "Medium_Fast": "Schneller",
"Medium_Slow": "Langsamer", "Medium_Slow": "Langsamer",
"Slow": "Langsam", "Slow": "Langsam",
"Fluctuating": "Schwankend" "Fluctuating": "Schwankend"
} as const; } as const;

View File

@ -1,23 +1,23 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Spieleinstellungen', "GAME_SETTINGS": "Spieleinstellungen",
"ACHIEVEMENTS": "Erfolge", "ACHIEVEMENTS": "Erfolge",
"STATS": "Statistiken", "STATS": "Statistiken",
"VOUCHERS": "Gutscheine", "VOUCHERS": "Gutscheine",
"EGG_LIST": "Eierliste", "EGG_LIST": "Eierliste",
"EGG_GACHA": "Eier-Gacha", "EGG_GACHA": "Eier-Gacha",
"MANAGE_DATA": "Daten verwalten", "MANAGE_DATA": "Daten verwalten",
"COMMUNITY": "Community", "COMMUNITY": "Community",
"SAVE_AND_QUIT": "Speichern und Beenden", "SAVE_AND_QUIT": "Speichern und Beenden",
"LOG_OUT": "Abmelden", "LOG_OUT": "Abmelden",
"slot": "Slot {{slotNumber}}", "slot": "Slot {{slotNumber}}",
"importSession": "Sitzung importieren", "importSession": "Sitzung importieren",
"importSlotSelect": "Wähle einen Slot zum Importieren.", "importSlotSelect": "Wähle einen Slot zum Importieren.",
"exportSession": "Sitzung exportieren", "exportSession": "Sitzung exportieren",
"exportSlotSelect": "Wähle einen Slot zum Exportieren.", "exportSlotSelect": "Wähle einen Slot zum Exportieren.",
"importData": "Daten importieren", "importData": "Daten importieren",
"exportData": "Daten exportieren", "exportData": "Daten exportieren",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?" "losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?"
} as const; } as const;

View File

@ -6,46 +6,46 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const menu: SimpleTranslationEntries = { export const menu: SimpleTranslationEntries = {
"cancel": "Abbrechen", "cancel": "Abbrechen",
"continue": "Fortfahren", "continue": "Fortfahren",
"dailyRun": "Täglicher Run (Beta)", "dailyRun": "Täglicher Run (Beta)",
"loadGame": "Spiel laden", "loadGame": "Spiel laden",
"newGame": "Neues Spiel", "newGame": "Neues Spiel",
"selectGameMode": "Wähle einen Spielmodus", "selectGameMode": "Wähle einen Spielmodus",
"logInOrCreateAccount": "Melde dich an oder erstelle einen Account zum starten. Keine Email nötig!", "logInOrCreateAccount": "Melde dich an oder erstelle einen Account zum starten. Keine Email nötig!",
"username": "Benutzername", "username": "Benutzername",
"password": "Passwort", "password": "Passwort",
"login": "Anmelden", "login": "Anmelden",
"register": "Registrieren", "register": "Registrieren",
"emptyUsername": "Benutzername darf nicht leer sein", "emptyUsername": "Benutzername darf nicht leer sein",
"invalidLoginUsername": "Der eingegebene Benutzername ist ungültig", "invalidLoginUsername": "Der eingegebene Benutzername ist ungültig",
"invalidRegisterUsername": "Benutzername darf nur Buchstaben, Zahlen oder Unterstriche enthalten", "invalidRegisterUsername": "Benutzername darf nur Buchstaben, Zahlen oder Unterstriche enthalten",
"invalidLoginPassword": "Das eingegebene Passwort ist ungültig", "invalidLoginPassword": "Das eingegebene Passwort ist ungültig",
"invalidRegisterPassword": "Passwort muss 6 Zeichen oder länger sein", "invalidRegisterPassword": "Passwort muss 6 Zeichen oder länger sein",
"usernameAlreadyUsed": "Der eingegebene Benutzername wird bereits verwendet", "usernameAlreadyUsed": "Der eingegebene Benutzername wird bereits verwendet",
"accountNonExistent": "Der eingegebene Benutzer existiert nicht", "accountNonExistent": "Der eingegebene Benutzer existiert nicht",
"unmatchingPassword": "Das eingegebene Passwort stimmt nicht überein", "unmatchingPassword": "Das eingegebene Passwort stimmt nicht überein",
"passwordNotMatchingConfirmPassword": "Passwort muss mit Bestätigungspasswort übereinstimmen", "passwordNotMatchingConfirmPassword": "Passwort muss mit Bestätigungspasswort übereinstimmen",
"confirmPassword": "Bestätige Passwort", "confirmPassword": "Bestätige Passwort",
"registrationAgeWarning": "Mit der Registrierung bestätigen Sie, dass Sie 13 Jahre oder älter sind.", "registrationAgeWarning": "Mit der Registrierung bestätigen Sie, dass Sie 13 Jahre oder älter sind.",
"backToLogin": "Zurück zur Anmeldung", "backToLogin": "Zurück zur Anmeldung",
"failedToLoadSaveData": "Speicherdaten konnten nicht geladen werden. Bitte laden Sie die Seite neu.\nWenn dies weiterhin der Fall ist, wenden Sie sich bitte an den Administrator.", "failedToLoadSaveData": "Speicherdaten konnten nicht geladen werden. Bitte laden Sie die Seite neu.\nWenn dies weiterhin der Fall ist, wenden Sie sich bitte an den Administrator.",
"sessionSuccess": "Sitzung erfolgreich geladen.", "sessionSuccess": "Sitzung erfolgreich geladen.",
"failedToLoadSession": "Ihre Sitzungsdaten konnten nicht geladen werden.\nSie könnten beschädigt sein.", "failedToLoadSession": "Ihre Sitzungsdaten konnten nicht geladen werden.\nSie könnten beschädigt sein.",
"boyOrGirl": "Bist du ein Junge oder ein Mädchen?", "boyOrGirl": "Bist du ein Junge oder ein Mädchen?",
"boy": "Junge", "boy": "Junge",
"girl": "Mädchen", "girl": "Mädchen",
"evolving": "Nanu?\n{{pokemonName}} entwickelt sich!", "evolving": "Nanu?\n{{pokemonName}} entwickelt sich!",
"stoppedEvolving": "Hm? {{pokemonName}} hat die Entwicklung \nabgebrochen.", // "Hm? Entwicklung wurde abgebrochen!" without naming the pokemon seems to be the original. "stoppedEvolving": "Hm? {{pokemonName}} hat die Entwicklung \nabgebrochen.", // "Hm? Entwicklung wurde abgebrochen!" without naming the pokemon seems to be the original.
"pauseEvolutionsQuestion": "Die Entwicklung von {{pokemonName}} vorübergehend pausieren?\nEntwicklungen können im Gruppenmenü wieder aktiviert werden.", "pauseEvolutionsQuestion": "Die Entwicklung von {{pokemonName}} vorübergehend pausieren?\nEntwicklungen können im Gruppenmenü wieder aktiviert werden.",
"evolutionsPaused": "Entwicklung von {{pokemonName}} pausiert.", "evolutionsPaused": "Entwicklung von {{pokemonName}} pausiert.",
"evolutionDone": "Glückwunsch!\nDein {{pokemonName}} entwickelte sich zu {{evolvedPokemonName}}!", "evolutionDone": "Glückwunsch!\nDein {{pokemonName}} entwickelte sich zu {{evolvedPokemonName}}!",
"dailyRankings": "Tägliche Rangliste", "dailyRankings": "Tägliche Rangliste",
"weeklyRankings": "Wöchentliche Rangliste", "weeklyRankings": "Wöchentliche Rangliste",
"noRankings": "Keine Rangliste", "noRankings": "Keine Rangliste",
"loading": "Lade…", "loading": "Lade…",
"playersOnline": "Spieler Online", "playersOnline": "Spieler Online",
"empty":"Leer", "empty":"Leer",
"yes":"Ja", "yes":"Ja",
"no":"Nein", "no":"Nein",
} as const; } as const;

View File

@ -226,13 +226,13 @@ export const modifierType: ModifierTypeTranslationEntries = {
"ENEMY_DAMAGE_REDUCTION": { name: "Schutzmarke", description: "Verringert den erhaltenen Schaden um 2,5%" }, "ENEMY_DAMAGE_REDUCTION": { name: "Schutzmarke", description: "Verringert den erhaltenen Schaden um 2,5%" },
"ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" }, "ENEMY_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" }, "ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" }, "ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" },
"ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" }, "ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" },
"ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" }, "ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" },
"ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" }, "ENEMY_ATTACK_BURN_CHANCE": { "name": "Brandmarke" },
"ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 10%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" }, "ENEMY_STATUS_EFFECT_HEAL_CHANCE": { "name": "Vollheilungsmarke", "description": "Fügt eine 10%ige Chance hinzu, jede Runde einen Statuszustand zu heilen" },
"ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" }, "ENEMY_ENDURE_CHANCE": { "name": "Ausdauer-Marke" },
"ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" }, "ENEMY_FUSED_CHANCE": { "name": "Fusionsmarke", "description": "Fügt eine 1%ige Chance hinzu, dass ein wildes Pokémon eine Fusion ist" },
}, },
TempBattleStatBoosterItem: { TempBattleStatBoosterItem: {

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const pokeball: SimpleTranslationEntries = { export const pokeball: SimpleTranslationEntries = {
"pokeBall": "Pokéball", "pokeBall": "Pokéball",
"greatBall": "Superball", "greatBall": "Superball",
"ultraBall": "Hyperball", "ultraBall": "Hyperball",
"rogueBall": "Rogueball", "rogueBall": "Rogueball",
"masterBall": "Meisterball", "masterBall": "Meisterball",
"luxuryBall": "Luxusball", "luxuryBall": "Luxusball",
} as const; } as const;

View File

@ -1,41 +1,41 @@
import { PokemonInfoTranslationEntries } from "#app/plugins/i18n"; import { PokemonInfoTranslationEntries } from "#app/plugins/i18n";
export const pokemonInfo: PokemonInfoTranslationEntries = { export const pokemonInfo: PokemonInfoTranslationEntries = {
Stat: { Stat: {
"HP": "Max. KP", "HP": "Max. KP",
"HPshortened": "MaxKP", "HPshortened": "MaxKP",
"ATK": "Angriff", "ATK": "Angriff",
"ATKshortened": "Ang", "ATKshortened": "Ang",
"DEF": "Verteidigung", "DEF": "Verteidigung",
"DEFshortened": "Vert", "DEFshortened": "Vert",
"SPATK": "Sp. Ang", "SPATK": "Sp. Ang",
"SPATKshortened": "SpAng", "SPATKshortened": "SpAng",
"SPDEF": "Sp. Vert", "SPDEF": "Sp. Vert",
"SPDEFshortened": "SpVert", "SPDEFshortened": "SpVert",
"SPD": "Initiative", "SPD": "Initiative",
"SPDshortened": "Init", "SPDshortened": "Init",
}, },
Type: { Type: {
"UNKNOWN": "Unbekannt", "UNKNOWN": "Unbekannt",
"NORMAL": "Normal", "NORMAL": "Normal",
"FIGHTING": "Kampf", "FIGHTING": "Kampf",
"FLYING": "Flug", "FLYING": "Flug",
"POISON": "Gift", "POISON": "Gift",
"GROUND": "Boden", "GROUND": "Boden",
"ROCK": "Gestein", "ROCK": "Gestein",
"BUG": "Käfer", "BUG": "Käfer",
"GHOST": "Geist", "GHOST": "Geist",
"STEEL": "Stahl", "STEEL": "Stahl",
"FIRE": "Feuer", "FIRE": "Feuer",
"WATER": "Wasser", "WATER": "Wasser",
"GRASS": "Pflanze", "GRASS": "Pflanze",
"ELECTRIC": "Elektro", "ELECTRIC": "Elektro",
"PSYCHIC": "Psycho", "PSYCHIC": "Psycho",
"ICE": "Eis", "ICE": "Eis",
"DRAGON": "Drache", "DRAGON": "Drache",
"DARK": "Unlicht", "DARK": "Unlicht",
"FAIRY": "Fee", "FAIRY": "Fee",
"STELLAR": "Stellar", "STELLAR": "Stellar",
}, },
} as const; } as const;

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,37 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const splashMessages: SimpleTranslationEntries = { export const splashMessages: SimpleTranslationEntries = {
"battlesWon": "Kämpfe gewonnen!", "battlesWon": "Kämpfe gewonnen!",
"joinTheDiscord": "Tritt dem Discord bei!", "joinTheDiscord": "Tritt dem Discord bei!",
"infiniteLevels": "Unendliche Level!", "infiniteLevels": "Unendliche Level!",
"everythingStacks": "Alles stapelt sich!", "everythingStacks": "Alles stapelt sich!",
"optionalSaveScumming": "Optionales Save Scumming!", "optionalSaveScumming": "Optionales Save Scumming!",
"biomes": "35 Biome!", "biomes": "35 Biome!",
"openSource": "Open Source!", "openSource": "Open Source!",
"playWithSpeed": "Spiele mit fünffacher Geschwindigkeit!", "playWithSpeed": "Spiele mit fünffacher Geschwindigkeit!",
"liveBugTesting": "Live-Bug-Tests!", "liveBugTesting": "Live-Bug-Tests!",
"heavyInfluence": "Starker RoR2-Einfluss!", "heavyInfluence": "Starker RoR2-Einfluss!",
"pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!", "pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!",
"nowWithMoreSalt": "Jetzt mit 33% mehr Salz!", "nowWithMoreSalt": "Jetzt mit 33% mehr Salz!",
"infiniteFusionAtHome": "Wir haben Infinite Fusionen zu Hause!", "infiniteFusionAtHome": "Wir haben Infinite Fusionen zu Hause!",
"brokenEggMoves": "Übermächtige Ei-Attacken!", "brokenEggMoves": "Übermächtige Ei-Attacken!",
"magnificent": "Herrlich!", "magnificent": "Herrlich!",
"mubstitute": "Melegator!", "mubstitute": "Melegator!",
"thatsCrazy": "Das ist verrückt!", "thatsCrazy": "Das ist verrückt!",
"oranceJuice": "Orangensaft!", "oranceJuice": "Orangensaft!",
"questionableBalancing": "Fragwürdiges Balancing!", "questionableBalancing": "Fragwürdiges Balancing!",
"coolShaders": "Coole Shader!", "coolShaders": "Coole Shader!",
"aiFree": "Ohne KI!", "aiFree": "Ohne KI!",
"suddenDifficultySpikes": "Plötzliche Schwierigkeitsspitzen!", "suddenDifficultySpikes": "Plötzliche Schwierigkeitsspitzen!",
"basedOnAnUnfinishedFlashGame": "Basierend auf einem unfertigen Flash-Spiel!", "basedOnAnUnfinishedFlashGame": "Basierend auf einem unfertigen Flash-Spiel!",
"moreAddictiveThanIntended": "Süchtig machender als beabsichtigt!", "moreAddictiveThanIntended": "Süchtig machender als beabsichtigt!",
"mostlyConsistentSeeds": "Meistens konsistente Seeds!", "mostlyConsistentSeeds": "Meistens konsistente Seeds!",
"achievementPointsDontDoAnything": "Erungenschaftspunkte tun nichts!", "achievementPointsDontDoAnything": "Erungenschaftspunkte tun nichts!",
"youDoNotStartAtLevel": "Du startest nicht auf Level 2000!", "youDoNotStartAtLevel": "Du startest nicht auf Level 2000!",
"dontTalkAboutTheManaphyEggIncident": "Wir reden nicht über den Manaphy-Ei-Vorfall!", "dontTalkAboutTheManaphyEggIncident": "Wir reden nicht über den Manaphy-Ei-Vorfall!",
"alsoTryPokengine": "Versuche auch Pokéngine!", "alsoTryPokengine": "Versuche auch Pokéngine!",
"alsoTryEmeraldRogue": "Versuche auch Emerald Rogue!", "alsoTryEmeraldRogue": "Versuche auch Emerald Rogue!",
"alsoTryRadicalRed": "Versuche auch Radical Red!", "alsoTryRadicalRed": "Versuche auch Radical Red!",
"eeveeExpo": "Evoli-Expo!", "eeveeExpo": "Evoli-Expo!",
"ynoproject": "YNO-Projekt!", "ynoproject": "YNO-Projekt!",
} as const; } as const;

View File

@ -6,39 +6,39 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const starterSelectUiHandler: SimpleTranslationEntries = { export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam": "Mit diesen Pokémon losziehen?", "confirmStartTeam": "Mit diesen Pokémon losziehen?",
"gen1": "I", "gen1": "I",
"gen2": "II", "gen2": "II",
"gen3": "III", "gen3": "III",
"gen4": "IV", "gen4": "IV",
"gen5": "V", "gen5": "V",
"gen6": "VI", "gen6": "VI",
"gen7": "VII", "gen7": "VII",
"gen8": "VIII", "gen8": "VIII",
"gen9": "IX", "gen9": "IX",
"growthRate": "Wachstum:", "growthRate": "Wachstum:",
"ability": "Fähgkeit:", "ability": "Fähgkeit:",
"passive": "Passiv:", "passive": "Passiv:",
"nature": "Wesen:", "nature": "Wesen:",
"eggMoves": "Ei-Attacken", "eggMoves": "Ei-Attacken",
"start": "Start", "start": "Start",
"addToParty": "Zum Team hinzufügen", "addToParty": "Zum Team hinzufügen",
"toggleIVs": "DVs anzeigen/verbergen", "toggleIVs": "DVs anzeigen/verbergen",
"manageMoves": "Attacken ändern", "manageMoves": "Attacken ändern",
"useCandies": "Bonbons verwenden", "useCandies": "Bonbons verwenden",
"selectMoveSwapOut": "Wähle die zu ersetzende Attacke.", "selectMoveSwapOut": "Wähle die zu ersetzende Attacke.",
"selectMoveSwapWith": "Wähle die gewünschte Attacke.", "selectMoveSwapWith": "Wähle die gewünschte Attacke.",
"unlockPassive": "Passiv-Skill freischalten", "unlockPassive": "Passiv-Skill freischalten",
"reduceCost": "Preis reduzieren", "reduceCost": "Preis reduzieren",
"cycleShiny": "R: Schillernd Ja/Nein", "cycleShiny": "R: Schillernd Ja/Nein",
"cycleForm": "F: Form ändern", "cycleForm": "F: Form ändern",
"cycleGender": "G: Geschlecht ändern", "cycleGender": "G: Geschlecht ändern",
"cycleAbility": "E: Fähigkeit ändern", "cycleAbility": "E: Fähigkeit ändern",
"cycleNature": "N: Wesen Ändern", "cycleNature": "N: Wesen Ändern",
"cycleVariant": "V: Seltenheit ändern", "cycleVariant": "V: Seltenheit ändern",
"enablePassive": "Passiv-Skill aktivieren", "enablePassive": "Passiv-Skill aktivieren",
"disablePassive": "Passiv-Skill deaktivieren", "disablePassive": "Passiv-Skill deaktivieren",
"locked": "Gesperrt", "locked": "Gesperrt",
"disabled": "Deaktiviert", "disabled": "Deaktiviert",
"uncaught": "Ungefangen" "uncaught": "Ungefangen"
} };

View File

@ -2,243 +2,243 @@ import {SimpleTranslationEntries} from "#app/plugins/i18n";
// Titles of special trainers like gym leaders, elite four, and the champion // Titles of special trainers like gym leaders, elite four, and the champion
export const titles: SimpleTranslationEntries = { export const titles: SimpleTranslationEntries = {
"elite_four": "Top Vier", "elite_four": "Top Vier",
"gym_leader": "Arenaleiter", "gym_leader": "Arenaleiter",
"gym_leader_female": "Arenaleiterin", "gym_leader_female": "Arenaleiterin",
"champion": "Champion", "champion": "Champion",
"rival": "Rivale", "rival": "Rivale",
"professor": "Professor", "professor": "Professor",
"frontier_brain": "Kampfkoryphäen", "frontier_brain": "Kampfkoryphäen",
// Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc. // Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc.
} as const; } as const;
// Titles of trainers like "Youngster" or "Lass" // Titles of trainers like "Youngster" or "Lass"
export const trainerClasses: SimpleTranslationEntries = { export const trainerClasses: SimpleTranslationEntries = {
"ace_trainer": "Ass-Trainer", "ace_trainer": "Ass-Trainer",
"ace_trainer_female": "Ass-Trainerin", "ace_trainer_female": "Ass-Trainerin",
"ace_duo": "Ass-Duo", "ace_duo": "Ass-Duo",
"artist": "Künstler", "artist": "Künstler",
"artist_female": "Künstlerin", "artist_female": "Künstlerin",
"backers": "Anhänger", "backers": "Anhänger",
"backpacker": "Backpacker", "backpacker": "Backpacker",
"backpacker_female": "Backpackerin", "backpacker_female": "Backpackerin",
"backpackers": "Backpacker", "backpackers": "Backpacker",
"baker": "Bäckerin", "baker": "Bäckerin",
"battle_girl": "Kämpferin", "battle_girl": "Kämpferin",
"beauty": "Schönheit", "beauty": "Schönheit",
"beginners": "Anfänger", "beginners": "Anfänger",
"biker": "Rowdy", "biker": "Rowdy",
"black_belt": "Schwarzgurt", "black_belt": "Schwarzgurt",
"breeder": "Pokémon Züchter", "breeder": "Pokémon Züchter",
"breeder_female": "Pokémon Züchterin", "breeder_female": "Pokémon Züchterin",
"breeders": "Pokémon Züchter", "breeders": "Pokémon Züchter",
"clerk": "Angestellter", "clerk": "Angestellter",
"clerk_female": "Angestellte", "clerk_female": "Angestellte",
"colleagues": "Geschäftspartner", "colleagues": "Geschäftspartner",
"crush_kin": "Mühlensippe", "crush_kin": "Mühlensippe",
"cyclist": "Biker", "cyclist": "Biker",
"cyclist_female": "Bikerin", "cyclist_female": "Bikerin",
"cyclists": "Biker", "cyclists": "Biker",
"dancer": "Tänzer", "dancer": "Tänzer",
"dancer_female": "Tänzerin", "dancer_female": "Tänzerin",
"depot_agent": "Bahnangestellter", "depot_agent": "Bahnangestellter",
"doctor": "Arzt", "doctor": "Arzt",
"doctor_female": "Ärztin", "doctor_female": "Ärztin",
"fisherman": "Angler", "fisherman": "Angler",
"fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian "fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian
"gentleman": "Gentleman", "gentleman": "Gentleman",
"guitarist": "Gitarrist", "guitarist": "Gitarrist",
"guitarist_female": "Gitarristin", "guitarist_female": "Gitarristin",
"harlequin": "Kasper", "harlequin": "Kasper",
"hiker": "Wanderer", "hiker": "Wanderer",
"hooligans": "Rabauken", "hooligans": "Rabauken",
"hoopster": "Basketballer", "hoopster": "Basketballer",
"infielder": "Baseballer", "infielder": "Baseballer",
"janitor": "Hausmeister", "janitor": "Hausmeister",
"lady": "Lady", "lady": "Lady",
"lass": "Göre", "lass": "Göre",
"linebacker": "Footballer", "linebacker": "Footballer",
"maid": "Zofe", "maid": "Zofe",
"madame": "Madam", "madame": "Madam",
"medical_team": "Mediziner", "medical_team": "Mediziner",
"musician": "Musiker", "musician": "Musiker",
"hex_maniac": "Hexe", "hex_maniac": "Hexe",
"nurse": "Pflegerin", "nurse": "Pflegerin",
"nursery_aide": "Erzieherin", "nursery_aide": "Erzieherin",
"officer": "Polizist", "officer": "Polizist",
"parasol_lady": "Schirmdame", "parasol_lady": "Schirmdame",
"pilot": "Pilot", "pilot": "Pilot",
"pokéfan": "Pokéfan", "pokéfan": "Pokéfan",
"pokéfan_female": "Pokéfan", "pokéfan_female": "Pokéfan",
"pokéfan_family": "Pokéfan-Pärchen", "pokéfan_family": "Pokéfan-Pärchen",
"preschooler": "Vorschüler", "preschooler": "Vorschüler",
"preschooler_female": "Vorschülerin", "preschooler_female": "Vorschülerin",
"preschoolers": "Vorschüler", "preschoolers": "Vorschüler",
"psychic": "Seher", "psychic": "Seher",
"psychic_female": "Seherin", "psychic_female": "Seherin",
"psychics": "Seher", "psychics": "Seher",
"pokémon_ranger": "Pokémon-Ranger", "pokémon_ranger": "Pokémon-Ranger",
"pokémon_ranger_female": "Pokémon-Ranger", "pokémon_ranger_female": "Pokémon-Ranger",
"pokémon_rangers": "Pokémon-Ranger", "pokémon_rangers": "Pokémon-Ranger",
"ranger": "Ranger", "ranger": "Ranger",
"restaurant_staff": "Restaurant Angestellte", "restaurant_staff": "Restaurant Angestellte",
"rich": "Rich", "rich": "Rich",
"rich_female": "Rich", "rich_female": "Rich",
"rich_boy": "Schnösel", "rich_boy": "Schnösel",
"rich_couple": "Reiches Paar", "rich_couple": "Reiches Paar",
"rich_kid": "Rich Kid", "rich_kid": "Rich Kid",
"rich_kid_female": "Rich Kid", "rich_kid_female": "Rich Kid",
"rich_kids": "Schnösel", "rich_kids": "Schnösel",
"roughneck": "Raufbold", "roughneck": "Raufbold",
"scientist": "Forscher", "scientist": "Forscher",
"scientist_female": "Forscherin", "scientist_female": "Forscherin",
"scientists": "Forscher", "scientists": "Forscher",
"smasher": "Tennis-Ass", "smasher": "Tennis-Ass",
"snow_worker": "Schneearbeiter", // There is a trainer type for this but no actual trainer class? They seem to be just workers but dressed differently "snow_worker": "Schneearbeiter", // There is a trainer type for this but no actual trainer class? They seem to be just workers but dressed differently
"snow_worker_female": "Schneearbeiterin", "snow_worker_female": "Schneearbeiterin",
"striker": "Fußballer", "striker": "Fußballer",
"school_kid": "Schulkind", "school_kid": "Schulkind",
"school_kid_female": "Schulkind", // Same in german but different in italian "school_kid_female": "Schulkind", // Same in german but different in italian
"school_kids": "Schüler", "school_kids": "Schüler",
"swimmer": "Schwimmer", "swimmer": "Schwimmer",
"swimmer_female": "Schwimmerin", "swimmer_female": "Schwimmerin",
"swimmers": "Schwimmerpaar", "swimmers": "Schwimmerpaar",
"twins": "Zwillinge", "twins": "Zwillinge",
"veteran": "Veteran", "veteran": "Veteran",
"veteran_female": "Veteran", // same in german, different in other languages "veteran_female": "Veteran", // same in german, different in other languages
"veteran_duo": "Veteranen", "veteran_duo": "Veteranen",
"waiter": "Servierer", "waiter": "Servierer",
"waitress": "Serviererin", "waitress": "Serviererin",
"worker": "Arbeiter", "worker": "Arbeiter",
"worker_female": "Arbeiterin", "worker_female": "Arbeiterin",
"workers": "Arbeiter", "workers": "Arbeiter",
"youngster": "Knirps" "youngster": "Knirps"
} as const; } as const;
// Names of special trainers like gym leaders, elite four, and the champion // Names of special trainers like gym leaders, elite four, and the champion
export const trainerNames: SimpleTranslationEntries = { export const trainerNames: SimpleTranslationEntries = {
"brock": "Rocko", "brock": "Rocko",
"misty": "Misty", "misty": "Misty",
"lt_surge": "Major Bob", "lt_surge": "Major Bob",
"erika": "Erika", "erika": "Erika",
"janine": "Janina", "janine": "Janina",
"sabrina": "Sabrina", "sabrina": "Sabrina",
"blaine": "Pyro", "blaine": "Pyro",
"giovanni": "Giovanni", "giovanni": "Giovanni",
"falkner": "Falk", "falkner": "Falk",
"bugsy": "Kai", "bugsy": "Kai",
"whitney": "Bianka", "whitney": "Bianka",
"morty": "Jens", "morty": "Jens",
"chuck": "Hartwig", "chuck": "Hartwig",
"jasmine": "Jasmin", "jasmine": "Jasmin",
"pryce": "Norbert", "pryce": "Norbert",
"clair": "Sandra", "clair": "Sandra",
"roxanne": "Felizia", "roxanne": "Felizia",
"brawly": "Kamillo", "brawly": "Kamillo",
"wattson": "Walter", "wattson": "Walter",
"flannery": "Flavia", "flannery": "Flavia",
"norman": "Norman", "norman": "Norman",
"winona": "Wibke", "winona": "Wibke",
"tate": "Ben", "tate": "Ben",
"liza": "Svenja", "liza": "Svenja",
"juan": "Juan", "juan": "Juan",
"roark": "Veit", "roark": "Veit",
"gardenia": "Silvana", "gardenia": "Silvana",
"maylene": "Hilda", "maylene": "Hilda",
"crasher_wake": "Wellenbrecher Marinus", "crasher_wake": "Wellenbrecher Marinus",
"fantina": "Lamina", "fantina": "Lamina",
"byron": "Adam", "byron": "Adam",
"candice": "Frida", "candice": "Frida",
"volkner": "Volkner", "volkner": "Volkner",
"cilan": "Benny", "cilan": "Benny",
"chili": "Maik", "chili": "Maik",
"cress": "Colin", "cress": "Colin",
"cheren": "Cheren", "cheren": "Cheren",
"lenora": "Aloe", "lenora": "Aloe",
"roxie": "Mica", "roxie": "Mica",
"burgh": "Artie", "burgh": "Artie",
"elesa": "Kamilla", "elesa": "Kamilla",
"clay": "Turner", "clay": "Turner",
"skyla": "Géraldine", "skyla": "Géraldine",
"brycen": "Sandro", "brycen": "Sandro",
"drayden": "Lysander", "drayden": "Lysander",
"marlon": "Benson", "marlon": "Benson",
"viola": "Viola", "viola": "Viola",
"grant": "Lino", "grant": "Lino",
"korrina": "Connie", "korrina": "Connie",
"ramos": "Amaro", "ramos": "Amaro",
"clemont": "Citro", "clemont": "Citro",
"valerie": "Valerie", "valerie": "Valerie",
"olympia": "Astrid", "olympia": "Astrid",
"wulfric": "Galantho", "wulfric": "Galantho",
"milo": "Yarro", "milo": "Yarro",
"nessa": "Kate", "nessa": "Kate",
"kabu": "Kabu", "kabu": "Kabu",
"bea": "Saida", "bea": "Saida",
"allister": "Nio", "allister": "Nio",
"opal": "Papella", "opal": "Papella",
"bede": "Betys", "bede": "Betys",
"gordie": "Mac", "gordie": "Mac",
"melony": "Mel", "melony": "Mel",
"piers": "Nezz", "piers": "Nezz",
"marnie": "Mary", "marnie": "Mary",
"raihan": "Roy", "raihan": "Roy",
"katy": "Ronah", "katy": "Ronah",
"brassius": "Colzo", "brassius": "Colzo",
"iono": "Enigmara", "iono": "Enigmara",
"kofu": "Kombu", "kofu": "Kombu",
"larry": "Aoki", "larry": "Aoki",
"ryme": "Etta", "ryme": "Etta",
"tulip": "Tulia", "tulip": "Tulia",
"grusha": "Grusha", "grusha": "Grusha",
"lorelei": "Lorelei", "lorelei": "Lorelei",
"bruno": "Bruno", "bruno": "Bruno",
"agatha": "Agathe", "agatha": "Agathe",
"lance": "Siegfried", "lance": "Siegfried",
"will": "Willi", "will": "Willi",
"koga": "Koga", "koga": "Koga",
"karen": "Melanie", "karen": "Melanie",
"sidney": "Ulrich", "sidney": "Ulrich",
"phoebe": "Antonia", "phoebe": "Antonia",
"glacia": "Frosina", "glacia": "Frosina",
"drake": "Dragan", "drake": "Dragan",
"aaron": "Herbaro", "aaron": "Herbaro",
"bertha": "Teresa", "bertha": "Teresa",
"flint": "Ignaz", "flint": "Ignaz",
"lucian": "Lucian", "lucian": "Lucian",
"shauntal": "Anissa", "shauntal": "Anissa",
"marshal": "Eugen", "marshal": "Eugen",
"grimsley": "Astor", "grimsley": "Astor",
"caitlin": "Kattlea", "caitlin": "Kattlea",
"malva": "Pachira", "malva": "Pachira",
"siebold": "Narcisse", "siebold": "Narcisse",
"wikstrom": "Thymelot", "wikstrom": "Thymelot",
"drasna": "Dracena", "drasna": "Dracena",
"hala": "Hala", "hala": "Hala",
"molayne": "Marlon", "molayne": "Marlon",
"olivia": "Mayla", "olivia": "Mayla",
"acerola": "Lola", "acerola": "Lola",
"kahili": "Kahili", "kahili": "Kahili",
"rika": "Cay", "rika": "Cay",
"poppy": "Poppy", "poppy": "Poppy",
"hassel": "Sinius", "hassel": "Sinius",
"crispin": "Matt", "crispin": "Matt",
"amarys": "Erin", "amarys": "Erin",
"lacey": "Tara", "lacey": "Tara",
"drayton": "Levy", "drayton": "Levy",
"blue": "Blau", "blue": "Blau",
"red": "Rot", "red": "Rot",
"steven": "Troy", "steven": "Troy",
"wallace": "Wassili", "wallace": "Wassili",
"cynthia": "Cynthia", "cynthia": "Cynthia",
"alder": "Lauro", "alder": "Lauro",
"iris": "Lilia", "iris": "Lilia",
"diantha": "Diantha", "diantha": "Diantha",
"hau": "Tali", "hau": "Tali",
"geeta": "Sagaria", "geeta": "Sagaria",
"nemona": "Nemila", "nemona": "Nemila",
"kieran": "Jo", "kieran": "Jo",
"leon": "Delion", "leon": "Delion",
"rival": "Finn", "rival": "Finn",
"rival_female": "Ivy", "rival_female": "Ivy",
} as const; } as const;

View File

@ -1,34 +1,34 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = { export const tutorial: SimpleTranslationEntries = {
"intro": `Willkommen bei PokéRogue! Dies ist ein kampforientiertes Pokémon-Fangame mit Roguelite-Elementen. "intro": `Willkommen bei PokéRogue! Dies ist ein kampforientiertes Pokémon-Fangame mit Roguelite-Elementen.
$Dieses Spiel ist nicht monetarisiert. $Dieses Spiel ist nicht monetarisiert.
$Wir erheben keinen Eigentumsanspruch an Pokémon oder\nverwendeten, urheberrechtlich geschützten Inhalten. $Wir erheben keinen Eigentumsanspruch an Pokémon oder\nverwendeten, urheberrechtlich geschützten Inhalten.
$Das Spiel befindet sich noch in der Entwicklung, ist aber voll spielbar. $Das Spiel befindet sich noch in der Entwicklung, ist aber voll spielbar.
$Für Fehlerberichte nutze bitte den PokéRogue Discord-Server. $Für Fehlerberichte nutze bitte den PokéRogue Discord-Server.
$Sollte das Spiel langsam laufen, überprüfe, ob in deinem Browser "Hardwarebeschleunigung" aktiviert ist.`, $Sollte das Spiel langsam laufen, überprüfe, ob in deinem Browser "Hardwarebeschleunigung" aktiviert ist.`,
"accessMenu": `Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.`, "accessMenu": "Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.",
"menu": `In diesem Menü hast du Zugriff auf die Einstellungen. "menu": `In diesem Menü hast du Zugriff auf die Einstellungen.
$Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern. $Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern.
$Das Menü verbirgt noch andere Funktionen - probier' sie gerne aus!`, $Das Menü verbirgt noch andere Funktionen - probier' sie gerne aus!`,
"starterSelect": `Hier kannst du deine Starter-Pokémon auswählen.\nSie begleiten dich am Anfang deines Abenteuers. "starterSelect": `Hier kannst du deine Starter-Pokémon auswählen.\nSie begleiten dich am Anfang deines Abenteuers.
$Jeder Starter hat einen Preis. Dein Team kann bis zu sechs\nMitglieder haben, solange der Gesamtpreis max. 10 beträgt. $Jeder Starter hat einen Preis. Dein Team kann bis zu sechs\nMitglieder haben, solange der Gesamtpreis max. 10 beträgt.
$Du kannst Geschlecht, Fähigkeit und Form beliebig auswählen,\nsobald du sie mindestens einmal gefangen hast. $Du kannst Geschlecht, Fähigkeit und Form beliebig auswählen,\nsobald du sie mindestens einmal gefangen hast.
$Die DVs ergeben sich aus den Höchstwerten aller Pokémon,\ndie du bereits gefangen hast. $Die DVs ergeben sich aus den Höchstwerten aller Pokémon,\ndie du bereits gefangen hast.
$Es lohnt sich also, das selbe Pokémon mehrmals zu fangen!`, $Es lohnt sich also, das selbe Pokémon mehrmals zu fangen!`,
"pokerus": `Jeden Tag haben drei zufällige Pokémon einen lila Rahmen. "pokerus": `Jeden Tag haben drei zufällige Pokémon einen lila Rahmen.
$Wenn du eins von ihnen besitzt, $Wenn du eins von ihnen besitzt,
$nimm es doch mal mit und sieh dir seinen Bericht an!`, $nimm es doch mal mit und sieh dir seinen Bericht an!`,
"statChange": `Statuswertveränderungen halten solange an, wie dein Pokémon auf dem Feld bleibt. "statChange": `Statuswertveränderungen halten solange an, wie dein Pokémon auf dem Feld bleibt.
$Pokémon werden am Anfang eines Trainerkampfes oder bei einem Arealwechsel automatisch zurückgerufen. $Pokémon werden am Anfang eines Trainerkampfes oder bei einem Arealwechsel automatisch zurückgerufen.
$Nutze C oder Shift, um aktuelle Statuswertveränderungen anzuzeigen.`, $Nutze C oder Shift, um aktuelle Statuswertveränderungen anzuzeigen.`,
"selectItem": `Nach jedem Kampf kannst du aus 3 zufälligen Items exakt eines auswählen. "selectItem": `Nach jedem Kampf kannst du aus 3 zufälligen Items exakt eines auswählen.
$Es gibt u. A. Heilitems, tragbare Items und Basis-Items, die dir einen permanenten Vorteil verschaffen. $Es gibt u. A. Heilitems, tragbare Items und Basis-Items, die dir einen permanenten Vorteil verschaffen.
$Die meisten tragbaren und permanenten Items werden stärker, wenn du sie mehrfach sammelst. $Die meisten tragbaren und permanenten Items werden stärker, wenn du sie mehrfach sammelst.
$Manche Items, wie Entwicklungssteine, tauchen nur auf, wenn du sie auch nutzen kannst. $Manche Items, wie Entwicklungssteine, tauchen nur auf, wenn du sie auch nutzen kannst.
@ -37,7 +37,7 @@ export const tutorial: SimpleTranslationEntries = {
$Du kannst Heilitems auch gegen Geld erwerben. Je weiter du kommst, desto mehr stehen dir zur Auswahl. $Du kannst Heilitems auch gegen Geld erwerben. Je weiter du kommst, desto mehr stehen dir zur Auswahl.
$Erledige deine Einkäufe als erstes, denn sobald du dein zufälliges Item auswählst, beginnt der nächste Kampf.`, $Erledige deine Einkäufe als erstes, denn sobald du dein zufälliges Item auswählst, beginnt der nächste Kampf.`,
"eggGacha": `Hier kannst du deine Gutscheine gegen Pokémon-Eier\ntauschen. "eggGacha": `Hier kannst du deine Gutscheine gegen Pokémon-Eier\ntauschen.
$Eier schlüpfen, nachdem du eine gewisse Anzahl Kämpfe\nabsolviert hast. Je seltener das Ei, desto länger dauert es. $Eier schlüpfen, nachdem du eine gewisse Anzahl Kämpfe\nabsolviert hast. Je seltener das Ei, desto länger dauert es.
$Geschlüpfte Pokémon werden nicht deinem Team hinzugefügt,\nsondern deinen verfügbaren Startern. $Geschlüpfte Pokémon werden nicht deinem Team hinzugefügt,\nsondern deinen verfügbaren Startern.
$In der Regel haben sie bessere DVs als in der Wildnis\ngefangene Pokémon. $In der Regel haben sie bessere DVs als in der Wildnis\ngefangene Pokémon.

View File

@ -4,41 +4,41 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* The weather namespace holds text displayed when weather is active during a battle * The weather namespace holds text displayed when weather is active during a battle
*/ */
export const weather: SimpleTranslationEntries = { export const weather: SimpleTranslationEntries = {
"sunnyStartMessage": "Die Sonnenlicht wird stärker!", "sunnyStartMessage": "Die Sonnenlicht wird stärker!",
"sunnyLapseMessage": "Die Sonnenlicht ist stark.", "sunnyLapseMessage": "Die Sonnenlicht ist stark.",
"sunnyClearMessage": "Die Sonnenlicht verliert wieder an Intensität.", "sunnyClearMessage": "Die Sonnenlicht verliert wieder an Intensität.",
"rainStartMessage": "Es fängt an zu regnen!", "rainStartMessage": "Es fängt an zu regnen!",
"rainLapseMessage": "Es regnet weiter.", "rainLapseMessage": "Es regnet weiter.",
"rainClearMessage": "Der Regen lässt nach.", "rainClearMessage": "Der Regen lässt nach.",
"sandstormStartMessage": "Ein Sandsturm kommt auf!", "sandstormStartMessage": "Ein Sandsturm kommt auf!",
"sandstormLapseMessage": "Der Sandsturm tobt.", "sandstormLapseMessage": "Der Sandsturm tobt.",
"sandstormClearMessage": "Der Sandsturm legt sich.", "sandstormClearMessage": "Der Sandsturm legt sich.",
"sandstormDamageMessage": " Der Sandsturm fügt {{pokemonPrefix}}{{pokemonName}} Schaden zu!", "sandstormDamageMessage": " Der Sandsturm fügt {{pokemonPrefix}}{{pokemonName}} Schaden zu!",
"hailStartMessage": "Es fängt an zu hageln!", "hailStartMessage": "Es fängt an zu hageln!",
"hailLapseMessage": "Der Hagelsturm tobt.", "hailLapseMessage": "Der Hagelsturm tobt.",
"hailClearMessage": "Der Hagelsturm legt sich.", "hailClearMessage": "Der Hagelsturm legt sich.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} wird von Hagelkörnern getroffen!", "hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} wird von Hagelkörnern getroffen!",
"snowStartMessage": "Es fängt an zu schneien!", "snowStartMessage": "Es fängt an zu schneien!",
"snowLapseMessage": "Der Schneesturm tobt.", "snowLapseMessage": "Der Schneesturm tobt.",
"snowClearMessage": "Der Schneesturm legt sich.", "snowClearMessage": "Der Schneesturm legt sich.",
"fogStartMessage": "Am Boden breitet sich dichter Nebel aus!", "fogStartMessage": "Am Boden breitet sich dichter Nebel aus!",
"fogLapseMessage": "Der Nebel bleibt dicht.", "fogLapseMessage": "Der Nebel bleibt dicht.",
"fogClearMessage": "Der Nebel lichtet sich.", "fogClearMessage": "Der Nebel lichtet sich.",
"heavyRainStartMessage": "Es fängt an, in Strömen zu regnen!", "heavyRainStartMessage": "Es fängt an, in Strömen zu regnen!",
"heavyRainLapseMessage": "Der strömende Regen hält an.", "heavyRainLapseMessage": "Der strömende Regen hält an.",
"heavyRainClearMessage": "Der strömende Regen lässt nach.", "heavyRainClearMessage": "Der strömende Regen lässt nach.",
"harshSunStartMessage": "Das Sonnenlicht wird sehr viel stärker!", "harshSunStartMessage": "Das Sonnenlicht wird sehr viel stärker!",
"harshSunLapseMessage": "Das Sonnenlicht ist sehr stark.", "harshSunLapseMessage": "Das Sonnenlicht ist sehr stark.",
"harshSunClearMessage": "Das Sonnenlicht verliert an Intensität.", "harshSunClearMessage": "Das Sonnenlicht verliert an Intensität.",
"strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!", "strongWindsStartMessage": "Alle Flug-Pokémon werden von rätselhaften Luftströmungen geschützt!",
"strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.", "strongWindsLapseMessage": "Die rätselhafte Luftströmung hält an.",
"strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.", "strongWindsClearMessage": "Die rätselhafte Luftströmung hat sich wieder geleget.",
} };

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const commandUiHandler: SimpleTranslationEntries = { export const commandUiHandler: SimpleTranslationEntries = {
"fight": "Fight", "fight": "Fight",
"ball": "Ball", "ball": "Ball",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"run": "Run", "run": "Run",
"actionMessage": "What will\n{{pokemonName}} do?", "actionMessage": "What will\n{{pokemonName}} do?",
} as const; } as const;

View File

@ -23,29 +23,29 @@ import { berry } from "./berry";
import { voucher } from "./voucher"; import { voucher } from "./voucher";
export const enConfig = { export const enConfig = {
ability: ability, ability: ability,
abilityTriggers: abilityTriggers, abilityTriggers: abilityTriggers,
battle: battle, battle: battle,
commandUiHandler: commandUiHandler, commandUiHandler: commandUiHandler,
egg: egg, egg: egg,
fightUiHandler: fightUiHandler, fightUiHandler: fightUiHandler,
growth: growth, growth: growth,
menu: menu, menu: menu,
menuUiHandler: menuUiHandler, menuUiHandler: menuUiHandler,
modifierType: modifierType, modifierType: modifierType,
move: move, move: move,
nature: nature, nature: nature,
pokeball: pokeball, pokeball: pokeball,
pokemon: pokemon, pokemon: pokemon,
pokemonInfo: pokemonInfo, pokemonInfo: pokemonInfo,
splashMessages: splashMessages, splashMessages: splashMessages,
starterSelectUiHandler: starterSelectUiHandler, starterSelectUiHandler: starterSelectUiHandler,
titles: titles, titles: titles,
trainerClasses: trainerClasses, trainerClasses: trainerClasses,
trainerNames: trainerNames, trainerNames: trainerNames,
tutorial: tutorial, tutorial: tutorial,
weather: weather, weather: weather,
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "Power", "power": "Power",
"accuracy": "Accuracy", "accuracy": "Accuracy",
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const growth: SimpleTranslationEntries = { export const growth: SimpleTranslationEntries = {
"Erratic": "Erratic", "Erratic": "Erratic",
"Fast": "Fast", "Fast": "Fast",
"Medium_Fast": "Medium Fast", "Medium_Fast": "Medium Fast",
"Medium_Slow": "Medium Slow", "Medium_Slow": "Medium Slow",
"Slow": "Slow", "Slow": "Slow",
"Fluctuating": "Fluctuating" "Fluctuating": "Fluctuating"
} as const; } as const;

View File

@ -1,23 +1,23 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Game Settings', "GAME_SETTINGS": "Game Settings",
"ACHIEVEMENTS": "Achievements", "ACHIEVEMENTS": "Achievements",
"STATS": "Stats", "STATS": "Stats",
"VOUCHERS": "Vouchers", "VOUCHERS": "Vouchers",
"EGG_LIST": "Egg List", "EGG_LIST": "Egg List",
"EGG_GACHA": "Egg Gacha", "EGG_GACHA": "Egg Gacha",
"MANAGE_DATA": "Manage Data", "MANAGE_DATA": "Manage Data",
"COMMUNITY": "Community", "COMMUNITY": "Community",
"SAVE_AND_QUIT": "Save and Quit", "SAVE_AND_QUIT": "Save and Quit",
"LOG_OUT": "Log Out", "LOG_OUT": "Log Out",
"slot": "Slot {{slotNumber}}", "slot": "Slot {{slotNumber}}",
"importSession": "Import Session", "importSession": "Import Session",
"importSlotSelect": "Select a slot to import to.", "importSlotSelect": "Select a slot to import to.",
"exportSession": "Export Session", "exportSession": "Export Session",
"exportSlotSelect": "Select a slot to export from.", "exportSlotSelect": "Select a slot to export from.",
"importData": "Import Data", "importData": "Import Data",
"exportData": "Export Data", "exportData": "Export Data",
"cancel": "Cancel", "cancel": "Cancel",
"losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?" "losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?"
} as const; } as const;

View File

@ -6,46 +6,46 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc. * account interactions, descriptive text, etc.
*/ */
export const menu: SimpleTranslationEntries = { export const menu: SimpleTranslationEntries = {
"cancel": "Cancel", "cancel": "Cancel",
"continue": "Continue", "continue": "Continue",
"dailyRun": "Daily Run (Beta)", "dailyRun": "Daily Run (Beta)",
"loadGame": "Load Game", "loadGame": "Load Game",
"newGame": "New Game", "newGame": "New Game",
"selectGameMode": "Select a game mode.", "selectGameMode": "Select a game mode.",
"logInOrCreateAccount": "Log in or create an account to start. No email required!", "logInOrCreateAccount": "Log in or create an account to start. No email required!",
"username": "Username", "username": "Username",
"password": "Password", "password": "Password",
"login": "Login", "login": "Login",
"register": "Register", "register": "Register",
"emptyUsername": "Username must not be empty", "emptyUsername": "Username must not be empty",
"invalidLoginUsername": "The provided username is invalid", "invalidLoginUsername": "The provided username is invalid",
"invalidRegisterUsername": "Username must only contain letters, numbers, or underscores", "invalidRegisterUsername": "Username must only contain letters, numbers, or underscores",
"invalidLoginPassword": "The provided password is invalid", "invalidLoginPassword": "The provided password is invalid",
"invalidRegisterPassword": "Password must be 6 characters or longer", "invalidRegisterPassword": "Password must be 6 characters or longer",
"usernameAlreadyUsed": "The provided username is already in use", "usernameAlreadyUsed": "The provided username is already in use",
"accountNonExistent": "The provided user does not exist", "accountNonExistent": "The provided user does not exist",
"unmatchingPassword": "The provided password does not match", "unmatchingPassword": "The provided password does not match",
"passwordNotMatchingConfirmPassword": "Password must match confirm password", "passwordNotMatchingConfirmPassword": "Password must match confirm password",
"confirmPassword": "Confirm Password", "confirmPassword": "Confirm Password",
"registrationAgeWarning": "By registering, you confirm you are of 13 years of age or older.", "registrationAgeWarning": "By registering, you confirm you are of 13 years of age or older.",
"backToLogin": "Back to Login", "backToLogin": "Back to Login",
"failedToLoadSaveData": "Failed to load save data. Please reload the page.\nIf this continues, please contact the administrator.", "failedToLoadSaveData": "Failed to load save data. Please reload the page.\nIf this continues, please contact the administrator.",
"sessionSuccess": "Session loaded successfully.", "sessionSuccess": "Session loaded successfully.",
"failedToLoadSession": "Your session data could not be loaded.\nIt may be corrupted.", "failedToLoadSession": "Your session data could not be loaded.\nIt may be corrupted.",
"boyOrGirl": "Are you a boy or a girl?", "boyOrGirl": "Are you a boy or a girl?",
"boy": "Boy", "boy": "Boy",
"girl": "Girl", "girl": "Girl",
"evolving": "What?\n{{pokemonName}} is evolving!", "evolving": "What?\n{{pokemonName}} is evolving!",
"stoppedEvolving": "{{pokemonName}} stopped evolving.", "stoppedEvolving": "{{pokemonName}} stopped evolving.",
"pauseEvolutionsQuestion": "Would you like to pause evolutions for {{pokemonName}}?\nEvolutions can be re-enabled from the party screen.", "pauseEvolutionsQuestion": "Would you like to pause evolutions for {{pokemonName}}?\nEvolutions can be re-enabled from the party screen.",
"evolutionsPaused": "Evolutions have been paused for {{pokemonName}}.", "evolutionsPaused": "Evolutions have been paused for {{pokemonName}}.",
"evolutionDone": "Congratulations!\nYour {{pokemonName}} evolved into {{evolvedPokemonName}}!", "evolutionDone": "Congratulations!\nYour {{pokemonName}} evolved into {{evolvedPokemonName}}!",
"dailyRankings": "Daily Rankings", "dailyRankings": "Daily Rankings",
"weeklyRankings": "Weekly Rankings", "weeklyRankings": "Weekly Rankings",
"noRankings": "No Rankings", "noRankings": "No Rankings",
"loading": "Loading…", "loading": "Loading…",
"playersOnline": "Players Online", "playersOnline": "Players Online",
"empty":"Empty", "empty":"Empty",
"yes":"Yes", "yes":"Yes",
"no":"No", "no":"No",
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const pokeball: SimpleTranslationEntries = { export const pokeball: SimpleTranslationEntries = {
"pokeBall": "Poké Ball", "pokeBall": "Poké Ball",
"greatBall": "Great Ball", "greatBall": "Great Ball",
"ultraBall": "Ultra Ball", "ultraBall": "Ultra Ball",
"rogueBall": "Rogue Ball", "rogueBall": "Rogue Ball",
"masterBall": "Master Ball", "masterBall": "Master Ball",
"luxuryBall": "Luxury Ball", "luxuryBall": "Luxury Ball",
} as const; } as const;

View File

@ -1,41 +1,41 @@
import { PokemonInfoTranslationEntries } from "#app/plugins/i18n"; import { PokemonInfoTranslationEntries } from "#app/plugins/i18n";
export const pokemonInfo: PokemonInfoTranslationEntries = { export const pokemonInfo: PokemonInfoTranslationEntries = {
Stat: { Stat: {
"HP": "Max. HP", "HP": "Max. HP",
"HPshortened": "MaxHP", "HPshortened": "MaxHP",
"ATK": "Attack", "ATK": "Attack",
"ATKshortened": "Atk", "ATKshortened": "Atk",
"DEF": "Defense", "DEF": "Defense",
"DEFshortened": "Def", "DEFshortened": "Def",
"SPATK": "Sp. Atk", "SPATK": "Sp. Atk",
"SPATKshortened": "SpAtk", "SPATKshortened": "SpAtk",
"SPDEF": "Sp. Def", "SPDEF": "Sp. Def",
"SPDEFshortened": "SpDef", "SPDEFshortened": "SpDef",
"SPD": "Speed", "SPD": "Speed",
"SPDshortened": "Spd" "SPDshortened": "Spd"
}, },
Type: { Type: {
"UNKNOWN": "Unknown", "UNKNOWN": "Unknown",
"NORMAL": "Normal", "NORMAL": "Normal",
"FIGHTING": "Fighting", "FIGHTING": "Fighting",
"FLYING": "Flying", "FLYING": "Flying",
"POISON": "Poison", "POISON": "Poison",
"GROUND": "Ground", "GROUND": "Ground",
"ROCK": "Rock", "ROCK": "Rock",
"BUG": "Bug", "BUG": "Bug",
"GHOST": "Ghost", "GHOST": "Ghost",
"STEEL": "Steel", "STEEL": "Steel",
"FIRE": "Fire", "FIRE": "Fire",
"WATER": "Water", "WATER": "Water",
"GRASS": "Grass", "GRASS": "Grass",
"ELECTRIC": "Electric", "ELECTRIC": "Electric",
"PSYCHIC": "Psychic", "PSYCHIC": "Psychic",
"ICE": "Ice", "ICE": "Ice",
"DRAGON": "Dragon", "DRAGON": "Dragon",
"DARK": "Dark", "DARK": "Dark",
"FAIRY": "Fairy", "FAIRY": "Fairy",
"STELLAR": "Stellar", "STELLAR": "Stellar",
}, },
} as const; } as const;

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,37 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const splashMessages: SimpleTranslationEntries = { export const splashMessages: SimpleTranslationEntries = {
"battlesWon": "Battles Won!", "battlesWon": "Battles Won!",
"joinTheDiscord": "Join the Discord!", "joinTheDiscord": "Join the Discord!",
"infiniteLevels": "Infinite Levels!", "infiniteLevels": "Infinite Levels!",
"everythingStacks": "Everything Stacks!", "everythingStacks": "Everything Stacks!",
"optionalSaveScumming": "Optional Save Scumming!", "optionalSaveScumming": "Optional Save Scumming!",
"biomes": "35 Biomes!", "biomes": "35 Biomes!",
"openSource": "Open Source!", "openSource": "Open Source!",
"playWithSpeed": "Play with 5x Speed!", "playWithSpeed": "Play with 5x Speed!",
"liveBugTesting": "Live Bug Testing!", "liveBugTesting": "Live Bug Testing!",
"heavyInfluence": "Heavy RoR2 Influence!", "heavyInfluence": "Heavy RoR2 Influence!",
"pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!", "pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!",
"nowWithMoreSalt": "Now with 33% More Salt!", "nowWithMoreSalt": "Now with 33% More Salt!",
"infiniteFusionAtHome": "Infinite Fusion at Home!", "infiniteFusionAtHome": "Infinite Fusion at Home!",
"brokenEggMoves": "Broken Egg Moves!", "brokenEggMoves": "Broken Egg Moves!",
"magnificent": "Magnificent!", "magnificent": "Magnificent!",
"mubstitute": "Mubstitute!", "mubstitute": "Mubstitute!",
"thatsCrazy": "That\'s Crazy!", "thatsCrazy": "That's Crazy!",
"oranceJuice": "Orance Juice!", "oranceJuice": "Orance Juice!",
"questionableBalancing": "Questionable Balancing!", "questionableBalancing": "Questionable Balancing!",
"coolShaders": "Cool Shaders!", "coolShaders": "Cool Shaders!",
"aiFree": "AI-Free!", "aiFree": "AI-Free!",
"suddenDifficultySpikes": "Sudden Difficulty Spikes!", "suddenDifficultySpikes": "Sudden Difficulty Spikes!",
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!", "basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
"moreAddictiveThanIntended": "More Addictive than Intended!", "moreAddictiveThanIntended": "More Addictive than Intended!",
"mostlyConsistentSeeds": "Mostly Consistent Seeds!", "mostlyConsistentSeeds": "Mostly Consistent Seeds!",
"achievementPointsDontDoAnything": "Achievement Points Don\'t Do Anything!", "achievementPointsDontDoAnything": "Achievement Points Don't Do Anything!",
"youDoNotStartAtLevel": "You Do Not Start at Level 2000!", "youDoNotStartAtLevel": "You Do Not Start at Level 2000!",
"dontTalkAboutTheManaphyEggIncident": "Don\'t Talk About the Manaphy Egg Incident!", "dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
"alsoTryPokengine": "Also Try Pokéngine!", "alsoTryPokengine": "Also Try Pokéngine!",
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!", "alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
"alsoTryRadicalRed": "Also Try Radical Red!", "alsoTryRadicalRed": "Also Try Radical Red!",
"eeveeExpo": "Eevee Expo!", "eeveeExpo": "Eevee Expo!",
"ynoproject": "YNOproject!", "ynoproject": "YNOproject!",
} as const; } as const;

View File

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

View File

@ -2,243 +2,243 @@ import {SimpleTranslationEntries} from "#app/plugins/i18n";
// Titles of special trainers like gym leaders, elite four, and the champion // Titles of special trainers like gym leaders, elite four, and the champion
export const titles: SimpleTranslationEntries = { export const titles: SimpleTranslationEntries = {
"elite_four": "Elite Four", "elite_four": "Elite Four",
"gym_leader": "Gym Leader", "gym_leader": "Gym Leader",
"gym_leader_female": "Gym Leader", "gym_leader_female": "Gym Leader",
"champion": "Champion", "champion": "Champion",
"rival": "Rival", "rival": "Rival",
"professor": "Professor", "professor": "Professor",
"frontier_brain": "Frontier Brain", "frontier_brain": "Frontier Brain",
// Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc. // Maybe if we add the evil teams we can add "Team Rocket" and "Team Aqua" etc. here as well as "Team Rocket Boss" and "Team Aqua Admin" etc.
} as const; } as const;
// Titles of trainers like "Youngster" or "Lass" // Titles of trainers like "Youngster" or "Lass"
export const trainerClasses: SimpleTranslationEntries = { export const trainerClasses: SimpleTranslationEntries = {
"ace_trainer": "Ace Trainer", "ace_trainer": "Ace Trainer",
"ace_trainer_female": "Ace Trainer", "ace_trainer_female": "Ace Trainer",
"ace_duo": "Ace Duo", "ace_duo": "Ace Duo",
"artist": "Artist", "artist": "Artist",
"artist_female": "Artist", "artist_female": "Artist",
"backers": "Backers", "backers": "Backers",
"backpacker": "Backpacker", "backpacker": "Backpacker",
"backpacker_female": "Backpacker", "backpacker_female": "Backpacker",
"backpackers": "Backpackers", "backpackers": "Backpackers",
"baker": "Baker", "baker": "Baker",
"battle_girl": "Battle Girl", "battle_girl": "Battle Girl",
"beauty": "Beauty", "beauty": "Beauty",
"beginners": "Beginners", "beginners": "Beginners",
"biker": "Biker", "biker": "Biker",
"black_belt": "Black Belt", "black_belt": "Black Belt",
"breeder": "Breeder", "breeder": "Breeder",
"breeder_female": "Breeder", "breeder_female": "Breeder",
"breeders": "Breeders", "breeders": "Breeders",
"clerk": "Clerk", "clerk": "Clerk",
"clerk_female": "Clerk", "clerk_female": "Clerk",
"colleagues": "Colleagues", "colleagues": "Colleagues",
"crush_kin": "Crush Kin", "crush_kin": "Crush Kin",
"cyclist": "Cyclist", "cyclist": "Cyclist",
"cyclist_female": "Cyclist", "cyclist_female": "Cyclist",
"cyclists": "Cyclists", "cyclists": "Cyclists",
"dancer": "Dancer", "dancer": "Dancer",
"dancer_female": "Dancer", "dancer_female": "Dancer",
"depot_agent": "Depot Agent", "depot_agent": "Depot Agent",
"doctor": "Doctor", "doctor": "Doctor",
"doctor_female": "Doctor", "doctor_female": "Doctor",
"fisherman": "Fisherman", "fisherman": "Fisherman",
"fisherman_female": "Fisherman", "fisherman_female": "Fisherman",
"gentleman": "Gentleman", "gentleman": "Gentleman",
"guitarist": "Guitarist", "guitarist": "Guitarist",
"guitarist_female": "Guitarist", "guitarist_female": "Guitarist",
"harlequin": "Harlequin", "harlequin": "Harlequin",
"hiker": "Hiker", "hiker": "Hiker",
"hooligans": "Hooligans", "hooligans": "Hooligans",
"hoopster": "Hoopster", "hoopster": "Hoopster",
"infielder": "Infielder", "infielder": "Infielder",
"janitor": "Janitor", "janitor": "Janitor",
"lady": "Lady", "lady": "Lady",
"lass": "Lass", "lass": "Lass",
"linebacker": "Linebacker", "linebacker": "Linebacker",
"maid": "Maid", "maid": "Maid",
"madame": "Madame", "madame": "Madame",
"medical_team": "Medical Team", "medical_team": "Medical Team",
"musician": "Musician", "musician": "Musician",
"hex_maniac": "Hex Maniac", "hex_maniac": "Hex Maniac",
"nurse": "Nurse", "nurse": "Nurse",
"nursery_aide": "Nursery Aide", "nursery_aide": "Nursery Aide",
"officer": "Officer", "officer": "Officer",
"parasol_lady": "Parasol Lady", "parasol_lady": "Parasol Lady",
"pilot": "Pilot", "pilot": "Pilot",
"pokéfan": "Poké Fan", "pokéfan": "Poké Fan",
"pokéfan_female": "Poké Fan", "pokéfan_female": "Poké Fan",
"pokéfan_family": "Poké Fan Family", "pokéfan_family": "Poké Fan Family",
"preschooler": "Preschooler", "preschooler": "Preschooler",
"preschooler_female": "Preschooler", "preschooler_female": "Preschooler",
"preschoolers": "Preschoolers", "preschoolers": "Preschoolers",
"psychic": "Psychic", "psychic": "Psychic",
"psychic_female": "Psychic", "psychic_female": "Psychic",
"psychics": "Psychics", "psychics": "Psychics",
"pokémon_ranger": "Pokémon Ranger", "pokémon_ranger": "Pokémon Ranger",
"pokémon_ranger_female": "Pokémon Ranger", "pokémon_ranger_female": "Pokémon Ranger",
"pokémon_rangers": "Pokémon Ranger", "pokémon_rangers": "Pokémon Ranger",
"ranger": "Ranger", "ranger": "Ranger",
"restaurant_staff": "Restaurant Staff", "restaurant_staff": "Restaurant Staff",
"rich": "Rich", "rich": "Rich",
"rich_female": "Rich", "rich_female": "Rich",
"rich_boy": "Rich Boy", "rich_boy": "Rich Boy",
"rich_couple": "Rich Couple", "rich_couple": "Rich Couple",
"rich_kid": "Rich Kid", "rich_kid": "Rich Kid",
"rich_kid_female": "Rich Kid", "rich_kid_female": "Rich Kid",
"rich_kids": "Rich Kids", "rich_kids": "Rich Kids",
"roughneck": "Roughneck", "roughneck": "Roughneck",
"scientist": "Scientist", "scientist": "Scientist",
"scientist_female": "Scientist", "scientist_female": "Scientist",
"scientists": "Scientists", "scientists": "Scientists",
"smasher": "Smasher", "smasher": "Smasher",
"snow_worker": "Snow Worker", "snow_worker": "Snow Worker",
"snow_worker_female": "Snow Worker", "snow_worker_female": "Snow Worker",
"striker": "Striker", "striker": "Striker",
"school_kid": "School Kid", "school_kid": "School Kid",
"school_kid_female": "School Kid", "school_kid_female": "School Kid",
"school_kids": "School Kids", "school_kids": "School Kids",
"swimmer": "Swimmer", "swimmer": "Swimmer",
"swimmer_female": "Swimmer", "swimmer_female": "Swimmer",
"swimmers": "Swimmers", "swimmers": "Swimmers",
"twins": "Twins", "twins": "Twins",
"veteran": "Veteran", "veteran": "Veteran",
"veteran_female": "Veteran", "veteran_female": "Veteran",
"veteran_duo": "Veteran Duo", "veteran_duo": "Veteran Duo",
"waiter": "Waiter", "waiter": "Waiter",
"waitress": "Waitress", "waitress": "Waitress",
"worker": "Worker", "worker": "Worker",
"worker_female": "Worker", "worker_female": "Worker",
"workers": "Workers", "workers": "Workers",
"youngster": "Youngster" "youngster": "Youngster"
} as const; } as const;
// Names of special trainers like gym leaders, elite four, and the champion // Names of special trainers like gym leaders, elite four, and the champion
export const trainerNames: SimpleTranslationEntries = { export const trainerNames: SimpleTranslationEntries = {
"brock": "Brock", "brock": "Brock",
"misty": "Misty", "misty": "Misty",
"lt_surge": "Lt Surge", "lt_surge": "Lt Surge",
"erika": "Erika", "erika": "Erika",
"janine": "Janine", "janine": "Janine",
"sabrina": "Sabrina", "sabrina": "Sabrina",
"blaine": "Blaine", "blaine": "Blaine",
"giovanni": "Giovanni", "giovanni": "Giovanni",
"falkner": "Falkner", "falkner": "Falkner",
"bugsy": "Bugsy", "bugsy": "Bugsy",
"whitney": "Whitney", "whitney": "Whitney",
"morty": "Morty", "morty": "Morty",
"chuck": "Chuck", "chuck": "Chuck",
"jasmine": "Jasmine", "jasmine": "Jasmine",
"pryce": "Pryce", "pryce": "Pryce",
"clair": "Clair", "clair": "Clair",
"roxanne": "Roxanne", "roxanne": "Roxanne",
"brawly": "Brawly", "brawly": "Brawly",
"wattson": "Wattson", "wattson": "Wattson",
"flannery": "Flannery", "flannery": "Flannery",
"norman": "Norman", "norman": "Norman",
"winona": "Winona", "winona": "Winona",
"tate": "Tate", "tate": "Tate",
"liza": "Liza", "liza": "Liza",
"juan": "Juan", "juan": "Juan",
"roark": "Roark", "roark": "Roark",
"gardenia": "Gardenia", "gardenia": "Gardenia",
"maylene": "Maylene", "maylene": "Maylene",
"crasher_wake": "Crasher Wake", "crasher_wake": "Crasher Wake",
"fantina": "Fantina", "fantina": "Fantina",
"byron": "Byron", "byron": "Byron",
"candice": "Candice", "candice": "Candice",
"volkner": "Volkner", "volkner": "Volkner",
"cilan": "Cilan", "cilan": "Cilan",
"chili": "Chili", "chili": "Chili",
"cress": "Cress", "cress": "Cress",
"cheren": "Cheren", "cheren": "Cheren",
"lenora": "Lenora", "lenora": "Lenora",
"roxie": "Roxie", "roxie": "Roxie",
"burgh": "Burgh", "burgh": "Burgh",
"elesa": "Elesa", "elesa": "Elesa",
"clay": "Clay", "clay": "Clay",
"skyla": "Skyla", "skyla": "Skyla",
"brycen": "Brycen", "brycen": "Brycen",
"drayden": "Drayden", "drayden": "Drayden",
"marlon": "Marlon", "marlon": "Marlon",
"viola": "Viola", "viola": "Viola",
"grant": "Grant", "grant": "Grant",
"korrina": "Korrina", "korrina": "Korrina",
"ramos": "Ramos", "ramos": "Ramos",
"clemont": "Clemont", "clemont": "Clemont",
"valerie": "Valerie", "valerie": "Valerie",
"olympia": "Olympia", "olympia": "Olympia",
"wulfric": "Wulfric", "wulfric": "Wulfric",
"milo": "Milo", "milo": "Milo",
"nessa": "Nessa", "nessa": "Nessa",
"kabu": "Kabu", "kabu": "Kabu",
"bea": "Bea", "bea": "Bea",
"allister": "Allister", "allister": "Allister",
"opal": "Opal", "opal": "Opal",
"bede": "Bede", "bede": "Bede",
"gordie": "Gordie", "gordie": "Gordie",
"melony": "Melony", "melony": "Melony",
"piers": "Piers", "piers": "Piers",
"marnie": "Marnie", "marnie": "Marnie",
"raihan": "Raihan", "raihan": "Raihan",
"katy": "Katy", "katy": "Katy",
"brassius": "Brassius", "brassius": "Brassius",
"iono": "Iono", "iono": "Iono",
"kofu": "Kofu", "kofu": "Kofu",
"larry": "Larry", "larry": "Larry",
"ryme": "Ryme", "ryme": "Ryme",
"tulip": "Tulip", "tulip": "Tulip",
"grusha": "Grusha", "grusha": "Grusha",
"lorelei": "Lorelei", "lorelei": "Lorelei",
"bruno": "Bruno", "bruno": "Bruno",
"agatha": "Agatha", "agatha": "Agatha",
"lance": "Lance", "lance": "Lance",
"will": "Will", "will": "Will",
"koga": "Koga", "koga": "Koga",
"karen": "Karen", "karen": "Karen",
"sidney": "Sidney", "sidney": "Sidney",
"phoebe": "Phoebe", "phoebe": "Phoebe",
"glacia": "Glacia", "glacia": "Glacia",
"drake": "Drake", "drake": "Drake",
"aaron": "Aaron", "aaron": "Aaron",
"bertha": "Bertha", "bertha": "Bertha",
"flint": "Flint", "flint": "Flint",
"lucian": "Lucian", "lucian": "Lucian",
"shauntal": "Shauntal", "shauntal": "Shauntal",
"marshal": "Marshal", "marshal": "Marshal",
"grimsley": "Grimsley", "grimsley": "Grimsley",
"caitlin": "Caitlin", "caitlin": "Caitlin",
"malva": "Malva", "malva": "Malva",
"siebold": "Siebold", "siebold": "Siebold",
"wikstrom": "Wikstrom", "wikstrom": "Wikstrom",
"drasna": "Drasna", "drasna": "Drasna",
"hala": "Hala", "hala": "Hala",
"molayne": "Molayne", "molayne": "Molayne",
"olivia": "Olivia", "olivia": "Olivia",
"acerola": "Acerola", "acerola": "Acerola",
"kahili": "Kahili", "kahili": "Kahili",
"rika": "Rika", "rika": "Rika",
"poppy": "Poppy", "poppy": "Poppy",
"hassel": "Hassel", "hassel": "Hassel",
"crispin": "Crispin", "crispin": "Crispin",
"amarys": "Amarys", "amarys": "Amarys",
"lacey": "Lacey", "lacey": "Lacey",
"drayton": "Drayton", "drayton": "Drayton",
"blue": "Blue", "blue": "Blue",
"red": "Red", "red": "Red",
"steven": "Steven", "steven": "Steven",
"wallace": "Wallace", "wallace": "Wallace",
"cynthia": "Cynthia", "cynthia": "Cynthia",
"alder": "Alder", "alder": "Alder",
"iris": "Iris", "iris": "Iris",
"diantha": "Diantha", "diantha": "Diantha",
"hau": "Hau", "hau": "Hau",
"geeta": "Geeta", "geeta": "Geeta",
"nemona": "Nemona", "nemona": "Nemona",
"kieran": "Kieran", "kieran": "Kieran",
"leon": "Leon", "leon": "Leon",
"rival": "Finn", "rival": "Finn",
"rival_female": "Ivy", "rival_female": "Ivy",
} as const; } as const;

View File

@ -1,30 +1,30 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const tutorial: SimpleTranslationEntries = { export const tutorial: SimpleTranslationEntries = {
"intro": `Welcome to PokéRogue! This is a battle-focused Pokémon fangame with roguelite elements. "intro": `Welcome to PokéRogue! This is a battle-focused Pokémon fangame with roguelite elements.
$This game is not monetized and we claim no ownership of Pokémon nor of the copyrighted assets used. $This game is not monetized and we claim no ownership of Pokémon nor of the copyrighted assets used.
$The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community. $The game is a work in progress, but fully playable.\nFor bug reports, please use the Discord community.
$If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`, $If the game runs slowly, please ensure 'Hardware Acceleration' is turned on in your browser settings.`,
"accessMenu": `To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.`, "accessMenu": "To access the menu, press M or Escape while awaiting input.\nThe menu contains settings and various features.",
"menu": `From this menu you can access the settings. "menu": `From this menu you can access the settings.
$From the settings you can change game speed, window style, and other options. $From the settings you can change game speed, window style, and other options.
$There are also various other features here, so be sure to check them all!`, $There are also various other features here, so be sure to check them all!`,
"starterSelect": `From this screen, you can select your starters.\nThese are your initial party members. "starterSelect": `From this screen, you can select your starters.\nThese are your initial party members.
$Each starter has a value. Your party can have up to\n6 members as long as the total does not exceed 10. $Each starter has a value. Your party can have up to\n6 members as long as the total does not exceed 10.
$You can also select gender, ability, and form depending on\nthe variants you've caught or hatched. $You can also select gender, ability, and form depending on\nthe variants you've caught or hatched.
$The IVs for a species are also the best of every one you've\ncaught or hatched, so try to get lots of the same species!`, $The IVs for a species are also the best of every one you've\ncaught or hatched, so try to get lots of the same species!`,
"pokerus": `A daily random 3 selectable starters have a purple border. "pokerus": `A daily random 3 selectable starters have a purple border.
$If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`, $If you see a starter you own with one of these,\ntry adding it to your party. Be sure to check its summary!`,
"statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled. "statChange": `Stat changes persist across battles as long as your Pokémon aren't recalled.
$Your Pokémon are recalled before a trainer battle and before entering a new biome. $Your Pokémon are recalled before a trainer battle and before entering a new biome.
$You can also view the stat changes for the Pokémon on the field by holding C or Shift.`, $You can also view the stat changes for the Pokémon on the field by holding C or Shift.`,
"selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one. "selectItem": `After every battle, you are given a choice of 3 random items.\nYou may only pick one.
$These range from consumables, to Pokémon held items, to passive permanent items. $These range from consumables, to Pokémon held items, to passive permanent items.
$Most non-consumable item effects will stack in various ways. $Most non-consumable item effects will stack in various ways.
$Some items will only show up if they can be used, such as evolution items. $Some items will only show up if they can be used, such as evolution items.
@ -33,7 +33,7 @@ export const tutorial: SimpleTranslationEntries = {
$You may purchase consumable items with money, and a larger variety will be available the further you get. $You may purchase consumable items with money, and a larger variety will be available the further you get.
$Be sure to buy these before you pick your random item, as it will progress to the next battle once you do.`, $Be sure to buy these before you pick your random item, as it will progress to the next battle once you do.`,
"eggGacha": `From this screen, you can redeem your vouchers for\nPokémon eggs. "eggGacha": `From this screen, you can redeem your vouchers for\nPokémon eggs.
$Eggs have to be hatched and get closer to hatching after\nevery battle. Rarer eggs take longer to hatch. $Eggs have to be hatched and get closer to hatching after\nevery battle. Rarer eggs take longer to hatch.
$Hatched Pokémon also won't be added to your party, they will\nbe added to your starters. $Hatched Pokémon also won't be added to your party, they will\nbe added to your starters.
$Pokémon hatched from eggs generally have better IVs than\nwild Pokémon. $Pokémon hatched from eggs generally have better IVs than\nwild Pokémon.

View File

@ -4,41 +4,41 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* The weather namespace holds text displayed when weather is active during a battle * The weather namespace holds text displayed when weather is active during a battle
*/ */
export const weather: SimpleTranslationEntries = { export const weather: SimpleTranslationEntries = {
"sunnyStartMessage": "The sunlight got bright!", "sunnyStartMessage": "The sunlight got bright!",
"sunnyLapseMessage": "The sunlight is strong.", "sunnyLapseMessage": "The sunlight is strong.",
"sunnyClearMessage": "The sunlight faded.", "sunnyClearMessage": "The sunlight faded.",
"rainStartMessage": "A downpour started!", "rainStartMessage": "A downpour started!",
"rainLapseMessage": "The downpour continues.", "rainLapseMessage": "The downpour continues.",
"rainClearMessage": "The rain stopped.", "rainClearMessage": "The rain stopped.",
"sandstormStartMessage": "A sandstorm brewed!", "sandstormStartMessage": "A sandstorm brewed!",
"sandstormLapseMessage": "The sandstorm rages.", "sandstormLapseMessage": "The sandstorm rages.",
"sandstormClearMessage": "The sandstorm subsided.", "sandstormClearMessage": "The sandstorm subsided.",
"sandstormDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is buffeted\nby the sandstorm!", "sandstormDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is buffeted\nby the sandstorm!",
"hailStartMessage": "It started to hail!", "hailStartMessage": "It started to hail!",
"hailLapseMessage": "Hail continues to fall.", "hailLapseMessage": "Hail continues to fall.",
"hailClearMessage": "The hail stopped.", "hailClearMessage": "The hail stopped.",
"hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is pelted\nby the hail!", "hailDamageMessage": "{{pokemonPrefix}}{{pokemonName}} is pelted\nby the hail!",
"snowStartMessage": "It started to snow!", "snowStartMessage": "It started to snow!",
"snowLapseMessage": "The snow is falling down.", "snowLapseMessage": "The snow is falling down.",
"snowClearMessage": "The snow stopped.", "snowClearMessage": "The snow stopped.",
"fogStartMessage": "A thick fog emerged!", "fogStartMessage": "A thick fog emerged!",
"fogLapseMessage": "The fog continues.", "fogLapseMessage": "The fog continues.",
"fogClearMessage": "The fog disappeared.", "fogClearMessage": "The fog disappeared.",
"heavyRainStartMessage": "A heavy downpour started!", "heavyRainStartMessage": "A heavy downpour started!",
"heavyRainLapseMessage": "The heavy downpour continues.", "heavyRainLapseMessage": "The heavy downpour continues.",
"heavyRainClearMessage": "The heavy rain stopped.", "heavyRainClearMessage": "The heavy rain stopped.",
"harshSunStartMessage": "The sunlight got hot!", "harshSunStartMessage": "The sunlight got hot!",
"harshSunLapseMessage": "The sun is scorching hot.", "harshSunLapseMessage": "The sun is scorching hot.",
"harshSunClearMessage": "The harsh sunlight faded.", "harshSunClearMessage": "The harsh sunlight faded.",
"strongWindsStartMessage": "A heavy wind began!", "strongWindsStartMessage": "A heavy wind began!",
"strongWindsLapseMessage": "The wind blows intensely.", "strongWindsLapseMessage": "The wind blows intensely.",
"strongWindsClearMessage": "The heavy wind stopped." "strongWindsClearMessage": "The heavy wind stopped."
} };

View File

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

View File

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

View File

@ -1,9 +1,9 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const commandUiHandler: SimpleTranslationEntries = { export const commandUiHandler: SimpleTranslationEntries = {
"fight": "Luchar", "fight": "Luchar",
"ball": "Balls", "ball": "Balls",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"run": "Huir", "run": "Huir",
"actionMessage": "¿Qué debería\nhacer {{pokemonName}}?", "actionMessage": "¿Qué debería\nhacer {{pokemonName}}?",
} as const; } as const;

View File

@ -23,29 +23,29 @@ import { berry } from "./berry";
import { voucher } from "./voucher"; import { voucher } from "./voucher";
export const esConfig = { export const esConfig = {
ability: ability, ability: ability,
abilityTriggers: abilityTriggers, abilityTriggers: abilityTriggers,
battle: battle, battle: battle,
commandUiHandler: commandUiHandler, commandUiHandler: commandUiHandler,
egg: egg, egg: egg,
fightUiHandler: fightUiHandler, fightUiHandler: fightUiHandler,
growth: growth, growth: growth,
menu: menu, menu: menu,
menuUiHandler: menuUiHandler, menuUiHandler: menuUiHandler,
modifierType: modifierType, modifierType: modifierType,
move: move, move: move,
nature: nature, nature: nature,
pokeball: pokeball, pokeball: pokeball,
pokemon: pokemon, pokemon: pokemon,
pokemonInfo: pokemonInfo, pokemonInfo: pokemonInfo,
splashMessages: splashMessages, splashMessages: splashMessages,
starterSelectUiHandler: starterSelectUiHandler, starterSelectUiHandler: starterSelectUiHandler,
titles: titles, titles: titles,
trainerClasses: trainerClasses, trainerClasses: trainerClasses,
trainerNames: trainerNames, trainerNames: trainerNames,
tutorial: tutorial, tutorial: tutorial,
weather: weather, weather: weather,
battleMessageUiHandler: battleMessageUiHandler, battleMessageUiHandler: battleMessageUiHandler,
berry: berry, berry: berry,
voucher: voucher, voucher: voucher,
} };

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const fightUiHandler: SimpleTranslationEntries = { export const fightUiHandler: SimpleTranslationEntries = {
"pp": "PP", "pp": "PP",
"power": "Potencia", "power": "Potencia",
"accuracy": "Precisión", "accuracy": "Precisión",
} as const; } as const;

View File

@ -1,10 +1,10 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const growth: SimpleTranslationEntries = { export const growth: SimpleTranslationEntries = {
"Erratic": "Errático", "Erratic": "Errático",
"Fast": "Rápido", "Fast": "Rápido",
"Medium_Fast": "Medio Rápido", "Medium_Fast": "Medio Rápido",
"Medium_Slow": "Medio Lento", "Medium_Slow": "Medio Lento",
"Slow": "Lento", "Slow": "Lento",
"Fluctuating": "Fluctuante" "Fluctuating": "Fluctuante"
} as const; } as const;

View File

@ -1,23 +1,23 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n"; import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = { export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Ajustes', "GAME_SETTINGS": "Ajustes",
"ACHIEVEMENTS": "Logros", "ACHIEVEMENTS": "Logros",
"STATS": "Estadísticas", "STATS": "Estadísticas",
"VOUCHERS": "Vales", "VOUCHERS": "Vales",
"EGG_LIST": "Lista de Huevos", "EGG_LIST": "Lista de Huevos",
"EGG_GACHA": "Gacha de Huevos", "EGG_GACHA": "Gacha de Huevos",
"MANAGE_DATA": "Gestionar Datos", "MANAGE_DATA": "Gestionar Datos",
"COMMUNITY": "Comunidad", "COMMUNITY": "Comunidad",
"SAVE_AND_QUIT": "Guardar y Salir", "SAVE_AND_QUIT": "Guardar y Salir",
"LOG_OUT": "Cerrar Sesión", "LOG_OUT": "Cerrar Sesión",
"slot": "Ranura {{slotNumber}}", "slot": "Ranura {{slotNumber}}",
"importSession": "Importar Sesión", "importSession": "Importar Sesión",
"importSlotSelect": "Selecciona una ranura para importar.", "importSlotSelect": "Selecciona una ranura para importar.",
"exportSession": "Exportar Sesión", "exportSession": "Exportar Sesión",
"exportSlotSelect": "Selecciona una ranura para exportar.", "exportSlotSelect": "Selecciona una ranura para exportar.",
"importData": "Importar Datos", "importData": "Importar Datos",
"exportData": "Exportar Datos", "exportData": "Exportar Datos",
"cancel": "Cancelar", "cancel": "Cancelar",
"losingProgressionWarning": "Perderás cualquier progreso desde el inicio de la batalla. ¿Continuar?" "losingProgressionWarning": "Perderás cualquier progreso desde el inicio de la batalla. ¿Continuar?"
} as const; } as const;

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