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

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

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

7
lefthook.yml Normal file
View File

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

6103
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,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,19 +203,21 @@ export class PostBattleInitStatChangeAbAttr extends PostBattleInitAbAttr {
applyPostBattleInit(pokemon: Pokemon, passive: boolean, args: any[]): boolean {
const statChangePhases: StatChangePhase[] = [];
if (this.selfTarget)
if (this.selfTarget) {
statChangePhases.push(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, this.stats, this.levels));
else {
for (let opponent of pokemon.getOpponents())
} else {
for (const opponent of pokemon.getOpponents()) {
statChangePhases.push(new StatChangePhase(pokemon.scene, opponent.getBattlerIndex(), false, this.stats, this.levels));
}
}
for (let statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData)
pokemon.scene.pushPhase(statChangePhase); // TODO: This causes the ability bar to be shown at the wrong time
else
for (const statChangePhase of statChangePhases) {
if (!this.selfTarget && !statChangePhase.getPokemon().summonData) {
pokemon.scene.pushPhase(statChangePhase);
} else { // TODO: This causes the ability bar to be shown at the wrong time
pokemon.scene.unshiftPhase(statChangePhase);
}
}
return true;
}
@ -257,7 +258,7 @@ export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr {
return pokemon.addTag(BattlerTagType.STURDY, 1);
}
return false
return false;
}
}
@ -392,9 +393,10 @@ class TypeImmunityStatChangeAbAttr extends TypeImmunityAbAttr {
if (ret) {
cancelled.value = true;
const simulated = args.length > 1 && args[1];
if (!simulated)
if (!simulated) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels));
}
}
return ret;
}
@ -417,9 +419,10 @@ class TypeImmunityAddBattlerTagAbAttr extends TypeImmunityAbAttr {
if (ret) {
cancelled.value = true;
const simulated = args.length > 1 && args[1];
if (!simulated)
if (!simulated) {
pokemon.addTag(this.tagType, this.turnCount, undefined, pokemon.id);
}
}
return ret;
}
@ -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;
}
@ -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;
@ -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,8 +1995,8 @@ function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
function getAnticipationCondition(): AbAttrCondition {
return (pokemon: Pokemon) => {
for (let opponent of pokemon.getOpponents()) {
for (let move of opponent.moveset) {
for (const opponent of pokemon.getOpponents()) {
for (const move of opponent.moveset) {
// move is super effective
if (move.getMove() instanceof AttackMove && pokemon.getAttackTypeEffectiveness(move.getMove().type, opponent) >= 2) {
return true;
@ -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,62 +2922,70 @@ function applyAbAttrsInternal<TAttr extends AbAttr>(attrType: { new(...args: any
pokemon: Pokemon, applyFunc: AbAttrApplyFunc<TAttr>, args: any[], isAsync: boolean = false, showAbilityInstant: boolean = false, quiet: boolean = false, passive: boolean = false): Promise<void> {
return new Promise(resolve => {
if (!pokemon.canApplyAbility(passive)) {
if (!passive)
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else
} else {
return resolve();
}
}
const ability = (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility());
const attrs = ability.getAttrs(attrType) as TAttr[];
const clearSpliceQueueAndResolve = () => {
pokemon.scene.clearPhaseQueueSplice();
if (!passive)
if (!passive) {
return applyAbAttrsInternal(attrType, pokemon, applyFunc, args, isAsync, showAbilityInstant, quiet, true).then(() => resolve());
else
} else {
return resolve();
}
};
const applyNextAbAttr = () => {
if (attrs.length)
if (attrs.length) {
applyAbAttr(attrs.shift());
else
} else {
clearSpliceQueueAndResolve();
}
};
const applyAbAttr = (attr: TAttr) => {
if (!canApplyAttr(pokemon, attr))
if (!canApplyAttr(pokemon, attr)) {
return applyNextAbAttr();
}
pokemon.scene.setPhaseQueueSplice();
const onApplySuccess = () => {
if (pokemon.battleData && !pokemon.battleData.abilitiesApplied.includes(ability.id)) {
pokemon.battleData.abilitiesApplied.push(ability.id);
}
if (attr.showAbility && !quiet) {
if (showAbilityInstant)
if (showAbilityInstant) {
pokemon.scene.abilityBar.showAbility(pokemon, passive);
else
} else {
queueShowAbility(pokemon, passive);
}
}
if (!quiet) {
const message = attr.getTriggerMessage(pokemon, (!passive ? pokemon.getAbility() : pokemon.getPassiveAbility()).name, args);
if (message) {
if (isAsync)
if (isAsync) {
pokemon.scene.ui.showText(message, null, () => pokemon.scene.ui.showText(null, 0), null, true);
else
} else {
pokemon.scene.queueMessage(message);
}
}
}
};
const result = applyFunc(attr, passive);
if (result instanceof Promise) {
result.then(success => {
if (success)
if (success) {
onApplySuccess();
}
applyNextAbAttr();
});
} else {
if (result)
if (result) {
onApplySuccess();
}
applyNextAbAttr();
}
};
@ -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)
@ -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,32 +184,36 @@ export async function printPokemon() {
moveData.version_group_details.filter(v => versions.indexOf(v.version_group.name) > -1).forEach(verData => {
const isMoveVer = verData.version_group.name === moveVer;
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_');
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
const learnMethod = verData.move_learn_method.name;
if (isMoveVer && learnMethod === 'level-up')
if (isMoveVer && learnMethod === "level-up") {
speciesFormLevelMoves[speciesKey][pokemonForm.formIndex].push([ verData.level_learned_at, moveId ]);
}
if ([ 'machine', 'tutor' ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === 'level-up')) {
if (!moveTmSpecies.hasOwnProperty(moveId))
if ([ "machine", "tutor" ].indexOf(learnMethod) > -1 || (useExistingTmList && tmSpecies.hasOwnProperty(moveId as Moves) && learnMethod === "level-up")) {
if (!moveTmSpecies.hasOwnProperty(moveId)) {
moveTmSpecies[moveId] = [];
}
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s[0] === speciesKey);
if (speciesIndex === -1)
if (speciesIndex === -1) {
moveTmSpecies[moveId].push([ speciesKey, formName ]);
else
} else {
(moveTmSpecies[moveId][speciesIndex] as string[]).push(formName);
}
}
});
});
if (JSON.stringify(speciesLevelMoves[speciesKey]) === JSON.stringify(speciesFormLevelMoves[speciesKey][pokemonForm.formIndex])) {
delete speciesFormLevelMoves[speciesKey][pokemonForm.formIndex];
if (!Object.keys(speciesFormLevelMoves[speciesKey]).length)
if (!Object.keys(speciesFormLevelMoves[speciesKey]).length) {
delete speciesFormLevelMoves[speciesKey];
}
}
}
matchingSpecies.forms.push(pokemonForm);
continue;
@ -214,7 +222,7 @@ export async function printPokemon() {
const species = await api.pokemon.getPokemonSpeciesByName(pokemon.species.name);
let speciesKey = species.name.toUpperCase().replace(/\-/g, '_');
let speciesKey = species.name.toUpperCase().replace(/\-/g, "_");
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === speciesKey);
@ -227,15 +235,16 @@ export async function printPokemon() {
let generationIndex = 0;
if (!region)
while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]);
else
if (!region) {
while (++generationIndex < 9 && dexId > generationDexNumbers[generationIndex]){}
} else {
generationIndex = regionalForms.indexOf(region.toLowerCase()) + 6;
}
const baseStats: integer[] = [];
let baseTotal = 0;
// Assume correct stat order in API result
for (let stat of pokemon.stats) {
for (const stat of pokemon.stats) {
baseStats.push(stat.base_stat);
baseTotal += stat.base_stat;
}
@ -250,7 +259,7 @@ export async function printPokemon() {
];
const pokemonSpecies = new PokemonSpecies(dexId, generationIndex, species.is_legendary && baseTotal < 660, species.is_legendary && baseTotal >= 660, species.is_mythical,
species.genera.find(g => g.language.name === 'en')?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities,
species.genera.find(g => g.language.name === "en")?.genus, type1 as Type, type2 > -1 ? type2 as Type : null, pokemon.height / 10, pokemon.weight / 10, ability1 as Abilities, ability2 as Abilities, abilityHidden as Abilities,
baseTotal, baseStats[0], baseStats[1], baseStats[2], baseStats[3], baseStats[4], baseStats[5], species.capture_rate, species.base_happiness, pokemon.base_experience, growthRateMap[species.growth_rate.name],
species.gender_rate < 9 ? 100 - (species.gender_rate * 12.5) : null, species.has_gender_differences, species.forms_switchable);
@ -262,8 +271,8 @@ export async function printPokemon() {
speciesLevelMoves[speciesKey] = [];
for (let version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === 'level-up'))) {
for (const version of versions) {
if (pokemon.moves.find(m => m.version_group_details.find(v => v.version_group.name === version && v.move_learn_method.name === "level-up"))) {
moveVer = version;
break;
}
@ -274,23 +283,26 @@ export async function printPokemon() {
if (moveVer) {
pokemon.moves.forEach(moveData => {
const verData = moveData.version_group_details.find(v => v.version_group.name === moveVer);
if (!verData)
if (!verData) {
return;
}
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_');
const moveName = moveData.move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
const moveId = Math.max(Utils.getEnumKeys(Moves).indexOf(moveName), 0);
switch (verData.move_learn_method.name) {
case 'level-up':
case "level-up":
speciesLevelMoves[speciesKey].push([ verData.level_learned_at, moveId ]);
break;
case 'machine':
case 'tutor':
case "machine":
case "tutor":
if (moveId > 0) {
if (!moveTmSpecies.hasOwnProperty(moveId))
if (!moveTmSpecies.hasOwnProperty(moveId)) {
moveTmSpecies[moveId] = [];
if (moveTmSpecies[moveId].indexOf(speciesKey) === -1)
}
if (moveTmSpecies[moveId].indexOf(speciesKey) === -1) {
moveTmSpecies[moveId].push(speciesKey);
}
speciesTmMoves.push(moveId);
}
break;
@ -298,7 +310,7 @@ export async function printPokemon() {
});
}
for (let f of pokemon.forms) {
for (const f of pokemon.forms) {
const form = await api.pokemon.getPokemonFormByName(f.name);
const formIndex = pokemonSpecies.forms.length;
@ -307,7 +319,7 @@ export async function printPokemon() {
: null;
const formName = matchingForm
? matchingForm.formName
: form.form_names.find(fn => fn.language.name === 'en')?.name || form.form_name;
: form.form_names.find(fn => fn.language.name === "en")?.name || form.form_name;
const formKey = matchingForm
? matchingForm.formKey
: form.form_name;
@ -321,7 +333,7 @@ export async function printPokemon() {
pokemonForm.generation = pokemonSpecies.generation;
if (!pokemonForm.formIndex && speciesTmMoves.length) {
for (let moveId of speciesTmMoves) {
for (const moveId of speciesTmMoves) {
const speciesIndex = moveTmSpecies[moveId].findIndex(s => s === speciesKey);
moveTmSpecies[moveId][speciesIndex] = [
speciesKey,
@ -336,86 +348,92 @@ export async function printPokemon() {
console.log(pokemonSpecies.name, pokemonSpecies);
}
for (let pokemonSpecies of pokemonSpeciesList) {
for (const pokemonSpecies of pokemonSpeciesList) {
const speciesKey = (pokemonSpecies as any).key as string;
enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ''},\n`;
pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : 'null'}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`;
enumStr += ` ${speciesKey}${pokemonSpecies.speciesId >= 2000 ? ` = ${pokemonSpecies.speciesId}` : ""},\n`;
pokemonSpeciesStr += ` new PokemonSpecies(Species.${speciesKey}, "${pokemonSpecies.name}", ${pokemonSpecies.generation}, ${pokemonSpecies.subLegendary}, ${pokemonSpecies.legendary}, ${pokemonSpecies.mythical}, "${pokemonSpecies.species}", Type.${Type[pokemonSpecies.type1]}, ${pokemonSpecies.type2 ? `Type.${Type[pokemonSpecies.type2]}` : "null"}, ${pokemonSpecies.height}, ${pokemonSpecies.weight}, Abilities.${Abilities[pokemonSpecies.ability1]}, Abilities.${Abilities[pokemonSpecies.ability2]}, Abilities.${Abilities[pokemonSpecies.abilityHidden]}, ${pokemonSpecies.baseTotal}, ${pokemonSpecies.baseStats[0]}, ${pokemonSpecies.baseStats[1]}, ${pokemonSpecies.baseStats[2]}, ${pokemonSpecies.baseStats[3]}, ${pokemonSpecies.baseStats[4]}, ${pokemonSpecies.baseStats[5]}, ${pokemonSpecies.catchRate}, ${pokemonSpecies.baseFriendship}, ${pokemonSpecies.baseExp}, GrowthRate.${GrowthRate[pokemonSpecies.growthRate]}, ${pokemonSpecies.malePercent}, ${pokemonSpecies.genderDiffs}`;
if (pokemonSpecies.forms.length > 1) {
pokemonSpeciesStr += `, ${pokemonSpecies.canChangeForm},`;
for (let form of pokemonSpecies.forms)
pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : 'null'}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ', true' : ''}),`;
pokemonSpeciesStr += '\n ';
for (const form of pokemonSpecies.forms) {
pokemonSpeciesStr += `\n new PokemonForm("${form.formName}", "${form.formName}", Type.${Type[form.type1]}, ${form.type2 ? `Type.${Type[form.type2]}` : "null"}, ${form.height}, ${form.weight}, Abilities.${Abilities[form.ability1]}, Abilities.${Abilities[form.ability2]}, Abilities.${Abilities[form.abilityHidden]}, ${form.baseTotal}, ${form.baseStats[0]}, ${form.baseStats[1]}, ${form.baseStats[2]}, ${form.baseStats[3]}, ${form.baseStats[4]}, ${form.baseStats[5]}, ${form.catchRate}, ${form.baseFriendship}, ${form.baseExp}${form.genderDiffs ? ", true" : ""}),`;
}
pokemonSpeciesStr += `),\n`;
pokemonSpeciesStr += "\n ";
}
pokemonSpeciesStr += "),\n";
}
let speciesLevelMovesStr = `export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n`;
let speciesFormLevelMovesStr = `export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n`;
let tmSpeciesStr = `export const tmSpecies: TmSpecies = {\n`;
let speciesLevelMovesStr = "export const pokemonSpeciesLevelMoves: PokemonSpeciesLevelMoves = {\n";
let speciesFormLevelMovesStr = "export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {\n";
let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
for (let species of Object.keys(speciesLevelMoves)) {
for (const species of Object.keys(speciesLevelMoves)) {
speciesLevelMovesStr += ` [Species.${species}]: [\n`;
const orderedLevelMoves = speciesLevelMoves[species].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0])
if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1;
});
for (let lm of orderedLevelMoves)
for (const lm of orderedLevelMoves) {
speciesLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
speciesLevelMovesStr += ` ],\n`;
}
for (let species of Object.keys(speciesFormLevelMoves)) {
speciesLevelMovesStr += " ],\n";
}
for (const species of Object.keys(speciesFormLevelMoves)) {
speciesFormLevelMovesStr += ` [Species.${species}]: {\n`;
for (let f of Object.keys(speciesFormLevelMoves[species])) {
for (const f of Object.keys(speciesFormLevelMoves[species])) {
speciesFormLevelMovesStr += ` ${f}: [\n`;
const orderedLevelMoves = speciesFormLevelMoves[species][f].sort((a: LevelMove, b: LevelMove) => {
if (a[0] !== b[0])
if (a[0] !== b[0]) {
return a[0] < b[0] ? -1 : 1;
}
return a[1] < b[1] ? -1 : 1;
});
for (let lm of orderedLevelMoves)
for (const lm of orderedLevelMoves) {
speciesFormLevelMovesStr += ` [ ${lm[0]}, Moves.${Moves[lm[1]]} ],\n`;
speciesFormLevelMovesStr += ` ],\n`;
}
speciesFormLevelMovesStr += ` },\n`;
speciesFormLevelMovesStr += " ],\n";
}
for (let moveId of Object.keys(moveTmSpecies)) {
speciesFormLevelMovesStr += " },\n";
}
for (const moveId of Object.keys(moveTmSpecies)) {
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (let species of moveTmSpecies[moveId]) {
if (typeof species === 'string')
for (const species of moveTmSpecies[moveId]) {
if (typeof species === "string") {
tmSpeciesStr += ` Species.${species},\n`;
else {
} else {
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length))
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
tmSpeciesStr += ` Species.${species[0]},\n`;
else {
} else {
tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (let form of forms)
for (const form of forms) {
tmSpeciesStr += ` '${form}',\n`;
tmSpeciesStr += ` ],\n`;
}
tmSpeciesStr += " ],\n";
}
}
}
tmSpeciesStr += ` ],\n`;
tmSpeciesStr += " ],\n";
}
enumStr += `\n};`;
pokemonSpeciesStr += ` );`;
speciesLevelMovesStr += `\n};`;
speciesFormLevelMovesStr += `\n};`;
tmSpeciesStr += `\n};`;
enumStr += "\n};";
pokemonSpeciesStr += " );";
speciesLevelMovesStr += "\n};";
speciesFormLevelMovesStr += "\n};";
tmSpeciesStr += "\n};";
console.log(enumStr);
console.log(pokemonSpeciesStr);
@ -423,39 +441,40 @@ export async function printPokemon() {
console.log(speciesFormLevelMovesStr);
console.log(tmSpeciesStr);
console.log(moveTmSpecies)
console.log(moveTmSpecies);
}
export async function printAbilities() {
const replaceText = true;
let abilityContent: string = await fs.readFile('./src/data/ability.ts');
let abilityContent: string = await fs.readFile("./src/data/ability.ts");
const api = new MainClient();
let enumStr = `export enum Abilities {\n NONE,`;
let abilityStr = ' allAbilities.push(';
let enumStr = "export enum Abilities {\n NONE,";
let abilityStr = " allAbilities.push(";
abilityContent = abilityContent.slice(abilityContent.indexOf(abilityStr));
let abilities: NamedAPIResource[] = [];
let offset = 0;
let abilitiesResponse = await api.pokemon.listAbilities(offset, 2000);
const offset = 0;
const abilitiesResponse = await api.pokemon.listAbilities(offset, 2000);
abilities = abilitiesResponse.results;
for (let a of abilities) {
for (const a of abilities) {
const ability = await api.pokemon.getAbilityByName(a.name);
const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_');
const abilityEnumName = ability.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
enumStr += `\n ${abilityEnumName},`;
console.log(ability.name, ability);
const matchingLineIndex = abilityContent.search(new RegExp(`new Ability\\\(Abilities.${abilityEnumName},`));
let matchingLine = matchingLineIndex > -1 ? abilityContent.slice(matchingLineIndex) : null;
if (matchingLine)
if (matchingLine) {
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
let abilityName = ability.names.find(ln => ln.language.name === 'en').name;
[ 'N', 'P' ].every(s => {
let abilityName = ability.names.find(ln => ln.language.name === "en").name;
[ "N", "P" ].every(s => {
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
abilityName += ` (${s})`;
return false;
@ -465,26 +484,29 @@ export async function printAbilities() {
let flavorText: string;
if (!matchingLine || replaceText) {
for (let version of versions) {
if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === 'en' && fte.version_group.name === version)?.flavor_text) || '') {
if (flavorText.indexOf('forgotten') > -1)
for (const version of versions) {
if ((flavorText = ability.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf("forgotten") > -1) {
continue;
}
break;
}
}
} else if (matchingLine)
} else if (matchingLine) {
flavorText = allAbilities[ability.id].description;
abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, '\\n').replace(/ /g, ' ').replace(//g, '\'') || ''}", ${generationMap[ability.generation.name]})`;
}
abilityStr += `\n new Ability(Abilities.${abilityEnumName}, "${abilityName}", "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${generationMap[ability.generation.name]})`;
if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf('\n');
if (newLineIndex > -1)
const newLineIndex = matchingLine.indexOf("\n");
if (newLineIndex > -1) {
abilityStr += matchingLine.slice(newLineIndex);
}
abilityStr += ',';
}
abilityStr += ",";
}
enumStr += `\n};`;
abilityStr += `\n);`;
enumStr += "\n};";
abilityStr += "\n);";
console.log(enumStr);
console.log(abilityStr);
@ -493,35 +515,36 @@ export async function printAbilities() {
export async function printMoves() {
const replaceText = true;
let moveContent: string = await fs.readFile('./src/data/move.ts');
let moveContent: string = await fs.readFile("./src/data/move.ts");
const api = new MainClient();
let enumStr = `export enum Moves {\n NONE,`;
let moveStr = ' allMoves.push(';
let enumStr = "export enum Moves {\n NONE,";
let moveStr = " allMoves.push(";
moveContent = moveContent.slice(moveContent.indexOf(moveStr));
let moves: NamedAPIResource[] = [];
let offset = 0;
let movesResponse = await api.move.listMoves(offset, 2000);
const offset = 0;
const movesResponse = await api.move.listMoves(offset, 2000);
moves = movesResponse.results;
console.log(moves);
for (let m of moves) {
for (const m of moves) {
const move = await api.move.getMoveByName(m.name);
const moveEnumName = move.name.toUpperCase().replace(/\_/g, '').replace(/\-/g, '_');
const moveEnumName = move.name.toUpperCase().replace(/\_/g, "").replace(/\-/g, "_");
enumStr += `\n ${moveEnumName},`;
console.log(move.name, move);
const matchingLineIndex = moveContent.search(new RegExp(`new (?:Attack|(?:Self)?Status)Move\\\(Moves.${Moves[move.id]},`));
let matchingLine = matchingLineIndex > -1 ? moveContent.slice(matchingLineIndex) : null;
if (matchingLine)
if (matchingLine) {
matchingLine = matchingLine.slice(0, matchingLine.search(/,(?: \/\/.*?)?(?:\r)?\n[ \t]+(?:new|\);)/));
}
let moveName = move.names.find(ln => ln.language.name === 'en').name;
[ 'N', 'P' ].every(s => {
let moveName = move.names.find(ln => ln.language.name === "en").name;
[ "N", "P" ].every(s => {
if (!matchingLine || matchingLine.indexOf(` (${s})`) > -1) {
moveName += ` (${s})`;
return false;
@ -531,32 +554,35 @@ export async function printMoves() {
let flavorText: string;
if (!matchingLine || replaceText) {
for (let version of versions) {
if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === 'en' && fte.version_group.name === version)?.flavor_text) || '') {
if (flavorText.indexOf('forgotten') > -1)
for (const version of versions) {
if ((flavorText = move.flavor_text_entries.find(fte => fte.language.name === "en" && fte.version_group.name === version)?.flavor_text) || "") {
if (flavorText.indexOf("forgotten") > -1) {
continue;
}
break;
}
}
} else if (matchingLine)
} else if (matchingLine) {
flavorText = allMoves[move.id].effect;
}
const moveTarget = targetMap[move.target.name];
moveStr += `\n new ${move.damage_class.name !== 'status' ? 'Attack' : (moveTarget === MoveTarget.USER ? 'Self' : '') + 'Status'}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== 'status' ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ''}${move.damage_class.name !== 'status' ? `, ${move.power || -1}` : ''}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, '\\n').replace(/ /g, ' ').replace(//g, '\'') || ''}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`;
const expectedTarget = move.damage_class.name !== 'status' || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER;
moveStr += `\n new ${move.damage_class.name !== "status" ? "Attack" : (moveTarget === MoveTarget.USER ? "Self" : "") + "Status"}Move(Moves.${moveEnumName}, "${moveName}", Type.${move.type.name.toUpperCase()}${move.damage_class.name !== "status" ? `, MoveCategory.${move.damage_class.name.toUpperCase()}` : ""}${move.damage_class.name !== "status" ? `, ${move.power || -1}` : ""}, ${move.accuracy || -1}, ${move.pp}, "${flavorText?.replace(/\n/g, "\\n").replace(/ /g, " ").replace(//g, "'") || ""}", ${move.effect_chance || -1}, ${move.priority}, ${generationMap[move.generation.name]})`;
const expectedTarget = move.damage_class.name !== "status" || moveTarget !== MoveTarget.USER ? MoveTarget.NEAR_OTHER : MoveTarget.USER;
if (matchingLine && matchingLine.length > 1) {
const newLineIndex = matchingLine.indexOf('\n');
const newLineIndex = matchingLine.indexOf("\n");
if (newLineIndex > -1) {
console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ''), newLineIndex)
moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, '');
console.log(matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, ""), newLineIndex);
moveStr += matchingLine.slice(newLineIndex).replace(/(?:\r)?\n[ \t]+.target\(.*?\)/g, "");
}
}
if (moveTarget !== expectedTarget)
if (moveTarget !== expectedTarget) {
moveStr += `\n .target(MoveTarget.${MoveTarget[moveTarget]})`;
moveStr += ',';
}
moveStr += ",";
}
enumStr += `\n};`;
moveStr += `\n);`;
enumStr += "\n};";
moveStr += "\n);";
console.log(enumStr);
console.log(moveStr);
@ -569,31 +595,33 @@ export async function printTmSpecies() {
const moveIds = Object.keys(tmSpecies).map(k => parseInt(k) as Moves);
for (let moveId of moveIds) {
for (const moveId of moveIds) {
const move = await api.move.getMoveById(moveId);
moveTmSpecies[moveId] = [];
for (let species of move.learned_by_pokemon) {
for (const species of move.learned_by_pokemon) {
const dexIdMatch = /\/(\d+)\//.exec(species.url);
if (!dexIdMatch)
if (!dexIdMatch) {
continue;
}
let dexId = parseInt(dexIdMatch[1]);
const dexId = parseInt(dexIdMatch[1]);
let matchingSpecies: PokemonSpecies;
let formKey = '';
let formKey = "";
console.log(species.name);
if (dexId < 10000)
if (dexId < 10000) {
matchingSpecies = allSpecies[dexId - 1];
else {
} else {
const pokemon = await api.pokemon.getPokemonById(dexId);
const speciesDexIdMatch = /\/(\d+)\//.exec(pokemon.species.url);
if (!speciesDexIdMatch)
if (!speciesDexIdMatch) {
continue;
}
const speciesDexId = parseInt(speciesDexIdMatch[1]);
@ -606,12 +634,13 @@ export async function printTmSpecies() {
if (regionKey) {
formKey = formKey.slice(regionKey.length + 1);
matchingSpecies = allSpecies.find(s => Species[s.speciesId] === `${regionKey.toUpperCase()}_${speciesKey}`);
} else
} else {
matchingSpecies = allSpecies[speciesDexId - 1];
}
}
if (!matchingSpecies) {
console.log('NO MATCH', species.name);
console.log("NO MATCH", species.name);
continue;
}
@ -619,40 +648,42 @@ export async function printTmSpecies() {
const matchingIndex = moveTmSpecies[moveId].findIndex(s => Array.isArray(s) ? s[0] === speciesKey : s === speciesKey);
if (matchingIndex === -1)
if (matchingIndex === -1) {
moveTmSpecies[moveId].push(!formKey ? speciesKey : [ speciesKey, formKey ]);
else {
if (!Array.isArray(moveTmSpecies[moveId][matchingIndex]))
moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, '' ];
} else {
if (!Array.isArray(moveTmSpecies[moveId][matchingIndex])) {
moveTmSpecies[moveId][matchingIndex] = [ moveTmSpecies[moveId][matchingIndex] as string, "" ];
}
(moveTmSpecies[moveId][matchingIndex] as string[]).push(formKey);
}
}
}
let tmSpeciesStr = `export const tmSpecies: TmSpecies = {\n`;
let tmSpeciesStr = "export const tmSpecies: TmSpecies = {\n";
for (let moveId of Object.keys(moveTmSpecies)) {
for (const moveId of Object.keys(moveTmSpecies)) {
tmSpeciesStr += ` [Moves.${Moves[parseInt(moveId)]}]: [\n`;
for (let species of moveTmSpecies[moveId]) {
if (typeof species === 'string')
for (const species of moveTmSpecies[moveId]) {
if (typeof species === "string") {
tmSpeciesStr += ` Species.${species},\n`;
else {
} else {
const matchingExistingSpecies = allSpecies.find(s => Species[s.speciesId] === species[0]);
const forms = (species as string[]).slice(1);
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length))
if (matchingExistingSpecies && (!pokemonFormLevelMoves.hasOwnProperty(matchingExistingSpecies.speciesId) || matchingExistingSpecies.forms.length <= 1 || (matchingExistingSpecies.forms.length === 2 && matchingExistingSpecies.forms[1].formKey.indexOf(SpeciesFormKey.MEGA) > -1) || matchingExistingSpecies.forms.length === forms.length)) {
tmSpeciesStr += ` Species.${species[0]},\n`;
else {
} else {
tmSpeciesStr += ` [\n Species.${species[0]},\n`;
for (let form of forms)
for (const form of forms) {
tmSpeciesStr += ` '${form}',\n`;
tmSpeciesStr += ` ],\n`;
}
tmSpeciesStr += " ],\n";
}
}
}
tmSpeciesStr += ` ],\n`;
tmSpeciesStr += " ],\n";
}
tmSpeciesStr += `\n};`;
tmSpeciesStr += "\n};";
console.log(tmSpeciesStr);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import { Gender } from "./gender";
import { AttackTypeBoosterModifier, FlinchChanceModifier } from "../modifier/modifier";
import { FlinchChanceModifier } from "../modifier/modifier";
import { Moves } from "./enums/moves";
import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon";
@ -185,7 +185,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
new SpeciesEvolution(Species.DUGTRIO, 26, null, null)
],
[Species.MEOWTH]: [
new SpeciesFormEvolution(Species.PERSIAN, '', '', 28, null, null)
new SpeciesFormEvolution(Species.PERSIAN, "", "", 28, null, null)
],
[Species.PSYDUCK]: [
new SpeciesEvolution(Species.GOLDUCK, 33, null, null)
@ -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)
@ -1619,13 +1620,14 @@ interface PokemonPrevolutions {
export const pokemonPrevolutions: PokemonPrevolutions = {};
{
const megaFormKeys = [ SpeciesFormKey.MEGA, '', SpeciesFormKey.MEGA_X, '', SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
const prevolutionKeys = Object.keys(pokemonEvolutions);
prevolutionKeys.forEach(pk => {
const evolutions = pokemonEvolutions[pk];
for (let ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1)
for (const ev of evolutions) {
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
continue;
}
pokemonPrevolutions[ev.speciesId] = parseInt(pk) as Species;
}
});

View File

@ -110,38 +110,46 @@ export class SpeciesFormChange {
}
canChange(pokemon: Pokemon): boolean {
if (pokemon.species.speciesId !== this.speciesId)
return false;
if (!pokemon.species.forms.length)
return false;
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey)
return false;
if (formKeys[pokemon.formIndex] === this.formKey)
return false;
for (let condition of this.conditions) {
if (!condition.predicate(pokemon))
if (pokemon.species.speciesId !== this.speciesId) {
return false;
}
if (!this.trigger.canChange(pokemon))
if (!pokemon.species.forms.length) {
return false;
}
const formKeys = pokemon.species.forms.map(f => f.formKey);
if (formKeys[pokemon.formIndex] !== this.preFormKey) {
return false;
}
if (formKeys[pokemon.formIndex] === this.formKey) {
return false;
}
for (const condition of this.conditions) {
if (!condition.predicate(pokemon)) {
return false;
}
}
if (!this.trigger.canChange(pokemon)) {
return false;
}
return true;
}
findTrigger(triggerType: { new(...args: any[]): SpeciesFormChangeTrigger }): SpeciesFormChangeTrigger {
if (!this.trigger.hasTriggerType(triggerType))
if (!this.trigger.hasTriggerType(triggerType)) {
return null;
}
let trigger = this.trigger;
const trigger = this.trigger;
if (trigger instanceof SpeciesFormChangeCompoundTrigger)
if (trigger instanceof SpeciesFormChangeCompoundTrigger) {
return trigger.triggers.find(t => t.hasTriggerType(triggerType));
}
return trigger;
}
@ -181,10 +189,11 @@ export class SpeciesFormChangeCompoundTrigger {
}
canChange(pokemon: Pokemon): boolean {
for (let trigger of this.triggers) {
if (!trigger.canChange(pokemon))
for (const trigger of this.triggers) {
if (!trigger.canChange(pokemon)) {
return false;
}
}
return true;
}
@ -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)}`;
@ -141,8 +151,9 @@ export abstract class PokemonSpeciesForm {
getRootSpeciesId(forStarter: boolean = false): Species {
let ret = this.speciesId;
while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret)))
while (pokemonPrevolutions.hasOwnProperty(ret) && (!forStarter || !speciesStarters.hasOwnProperty(ret))) {
ret = pokemonPrevolutions[ret];
}
return ret;
}
@ -159,8 +170,9 @@ export abstract class PokemonSpeciesForm {
}
getLevelMoves(): LevelMoves {
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex))
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0);
}
return pokemonSpeciesLevelMoves[this.speciesId].slice(0);
}
@ -199,7 +211,7 @@ export abstract class PokemonSpeciesForm {
* @returns The species' base stat amount.
*/
getBaseStat(stat: Stat): integer {
return this.baseStats[stat]
return this.baseStats[stat];
}
getBaseExp(): integer {
@ -218,25 +230,25 @@ export abstract class PokemonSpeciesForm {
}
getSpriteAtlasPath(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, '/');
return `${/_[1-3]$/.test(spriteId) ? 'variant/' : ''}${spriteId}`;
const spriteId = this.getSpriteId(female, formIndex, shiny, variant).replace(/\_{2}/g, "/");
return `${/_[1-3]$/.test(spriteId) ? "variant/" : ""}${spriteId}`;
}
getSpriteId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer, back?: boolean): string {
if (formIndex === undefined || this instanceof PokemonForm)
if (formIndex === undefined || this instanceof PokemonForm) {
formIndex = this.formIndex;
}
const formSpriteKey = this.getFormSpriteKey(formIndex);
const showGenderDiffs = this.genderDiffs && female && ![ SpeciesFormKey.MEGA, SpeciesFormKey.GIGANTAMAX ].find(k => formSpriteKey === k);
const baseSpriteKey = `${showGenderDiffs ? 'female__' : ''}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ''}`;
const baseSpriteKey = `${showGenderDiffs ? "female__" : ""}${this.speciesId}${formSpriteKey ? `-${formSpriteKey}` : ""}`;
let variantSet: VariantSet;
let config = variantData;
`${back ? 'back__' : ''}${baseSpriteKey}`.split('__').map(p => config ? config = config[p] : null);
variantSet = config as VariantSet;
`${back ? "back__" : ""}${baseSpriteKey}`.split("__").map(p => config ? config = config[p] : null);
const variantSet = config as VariantSet;
return `${back ? 'back__' : ''}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? 'shiny__' : ''}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ''}`;
return `${back ? "back__" : ""}${shiny && (!variantSet || (!variant && !variantSet[variant || 0])) ? "shiny__" : ""}${baseSpriteKey}${shiny && variantSet && variantSet[variant || 0] === 2 ? `_${variant + 1}` : ""}`;
}
getSpriteKey(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
@ -247,19 +259,21 @@ export abstract class PokemonSpeciesForm {
getIconAtlasKey(formIndex?: integer, shiny?: boolean, variant?: integer): string {
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
return `pokemon_icons_${this.generation}${isVariant ? 'v' : ''}`;
return `pokemon_icons_${this.generation}${isVariant ? "v" : ""}`;
}
getIconId(female: boolean, formIndex?: integer, shiny?: boolean, variant?: integer): string {
if (formIndex === undefined)
if (formIndex === undefined) {
formIndex = this.formIndex;
}
let ret = this.speciesId.toString();
const isVariant = shiny && variantData[this.speciesId] && variantData[this.speciesId][variant];
if (shiny && !isVariant)
ret += 's';
if (shiny && !isVariant) {
ret += "s";
}
switch (this.speciesId) {
case Species.HIPPOPOTAS:
@ -267,7 +281,7 @@ export abstract class PokemonSpeciesForm {
case Species.UNFEZANT:
case Species.FRILLISH:
case Species.JELLICENT:
ret += female ? '-f' : '';
ret += female ? "-f" : "";
break;
}
@ -278,16 +292,18 @@ export abstract class PokemonSpeciesForm {
break;
case Species.ZACIAN:
case Species.ZAMAZENTA:
if (formSpriteKey.startsWith('behemoth'))
formSpriteKey = 'crowned';
if (formSpriteKey.startsWith("behemoth")) {
formSpriteKey = "crowned";
}
default:
ret += `-${formSpriteKey}`;
break;
}
}
if (isVariant)
if (isVariant) {
ret += `_${variant + 1}`;
}
return ret;
}
@ -322,33 +338,33 @@ export abstract class PokemonSpeciesForm {
case SpeciesFormKey.GIGANTAMAX:
case SpeciesFormKey.GIGANTAMAX_SINGLE:
case SpeciesFormKey.GIGANTAMAX_RAPID:
case 'white':
case 'black':
case 'therian':
case 'sky':
case 'gorging':
case 'gulping':
case 'no-ice':
case 'hangry':
case 'crowned':
case 'eternamax':
case 'four':
case 'droopy':
case 'stretchy':
case 'roaming':
case 'complete':
case '10':
case 'super':
case 'unbound':
case 'pau':
case 'pompom':
case 'sensu':
case 'dusk':
case 'midnight':
case 'school':
case 'dawn-wings':
case 'dusk-mane':
case 'ultra':
case "white":
case "black":
case "therian":
case "sky":
case "gorging":
case "gulping":
case "no-ice":
case "hangry":
case "crowned":
case "eternamax":
case "four":
case "droopy":
case "stretchy":
case "roaming":
case "complete":
case "10":
case "super":
case "unbound":
case "pau":
case "pompom":
case "sensu":
case "dusk":
case "midnight":
case "school":
case "dawn-wings":
case "dusk-mane":
case "ultra":
ret += `-${formKey}`;
break;
}
@ -358,18 +374,21 @@ export abstract class PokemonSpeciesForm {
validateStarterMoveset(moveset: StarterMoveset, eggMoves: integer): boolean {
const rootSpeciesId = this.getRootSpeciesId();
for (let moveId of moveset) {
for (const moveId of moveset) {
if (speciesEggMoves.hasOwnProperty(rootSpeciesId)) {
const eggMoveIndex = speciesEggMoves[rootSpeciesId].findIndex(m => m === moveId);
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex))
if (eggMoveIndex > -1 && eggMoves & Math.pow(2, eggMoveIndex)) {
continue;
}
}
if (pokemonFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId))
if (!pokemonFormLevelMoves[this.speciesId][this.formIndex].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false;
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId))
}
} else if (!pokemonSpeciesLevelMoves[this.speciesId].find(lm => lm[0] <= 5 && lm[1] === moveId)) {
return false;
}
}
return true;
}
@ -391,19 +410,20 @@ export abstract class PokemonSpeciesForm {
frameRate: 12,
repeat: -1
});
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace('variant/', '').replace(/_[1-3]$/, '');
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);
if (useExpSprite)
if (useExpSprite) {
spritePath = `exp/${spritePath}`;
let variantSet: VariantSet;
}
let config = variantData;
spritePath.split('/').map(p => config ? config = config[p] : null);
variantSet = config as VariantSet;
spritePath.split("/").map(p => config ? config = config[p] : null);
const variantSet = config as VariantSet;
if (variantSet && variantSet[variant] === 1) {
const populateVariantColors = (key: string): Promise<void> => {
return new Promise(resolve => {
if (variantColorCache.hasOwnProperty(key))
if (variantColorCache.hasOwnProperty(key)) {
return resolve();
}
scene.cachedFetch(`./images/pokemon/variant/${spritePath}.json`).then(res => res.json()).then(c => {
variantColorCache[key] = c;
resolve();
@ -416,21 +436,25 @@ export abstract class PokemonSpeciesForm {
resolve();
});
if (startLoad) {
if (!scene.load.isLoading())
if (!scene.load.isLoading()) {
scene.load.start();
} else
}
} else {
resolve();
}
});
}
cry(scene: BattleScene, soundConfig?: Phaser.Types.Sound.SoundConfig, ignorePlay?: boolean): AnySound {
const cryKey = this.getCryKey(this.formIndex);
let cry = scene.sound.get(cryKey) as AnySound;
if (cry?.pendingRemove)
if (cry?.pendingRemove) {
cry = null;
}
cry = scene.playSound(cry || cryKey, soundConfig);
if (ignorePlay)
if (ignorePlay) {
cry.stop();
}
return cry;
}
@ -440,11 +464,11 @@ export abstract class PokemonSpeciesForm {
const sourceFrame = sourceTexture.frames[sourceTexture.firstFrame];
const sourceImage = sourceTexture.getSourceImage() as HTMLImageElement;
const canvas = document.createElement('canvas');
const canvas = document.createElement("canvas");
const spriteColors: integer[][] = [];
const context = canvas.getContext('2d');
const context = canvas.getContext("2d");
const frame = sourceFrame;
canvas.width = frame.width;
canvas.height = frame.height;
@ -456,16 +480,18 @@ export abstract class PokemonSpeciesForm {
if (pixelData[i + 3]) {
const pixel = pixelData.slice(i, i + 4);
const [ r, g, b, a ] = pixel;
if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b))
if (!spriteColors.find(c => c[0] === r && c[1] === g && c[2] === b)) {
spriteColors.push([ r, g, b, a ]);
}
}
}
const pixelColors = [];
for (let i = 0; i < pixelData.length; i += 4) {
const total = pixelData.slice(i, i + 3).reduce((total: integer, value: integer) => total + value, 0);
if (!total)
if (!total) {
continue;
}
pixelColors.push(argbFromRgba({ r: pixelData[i], g: pixelData[i + 1], b: pixelData[i + 2], a: pixelData[i + 3] }));
}
@ -476,7 +502,7 @@ export abstract class PokemonSpeciesForm {
scene.executeWithSeedOffset(() => {
paletteColors = QuantizerCelebi.quantize(pixelColors, 2);
}, 0, 'This result should not vary');
}, 0, "This result should not vary");
Math.random = originalRandom;
@ -538,10 +564,11 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
case SpeciesFormKey.MEGA_Y:
return `Mega ${this.name} Y`;
default:
if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1)
if (form.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1) {
return `G-Max ${this.name}`;
}
}
}
return this.name;
}
@ -580,80 +607,88 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
if (prevolutionLevels.length) {
for (let pl = prevolutionLevels.length - 1; pl >= 0; pl--) {
const prevolutionLevel = prevolutionLevels[pl];
if (level < prevolutionLevel[1])
if (level < prevolutionLevel[1]) {
return prevolutionLevel[0];
}
}
}
if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId))
if (!allowEvolving || !pokemonEvolutions.hasOwnProperty(this.speciesId)) {
return this.speciesId;
}
const evolutions = pokemonEvolutions[this.speciesId];
const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeIn');
const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction('Sine.easeOut');
const easeInFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeIn");
const easeOutFunc = Phaser.Tweens.Builders.GetEaseFunction("Sine.easeOut");
const evolutionPool: Map<number, Species> = new Map();
let totalWeight = 0;
let noEvolutionChance = 1;
for (let ev of evolutions) {
if (ev.level > level)
for (const ev of evolutions) {
if (ev.level > level) {
continue;
}
let evolutionChance: number;
const evolutionSpecies = getPokemonSpecies(ev.speciesId);
const isRegionalEvolution = !this.isRegional() && evolutionSpecies.isRegional();
if (!forTrainer && isRegionalEvolution)
if (!forTrainer && isRegionalEvolution) {
evolutionChance = 0;
else {
} else {
if (ev.wildDelay === SpeciesWildEvolutionDelay.NONE) {
if (strength === PartyMemberStrength.STRONGER)
if (strength === PartyMemberStrength.STRONGER) {
evolutionChance = 1;
else {
} else {
const maxLevelDiff = this.getStrengthLevelDiff(strength);
const minChance: number = 0.875 - 0.125 * strength;
evolutionChance = Math.min(minChance + easeInFunc(Math.min(level - ev.level, maxLevelDiff) / maxLevelDiff) * (1 - minChance), 1);
}
} else {
let preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1);
const preferredMinLevel = Math.max((ev.level - 1) + ev.wildDelay * this.getStrengthLevelDiff(strength), 1);
let evolutionLevel = Math.max(ev.level > 1 ? ev.level : Math.floor(preferredMinLevel / 2), 1);
if (ev.level <= 1 && pokemonPrevolutions.hasOwnProperty(this.speciesId)) {
const prevolutionLevel = pokemonEvolutions[pokemonPrevolutions[this.speciesId]].find(ev => ev.speciesId === this.speciesId).level;
if (prevolutionLevel > 1)
if (prevolutionLevel > 1) {
evolutionLevel = prevolutionLevel;
}
}
evolutionChance = Math.min(0.65 * easeInFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel) / preferredMinLevel) + 0.35 * easeOutFunc(Math.min(Math.max(level - evolutionLevel, 0), preferredMinLevel * 2.5) / (preferredMinLevel * 2.5)), 1);
}
}
if (evolutionChance > 0) {
if (isRegionalEvolution)
if (isRegionalEvolution) {
evolutionChance /= (evolutionSpecies.isRareRegional() ? 16 : 4);
}
totalWeight += evolutionChance;
evolutionPool.set(totalWeight, ev.speciesId);
if ((1 - evolutionChance) < noEvolutionChance)
if ((1 - evolutionChance) < noEvolutionChance) {
noEvolutionChance = 1 - evolutionChance;
}
}
}
if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance)
if (noEvolutionChance === 1 || Phaser.Math.RND.realInRange(0, 1) < noEvolutionChance) {
return this.speciesId;
}
const randValue = evolutionPool.size === 1 ? 0 : Utils.randSeedInt(totalWeight);
for (let weight of evolutionPool.keys()) {
if (randValue < weight)
for (const weight of evolutionPool.keys()) {
if (randValue < weight) {
return getPokemonSpecies(evolutionPool.get(weight)).getSpeciesForLevel(level, true, forTrainer, strength);
}
}
return this.speciesId;
}
@ -664,16 +699,17 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
//console.log(Species[this.speciesId], pokemonEvolutions[this.speciesId])
if (pokemonEvolutions.hasOwnProperty(this.speciesId)) {
for (let e of pokemonEvolutions[this.speciesId]) {
for (const e of pokemonEvolutions[this.speciesId]) {
const speciesId = e.speciesId;
const level = e.level;
evolutionLevels.push([ speciesId, level ]);
//console.log(Species[speciesId], getPokemonSpecies(speciesId), getPokemonSpecies(speciesId).getEvolutionLevels());
const nextEvolutionLevels = getPokemonSpecies(speciesId).getEvolutionLevels();
for (let npl of nextEvolutionLevels)
for (const npl of nextEvolutionLevels) {
evolutionLevels.push(npl);
}
}
}
return evolutionLevels;
}
@ -682,18 +718,19 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
const prevolutionLevels = [];
const allEvolvingPokemon = Object.keys(pokemonEvolutions);
for (let p of allEvolvingPokemon) {
for (let e of pokemonEvolutions[p]) {
for (const p of allEvolvingPokemon) {
for (const e of pokemonEvolutions[p]) {
if (e.speciesId === this.speciesId && (!this.forms.length || !e.evoFormKey || e.evoFormKey === this.forms[this.formIndex].formKey)) {
const speciesId = parseInt(p) as Species;
let level = e.level;
const level = e.level;
prevolutionLevels.push([ speciesId, level ]);
const subPrevolutionLevels = getPokemonSpecies(speciesId).getPrevolutionLevels();
for (let spl of subPrevolutionLevels)
for (const spl of subPrevolutionLevels) {
prevolutionLevels.push(spl);
}
}
}
}
return prevolutionLevels;
}
@ -747,7 +784,7 @@ export default class PokemonSpecies extends PokemonSpeciesForm implements Locali
}
return this.forms?.length
? this.forms[formIndex || 0].getFormSpriteKey()
: '';
: "";
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,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!`,
"blockRecoilDamage" : "{{pokemonName}}'s {{abilityName}}\nprotected it from recoil!",
"badDreams": "{{pokemonName}} is tormented!",
} as const;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Ajustes',
"GAME_SETTINGS": "Ajustes",
"ACHIEVEMENTS": "Logros",
"STATS": "Estadísticas",
"VOUCHERS": "Vales",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -711,7 +711,7 @@ export const ability: AbilityTranslationEntries = {
},
megaLauncher: {
name: "Megalancio",
description: 'Potenzia le mosse "pulsar", Forzasfera e Ondasana.',
description: "Potenzia le mosse \"pulsar\", Forzasfera e Ondasana.",
},
grassPelt: {
name: "Peloderba",

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const menuUiHandler: SimpleTranslationEntries = {
"GAME_SETTINGS": 'Impostazioni',
"GAME_SETTINGS": "Impostazioni",
"ACHIEVEMENTS": "Risultati",
"STATS": "Statistiche",
"VOUCHERS": "Biglietti",

View File

@ -18,7 +18,7 @@ export const splashMessages: SimpleTranslationEntries = {
"magnificent": "Magnifico!",
"mubstitute": "Mubstitute!",
"thatsCrazy": "È Pazzesco!",
"oranceJuice": "Succo d\'Arancia!",
"oranceJuice": "Succo d'Arancia!",
"questionableBalancing": "Bilanciamento Discutibile!",
"coolShaders": "Shader fantastici!",
"aiFree": "Senza Intelligenza Artificiale!",

View File

@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc.
*/
export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam":'Vuoi iniziare con questi Pokémon?',
"confirmStartTeam":"Vuoi iniziare con questi Pokémon?",
"gen1": "I",
"gen2": "II",
"gen3": "III",
@ -20,25 +20,25 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"ability": "Abilità:",
"passive": "Passiva:",
"nature": "Natura:",
"eggMoves": 'Mosse delle uova',
"eggMoves": "Mosse delle uova",
"start": "Inizia",
"addToParty": "Aggiungi al Gruppo",
"toggleIVs": 'Vedi/Nascondi IV',
"manageMoves": 'Gestisci Mosse',
"useCandies": 'Usa Caramelle',
"toggleIVs": "Vedi/Nascondi IV",
"manageMoves": "Gestisci Mosse",
"useCandies": "Usa Caramelle",
"selectMoveSwapOut": "Seleziona una mossa da scambiare.",
"selectMoveSwapWith": "Seleziona una mossa da scambiare con",
"unlockPassive": "Sblocca Passiva",
"reduceCost": "Riduci Costo",
"cycleShiny": "R: Alterna Shiny",
"cycleForm": 'F: Alterna Forma',
"cycleGender": 'G: Alterna Sesso',
"cycleAbility": 'E: Alterna Abilità',
"cycleNature": 'N: Alterna Natura',
"cycleVariant": 'V: Alterna Variante',
"cycleForm": "F: Alterna Forma",
"cycleGender": "G: Alterna Sesso",
"cycleAbility": "E: Alterna Abilità",
"cycleNature": "N: Alterna Natura",
"cycleVariant": "V: Alterna Variante",
"enablePassive": "Attiva Passiva",
"disablePassive": "Disattiva Passiva",
"locked": "Bloccato",
"disabled": "Disabilitato",
"uncaught": "Non Catturato"
}
};

View File

@ -6,7 +6,7 @@ export const tutorial: SimpleTranslationEntries = {
$Il gioco è work-in-progress ma giocabile al 100%.\nPer reportare eventuali bugs è possibile discuterne sul nostro Discord.
$Se il game risulta 'lento', assicurati di aver abilitato l'Accelerazione Hardware nelle impostazioni del tuo Browser`,
"accessMenu": `Per accedere al menù, press M o Esc.\nDal menù puoi cambiare impostazioni, controllare la wiki e accedere a varie features.`,
"accessMenu": "Per accedere al menù, press M o Esc.\nDal menù puoi cambiare impostazioni, controllare la wiki e accedere a varie features.",
"menu": `Da questo menù puoi accedere alle impostazioni.
$Dalle impostazioni puoi cambiare velocità di gioco, stile di finestra e altre opzioni.

View File

@ -41,4 +41,4 @@ export const weather: SimpleTranslationEntries = {
"strongWindsStartMessage": "È apparsa una corrente d'aria misteriosa!",
"strongWindsLapseMessage": "La corrente d'aria soffia intensamente.",
"strongWindsClearMessage": "La corrente d'aria è cessata."
}
};

View File

@ -1,5 +1,5 @@
import { SimpleTranslationEntries } from "#app/plugins/i18n";
export const abilityTriggers: SimpleTranslationEntries = {
'blockRecoilDamage' : `{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano de recuo!`,
"blockRecoilDamage" : "{{abilityName}} de {{pokemonName}}\nprotegeu-o do dano de recuo!",
} as const;

View File

@ -21,7 +21,7 @@ export const battle: SimpleTranslationEntries = {
"hitResultNoEffect": "Isso não afeta {{pokemonName}}!",
"hitResultOneHitKO": "Foi um nocaute de um golpe!",
"attackFailed": "Mas falhou!",
"attackHitsCount": `Acertou {{count}} vezes.`,
"attackHitsCount": "Acertou {{count}} vezes.",
"expGain": "{{pokemonName}} ganhou\n{{exp}} pontos de experiência.",
"levelUp": "{{pokemonName}} subiu para \nNv. {{level}}!",
"learnMove": "{{pokemonName}} aprendeu {{moveName}}!",

View File

@ -47,4 +47,4 @@ export const ptBrConfig = {
modifierType: modifierType,
berry: berry,
voucher: voucher,
}
};

View File

@ -6,7 +6,7 @@ import { SimpleTranslationEntries } from "#app/plugins/i18n";
* account interactions, descriptive text, etc.
*/
export const starterSelectUiHandler: SimpleTranslationEntries = {
"confirmStartTeam": 'Começar com esses Pokémon?',
"confirmStartTeam": "Começar com esses Pokémon?",
"gen1": "I",
"gen2": "II",
"gen3": "III",
@ -31,14 +31,14 @@ export const starterSelectUiHandler: SimpleTranslationEntries = {
"unlockPassive": "Aprender Passiva",
"reduceCost": "Reduzir Custo",
"cycleShiny": "R: Mudar Shiny",
"cycleForm": 'F: Mudar Forma',
"cycleGender": 'G: Mudar Gênero',
"cycleAbility": 'E: Mudar Habilidade',
"cycleNature": 'N: Mudar Natureza',
"cycleVariant": 'V: Mudar Variante',
"cycleForm": "F: Mudar Forma",
"cycleGender": "G: Mudar Gênero",
"cycleAbility": "E: Mudar Habilidade",
"cycleNature": "N: Mudar Natureza",
"cycleVariant": "V: Mudar Variante",
"enablePassive": "Ativar Passiva",
"disablePassive": "Desativar Passiva",
"locked": "Bloqueada",
"disabled": "Desativada",
"uncaught": "Não capturado"
}
};

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