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

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,6 @@ import { GameMode } from "./game-mode";
import { BattleSpec } from "./enums/battle-spec";
import { PlayerGender } from "./system/game-data";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { MoneyAchv } from "./system/achv";
import { PokeballType } from "./data/pokeball";
export enum BattleType {
@ -34,268 +33,284 @@ export interface TurnCommand {
targets?: BattlerIndex[];
skip?: boolean;
args?: any[];
};
}
interface TurnCommands {
[key: integer]: TurnCommand
}
export default class Battle {
protected gameMode: GameMode;
public waveIndex: integer;
public battleType: BattleType;
public battleSpec: BattleSpec;
public trainer: Trainer;
public enemyLevels: integer[];
public enemyParty: EnemyPokemon[];
public seenEnemyPartyMemberIds: Set<integer>;
public double: boolean;
public started: boolean;
public enemySwitchCounter: integer;
public turn: integer;
public turnCommands: TurnCommands;
public playerParticipantIds: Set<integer>;
public battleScore: integer;
public postBattleLoot: PokemonHeldItemModifier[];
public escapeAttempts: integer;
public lastMove: Moves;
public battleSeed: string;
private battleSeedState: string;
public moneyScattered: number;
public lastUsedPokeball: PokeballType;
protected gameMode: GameMode;
public waveIndex: integer;
public battleType: BattleType;
public battleSpec: BattleSpec;
public trainer: Trainer;
public enemyLevels: integer[];
public enemyParty: EnemyPokemon[];
public seenEnemyPartyMemberIds: Set<integer>;
public double: boolean;
public started: boolean;
public enemySwitchCounter: integer;
public turn: integer;
public turnCommands: TurnCommands;
public playerParticipantIds: Set<integer>;
public battleScore: integer;
public postBattleLoot: PokemonHeldItemModifier[];
public escapeAttempts: integer;
public lastMove: Moves;
public battleSeed: string;
private battleSeedState: string;
public moneyScattered: number;
public lastUsedPokeball: PokeballType;
private rngCounter: integer = 0;
private rngCounter: integer = 0;
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) {
this.gameMode = gameMode;
this.waveIndex = waveIndex;
this.battleType = battleType;
this.trainer = trainer;
this.initBattleSpec();
this.enemyLevels = battleType !== BattleType.TRAINER
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer.getPartyLevels(this.waveIndex);
this.enemyParty = [];
this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = double;
this.enemySwitchCounter = 0;
this.turn = 0;
this.playerParticipantIds = new Set<integer>();
this.battleScore = 0;
this.postBattleLoot = [];
this.escapeAttempts = 0;
this.started = false;
this.battleSeed = Utils.randomString(16, true);
this.battleSeedState = null;
this.moneyScattered = 0;
this.lastUsedPokeball = null;
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer: Trainer, double: boolean) {
this.gameMode = gameMode;
this.waveIndex = waveIndex;
this.battleType = battleType;
this.trainer = trainer;
this.initBattleSpec();
this.enemyLevels = battleType !== BattleType.TRAINER
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer.getPartyLevels(this.waveIndex);
this.enemyParty = [];
this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = double;
this.enemySwitchCounter = 0;
this.turn = 0;
this.playerParticipantIds = new Set<integer>();
this.battleScore = 0;
this.postBattleLoot = [];
this.escapeAttempts = 0;
this.started = false;
this.battleSeed = Utils.randomString(16, true);
this.battleSeedState = null;
this.moneyScattered = 0;
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 spec = BattleSpec.DEFAULT;
if (this.gameMode.isWaveFinal(this.waveIndex) && this.gameMode.isClassic)
spec = BattleSpec.FINAL_BOSS;
this.battleSpec = spec;
}
private getLevelForWave(): integer {
let levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
let baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const 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;
}
let levelOffset = 0;
let levelOffset = 0;
const deviation = 10 / levelWaveIndex;
levelOffset = Math.abs(this.randSeedGaussForLevel(deviation));
const deviation = 10 / levelWaveIndex;
levelOffset = Math.abs(this.randSeedGaussForLevel(deviation));
return Math.max(Math.round(baseLevel + levelOffset), 1);
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;
}
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;
}
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;
}
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);
}
addParticipant(playerPokemon: PlayerPokemon): void {
this.playerParticipantIds.add(playerPokemon.id);
}
removeFaintedParticipant(playerPokemon: PlayerPokemon): void {
this.playerParticipantIds.delete(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;
}));
}
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);
pickUpScatteredMoney(scene: BattleScene): void {
const moneyAmount = new Utils.IntegerHolder(scene.currentBattle.moneyScattered);
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
scene.addMoney(moneyAmount.value);
scene.addMoney(moneyAmount.value);
scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString('en-US')}!`, null, true);
scene.queueMessage(`You picked up ₽${moneyAmount.value.toLocaleString("en-US")}!`, null, true);
scene.currentBattle.moneyScattered = 0;
scene.currentBattle.moneyScattered = 0;
}
addBattleScore(scene: BattleScene): void {
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();
}
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;
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";
}
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 (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';
}
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 (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;
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);
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";
}
scene.rngCounter = this.rngCounter++;
scene.rngSeedOverride = this.battleSeed;
ret = Utils.randSeedInt(range, min);
this.battleSeedState = Phaser.Math.RND.state();
Phaser.Math.RND.state(state);
scene.rngCounter = tempRngCounter;
scene.rngSeedOverride = tempSeedOverride;
return ret;
if (pokemon.species.speciesId === Species.RESHIRAM || pokemon.species.speciesId === Species.ZEKROM) {
return "battle_legendary_res_zek";
}
if (pokemon.species.speciesId === Species.KYUREM) {
return "battle_legendary_kyurem";
}
if (pokemon.species.legendary) {
return "battle_legendary_res_zek";
}
return "battle_legendary_unova";
}
}
if (scene.gameMode.isClassic && this.waveIndex <= 4) {
return "battle_wild";
}
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 {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double);
if (config.getEnemyParty)
this.enemyParty = config.getEnemyParty(scene);
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : null, config.double);
if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty(scene);
}
}
}
type GetTrainerFunc = (scene: BattleScene) => Trainer;
type GetEnemyPartyFunc = (scene: BattleScene) => EnemyPokemon[];
export class FixedBattleConfig {
public battleType: BattleType;
public double: boolean;
public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: integer;
public battleType: BattleType;
public double: boolean;
public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: integer;
setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType;
return this;
}
setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType;
return this;
}
setDouble(double: boolean): FixedBattleConfig {
this.double = double;
return this;
}
setDouble(double: boolean): FixedBattleConfig {
this.double = double;
return this;
}
setGetTrainerFunc(getTrainerFunc: GetTrainerFunc): FixedBattleConfig {
this.getTrainer = getTrainerFunc;
return this;
}
setGetTrainerFunc(getTrainerFunc: GetTrainerFunc): FixedBattleConfig {
this.getTrainer = getTrainerFunc;
return this;
}
setGetEnemyPartyFunc(getEnemyPartyFunc: GetEnemyPartyFunc): FixedBattleConfig {
this.getEnemyParty = getEnemyPartyFunc;
return this;
}
setGetEnemyPartyFunc(getEnemyPartyFunc: GetEnemyPartyFunc): FixedBattleConfig {
this.getEnemyParty = getEnemyPartyFunc;
return this;
}
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this;
}
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this;
}
}
function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[]): GetTrainerFunc {
return (scene: BattleScene) => {
const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = [];
for (let trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry)
: trainerPoolEntry;
trainerTypes.push(trainerType);
}
return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT);
};
return (scene: BattleScene) => {
const rand = Utils.randSeedInt(trainerPool.length);
const trainerTypes: TrainerType[] = [];
for (const trainerPoolEntry of trainerPool) {
const trainerType = Array.isArray(trainerPoolEntry)
? Utils.randSeedItem(trainerPoolEntry)
: trainerPoolEntry;
trainerTypes.push(trainerType);
}
return new Trainer(scene, trainerTypes[rand], TrainerVariant.DEFAULT);
};
}
interface FixedBattleConfigs {
@ -303,28 +318,28 @@ interface FixedBattleConfigs {
}
export const fixedBattles: FixedBattleConfigs = {
[5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[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 ])),
[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 ])),
[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 ])),
[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 ])),
[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 ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
};
[5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[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 ])),
[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 ])),
[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 ])),
[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 ])),
[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 ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.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
*/
const pad_dualshock = {
padID: 'Dualshock',
padType: 'Sony',
gamepadMapping: {
RC_S: 0,
RC_E: 1,
RC_W: 2,
RC_N: 3,
START: 9, // Options
SELECT: 8, // Share
LB: 4,
RB: 5,
LT: 6,
RT: 7,
LS: 10,
RS: 11,
LC_N: 12,
LC_S: 13,
LC_W: 14,
LC_E: 15,
MENU: 16,
TOUCH: 17
},
padID: "Dualshock",
padType: "Sony",
gamepadMapping: {
RC_S: 0,
RC_E: 1,
RC_W: 2,
RC_N: 3,
START: 9, // Options
SELECT: 8, // Share
LB: 4,
RB: 5,
LT: 6,
RT: 7,
LS: 10,
RS: 11,
LC_N: 12,
LC_S: 13,
LC_W: 14,
LC_E: 15,
MENU: 16,
TOUCH: 17
},
};
export default pad_dualshock;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -3,4 +3,4 @@ export enum EggTier {
GREAT,
ULTRA,
MASTER
}
}

View File

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

View File

@ -2163,7 +2163,7 @@ export enum Species {
PALDEA_WOOPER = 8194,
/**{@link https://bulbapedia.bulbagarden.net/wiki/Ursaluna_(Pokémon) | Source} */
BLOODMOON_URSALUNA = 8901,
};
}
export const defaultStarterSpecies: Species[] = [
Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE,
@ -2175,4 +2175,4 @@ export const defaultStarterSpecies: Species[] = [
Species.ROWLET, Species.LITTEN, Species.POPPLIO,
Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE,
Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY
];
];

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,26 +24,30 @@ export class Terrain {
}
lapse(): boolean {
if (this.turnsLeft)
if (this.turnsLeft) {
return !!--this.turnsLeft;
}
return true;
}
getAttackTypeMultiplier(attackType: Type): number {
switch (this.terrainType) {
case TerrainType.ELECTRIC:
if (attackType === Type.ELECTRIC)
return 1.3;
break;
case TerrainType.GRASSY:
if (attackType === Type.GRASS)
return 1.3;
break;
case TerrainType.PSYCHIC:
if (attackType === Type.PSYCHIC)
return 1.3;
break;
case TerrainType.ELECTRIC:
if (attackType === Type.ELECTRIC) {
return 1.3;
}
break;
case TerrainType.GRASSY:
if (attackType === Type.GRASS) {
return 1.3;
}
break;
case TerrainType.PSYCHIC:
if (attackType === Type.PSYCHIC) {
return 1.3;
}
break;
}
return 1;
@ -51,12 +55,12 @@ export class Terrain {
isMoveTerrainCancelled(user: Pokemon, targets: BattlerIndex[], move: Move): boolean {
switch (this.terrainType) {
case TerrainType.PSYCHIC:
if (!move.getAttrs(ProtectAttr).length) {
const priority = new Utils.IntegerHolder(move.priority);
applyAbAttrs(IncrementMovePriorityAbAttr, user, null, move, priority);
return priority.value > 0 && user.getOpponents().filter(o => targets.includes(o.getBattlerIndex())).length > 0;
}
case TerrainType.PSYCHIC:
if (!move.getAttrs(ProtectAttr).length) {
const priority = new Utils.IntegerHolder(move.priority);
applyAbAttrs(IncrementMovePriorityAbAttr, user, null, move, priority);
return priority.value > 0 && user.getOpponents().filter(o => targets.includes(o.getBattlerIndex())).length > 0;
}
}
return false;
@ -65,15 +69,15 @@ export class Terrain {
export function getTerrainColor(terrainType: TerrainType): [ integer, integer, integer ] {
switch (terrainType) {
case TerrainType.MISTY:
return [ 232, 136, 200 ];
case TerrainType.ELECTRIC:
return [ 248, 248, 120 ];
case TerrainType.GRASSY:
return [ 120, 200, 80 ];
case TerrainType.PSYCHIC:
return [ 160, 64, 160 ];
case TerrainType.MISTY:
return [ 232, 136, 200 ];
case TerrainType.ELECTRIC:
return [ 248, 248, 120 ];
case TerrainType.GRASSY:
return [ 120, 200, 80 ];
case TerrainType.PSYCHIC:
return [ 160, 64, 160 ];
}
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[];
constructor(type: TrainerType, ...urls: string[]) {
this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, '_') ];
this.urls = urls.length ? urls : [ Utils.toReadableString(TrainerType[type]).replace(/ /g, "_") ];
}
hasGenderVariant(...femaleUrls: string[]): TrainerNameConfig {
@ -19,6 +19,8 @@ interface TrainerNameConfigs {
[key: integer]: TrainerNameConfig
}
// used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.ACE_TRAINER]: new TrainerNameConfig(TrainerType.ACE_TRAINER),
[TrainerType.ARTIST]: new TrainerNameConfig(TrainerType.ARTIST),
@ -27,13 +29,13 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.BAKER]: new TrainerNameConfig(TrainerType.BAKER),
[TrainerType.BEAUTY]: new TrainerNameConfig(TrainerType.BEAUTY),
[TrainerType.BIKER]: new TrainerNameConfig(TrainerType.BIKER),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant('Battle_Girl'),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, 'Pokémon_Breeder'),
[TrainerType.BLACK_BELT]: new TrainerNameConfig(TrainerType.BLACK_BELT).hasGenderVariant("Battle_Girl"),
[TrainerType.BREEDER]: new TrainerNameConfig(TrainerType.BREEDER, "Pokémon_Breeder"),
[TrainerType.CLERK]: new TrainerNameConfig(TrainerType.CLERK),
[TrainerType.CYCLIST]: new TrainerNameConfig(TrainerType.CYCLIST),
[TrainerType.DANCER]: new TrainerNameConfig(TrainerType.DANCER),
[TrainerType.DEPOT_AGENT]: new TrainerNameConfig(TrainerType.DEPOT_AGENT),
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant('Nurse'),
[TrainerType.DOCTOR]: new TrainerNameConfig(TrainerType.DOCTOR).hasGenderVariant("Nurse"),
[TrainerType.FISHERMAN]: new TrainerNameConfig(TrainerType.FISHERMAN),
[TrainerType.GUITARIST]: new TrainerNameConfig(TrainerType.GUITARIST),
[TrainerType.HARLEQUIN]: new TrainerNameConfig(TrainerType.HARLEQUIN),
@ -50,113 +52,118 @@ const trainerNameConfigs: TrainerNameConfigs = {
[TrainerType.OFFICER]: new TrainerNameConfig(TrainerType.OFFICER),
[TrainerType.PARASOL_LADY]: new TrainerNameConfig(TrainerType.PARASOL_LADY),
[TrainerType.PILOT]: new TrainerNameConfig(TrainerType.PILOT),
[TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, 'Poké_Fan'),
[TrainerType.POKEFAN]: new TrainerNameConfig(TrainerType.POKEFAN, "Poké_Fan"),
[TrainerType.PRESCHOOLER]: new TrainerNameConfig(TrainerType.PRESCHOOLER),
[TrainerType.PSYCHIC]: new TrainerNameConfig(TrainerType.PSYCHIC),
[TrainerType.RANGER]: new TrainerNameConfig(TrainerType.RANGER),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, 'Gentleman').hasGenderVariant('Madame'),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, 'Rich_Boy').hasGenderVariant('Lady'),
[TrainerType.RICH]: new TrainerNameConfig(TrainerType.RICH, "Gentleman").hasGenderVariant("Madame"),
[TrainerType.RICH_KID]: new TrainerNameConfig(TrainerType.RICH_KID, "Rich_Boy").hasGenderVariant("Lady"),
[TrainerType.ROUGHNECK]: new TrainerNameConfig(TrainerType.ROUGHNECK),
[TrainerType.SCIENTIST]: new TrainerNameConfig(TrainerType.SCIENTIST),
[TrainerType.SMASHER]: new TrainerNameConfig(TrainerType.SMASHER),
[TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, 'Worker'),
[TrainerType.SNOW_WORKER]: new TrainerNameConfig(TrainerType.SNOW_WORKER, "Worker"),
[TrainerType.STRIKER]: new TrainerNameConfig(TrainerType.STRIKER),
[TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, 'School_Kid'),
[TrainerType.SCHOOL_KID]: new TrainerNameConfig(TrainerType.SCHOOL_KID, "School_Kid"),
[TrainerType.SWIMMER]: new TrainerNameConfig(TrainerType.SWIMMER),
[TrainerType.TWINS]: new TrainerNameConfig(TrainerType.TWINS),
[TrainerType.VETERAN]: new TrainerNameConfig(TrainerType.VETERAN),
[TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant('Waitress'),
[TrainerType.WAITER]: new TrainerNameConfig(TrainerType.WAITER).hasGenderVariant("Waitress"),
[TrainerType.WORKER]: new TrainerNameConfig(TrainerType.WORKER),
[TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant('Lass')
[TrainerType.YOUNGSTER]: new TrainerNameConfig(TrainerType.YOUNGSTER).hasGenderVariant("Lass")
};
export const trainerNamePools = {
[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.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.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.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.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.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.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.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.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.HOOLIGANS]: ["Jim & Cas","Rob & Sal"],
[TrainerType.HOOPSTER]: ["Bobby","John","Lamarcus","Derrick","Nicolas"],
[TrainerType.INFIELDER]: ["Alex","Connor","Todd"],
[TrainerType.JANITOR]: ["Caleb","Geoff","Brady","Felix","Orville","Melvin","Shawn"],
[TrainerType.LINEBACKER]: ["Bob","Dan","Jonah"],
[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.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.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.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.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.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.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.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.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.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.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.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.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"],
[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.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.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.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.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.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.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.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.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.HOOLIGANS]: ["Jim & Cas","Rob & Sal"],
[TrainerType.HOOPSTER]: ["Bobby","John","Lamarcus","Derrick","Nicolas"],
[TrainerType.INFIELDER]: ["Alex","Connor","Todd"],
[TrainerType.JANITOR]: ["Caleb","Geoff","Brady","Felix","Orville","Melvin","Shawn"],
[TrainerType.LINEBACKER]: ["Bob","Dan","Jonah"],
[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.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.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.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.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.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.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.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.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.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.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.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.HEX_MANIAC]: ["Kindra","Patricia","Tammy","Tasha","Valerie","Alaina","Kathleen","Leah","Makie","Sylvia","Anina","Arachna","Carrie","Desdemona","Josette","Luna","Melanie","Osanna","Raziah"],
};
// function used in a commented code
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNames: Set<string>, femaleTrainerNames: Set<string>, forceFemale: boolean = false) {
return new Promise<void>(resolve => {
fetch(`https://bulbapedia.bulbagarden.net/wiki/${url}_(Trainer_class)`)
.then(response => response.text())
.then(html => {
console.log(url);
const htmlDoc = parser.parseFromString(html, 'text/html');
const trainerListHeader = htmlDoc.querySelector('#Trainer_list').parentElement;
const htmlDoc = parser.parseFromString(html, "text/html");
const trainerListHeader = htmlDoc.querySelector("#Trainer_list").parentElement;
const elements = [...trainerListHeader.parentElement.childNodes];
const startChildIndex = elements.indexOf(trainerListHeader);
const endChildIndex = elements.findIndex(h => h.nodeName === 'H2' && elements.indexOf(h) > startChildIndex);
const endChildIndex = elements.findIndex(h => h.nodeName === "H2" && elements.indexOf(h) > startChildIndex);
const tables = elements.filter(t => {
if (t.nodeName !== 'TABLE' || t['className'] !== 'expandable')
if (t.nodeName !== "TABLE" || t["className"] !== "expandable") {
return false;
}
const childIndex = elements.indexOf(t);
return childIndex > startChildIndex && childIndex < endChildIndex;
}).map(t => t as Element);
console.log(url, tables)
for (let table of tables) {
const trainerRows = [...table.querySelectorAll('tr:not(:first-child)')].filter(r => r.children.length === 9);
for (let row of trainerRows) {
console.log(url, tables);
for (const table of tables) {
const trainerRows = [...table.querySelectorAll("tr:not(:first-child)")].filter(r => r.children.length === 9);
for (const row of trainerRows) {
const nameCell = row.firstElementChild;
const content = nameCell.innerHTML;
if (content.indexOf(' <a ') > -1) {
if (content.indexOf(" <a ") > -1) {
const female = /♀/.test(content);
if (url === 'Twins')
console.log(content)
if (url === "Twins") {
console.log(content);
}
const nameMatch = />([a-z]+(?: &amp; [a-z]+)?)<\/a>/i.exec(content);
if (nameMatch)
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace('&amp;', '&'));
if (nameMatch) {
(female || forceFemale ? femaleTrainerNames : trainerNames).add(nameMatch[1].replace("&amp;", "&"));
}
}
}
}
resolve();
});
});
});
}
/*export function scrapeTrainerNames() {
@ -190,4 +197,4 @@ function fetchAndPopulateTrainerNames(url: string, parser: DOMParser, trainerNam
output += `\n};`;
console.log(output);
});
}*/
}*/

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 {
switch (variant) {
case 0:
return 0xf8c020;
case 1:
return 0x20f8f0;
case 2:
return 0xe81048;
case 0:
return 0xf8c020;
case 1:
return 0x20f8f0;
case 2:
return 0xe81048;
}
}
}

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
export enum UiTheme {
DEFAULT,
LEGACY
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import Phaser, {Time} from "phaser";
import * as Utils from "./utils";
import {initTouchControls} from './touch-controls';
import {initTouchControls} from "./touch-controls";
import pad_generic from "./configs/pad_generic";
import pad_unlicensedSNES from "./configs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/pad_xbox360";
@ -46,19 +46,19 @@ const repeatInputDelayMillis = 250;
* providing a unified interface for all input-related interactions.
*/
export class InputsController {
private buttonKeys: Phaser.Input.Keyboard.Key[][];
private gamepads: Array<string> = new Array();
private scene: Phaser.Scene;
private buttonKeys: Phaser.Input.Keyboard.Key[][];
private gamepads: Array<string> = new Array();
private scene: Phaser.Scene;
private buttonLock: Button;
private buttonLock2: Button;
private interactions: Map<Button, Map<string, boolean>> = new Map();
private time: Time;
private player: Map<String, GamepadMapping> = new Map();
private buttonLock: Button;
private buttonLock2: Button;
private interactions: Map<Button, Map<string, boolean>> = new Map();
private time: Time;
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.
*
* @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.
* It concludes by calling the `init` method to complete the setup.
*/
constructor(scene: Phaser.Scene) {
this.scene = scene;
this.time = this.scene.time;
this.buttonKeys = [];
constructor(scene: Phaser.Scene) {
this.scene = scene;
this.time = this.scene.time;
this.buttonKeys = [];
for (const b of Utils.getEnumValues(Button)) {
this.interactions[b] = {
pressTime: false,
isPressed: false,
source: null,
}
}
// We don't want the menu key to be repeated
delete this.interactions[Button.MENU];
delete this.interactions[Button.STATS];
this.init();
for (const b of Utils.getEnumValues(Button)) {
this.interactions[b] = {
pressTime: false,
isPressed: false,
source: null,
};
}
// 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.
*
* @remarks
@ -95,46 +95,46 @@ export class InputsController {
* 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.
*/
init(): void {
this.events = new Phaser.Events.EventEmitter();
this.scene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus()
})
init(): void {
this.events = new Phaser.Events.EventEmitter();
this.scene.game.events.on(Phaser.Core.Events.BLUR, () => {
this.loseFocus();
});
if (typeof this.scene.input.gamepad !== 'undefined') {
this.scene.input.gamepad.on('connected', function (thisGamepad) {
this.refreshGamepads();
this.setupGamepad(thisGamepad);
}, this);
if (typeof this.scene.input.gamepad !== "undefined") {
this.scene.input.gamepad.on("connected", function (thisGamepad) {
this.refreshGamepads();
this.setupGamepad(thisGamepad);
}, this);
// Check to see if the gamepad has already been setup by the browser
this.scene.input.gamepad.refreshPads();
if (this.scene.input.gamepad.total) {
this.refreshGamepads();
for (const thisGamepad of this.gamepads) {
this.scene.input.gamepad.emit('connected', thisGamepad);
}
}
this.scene.input.gamepad.on('down', this.gamepadButtonDown, this);
this.scene.input.gamepad.on('up', this.gamepadButtonUp, this);
// Check to see if the gamepad has already been setup by the browser
this.scene.input.gamepad.refreshPads();
if (this.scene.input.gamepad.total) {
this.refreshGamepads();
for (const thisGamepad of this.gamepads) {
this.scene.input.gamepad.emit("connected", thisGamepad);
}
}
// Keyboard
this.setupKeyboardControls();
this.scene.input.gamepad.on("down", this.gamepadButtonDown, this);
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.
*
* @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.
*/
loseFocus(): void {
this.deactivatePressedKey();
}
loseFocus(): void {
this.deactivatePressedKey();
}
/**
/**
* Enables or disables support for gamepad input.
*
* @param value - A boolean indicating whether gamepad support should be enabled (true) or disabled (false).
@ -142,17 +142,17 @@ export class InputsController {
* @remarks
* 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 {
if (value) {
this.gamepadSupport = true;
} else {
this.gamepadSupport = false;
// if we disable the gamepad, we want to release every key pressed
this.deactivatePressedKey();
}
setGamepadSupport(value: boolean): void {
if (value) {
this.gamepadSupport = true;
} else {
this.gamepadSupport = false;
// if we disable the gamepad, we want to release every key pressed
this.deactivatePressedKey();
}
}
/**
/**
* Updates the interaction handling by processing input states.
* 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,
* preventing potential infinite loops by removing the last processed movement time for the button.
*/
update(): void {
for (const b of Utils.getEnumValues(Button).reverse()) {
if (
this.interactions.hasOwnProperty(b) &&
update(): void {
for (const b of Utils.getEnumValues(Button).reverse()) {
if (
this.interactions.hasOwnProperty(b) &&
this.repeatInputDurationJustPassed(b) &&
this.interactions[b].isPressed
) {
// Prevents repeating button interactions when gamepad support is disabled.
if (!this.gamepadSupport && this.interactions[b].source === 'gamepad') {
// Deletes the last interaction for a button if gamepad is disabled.
this.delLastProcessedMovementTime(b);
return;
}
// Emits an event for the button press.
this.events.emit('input_down', {
controller_type: this.interactions[b].source,
button: b,
});
this.setLastProcessedMovementTime(b, this.interactions[b].source);
}
) {
// Prevents repeating button interactions when gamepad support is disabled.
if (!this.gamepadSupport && this.interactions[b].source === "gamepad") {
// Deletes the last interaction for a button if gamepad is disabled.
this.delLastProcessedMovementTime(b);
return;
}
// Emits an event for the button press.
this.events.emit("input_down", {
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.
*
* @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
* that the gamepad controls are correctly mapped to in-game actions.
*/
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
let gamepadID = thisGamepad.id.toLowerCase();
const mappedPad = this.mapGamepad(gamepadID);
this.player['mapping'] = mappedPad.gamepadMapping;
}
setupGamepad(thisGamepad: Phaser.Input.Gamepad.Gamepad): void {
const gamepadID = thisGamepad.id.toLowerCase();
const mappedPad = this.mapGamepad(gamepadID);
this.player["mapping"] = mappedPad.gamepadMapping;
}
/**
/**
* Refreshes and re-indexes the list of connected gamepads.
*
* @remarks
@ -212,18 +212,18 @@ export class InputsController {
* 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.
*/
refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason.
this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) {
return el != null;
});
refreshGamepads(): void {
// Sometimes, gamepads are undefined. For some reason.
this.gamepads = this.scene.input.gamepad.gamepads.filter(function (el) {
return el !== null;
});
for (const [index, thisGamepad] of this.gamepads.entries()) {
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
}
for (const [index, thisGamepad] of this.gamepads.entries()) {
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
}
}
/**
/**
* 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.
@ -234,31 +234,33 @@ export class InputsController {
* The mapping includes directional controls, action buttons, and system commands among others,
* adjusted for any custom settings such as swapped action buttons.
*/
getActionGamepadMapping(): ActionGamepadMapping {
const gamepadMapping = {};
if (!this.player?.mapping) return gamepadMapping;
gamepadMapping[this.player.mapping.LC_N] = Button.UP;
gamepadMapping[this.player.mapping.LC_S] = Button.DOWN;
gamepadMapping[this.player.mapping.LC_W] = Button.LEFT;
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;
getActionGamepadMapping(): ActionGamepadMapping {
const gamepadMapping = {};
if (!this.player?.mapping) {
return gamepadMapping;
}
gamepadMapping[this.player.mapping.LC_N] = Button.UP;
gamepadMapping[this.player.mapping.LC_S] = Button.DOWN;
gamepadMapping[this.player.mapping.LC_W] = Button.LEFT;
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.
*
* @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.
* - If mapped, emits an 'input_down' event with the controller type and button action, and updates the interaction of this button.
*/
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return;
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');
}
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) {
return;
}
const actionMapping = this.getActionGamepadMapping();
const buttonDown = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonDown !== undefined) {
this.events.emit("input_down", {
controller_type: "gamepad",
button: buttonDown,
});
this.setLastProcessedMovementTime(buttonDown, "gamepad");
}
}
/**
/**
* 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.
@ -297,20 +301,22 @@ export class InputsController {
* - 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.
*/
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) return;
const actionMapping = this.getActionGamepadMapping();
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) {
this.events.emit('input_up', {
controller_type: 'gamepad',
button: buttonUp,
});
this.delLastProcessedMovementTime(buttonUp);
}
gamepadButtonUp(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
if (!this.gamepadSupport) {
return;
}
const actionMapping = this.getActionGamepadMapping();
const buttonUp = actionMapping.hasOwnProperty(button.index) && actionMapping[button.index];
if (buttonUp !== undefined) {
this.events.emit("input_up", {
controller_type: "gamepad",
button: buttonUp,
});
this.delLastProcessedMovementTime(buttonUp);
}
}
/**
/**
* Configures keyboard controls for the game, mapping physical keys to game actions.
*
* @remarks
@ -328,43 +334,44 @@ export class InputsController {
* 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.
*/
setupKeyboardControls(): void {
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
const keyConfig = {
[Button.UP]: [keyCodes.UP, keyCodes.W],
[Button.DOWN]: [keyCodes.DOWN, keyCodes.S],
[Button.LEFT]: [keyCodes.LEFT, keyCodes.A],
[Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D],
[Button.SUBMIT]: [keyCodes.ENTER],
[Button.ACTION]: [keyCodes.SPACE, keyCodes.Z],
[Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X],
[Button.MENU]: [keyCodes.ESC, keyCodes.M],
[Button.STATS]: [keyCodes.SHIFT, keyCodes.C],
[Button.CYCLE_SHINY]: [keyCodes.R],
[Button.CYCLE_FORM]: [keyCodes.F],
[Button.CYCLE_GENDER]: [keyCodes.G],
[Button.CYCLE_ABILITY]: [keyCodes.E],
[Button.CYCLE_NATURE]: [keyCodes.N],
[Button.CYCLE_VARIANT]: [keyCodes.V],
[Button.SPEED_UP]: [keyCodes.PLUS],
[Button.SLOW_DOWN]: [keyCodes.MINUS]
};
const mobileKeyConfig = {};
for (const b of Utils.getEnumValues(Button)) {
const keys: Phaser.Input.Keyboard.Key[] = [];
if (keyConfig.hasOwnProperty(b)) {
for (let k of keyConfig[b])
keys.push(this.scene.input.keyboard.addKey(k, false));
mobileKeyConfig[Button[b]] = keys[0];
}
this.buttonKeys[b] = keys;
setupKeyboardControls(): void {
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
const keyConfig = {
[Button.UP]: [keyCodes.UP, keyCodes.W],
[Button.DOWN]: [keyCodes.DOWN, keyCodes.S],
[Button.LEFT]: [keyCodes.LEFT, keyCodes.A],
[Button.RIGHT]: [keyCodes.RIGHT, keyCodes.D],
[Button.SUBMIT]: [keyCodes.ENTER],
[Button.ACTION]: [keyCodes.SPACE, keyCodes.Z],
[Button.CANCEL]: [keyCodes.BACKSPACE, keyCodes.X],
[Button.MENU]: [keyCodes.ESC, keyCodes.M],
[Button.STATS]: [keyCodes.SHIFT, keyCodes.C],
[Button.CYCLE_SHINY]: [keyCodes.R],
[Button.CYCLE_FORM]: [keyCodes.F],
[Button.CYCLE_GENDER]: [keyCodes.G],
[Button.CYCLE_ABILITY]: [keyCodes.E],
[Button.CYCLE_NATURE]: [keyCodes.N],
[Button.CYCLE_VARIANT]: [keyCodes.V],
[Button.SPEED_UP]: [keyCodes.PLUS],
[Button.SLOW_DOWN]: [keyCodes.MINUS]
};
const mobileKeyConfig = {};
for (const b of Utils.getEnumValues(Button)) {
const keys: Phaser.Input.Keyboard.Key[] = [];
if (keyConfig.hasOwnProperty(b)) {
for (const k of keyConfig[b]) {
keys.push(this.scene.input.keyboard.addKey(k, false));
}
initTouchControls(mobileKeyConfig);
this.listenInputKeyboard();
mobileKeyConfig[Button[b]] = keys[0];
}
this.buttonKeys[b] = keys;
}
/**
initTouchControls(mobileKeyConfig);
this.listenInputKeyboard();
}
/**
* Sets up event listeners for keyboard inputs on all registered keys.
*
* @remarks
@ -382,28 +389,28 @@ export class InputsController {
* 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.
*/
listenInputKeyboard(): void {
this.buttonKeys.forEach((row, index) => {
for (const key of row) {
key.on('down', () => {
this.events.emit('input_down', {
controller_type: 'keyboard',
button: index,
});
this.setLastProcessedMovementTime(index, 'keyboard');
});
key.on('up', () => {
this.events.emit('input_up', {
controller_type: 'keyboard',
button: index,
});
this.delLastProcessedMovementTime(index);
});
}
listenInputKeyboard(): void {
this.buttonKeys.forEach((row, index) => {
for (const key of row) {
key.on("down", () => {
this.events.emit("input_down", {
controller_type: "keyboard",
button: index,
});
this.setLastProcessedMovementTime(index, "keyboard");
});
}
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.
*
* @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 no specific identifiers are recognized, a generic gamepad configuration is returned.
*/
mapGamepad(id: string): GamepadConfig {
id = id.toLowerCase();
mapGamepad(id: string): GamepadConfig {
id = id.toLowerCase();
if (id.includes('081f') && id.includes('e401')) {
return pad_unlicensedSNES;
} else if (id.includes('xbox') && id.includes('360')) {
return pad_xbox360;
} else if (id.includes('054c')) {
return pad_dualshock;
}
return pad_generic;
if (id.includes("081f") && id.includes("e401")) {
return pad_unlicensedSNES;
} else if (id.includes("xbox") && id.includes("360")) {
return pad_xbox360;
} else if (id.includes("054c")) {
return pad_dualshock;
}
/**
return pad_generic;
}
/**
* repeatInputDurationJustPassed returns true if @param button has been held down long
* 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.
*/
repeatInputDurationJustPassed(button: Button): boolean {
if (!this.isButtonLocked(button)) return false;
if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) {
return true;
}
repeatInputDurationJustPassed(button: Button): boolean {
if (!this.isButtonLocked(button)) {
return false;
}
if (this.time.now - this.interactions[button].pressTime >= repeatInputDelayMillis) {
return true;
}
}
/**
/**
* This method updates the interaction state to reflect that the button is pressed.
*
* @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.
*/
setLastProcessedMovementTime(button: Button, source: String = 'keyboard'): void {
if (!this.interactions.hasOwnProperty(button)) return;
this.setButtonLock(button);
this.interactions[button].pressTime = this.time.now;
this.interactions[button].isPressed = true;
this.interactions[button].source = source;
setLastProcessedMovementTime(button: Button, source: String = "keyboard"): void {
if (!this.interactions.hasOwnProperty(button)) {
return;
}
this.setButtonLock(button);
this.interactions[button].pressTime = this.time.now;
this.interactions[button].isPressed = true;
this.interactions[button].source = source;
}
/**
/**
* Clears the last interaction for a specified button.
*
* @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.
*/
delLastProcessedMovementTime(button: Button): void {
if (!this.interactions.hasOwnProperty(button)) return;
this.releaseButtonLock(button);
this.interactions[button].pressTime = null;
this.interactions[button].isPressed = false;
this.interactions[button].source = null;
delLastProcessedMovementTime(button: Button): void {
if (!this.interactions.hasOwnProperty(button)) {
return;
}
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.
*
* @remarks
@ -505,19 +518,19 @@ export class InputsController {
*
* This method is typically called when needing to ensure that all inputs are neutralized.
*/
deactivatePressedKey(): void {
this.releaseButtonLock(this.buttonLock);
this.releaseButtonLock(this.buttonLock2);
for (const b of Utils.getEnumValues(Button)) {
if (this.interactions.hasOwnProperty(b)) {
this.interactions[b].pressTime = null;
this.interactions[b].isPressed = false;
this.interactions[b].source = null;
}
}
deactivatePressedKey(): void {
this.releaseButtonLock(this.buttonLock);
this.releaseButtonLock(this.buttonLock2);
for (const b of Utils.getEnumValues(Button)) {
if (this.interactions.hasOwnProperty(b)) {
this.interactions[b].pressTime = null;
this.interactions[b].isPressed = false;
this.interactions[b].source = null;
}
}
}
/**
/**
* Checks if a specific button is currently locked.
*
* @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.
* It checks against two separate lock variables, allowing for up to two buttons to be locked simultaneously.
*/
isButtonLocked(button: Button): boolean {
return (this.buttonLock === button || this.buttonLock2 === button);
}
isButtonLocked(button: Button): boolean {
return (this.buttonLock === button || this.buttonLock2 === button);
}
/**
/**
* Sets a lock on a given button if it is not already locked.
*
* @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.
* This mechanism allows for up to two buttons to be locked at the same time.
*/
setButtonLock(button: Button): void {
if (this.buttonLock === button || this.buttonLock2 === button) return;
if (this.buttonLock === button) this.buttonLock2 = button;
else if (this.buttonLock2 === button) this.buttonLock = button;
else if (!!this.buttonLock) this.buttonLock2 = button;
else this.buttonLock = button;
setButtonLock(button: Button): void {
if (this.buttonLock === button || this.buttonLock2 === button) {
return;
}
if (this.buttonLock === button) {
this.buttonLock2 = button;
} else if (this.buttonLock2 === button) {
this.buttonLock = button;
} else if (!!this.buttonLock) {
this.buttonLock2 = button;
} else {
this.buttonLock = button;
}
}
/**
/**
* Releases a lock on a specific button, allowing it to be processed again.
*
* @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.
* This action frees the button to be processed again, ensuring it can respond to new inputs.
*/
releaseButtonLock(button: Button): void {
if (this.buttonLock === button) this.buttonLock = null;
else if (this.buttonLock2 === button) this.buttonLock2 = null;
releaseButtonLock(button: Button): void {
if (this.buttonLock === button) {
this.buttonLock = null;
} else if (this.buttonLock2 === button) {
this.buttonLock2 = null;
}
}
}
}

View File

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

View File

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

View File

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

View File

@ -45,4 +45,4 @@ export const berry: BerryTranslationEntries = {
name: "Jonagobeere",
effect: "Stellt 10 AP für eine Attacke wieder her, wenn deren AP auf 0 fallen"
},
} as const;
} as const;

View File

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

View File

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

View File

@ -18,4 +18,4 @@ export const egg: SimpleTranslationEntries = {
"tooManyEggs": "Du hast schon zu viele Eier!",
"pull": "Pull",
"pulls": "Pulls"
} as const;
} as const;

View File

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

View File

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

View File

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

View File

@ -6,46 +6,46 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc.
*/
export const menu: SimpleTranslationEntries = {
"cancel": "Abbrechen",
"continue": "Fortfahren",
"dailyRun": "Täglicher Run (Beta)",
"loadGame": "Spiel laden",
"newGame": "Neues Spiel",
"selectGameMode": "Wähle einen Spielmodus",
"logInOrCreateAccount": "Melde dich an oder erstelle einen Account zum starten. Keine Email nötig!",
"username": "Benutzername",
"password": "Passwort",
"login": "Anmelden",
"register": "Registrieren",
"emptyUsername": "Benutzername darf nicht leer sein",
"invalidLoginUsername": "Der eingegebene Benutzername ist ungültig",
"invalidRegisterUsername": "Benutzername darf nur Buchstaben, Zahlen oder Unterstriche enthalten",
"invalidLoginPassword": "Das eingegebene Passwort ist ungültig",
"invalidRegisterPassword": "Passwort muss 6 Zeichen oder länger sein",
"usernameAlreadyUsed": "Der eingegebene Benutzername wird bereits verwendet",
"accountNonExistent": "Der eingegebene Benutzer existiert nicht",
"unmatchingPassword": "Das eingegebene Passwort stimmt nicht überein",
"passwordNotMatchingConfirmPassword": "Passwort muss mit Bestätigungspasswort übereinstimmen",
"confirmPassword": "Bestätige Passwort",
"registrationAgeWarning": "Mit der Registrierung bestätigen Sie, dass Sie 13 Jahre oder älter sind.",
"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.",
"sessionSuccess": "Sitzung erfolgreich geladen.",
"failedToLoadSession": "Ihre Sitzungsdaten konnten nicht geladen werden.\nSie könnten beschädigt sein.",
"boyOrGirl": "Bist du ein Junge oder ein Mädchen?",
"boy": "Junge",
"girl": "Mädchen",
"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.
"pauseEvolutionsQuestion": "Die Entwicklung von {{pokemonName}} vorübergehend pausieren?\nEntwicklungen können im Gruppenmenü wieder aktiviert werden.",
"evolutionsPaused": "Entwicklung von {{pokemonName}} pausiert.",
"evolutionDone": "Glückwunsch!\nDein {{pokemonName}} entwickelte sich zu {{evolvedPokemonName}}!",
"dailyRankings": "Tägliche Rangliste",
"weeklyRankings": "Wöchentliche Rangliste",
"noRankings": "Keine Rangliste",
"loading": "Lade…",
"playersOnline": "Spieler Online",
"empty":"Leer",
"yes":"Ja",
"no":"Nein",
"cancel": "Abbrechen",
"continue": "Fortfahren",
"dailyRun": "Täglicher Run (Beta)",
"loadGame": "Spiel laden",
"newGame": "Neues Spiel",
"selectGameMode": "Wähle einen Spielmodus",
"logInOrCreateAccount": "Melde dich an oder erstelle einen Account zum starten. Keine Email nötig!",
"username": "Benutzername",
"password": "Passwort",
"login": "Anmelden",
"register": "Registrieren",
"emptyUsername": "Benutzername darf nicht leer sein",
"invalidLoginUsername": "Der eingegebene Benutzername ist ungültig",
"invalidRegisterUsername": "Benutzername darf nur Buchstaben, Zahlen oder Unterstriche enthalten",
"invalidLoginPassword": "Das eingegebene Passwort ist ungültig",
"invalidRegisterPassword": "Passwort muss 6 Zeichen oder länger sein",
"usernameAlreadyUsed": "Der eingegebene Benutzername wird bereits verwendet",
"accountNonExistent": "Der eingegebene Benutzer existiert nicht",
"unmatchingPassword": "Das eingegebene Passwort stimmt nicht überein",
"passwordNotMatchingConfirmPassword": "Passwort muss mit Bestätigungspasswort übereinstimmen",
"confirmPassword": "Bestätige Passwort",
"registrationAgeWarning": "Mit der Registrierung bestätigen Sie, dass Sie 13 Jahre oder älter sind.",
"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.",
"sessionSuccess": "Sitzung erfolgreich geladen.",
"failedToLoadSession": "Ihre Sitzungsdaten konnten nicht geladen werden.\nSie könnten beschädigt sein.",
"boyOrGirl": "Bist du ein Junge oder ein Mädchen?",
"boy": "Junge",
"girl": "Mädchen",
"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.
"pauseEvolutionsQuestion": "Die Entwicklung von {{pokemonName}} vorübergehend pausieren?\nEntwicklungen können im Gruppenmenü wieder aktiviert werden.",
"evolutionsPaused": "Entwicklung von {{pokemonName}} pausiert.",
"evolutionDone": "Glückwunsch!\nDein {{pokemonName}} entwickelte sich zu {{evolvedPokemonName}}!",
"dailyRankings": "Tägliche Rangliste",
"weeklyRankings": "Wöchentliche Rangliste",
"noRankings": "Keine Rangliste",
"loading": "Lade…",
"playersOnline": "Spieler Online",
"empty":"Leer",
"yes":"Ja",
"no":"Nein",
} 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_HEAL": { name: "Wiederherstellungsmarke", description: "Heilt 2% der maximalen KP pro Runde" },
"ENEMY_ATTACK_POISON_CHANCE": { name: "Giftmarke" },
"ENEMY_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" },
"ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" },
"ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" },
"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_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_ATTACK_PARALYZE_CHANCE": { "name": "Lähmungsmarke" },
"ENEMY_ATTACK_SLEEP_CHANCE": { "name": "Schlafmarke" },
"ENEMY_ATTACK_FREEZE_CHANCE": { "name": "Gefriermarke" },
"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_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" },
},
TempBattleStatBoosterItem: {
@ -385,4 +385,4 @@ export const modifierType: ModifierTypeTranslationEntries = {
"CHILL_DRIVE": "Gefriermodul",
"DOUSE_DRIVE": "Aquamodul",
},
} as const;
} as const;

View File

@ -3809,4 +3809,4 @@ export const move: MoveTranslationEntries = {
name: "Giftkettung",
effect: "Der Anwender umwickelt das Ziel mit einer Kette aus Toxinen, die in dessen Körper eindringen und ihm schaden. Das Ziel wird eventuell schwer vergiftet."
}
} as const;
} as const;

View File

@ -26,4 +26,4 @@ export const nature: SimpleTranslationEntries = {
"Sassy": "Forsch",
"Careful": "Sacht",
"Quirky": "Kauzig"
} as const;
} as const;

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -6,39 +6,39 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc.
*/
export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam": "Mit diesen Pokémon losziehen?",
"gen1": "I",
"gen2": "II",
"gen3": "III",
"gen4": "IV",
"gen5": "V",
"gen6": "VI",
"gen7": "VII",
"gen8": "VIII",
"gen9": "IX",
"growthRate": "Wachstum:",
"ability": "Fähgkeit:",
"passive": "Passiv:",
"nature": "Wesen:",
"eggMoves": "Ei-Attacken",
"start": "Start",
"addToParty": "Zum Team hinzufügen",
"toggleIVs": "DVs anzeigen/verbergen",
"manageMoves": "Attacken ändern",
"useCandies": "Bonbons verwenden",
"selectMoveSwapOut": "Wähle die zu ersetzende Attacke.",
"selectMoveSwapWith": "Wähle die gewünschte Attacke.",
"unlockPassive": "Passiv-Skill freischalten",
"reduceCost": "Preis reduzieren",
"cycleShiny": "R: Schillernd Ja/Nein",
"cycleForm": "F: Form ändern",
"cycleGender": "G: Geschlecht ändern",
"cycleAbility": "E: Fähigkeit ändern",
"cycleNature": "N: Wesen Ändern",
"cycleVariant": "V: Seltenheit ändern",
"enablePassive": "Passiv-Skill aktivieren",
"disablePassive": "Passiv-Skill deaktivieren",
"locked": "Gesperrt",
"disabled": "Deaktiviert",
"uncaught": "Ungefangen"
}
"confirmStartTeam": "Mit diesen Pokémon losziehen?",
"gen1": "I",
"gen2": "II",
"gen3": "III",
"gen4": "IV",
"gen5": "V",
"gen6": "VI",
"gen7": "VII",
"gen8": "VIII",
"gen9": "IX",
"growthRate": "Wachstum:",
"ability": "Fähgkeit:",
"passive": "Passiv:",
"nature": "Wesen:",
"eggMoves": "Ei-Attacken",
"start": "Start",
"addToParty": "Zum Team hinzufügen",
"toggleIVs": "DVs anzeigen/verbergen",
"manageMoves": "Attacken ändern",
"useCandies": "Bonbons verwenden",
"selectMoveSwapOut": "Wähle die zu ersetzende Attacke.",
"selectMoveSwapWith": "Wähle die gewünschte Attacke.",
"unlockPassive": "Passiv-Skill freischalten",
"reduceCost": "Preis reduzieren",
"cycleShiny": "R: Schillernd Ja/Nein",
"cycleForm": "F: Form ändern",
"cycleGender": "G: Geschlecht ändern",
"cycleAbility": "E: Fähigkeit ändern",
"cycleNature": "N: Wesen Ändern",
"cycleVariant": "V: Seltenheit ändern",
"enablePassive": "Passiv-Skill aktivieren",
"disablePassive": "Passiv-Skill deaktivieren",
"locked": "Gesperrt",
"disabled": "Deaktiviert",
"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
export const titles: SimpleTranslationEntries = {
"elite_four": "Top Vier",
"gym_leader": "Arenaleiter",
"gym_leader_female": "Arenaleiterin",
"champion": "Champion",
"rival": "Rivale",
"professor": "Professor",
"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.
"elite_four": "Top Vier",
"gym_leader": "Arenaleiter",
"gym_leader_female": "Arenaleiterin",
"champion": "Champion",
"rival": "Rivale",
"professor": "Professor",
"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.
} as const;
// Titles of trainers like "Youngster" or "Lass"
export const trainerClasses: SimpleTranslationEntries = {
"ace_trainer": "Ass-Trainer",
"ace_trainer_female": "Ass-Trainerin",
"ace_duo": "Ass-Duo",
"artist": "Künstler",
"artist_female": "Künstlerin",
"backers": "Anhänger",
"backpacker": "Backpacker",
"backpacker_female": "Backpackerin",
"backpackers": "Backpacker",
"baker": "Bäckerin",
"battle_girl": "Kämpferin",
"beauty": "Schönheit",
"beginners": "Anfänger",
"biker": "Rowdy",
"black_belt": "Schwarzgurt",
"breeder": "Pokémon Züchter",
"breeder_female": "Pokémon Züchterin",
"breeders": "Pokémon Züchter",
"clerk": "Angestellter",
"clerk_female": "Angestellte",
"colleagues": "Geschäftspartner",
"crush_kin": "Mühlensippe",
"cyclist": "Biker",
"cyclist_female": "Bikerin",
"cyclists": "Biker",
"dancer": "Tänzer",
"dancer_female": "Tänzerin",
"depot_agent": "Bahnangestellter",
"doctor": "Arzt",
"doctor_female": "Ärztin",
"fisherman": "Angler",
"fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian
"gentleman": "Gentleman",
"guitarist": "Gitarrist",
"guitarist_female": "Gitarristin",
"harlequin": "Kasper",
"hiker": "Wanderer",
"hooligans": "Rabauken",
"hoopster": "Basketballer",
"infielder": "Baseballer",
"janitor": "Hausmeister",
"lady": "Lady",
"lass": "Göre",
"linebacker": "Footballer",
"maid": "Zofe",
"madame": "Madam",
"medical_team": "Mediziner",
"musician": "Musiker",
"hex_maniac": "Hexe",
"nurse": "Pflegerin",
"nursery_aide": "Erzieherin",
"officer": "Polizist",
"parasol_lady": "Schirmdame",
"pilot": "Pilot",
"pokéfan": "Pokéfan",
"pokéfan_female": "Pokéfan",
"pokéfan_family": "Pokéfan-Pärchen",
"preschooler": "Vorschüler",
"preschooler_female": "Vorschülerin",
"preschoolers": "Vorschüler",
"psychic": "Seher",
"psychic_female": "Seherin",
"psychics": "Seher",
"pokémon_ranger": "Pokémon-Ranger",
"pokémon_ranger_female": "Pokémon-Ranger",
"pokémon_rangers": "Pokémon-Ranger",
"ranger": "Ranger",
"restaurant_staff": "Restaurant Angestellte",
"rich": "Rich",
"rich_female": "Rich",
"rich_boy": "Schnösel",
"rich_couple": "Reiches Paar",
"rich_kid": "Rich Kid",
"rich_kid_female": "Rich Kid",
"rich_kids": "Schnösel",
"roughneck": "Raufbold",
"scientist": "Forscher",
"scientist_female": "Forscherin",
"scientists": "Forscher",
"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_female": "Schneearbeiterin",
"striker": "Fußballer",
"school_kid": "Schulkind",
"school_kid_female": "Schulkind", // Same in german but different in italian
"school_kids": "Schüler",
"swimmer": "Schwimmer",
"swimmer_female": "Schwimmerin",
"swimmers": "Schwimmerpaar",
"twins": "Zwillinge",
"veteran": "Veteran",
"veteran_female": "Veteran", // same in german, different in other languages
"veteran_duo": "Veteranen",
"waiter": "Servierer",
"waitress": "Serviererin",
"worker": "Arbeiter",
"worker_female": "Arbeiterin",
"workers": "Arbeiter",
"youngster": "Knirps"
"ace_trainer": "Ass-Trainer",
"ace_trainer_female": "Ass-Trainerin",
"ace_duo": "Ass-Duo",
"artist": "Künstler",
"artist_female": "Künstlerin",
"backers": "Anhänger",
"backpacker": "Backpacker",
"backpacker_female": "Backpackerin",
"backpackers": "Backpacker",
"baker": "Bäckerin",
"battle_girl": "Kämpferin",
"beauty": "Schönheit",
"beginners": "Anfänger",
"biker": "Rowdy",
"black_belt": "Schwarzgurt",
"breeder": "Pokémon Züchter",
"breeder_female": "Pokémon Züchterin",
"breeders": "Pokémon Züchter",
"clerk": "Angestellter",
"clerk_female": "Angestellte",
"colleagues": "Geschäftspartner",
"crush_kin": "Mühlensippe",
"cyclist": "Biker",
"cyclist_female": "Bikerin",
"cyclists": "Biker",
"dancer": "Tänzer",
"dancer_female": "Tänzerin",
"depot_agent": "Bahnangestellter",
"doctor": "Arzt",
"doctor_female": "Ärztin",
"fisherman": "Angler",
"fisherman_female": "Angler", // Seems to be the same in german but exists in other languages like italian
"gentleman": "Gentleman",
"guitarist": "Gitarrist",
"guitarist_female": "Gitarristin",
"harlequin": "Kasper",
"hiker": "Wanderer",
"hooligans": "Rabauken",
"hoopster": "Basketballer",
"infielder": "Baseballer",
"janitor": "Hausmeister",
"lady": "Lady",
"lass": "Göre",
"linebacker": "Footballer",
"maid": "Zofe",
"madame": "Madam",
"medical_team": "Mediziner",
"musician": "Musiker",
"hex_maniac": "Hexe",
"nurse": "Pflegerin",
"nursery_aide": "Erzieherin",
"officer": "Polizist",
"parasol_lady": "Schirmdame",
"pilot": "Pilot",
"pokéfan": "Pokéfan",
"pokéfan_female": "Pokéfan",
"pokéfan_family": "Pokéfan-Pärchen",
"preschooler": "Vorschüler",
"preschooler_female": "Vorschülerin",
"preschoolers": "Vorschüler",
"psychic": "Seher",
"psychic_female": "Seherin",
"psychics": "Seher",
"pokémon_ranger": "Pokémon-Ranger",
"pokémon_ranger_female": "Pokémon-Ranger",
"pokémon_rangers": "Pokémon-Ranger",
"ranger": "Ranger",
"restaurant_staff": "Restaurant Angestellte",
"rich": "Rich",
"rich_female": "Rich",
"rich_boy": "Schnösel",
"rich_couple": "Reiches Paar",
"rich_kid": "Rich Kid",
"rich_kid_female": "Rich Kid",
"rich_kids": "Schnösel",
"roughneck": "Raufbold",
"scientist": "Forscher",
"scientist_female": "Forscherin",
"scientists": "Forscher",
"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_female": "Schneearbeiterin",
"striker": "Fußballer",
"school_kid": "Schulkind",
"school_kid_female": "Schulkind", // Same in german but different in italian
"school_kids": "Schüler",
"swimmer": "Schwimmer",
"swimmer_female": "Schwimmerin",
"swimmers": "Schwimmerpaar",
"twins": "Zwillinge",
"veteran": "Veteran",
"veteran_female": "Veteran", // same in german, different in other languages
"veteran_duo": "Veteranen",
"waiter": "Servierer",
"waitress": "Serviererin",
"worker": "Arbeiter",
"worker_female": "Arbeiterin",
"workers": "Arbeiter",
"youngster": "Knirps"
} as const;
// Names of special trainers like gym leaders, elite four, and the champion
export const trainerNames: SimpleTranslationEntries = {
"brock": "Rocko",
"misty": "Misty",
"lt_surge": "Major Bob",
"erika": "Erika",
"janine": "Janina",
"sabrina": "Sabrina",
"blaine": "Pyro",
"giovanni": "Giovanni",
"falkner": "Falk",
"bugsy": "Kai",
"whitney": "Bianka",
"morty": "Jens",
"chuck": "Hartwig",
"jasmine": "Jasmin",
"pryce": "Norbert",
"clair": "Sandra",
"roxanne": "Felizia",
"brawly": "Kamillo",
"wattson": "Walter",
"flannery": "Flavia",
"norman": "Norman",
"winona": "Wibke",
"tate": "Ben",
"liza": "Svenja",
"juan": "Juan",
"roark": "Veit",
"gardenia": "Silvana",
"maylene": "Hilda",
"crasher_wake": "Wellenbrecher Marinus",
"fantina": "Lamina",
"byron": "Adam",
"candice": "Frida",
"volkner": "Volkner",
"cilan": "Benny",
"chili": "Maik",
"cress": "Colin",
"cheren": "Cheren",
"lenora": "Aloe",
"roxie": "Mica",
"burgh": "Artie",
"elesa": "Kamilla",
"clay": "Turner",
"skyla": "Géraldine",
"brycen": "Sandro",
"drayden": "Lysander",
"marlon": "Benson",
"viola": "Viola",
"grant": "Lino",
"korrina": "Connie",
"ramos": "Amaro",
"clemont": "Citro",
"valerie": "Valerie",
"olympia": "Astrid",
"wulfric": "Galantho",
"milo": "Yarro",
"nessa": "Kate",
"kabu": "Kabu",
"bea": "Saida",
"allister": "Nio",
"opal": "Papella",
"bede": "Betys",
"gordie": "Mac",
"melony": "Mel",
"piers": "Nezz",
"marnie": "Mary",
"raihan": "Roy",
"katy": "Ronah",
"brassius": "Colzo",
"iono": "Enigmara",
"kofu": "Kombu",
"larry": "Aoki",
"ryme": "Etta",
"tulip": "Tulia",
"grusha": "Grusha",
"lorelei": "Lorelei",
"bruno": "Bruno",
"agatha": "Agathe",
"lance": "Siegfried",
"will": "Willi",
"koga": "Koga",
"karen": "Melanie",
"sidney": "Ulrich",
"phoebe": "Antonia",
"glacia": "Frosina",
"drake": "Dragan",
"aaron": "Herbaro",
"bertha": "Teresa",
"flint": "Ignaz",
"lucian": "Lucian",
"shauntal": "Anissa",
"marshal": "Eugen",
"grimsley": "Astor",
"caitlin": "Kattlea",
"malva": "Pachira",
"siebold": "Narcisse",
"wikstrom": "Thymelot",
"drasna": "Dracena",
"hala": "Hala",
"molayne": "Marlon",
"olivia": "Mayla",
"acerola": "Lola",
"kahili": "Kahili",
"rika": "Cay",
"poppy": "Poppy",
"hassel": "Sinius",
"crispin": "Matt",
"amarys": "Erin",
"lacey": "Tara",
"drayton": "Levy",
"blue": "Blau",
"red": "Rot",
"steven": "Troy",
"wallace": "Wassili",
"cynthia": "Cynthia",
"alder": "Lauro",
"iris": "Lilia",
"diantha": "Diantha",
"hau": "Tali",
"geeta": "Sagaria",
"nemona": "Nemila",
"kieran": "Jo",
"leon": "Delion",
"rival": "Finn",
"rival_female": "Ivy",
} as const;
"brock": "Rocko",
"misty": "Misty",
"lt_surge": "Major Bob",
"erika": "Erika",
"janine": "Janina",
"sabrina": "Sabrina",
"blaine": "Pyro",
"giovanni": "Giovanni",
"falkner": "Falk",
"bugsy": "Kai",
"whitney": "Bianka",
"morty": "Jens",
"chuck": "Hartwig",
"jasmine": "Jasmin",
"pryce": "Norbert",
"clair": "Sandra",
"roxanne": "Felizia",
"brawly": "Kamillo",
"wattson": "Walter",
"flannery": "Flavia",
"norman": "Norman",
"winona": "Wibke",
"tate": "Ben",
"liza": "Svenja",
"juan": "Juan",
"roark": "Veit",
"gardenia": "Silvana",
"maylene": "Hilda",
"crasher_wake": "Wellenbrecher Marinus",
"fantina": "Lamina",
"byron": "Adam",
"candice": "Frida",
"volkner": "Volkner",
"cilan": "Benny",
"chili": "Maik",
"cress": "Colin",
"cheren": "Cheren",
"lenora": "Aloe",
"roxie": "Mica",
"burgh": "Artie",
"elesa": "Kamilla",
"clay": "Turner",
"skyla": "Géraldine",
"brycen": "Sandro",
"drayden": "Lysander",
"marlon": "Benson",
"viola": "Viola",
"grant": "Lino",
"korrina": "Connie",
"ramos": "Amaro",
"clemont": "Citro",
"valerie": "Valerie",
"olympia": "Astrid",
"wulfric": "Galantho",
"milo": "Yarro",
"nessa": "Kate",
"kabu": "Kabu",
"bea": "Saida",
"allister": "Nio",
"opal": "Papella",
"bede": "Betys",
"gordie": "Mac",
"melony": "Mel",
"piers": "Nezz",
"marnie": "Mary",
"raihan": "Roy",
"katy": "Ronah",
"brassius": "Colzo",
"iono": "Enigmara",
"kofu": "Kombu",
"larry": "Aoki",
"ryme": "Etta",
"tulip": "Tulia",
"grusha": "Grusha",
"lorelei": "Lorelei",
"bruno": "Bruno",
"agatha": "Agathe",
"lance": "Siegfried",
"will": "Willi",
"koga": "Koga",
"karen": "Melanie",
"sidney": "Ulrich",
"phoebe": "Antonia",
"glacia": "Frosina",
"drake": "Dragan",
"aaron": "Herbaro",
"bertha": "Teresa",
"flint": "Ignaz",
"lucian": "Lucian",
"shauntal": "Anissa",
"marshal": "Eugen",
"grimsley": "Astor",
"caitlin": "Kattlea",
"malva": "Pachira",
"siebold": "Narcisse",
"wikstrom": "Thymelot",
"drasna": "Dracena",
"hala": "Hala",
"molayne": "Marlon",
"olivia": "Mayla",
"acerola": "Lola",
"kahili": "Kahili",
"rika": "Cay",
"poppy": "Poppy",
"hassel": "Sinius",
"crispin": "Matt",
"amarys": "Erin",
"lacey": "Tara",
"drayton": "Levy",
"blue": "Blau",
"red": "Rot",
"steven": "Troy",
"wallace": "Wassili",
"cynthia": "Cynthia",
"alder": "Lauro",
"iris": "Lilia",
"diantha": "Diantha",
"hau": "Tali",
"geeta": "Sagaria",
"nemona": "Nemila",
"kieran": "Jo",
"leon": "Delion",
"rival": "Finn",
"rival_female": "Ivy",
} as const;

View File

@ -1,34 +1,34 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
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.
$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.
$Für Fehlerberichte nutze bitte den PokéRogue Discord-Server.
$Sollte das Spiel langsam laufen, überprüfe, ob in deinem Browser "Hardwarebeschleunigung" aktiviert ist.`,
"accessMenu": `Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.`,
"accessMenu": "Nutze M oder Esc, um das Menü zu öffnen. Dort hast du Zugriff auf die Einstellungen und andere Funktionen.",
"menu": `In diesem Menü hast du Zugriff auf die Einstellungen.
"menu": `In diesem Menü hast du Zugriff auf die Einstellungen.
$Dort kannst du u. A. die Spielgeschwin-\ndigkeit und das Fensterdesign ändern.
$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.
$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.
$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,
$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.
$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.
$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.
@ -37,10 +37,10 @@ export const tutorial: SimpleTranslationEntries = {
$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.`,
"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.
$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.
$Es gibt sogar Pokémon, die du nur aus Eiern erhalten kannst.
$Es gibt drei Gacha-Maschinen mit je unterschiedlichen Boni,\nalso such' dir die aus, die dir am besten gefällt!`,
} as const;
} as const;

View File

@ -8,4 +8,4 @@ export const voucher: SimpleTranslationEntries = {
"eggVoucherGold": "Ei-Gutschein Gold",
"locked": "Gesperrt",
"defeatTrainer": "Besiege {{trainerName}}"
} as const;
} as const;

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

View File

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

View File

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

View File

@ -7,4 +7,4 @@ export const battleMessageUiHandler: SimpleTranslationEntries = {
"ivPrettyGood": "Pretty Good",
"ivDecent": "Decent",
"ivNoGood": "No Good",
} as const;
} as const;

View File

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

View File

@ -45,4 +45,4 @@ export const berry: BerryTranslationEntries = {
name: "Leppa Berry",
effect: "Restores 10 PP to a move if its PP reaches 0",
},
} as const;
} as const;

View File

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

View File

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

View File

@ -18,4 +18,4 @@ export const egg: SimpleTranslationEntries = {
"tooManyEggs": "You have too many eggs!",
"pull": "Pull",
"pulls": "Pulls"
} as const;
} as const;

View File

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

View File

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

View File

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

View File

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

View File

@ -384,4 +384,4 @@ export const modifierType: ModifierTypeTranslationEntries = {
"CHILL_DRIVE": "Chill Drive",
"DOUSE_DRIVE": "Douse Drive",
},
} as const;
} as const;

View File

@ -3809,4 +3809,4 @@ export const move: MoveTranslationEntries = {
name: "Malignant Chain",
effect: "The user pours toxins into the target by wrapping them in a toxic, corrosive chain. This may also leave the target badly poisoned."
}
} as const;
} as const;

View File

@ -26,4 +26,4 @@ export const nature: SimpleTranslationEntries = {
"Sassy": "Sassy",
"Careful": "Careful",
"Quirky": "Quirky"
} as const;
} as const;

View File

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

View File

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

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