Merge branch 'beta' into fix-diamond-storm

This commit is contained in:
NightKev 2024-10-04 00:04:37 -07:00 committed by GitHub
commit ad8900398f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
434 changed files with 7924 additions and 6713 deletions

View File

@ -3,4 +3,4 @@ VITE_BYPASS_TUTORIAL=0
VITE_SERVER_URL=https://apibeta.pokerogue.net
VITE_DISCORD_CLIENT_ID=1248062921129459756
VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com
VITE_I18N_DEBUG=1
VITE_I18N_DEBUG=0

View File

@ -3,5 +3,5 @@ VITE_BYPASS_TUTORIAL=0
VITE_SERVER_URL=http://localhost:8001
VITE_DISCORD_CLIENT_ID=1234567890
VITE_GOOGLE_CLIENT_ID=1234567890
VITE_I18N_DEBUG=1
VITE_I18N_DEBUG=0
VITE_PORT=8000

View File

@ -1,9 +1,7 @@
/**
* This script creates a test boilerplate file for a move or ability.
* @param {string} type - The type of test to create. Either "move", "ability",
* or "item".
* @param {string} fileName - The name of the file to create.
* @example npm run create-test move tackle
* This script creates a test boilerplate file in the appropriate
* directory based on the type selected.
* @example npm run create-test
*/
import fs from "fs";
@ -34,7 +32,7 @@ async function promptTestType() {
console.log("Exiting...");
return process.exit();
} else if (!typeChoices.includes(typeAnswer.selectedOption)) {
console.error('Please provide a valid type ("move", "ability", or "item")!');
console.error(`Please provide a valid type (${typeChoices.join(", ")})!`);
return await promptTestType();
}
@ -102,7 +100,7 @@ async function runInteractive() {
description = `Mystery Encounter - ${formattedName}`;
break;
default:
console.error('Invalid type. Please use "move", "ability", or "item".');
console.error(`Invalid type. Please use one of the following: ${typeChoices.join(", ")}.`);
process.exit(1);
}

View File

@ -41,6 +41,11 @@ export default [
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
"array-bracket-spacing": ["error", "always", { "objectsInArrays": false, "arraysInArrays": false }], // Enforces consistent spacing inside array brackets
"object-curly-spacing": ["error", "always", { "arraysInObjects": false, "objectsInObjects": false }], // Enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers
"computed-property-spacing": ["error", "never" ], // Enforces consistent spacing inside computed property brackets
"space-infix-ops": ["error", { "int32Hint": false }], // Enforces spacing around infix operators
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], // Disallows multiple empty lines
}
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

View File

@ -20,7 +20,7 @@ export function initLoggedInUser(): void {
export function updateUserInfo(): Promise<[boolean, integer]> {
return new Promise<[boolean, integer]>(resolve => {
if (bypassLogin) {
loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false};
loggedInUser = { username: "Guest", lastSessionSlot: -1, discordId: "", googleId: "", hasAdminRole: false };
let lastSessionSlot = -1;
for (let s = 0; s < 5; s++) {
if (localStorage.getItem(`sessionData${s ? s : ""}_${loggedInUser.username}`)) {

View File

@ -25,7 +25,7 @@ import { trainerConfigs, TrainerSlot } from "./data/trainer-config";
import Trainer, { TrainerVariant } from "./field/trainer";
import TrainerData from "./system/trainer-data";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { pokemonPrevolutions } from "./data/pokemon-evolutions";
import { pokemonPrevolutions } from "./data/balance/pokemon-evolutions";
import PokeballTray from "./ui/pokeball-tray";
import InvertPostFX from "./pipelines/invert";
import { Achv, achvs, ModifierAchv, MoneyAchv } from "./system/achv";
@ -42,7 +42,7 @@ import PokemonSpriteSparkleHandler from "./field/pokemon-sprite-sparkle-handler"
import CharSprite from "./ui/char-sprite";
import DamageNumberHandler from "./field/damage-number-handler";
import PokemonInfoContainer from "./ui/pokemon-info-container";
import { biomeDepths, getBiomeName } from "./data/biomes";
import { biomeDepths, getBiomeName } from "./data/balance/biomes";
import { SceneBase } from "./scene-base";
import CandyBar from "./ui/candy-bar";
import { Variant, variantData } from "./data/variant";
@ -889,6 +889,9 @@ export default class BattleScene extends SceneBase {
}
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
if (Overrides.OPP_FUSION_OVERRIDE) {
pokemon.generateFusionSpecies();
}
overrideModifiers(this, false);
overrideHeldItems(this, pokemon, false);
@ -1261,7 +1264,7 @@ export default class BattleScene extends SceneBase {
const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0;
const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49;
const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne);
const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
const resetArenaState = isNewBiome || [ BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER ].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS;
this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
this.trySpreadPokerus();
if (!isNewBiome && (newWaveIndex % 10) === 5) {
@ -1758,14 +1761,14 @@ export default class BattleScene extends SceneBase {
if (fromArenaPool) {
return this.arena.randomSpecies(waveIndex, level, undefined, getPartyLuckValue(this.party));
}
const filteredSpecies = speciesFilter ? [...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => {
const filteredSpecies = speciesFilter ? [ ...new Set(allSpecies.filter(s => s.isCatchable()).filter(speciesFilter).map(s => {
if (!filterAllEvolutions) {
while (pokemonPrevolutions.hasOwnProperty(s.speciesId)) {
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);
}
}
return s;
}))] : allSpecies.filter(s => s.isCatchable());
})) ] : allSpecies.filter(s => s.isCatchable());
return filteredSpecies[Utils.randSeedInt(filteredSpecies.length)];
}
@ -1885,14 +1888,14 @@ export default class BattleScene extends SceneBase {
case "battle_anims":
case "cry":
if (soundDetails[1].startsWith("PRSFX- ")) {
sound.setVolume(this.masterVolume*this.fieldVolume*0.5);
sound.setVolume(this.masterVolume * this.fieldVolume * 0.5);
} else {
sound.setVolume(this.masterVolume*this.fieldVolume);
sound.setVolume(this.masterVolume * this.fieldVolume);
}
break;
case "se":
case "ui":
sound.setVolume(this.masterVolume*this.seVolume);
sound.setVolume(this.masterVolume * this.seVolume);
}
}
}
@ -2221,7 +2224,7 @@ export default class BattleScene extends SceneBase {
*
*/
pushConditionalPhase(phase: Phase, condition: () => boolean): void {
this.conditionalQueue.push([condition, phase]);
this.conditionalQueue.push([ condition, phase ]);
}
/**
@ -2445,7 +2448,10 @@ export default class BattleScene extends SceneBase {
}
if ((modifier as PersistentModifier).add(this.modifiers, !!virtual, this)) {
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
success = modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
const pokemon = this.getPokemonById(modifier.pokemonId);
if (pokemon) {
success = modifier.apply(pokemon, true);
}
}
if (playSound && !this.sound.get(soundName)) {
this.playSound(soundName);
@ -2472,7 +2478,7 @@ export default class BattleScene extends SceneBase {
for (const p in this.party) {
const pokemon = this.party[p];
const args: any[] = [ pokemon ];
const args: unknown[] = [];
if (modifier instanceof PokemonHpRestoreModifier) {
if (!(modifier as PokemonHpRestoreModifier).fainted) {
const hpRestoreMultiplier = new Utils.IntegerHolder(1);
@ -2485,8 +2491,8 @@ export default class BattleScene extends SceneBase {
args.push(this.getPokemonById(modifier.fusePokemonId) as PlayerPokemon);
}
if (modifier.shouldApply(args)) {
const result = modifier.apply(args);
if (modifier.shouldApply(pokemon, ...args)) {
const result = modifier.apply(pokemon, ...args);
if (result instanceof Promise) {
modifierPromises.push(result.then(s => success ||= s));
} else {
@ -2495,11 +2501,11 @@ export default class BattleScene extends SceneBase {
}
}
return Promise.allSettled([this.party.map(p => p.updateInfo(instant)), ...modifierPromises]).then(() => resolve(success));
return Promise.allSettled([ this.party.map(p => p.updateInfo(instant)), ...modifierPromises ]).then(() => resolve(success));
} else {
const args = [ this ];
if (modifier.shouldApply(args)) {
const result = modifier.apply(args);
if (modifier.shouldApply(...args)) {
const result = modifier.apply(...args);
if (result instanceof Promise) {
return result.then(success => resolve(success));
} else {
@ -2521,7 +2527,10 @@ export default class BattleScene extends SceneBase {
}
if ((modifier as PersistentModifier).add(this.enemyModifiers, false, this)) {
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
modifier.apply([ this.getPokemonById(modifier.pokemonId), true ]);
const pokemon = this.getPokemonById(modifier.pokemonId);
if (pokemon) {
modifier.apply(pokemon, true);
}
}
for (const rm of modifiersToRemove) {
this.removeModifier(rm, true);
@ -2755,7 +2764,10 @@ export default class BattleScene extends SceneBase {
if (modifierIndex > -1) {
modifiers.splice(modifierIndex, 1);
if (modifier instanceof PokemonFormChangeItemModifier || modifier instanceof TerastallizeModifier) {
modifier.apply([ this.getPokemonById(modifier.pokemonId), false ]);
const pokemon = this.getPokemonById(modifier.pokemonId);
if (pokemon) {
modifier.apply(pokemon, false);
}
}
return true;
}
@ -2773,38 +2785,66 @@ export default class BattleScene extends SceneBase {
return (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType);
}
findModifiers(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier[] {
return (player ? this.modifiers : this.enemyModifiers).filter(m => (modifierFilter as ModifierPredicate)(m));
/**
* Get all of the modifiers that pass the `modifierFilter` function
* @param modifierFilter The function used to filter a target's modifiers
* @param isPlayer Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @returns the list of all modifiers that passed the `modifierFilter` function
*/
findModifiers(modifierFilter: ModifierPredicate, isPlayer: boolean = true): PersistentModifier[] {
return (isPlayer ? this.modifiers : this.enemyModifiers).filter(modifierFilter);
}
/**
* Find the first modifier that pass the `modifierFilter` function
* @param modifierFilter The function used to filter a target's modifiers
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @returns the first modifier that passed the `modifierFilter` function; `undefined` if none passed
*/
findModifier(modifierFilter: ModifierPredicate, player: boolean = true): PersistentModifier | undefined {
return (player ? this.modifiers : this.enemyModifiers).find(m => (modifierFilter as ModifierPredicate)(m));
return (player ? this.modifiers : this.enemyModifiers).find(modifierFilter);
}
applyShuffledModifiers(scene: BattleScene, modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
/**
* Apply all modifiers that match `modifierType` in a random order
* @param scene {@linkcode BattleScene} used to randomize the order of modifiers
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply`
* @returns the list of all modifiers that matched `modifierType` and were applied.
*/
applyShuffledModifiers<T extends PersistentModifier>(scene: BattleScene, modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
let modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
scene.executeWithSeedOffset(() => {
const shuffleModifiers = mods => {
if (mods.length < 1) {
return mods;
}
const rand = Utils.randSeedInt(mods.length);
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
return [ mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand)) ];
};
modifiers = shuffleModifiers(modifiers);
}, scene.currentBattle.turn << 4, scene.waveSeed);
return this.applyModifiersInternal(modifiers, player, args);
}
applyModifiers(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier[] {
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
/**
* Apply all modifiers that match `modifierType`
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply`
* @returns the list of all modifiers that matched `modifierType` and were applied.
*/
applyModifiers<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T[] {
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
return this.applyModifiersInternal(modifiers, player, args);
}
applyModifiersInternal(modifiers: PersistentModifier[], player: boolean, args: any[]): PersistentModifier[] {
const appliedModifiers: PersistentModifier[] = [];
/** Helper function to apply all passed modifiers */
applyModifiersInternal<T extends PersistentModifier>(modifiers: T[], player: boolean, args: Parameters<T["apply"]>): T[] {
const appliedModifiers: T[] = [];
for (const modifier of modifiers) {
if (modifier.apply(args)) {
if (modifier.apply(...args)) {
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
appliedModifiers.push(modifier);
}
@ -2813,10 +2853,17 @@ export default class BattleScene extends SceneBase {
return appliedModifiers;
}
applyModifier(modifierType: Constructor<Modifier>, player: boolean = true, ...args: any[]): PersistentModifier | null {
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter(m => m instanceof modifierType && m.shouldApply(args));
/**
* Apply the first modifier that matches `modifierType`
* @param modifierType The type of modifier to apply; must extend {@linkcode PersistentModifier}
* @param player Whether to search the player (`true`) or the enemy (`false`); Defaults to `true`
* @param ...args The list of arguments needed to invoke `modifierType.apply`
* @returns the first modifier that matches `modifierType` and was applied; return `null` if none matched
*/
applyModifier<T extends PersistentModifier>(modifierType: Constructor<T>, player: boolean = true, ...args: Parameters<T["apply"]>): T | null {
const modifiers = (player ? this.modifiers : this.enemyModifiers).filter((m): m is T => m instanceof modifierType && m.shouldApply(...args));
for (const modifier of modifiers) {
if (modifier.apply(args)) {
if (modifier.apply(...args)) {
console.log("Applied", modifier.type.name, !player ? "(enemy)" : "");
return modifier;
}
@ -2882,7 +2929,7 @@ export default class BattleScene extends SceneBase {
}
}
validateAchv(achv: Achv, args?: any[]): boolean {
validateAchv(achv: Achv, args?: unknown[]): boolean {
if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) {
this.gameData.achvUnlocks[achv.id] = new Date().getTime();
this.ui.achvBar.showAchv(achv);
@ -2895,7 +2942,7 @@ export default class BattleScene extends SceneBase {
return false;
}
validateVoucher(voucher: Voucher, args?: any[]): boolean {
validateVoucher(voucher: Voucher, args?: unknown[]): boolean {
if (!this.gameData.voucherUnlocks.hasOwnProperty(voucher.id) && voucher.validate(this, args)) {
this.gameData.voucherUnlocks[voucher.id] = new Date().getTime();
this.ui.achvBar.showAchv(voucher);
@ -2934,7 +2981,7 @@ export default class BattleScene extends SceneBase {
keys.push(p.getBattleSpriteKey(true, true));
keys.push("cry/" + p.species.getCryKey(p.formIndex));
if (p.fusionSpecies) {
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex));
}
});
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
@ -2943,7 +2990,7 @@ export default class BattleScene extends SceneBase {
keys.push(p.getSpriteKey(true));
keys.push("cry/" + p.species.getCryKey(p.formIndex));
if (p.fusionSpecies) {
keys.push("cry/"+p.fusionSpecies.getCryKey(p.fusionFormIndex));
keys.push("cry/" + p.fusionSpecies.getCryKey(p.fusionFormIndex));
}
});
return keys;
@ -3091,7 +3138,7 @@ export default class BattleScene extends SceneBase {
* @param sessionDataEncounterType
*/
private isWaveMysteryEncounter(newBattleType: BattleType, waveIndex: number, sessionDataEncounterType?: MysteryEncounterType): boolean {
const [lowestMysteryEncounterWave, highestMysteryEncounterWave] = this.gameMode.getMysteryEncounterLegalWaves();
const [ lowestMysteryEncounterWave, highestMysteryEncounterWave ] = this.gameMode.getMysteryEncounterLegalWaves();
if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(waveIndex) && waveIndex < highestMysteryEncounterWave && waveIndex > lowestMysteryEncounterWave) {
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
@ -3157,7 +3204,7 @@ export default class BattleScene extends SceneBase {
}
// See Enum values for base tier weights
const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE];
const tierWeights = [ MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE ];
// Adjust tier weights by previously encountered events to lower odds of only Common/Great in run
this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => {

View File

@ -497,7 +497,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
}
/* 1/3 chance for evil team grunts to be double battles */
const evilTeamGrunts = [TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT];
const evilTeamGrunts = [ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ];
const isEvilTeamGrunt = evilTeamGrunts.includes(trainerTypes[rand]);
if (trainerConfigs[trainerTypes[rand]].hasDouble && isEvilTeamGrunt) {
@ -527,34 +527,34 @@ export const classicFixedBattles: FixedBattleConfigs = {
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_2, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_3, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
[64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true)),
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)),
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_4, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
[114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ] ], true, 1)),
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)),
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_5, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA], allowLuckUpgrades: false }),
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
@ -567,5 +567,5 @@ export const classicFixedBattles: FixedBattleConfigs = {
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
.setGetTrainerFunc(scene => new Trainer(scene, TrainerType.RIVAL_6, scene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
.setCustomModifierRewards({ guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], allowLuckUpgrades: false })
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false })
};

View File

@ -1,5 +1,5 @@
import {Button} from "#enums/buttons";
import {SettingKeyboard} from "#app/system/settings/settings-keyboard";
import { Button } from "#enums/buttons";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
const cfg_keyboard_qwerty = {
padID: "default",

View File

@ -1,4 +1,4 @@
import {Device} from "#enums/devices";
import { Device } from "#enums/devices";
/**
* Retrieves the key associated with the specified keycode from the mapping.

View File

@ -1,5 +1,5 @@
import {SettingGamepad} from "../../system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
import { SettingGamepad } from "../../system/settings/settings-gamepad";
import { Button } from "#enums/buttons";
/**
* Dualshock mapping

View File

@ -1,5 +1,5 @@
import {SettingGamepad} from "../../system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
import { SettingGamepad } from "../../system/settings/settings-gamepad";
import { Button } from "#enums/buttons";
/**
* Generic pad mapping

View File

@ -1,5 +1,5 @@
import {SettingGamepad} from "#app/system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
import { SettingGamepad } from "#app/system/settings/settings-gamepad";
import { Button } from "#enums/buttons";
/**
* Nintendo Pro Controller mapping

View File

@ -1,5 +1,5 @@
import {SettingGamepad} from "../../system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
import { SettingGamepad } from "../../system/settings/settings-gamepad";
import { Button } from "#enums/buttons";
/**
* 081f-e401 - UnlicensedSNES

View File

@ -1,5 +1,5 @@
import {SettingGamepad} from "../../system/settings/settings-gamepad";
import {Button} from "#enums/buttons";
import { SettingGamepad } from "../../system/settings/settings-gamepad";
import { Button } from "#enums/buttons";
/**
* Generic pad mapping

View File

@ -162,7 +162,7 @@ export class BlockRecoilDamageAttr extends AbAttr {
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]) {
return i18next.t("abilityTriggers:blockRecoilDamage", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
return i18next.t("abilityTriggers:blockRecoilDamage", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
}
}
@ -964,7 +964,7 @@ export class PostDefendPerishSongAbAttr extends PostDefendAbAttr {
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:perishBody", {pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName});
return i18next.t("abilityTriggers:perishBody", { pokemonName: getPokemonNameWithAffix(pokemon), abilityName: abilityName });
}
}
@ -1268,7 +1268,7 @@ export class PokemonTypeChangeAbAttr extends PreAttackAbAttr {
if (pokemon.getTypes().some((t) => t !== moveType)) {
if (!simulated) {
this.moveType = moveType;
pokemon.summonData.types = [moveType];
pokemon.summonData.types = [ moveType ];
pokemon.updateInfo();
}
@ -2814,7 +2814,7 @@ export class PreApplyBattlerTagImmunityAbAttr extends PreApplyBattlerTagAbAttr {
constructor(immuneTagTypes: BattlerTagType | BattlerTagType[]) {
super();
this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [immuneTagTypes];
this.immuneTagTypes = Array.isArray(immuneTagTypes) ? immuneTagTypes : [ immuneTagTypes ];
}
applyPreApplyBattlerTag(pokemon: Pokemon, passive: boolean, simulated: boolean, tag: BattlerTag, cancelled: Utils.BooleanHolder, args: any[]): boolean {
@ -3099,17 +3099,17 @@ function getAnticipationCondition(): AbAttrCondition {
// edge case for hidden power, type is computed
if (move.getMove().id === Moves.HIDDEN_POWER) {
const iv_val = Math.floor(((opponent.ivs[Stat.HP] & 1)
+(opponent.ivs[Stat.ATK] & 1) * 2
+(opponent.ivs[Stat.DEF] & 1) * 4
+(opponent.ivs[Stat.SPD] & 1) * 8
+(opponent.ivs[Stat.SPATK] & 1) * 16
+(opponent.ivs[Stat.SPDEF] & 1) * 32) * 15/63);
+ (opponent.ivs[Stat.ATK] & 1) * 2
+ (opponent.ivs[Stat.DEF] & 1) * 4
+ (opponent.ivs[Stat.SPD] & 1) * 8
+ (opponent.ivs[Stat.SPATK] & 1) * 16
+ (opponent.ivs[Stat.SPDEF] & 1) * 32) * 15 / 63);
const type = [
Type.FIGHTING, Type.FLYING, Type.POISON, Type.GROUND,
Type.ROCK, Type.BUG, Type.GHOST, Type.STEEL,
Type.FIRE, Type.WATER, Type.GRASS, Type.ELECTRIC,
Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK][iv_val];
Type.PSYCHIC, Type.ICE, Type.DRAGON, Type.DARK ][iv_val];
if (pokemon.getAttackTypeEffectiveness(type, opponent) >= 2) {
return true;
@ -3644,7 +3644,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
if ((opp.status?.effect === StatusEffect.SLEEP || opp.hasAbility(Abilities.COMATOSE)) && !opp.hasAbilityWithAttr(BlockNonDirectDamageAbAttr)) {
if (!simulated) {
opp.damageAndUpdate(Utils.toDmgValue(opp.getMaxHp() / 8), HitResult.OTHER);
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", {pokemonName: getPokemonNameWithAffix(opp)}));
pokemon.scene.queueMessage(i18next.t("abilityTriggers:badDreams", { pokemonName: getPokemonNameWithAffix(opp) }));
}
hadEffect = true;
}
@ -3755,8 +3755,8 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
*/
applyPostMoveUsed(dancer: Pokemon, move: PokemonMove, source: Pokemon, targets: BattlerIndex[], simulated: boolean, args: any[]): boolean | Promise<boolean> {
// List of tags that prevent the Dancer from replicating the move
const forbiddenTags = [BattlerTagType.FLYING, BattlerTagType.UNDERWATER,
BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN];
const forbiddenTags = [ BattlerTagType.FLYING, BattlerTagType.UNDERWATER,
BattlerTagType.UNDERGROUND, BattlerTagType.HIDDEN ];
// The move to replicate cannot come from the Dancer
if (source.getBattlerIndex() !== dancer.getBattlerIndex()
&& !dancer.summonData.tags.some(tag => forbiddenTags.includes(tag.tagType))) {
@ -3767,7 +3767,7 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, target, move, true, true));
} else if (move.getMove() instanceof SelfStatusMove) {
// If the move is a SelfStatusMove (ie. Swords Dance) the Dancer should replicate it on itself
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [dancer.getBattlerIndex()], move, true, true));
dancer.scene.unshiftPhase(new MovePhase(dancer.scene, dancer, [ dancer.getBattlerIndex() ], move, true, true));
}
}
return true;
@ -3784,9 +3784,9 @@ export class PostDancingMoveAbAttr extends PostMoveUsedAbAttr {
*/
getTarget(dancer: Pokemon, source: Pokemon, targets: BattlerIndex[]) : BattlerIndex[] {
if (dancer.isPlayer()) {
return source.isPlayer() ? targets : [source.getBattlerIndex()];
return source.isPlayer() ? targets : [ source.getBattlerIndex() ];
}
return source.isPlayer() ? [source.getBattlerIndex()] : targets;
return source.isPlayer() ? [ source.getBattlerIndex() ] : targets;
}
}
@ -4561,7 +4561,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
const turnCommand =
pokemon.scene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
const isCommandFight = turnCommand?.command === Command.FIGHT;
const move = turnCommand?.move?.move ?allMoves[turnCommand.move.move] : null;
const move = turnCommand?.move?.move ? allMoves[turnCommand.move.move] : null;
const isDamageMove = move?.category === MoveCategory.PHYSICAL || move?.category === MoveCategory.SPECIAL;
if (isCommandFight && isDamageMove) {
@ -4574,7 +4574,7 @@ export class BypassSpeedChanceAbAttr extends AbAttr {
}
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:quickDraw", {pokemonName: getPokemonNameWithAffix(pokemon)});
return i18next.t("abilityTriggers:quickDraw", { pokemonName: getPokemonNameWithAffix(pokemon) });
}
}
@ -4622,7 +4622,7 @@ async function applyAbAttrsInternal<TAttr extends AbAttr>(
simulated: boolean = false,
messages: string[] = [],
) {
for (const passive of [false, true]) {
for (const passive of [ false, true ]) {
if (!pokemon?.canApplyAbility(passive)) {
continue;
}
@ -4872,7 +4872,7 @@ export function initAbilities() {
.attr(TypeImmunityHealAbAttr, Type.WATER)
.ignorable(),
new Ability(Abilities.OBLIVIOUS, 3)
.attr(BattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT])
.attr(BattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT ])
.attr(IntimidateImmunityAbAttr)
.ignorable(),
new Ability(Abilities.CLOUD_NINE, 3)
@ -5017,10 +5017,10 @@ export function initAbilities() {
new Ability(Abilities.CUTE_CHARM, 3)
.attr(PostDefendContactApplyTagChanceAbAttr, 30, BattlerTagType.INFATUATED),
new Ability(Abilities.PLUS, 3)
.conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.ignorable(),
new Ability(Abilities.MINUS, 3)
.conditionalAttr(p => p.scene.currentBattle.double && [Abilities.PLUS, Abilities.MINUS].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.conditionalAttr(p => p.scene.currentBattle.double && [ Abilities.PLUS, Abilities.MINUS ].some(a => p.getAlly().hasAbility(a)), StatMultiplierAbAttr, Stat.SPATK, 1.5)
.ignorable(),
new Ability(Abilities.FORECAST, 3)
.attr(UncopiableAbilityAbAttr)
@ -5138,7 +5138,7 @@ export function initAbilities() {
.conditionalAttr(pokemon => !!pokemon.status || pokemon.hasAbility(Abilities.COMATOSE), StatMultiplierAbAttr, Stat.SPD, 1.5),
new Ability(Abilities.NORMALIZE, 4)
.attr(MoveTypeChangeAbAttr, Type.NORMAL, 1.2, (user, target, move) => {
return ![Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST].includes(move.id);
return ![ Moves.HIDDEN_POWER, Moves.WEATHER_BALL, Moves.NATURAL_GIFT, Moves.JUDGMENT, Moves.TECHNO_BLAST ].includes(move.id);
}),
new Ability(Abilities.SNIPER, 4)
.attr(MultCritAbAttr, 1.5),
@ -5184,7 +5184,7 @@ export function initAbilities() {
new Ability(Abilities.SLOW_START, 4)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
new Ability(Abilities.SCRAPPY, 4)
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ])
.attr(IntimidateImmunityAbAttr),
new Ability(Abilities.STORM_DRAIN, 4)
.attr(RedirectTypeMoveAbAttr, Type.WATER)
@ -5225,7 +5225,7 @@ export function initAbilities() {
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT))
.condition(getSheerForceHitDisableAbCondition()),
new Ability(Abilities.SHEER_FORCE, 5)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461/4096)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.chance >= 1, 5461 / 4096)
.attr(MoveEffectChanceMultiplierAbAttr, 0)
.partial(),
new Ability(Abilities.CONTRARY, 5)
@ -5234,7 +5234,7 @@ export function initAbilities() {
new Ability(Abilities.UNNERVE, 5)
.attr(PreventBerryUseAbAttr),
new Ability(Abilities.DEFIANT, 5)
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.ATK], 2),
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.ATK ], 2),
new Ability(Abilities.DEFEATIST, 5)
.attr(StatMultiplierAbAttr, Stat.ATK, 0.5)
.attr(StatMultiplierAbAttr, Stat.SPATK, 0.5)
@ -5320,7 +5320,7 @@ export function initAbilities() {
return move.category !== MoveCategory.STATUS
&& (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST);
}, Stat.SPD, 1)
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1),
.attr(PostIntimidateStatStageChangeAbAttr, [ Stat.SPD ], 1),
new Ability(Abilities.MAGIC_BOUNCE, 5)
.ignorable()
.unimplemented(),
@ -5357,12 +5357,12 @@ export function initAbilities() {
.attr(PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonTeravolt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) }))
.attr(MoveAbilityBypassAbAttr),
new Ability(Abilities.AROMA_VEIL, 6)
.attr(UserFieldBattlerTagImmunityAbAttr, [BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK]),
.attr(UserFieldBattlerTagImmunityAbAttr, [ BattlerTagType.INFATUATED, BattlerTagType.TAUNT, BattlerTagType.DISABLED, BattlerTagType.TORMENT, BattlerTagType.HEAL_BLOCK ]),
new Ability(Abilities.FLOWER_VEIL, 6)
.ignorable()
.unimplemented(),
new Ability(Abilities.CHEEK_POUCH, 6)
.attr(HealFromBerryUseAbAttr, 1/3),
.attr(HealFromBerryUseAbAttr, 1 / 3),
new Ability(Abilities.PROTEAN, 6)
.attr(PokemonTypeChangeAbAttr),
//.condition((p) => !p.summonData?.abilitiesApplied.includes(Abilities.PROTEAN)), //Gen 9 Implementation
@ -5375,7 +5375,7 @@ export function initAbilities() {
.attr(MoveImmunityAbAttr, (pokemon, attacker, move) => pokemon !== attacker && move.hasFlag(MoveFlags.BALLBOMB_MOVE))
.ignorable(),
new Ability(Abilities.COMPETITIVE, 6)
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [Stat.SPATK], 2),
.attr(PostStatStageChangeStatStageChangeAbAttr, (target, statsChanged, stages) => stages < 0, [ Stat.SPATK ], 2),
new Ability(Abilities.STRONG_JAW, 6)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.BITING_MOVE), 1.5),
new Ability(Abilities.REFRIGERATE, 6)
@ -5471,7 +5471,7 @@ export function initAbilities() {
new Ability(Abilities.STEELWORKER, 7)
.attr(MoveTypePowerBoostAbAttr, Type.STEEL),
new Ability(Abilities.BERSERK, 7)
.attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [Stat.SPATK], 1)
.attr(PostDefendHpGatedStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.SPATK ], 1)
.condition(getSheerForceHitDisableAbCondition()),
new Ability(Abilities.SLUSH_RUSH, 7)
.attr(StatMultiplierAbAttr, Stat.SPD, 2)
@ -5528,7 +5528,7 @@ export function initAbilities() {
.bypassFaint()
.partial(),
new Ability(Abilities.CORROSION, 7) // TODO: Test Corrosion against Magic Bounce once it is implemented
.attr(IgnoreTypeStatusEffectImmunityAbAttr, [StatusEffect.POISON, StatusEffect.TOXIC], [Type.STEEL, Type.POISON])
.attr(IgnoreTypeStatusEffectImmunityAbAttr, [ StatusEffect.POISON, StatusEffect.TOXIC ], [ Type.STEEL, Type.POISON ])
.partial(),
new Ability(Abilities.COMATOSE, 7)
.attr(UncopiableAbilityAbAttr)
@ -5545,7 +5545,7 @@ export function initAbilities() {
new Ability(Abilities.DANCER, 7)
.attr(PostDancingMoveAbAttr),
new Ability(Abilities.BATTERY, 7)
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3),
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL ], 1.3),
new Ability(Abilities.FLUFFY, 7)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2)
@ -5671,11 +5671,11 @@ export function initAbilities() {
.bypassFaint()
.ignorable(),
new Ability(Abilities.POWER_SPOT, 8)
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL], 1.3),
.attr(AllyMoveCategoryPowerBoostAbAttr, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ], 1.3),
new Ability(Abilities.MIMICRY, 8)
.unimplemented(),
new Ability(Abilities.SCREEN_CLEANER, 8)
.attr(PostSummonRemoveArenaTagAbAttr, [ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT]),
.attr(PostSummonRemoveArenaTagAbAttr, [ ArenaTagType.AURORA_VEIL, ArenaTagType.LIGHT_SCREEN, ArenaTagType.REFLECT ]),
new Ability(Abilities.STEELY_SPIRIT, 8)
.attr(UserFieldMoveTypePowerBoostAbAttr, Type.STEEL),
new Ability(Abilities.PERISH_BODY, 8)
@ -5758,7 +5758,7 @@ export function initAbilities() {
.attr(PostSummonStatStageChangeOnArenaAbAttr, ArenaTagType.TAILWIND)
.ignorable(),
new Ability(Abilities.GUARD_DOG, 9)
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.ATK], 1, true)
.attr(PostIntimidateStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
.attr(ForceSwitchOutImmunityAbAttr)
.ignorable(),
new Ability(Abilities.ROCKY_PAYLOAD, 9)
@ -5847,7 +5847,7 @@ export function initAbilities() {
.attr(PreventBypassSpeedChanceAbAttr, (pokemon, move) => move.category === MoveCategory.STATUS)
.attr(MoveAbilityBypassAbAttr, (pokemon, move: Move) => move.category === MoveCategory.STATUS),
new Ability(Abilities.MINDS_EYE, 9)
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [Type.NORMAL, Type.FIGHTING])
.attr(IgnoreTypeImmunityAbAttr, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ])
.attr(ProtectStatAbAttr, Stat.ACC)
.attr(IgnoreOpponentStatStagesAbAttr, [ Stat.EVA ])
.ignorable(),

View File

@ -135,7 +135,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
*/
apply(arena: Arena, args: any[]): boolean {
if (this.weakenedCategories.includes((args[0] as MoveCategory))) {
(args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732/4096 : 0.5;
(args[2] as Utils.NumberHolder).value = (args[1] as boolean) ? 2732 / 4096 : 0.5;
return true;
}
return false;
@ -148,7 +148,7 @@ export class WeakenMoveScreenTag extends ArenaTag {
*/
class ReflectTag extends WeakenMoveScreenTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [MoveCategory.PHYSICAL]);
super(ArenaTagType.REFLECT, turnCount, Moves.REFLECT, sourceId, side, [ MoveCategory.PHYSICAL ]);
}
onAdd(arena: Arena, quiet: boolean = false): void {
@ -164,7 +164,7 @@ class ReflectTag extends WeakenMoveScreenTag {
*/
class LightScreenTag extends WeakenMoveScreenTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [MoveCategory.SPECIAL]);
super(ArenaTagType.LIGHT_SCREEN, turnCount, Moves.LIGHT_SCREEN, sourceId, side, [ MoveCategory.SPECIAL ]);
}
onAdd(arena: Arena, quiet: boolean = false): void {
@ -180,7 +180,7 @@ class LightScreenTag extends WeakenMoveScreenTag {
*/
class AuroraVeilTag extends WeakenMoveScreenTag {
constructor(turnCount: integer, sourceId: integer, side: ArenaTagSide) {
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [MoveCategory.SPECIAL, MoveCategory.PHYSICAL]);
super(ArenaTagType.AURORA_VEIL, turnCount, Moves.AURORA_VEIL, sourceId, side, [ MoveCategory.SPECIAL, MoveCategory.PHYSICAL ]);
}
onAdd(arena: Arena, quiet: boolean = false): void {
@ -988,7 +988,7 @@ class ImprisonTag extends ArenaTrapTag {
party?.forEach((p: PlayerPokemon | EnemyPokemon ) => {
p.addTag(BattlerTagType.IMPRISON, 1, Moves.IMPRISON, this.sourceId);
});
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", {pokemonNameWithAffix: getPokemonNameWithAffix(this.source)}));
scene.queueMessage(i18next.t("battlerTags:imprisonOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(this.source) }));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import { allMoves } from "./move";
import * as Utils from "../utils";
import { allMoves } from "#app/data/move";
import * as Utils from "#app/utils";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";

View File

@ -0,0 +1,574 @@
import { Abilities } from "#app/enums/abilities";
import { Species } from "#app/enums/species";
export const starterPassiveAbilities = {
[Species.BULBASAUR]: Abilities.GRASSY_SURGE,
[Species.CHARMANDER]: Abilities.BEAST_BOOST,
[Species.SQUIRTLE]: Abilities.STURDY,
[Species.CATERPIE]: Abilities.MAGICIAN,
[Species.WEEDLE]: Abilities.TINTED_LENS,
[Species.PIDGEY]: Abilities.SHEER_FORCE,
[Species.RATTATA]: Abilities.STRONG_JAW,
[Species.SPEAROW]: Abilities.MOXIE,
[Species.EKANS]: Abilities.REGENERATOR,
[Species.SANDSHREW]: Abilities.TOUGH_CLAWS,
[Species.NIDORAN_F]: Abilities.FLARE_BOOST,
[Species.NIDORAN_M]: Abilities.GUTS,
[Species.VULPIX]: Abilities.FUR_COAT,
[Species.ZUBAT]: Abilities.INTIMIDATE,
[Species.ODDISH]: Abilities.TRIAGE,
[Species.PARAS]: Abilities.TRIAGE,
[Species.VENONAT]: Abilities.SIMPLE,
[Species.DIGLETT]: Abilities.STURDY,
[Species.MEOWTH]: Abilities.TOUGH_CLAWS,
[Species.PSYDUCK]: Abilities.SIMPLE,
[Species.MANKEY]: Abilities.IRON_FIST,
[Species.GROWLITHE]: Abilities.SPEED_BOOST,
[Species.POLIWAG]: Abilities.NO_GUARD,
[Species.ABRA]: Abilities.PSYCHIC_SURGE,
[Species.MACHOP]: Abilities.QUICK_FEET,
[Species.BELLSPROUT]: Abilities.FLOWER_GIFT,
[Species.TENTACOOL]: Abilities.TOXIC_CHAIN,
[Species.GEODUDE]: Abilities.DRY_SKIN,
[Species.PONYTA]: Abilities.MAGIC_GUARD,
[Species.SLOWPOKE]: Abilities.UNAWARE,
[Species.MAGNEMITE]: Abilities.LEVITATE,
[Species.FARFETCHD]: Abilities.SNIPER,
[Species.DODUO]: Abilities.PARENTAL_BOND,
[Species.SEEL]: Abilities.WATER_BUBBLE,
[Species.GRIMER]: Abilities.WATER_ABSORB,
[Species.SHELLDER]: Abilities.ICE_SCALES,
[Species.GASTLY]: Abilities.SHADOW_SHIELD,
[Species.ONIX]: Abilities.ROCKY_PAYLOAD,
[Species.DROWZEE]: Abilities.MAGICIAN,
[Species.KRABBY]: Abilities.THERMAL_EXCHANGE,
[Species.VOLTORB]: Abilities.TRANSISTOR,
[Species.EXEGGCUTE]: Abilities.RIPEN,
[Species.CUBONE]: Abilities.PARENTAL_BOND,
[Species.LICKITUNG]: Abilities.CHEEK_POUCH,
[Species.KOFFING]: Abilities.PARENTAL_BOND,
[Species.RHYHORN]: Abilities.FILTER,
[Species.TANGELA]: Abilities.SEED_SOWER,
[Species.KANGASKHAN]: Abilities.GUTS,
[Species.HORSEA]: Abilities.DRAGONS_MAW,
[Species.GOLDEEN]: Abilities.MULTISCALE,
[Species.STARYU]: Abilities.REGENERATOR,
[Species.SCYTHER]: Abilities.TINTED_LENS,
[Species.PINSIR]: Abilities.TINTED_LENS,
[Species.TAUROS]: Abilities.STAMINA,
[Species.MAGIKARP]: Abilities.MULTISCALE,
[Species.LAPRAS]: Abilities.LIGHTNING_ROD,
[Species.DITTO]: Abilities.ADAPTABILITY,
[Species.EEVEE]: Abilities.PICKUP,
[Species.PORYGON]: Abilities.PROTEAN,
[Species.OMANYTE]: Abilities.STURDY,
[Species.KABUTO]: Abilities.TOUGH_CLAWS,
[Species.AERODACTYL]: Abilities.ORICHALCUM_PULSE,
[Species.ARTICUNO]: Abilities.SNOW_WARNING,
[Species.ZAPDOS]: Abilities.DRIZZLE,
[Species.MOLTRES]: Abilities.DROUGHT,
[Species.DRATINI]: Abilities.AERILATE,
[Species.MEWTWO]: Abilities.NEUROFORCE,
[Species.MEW]: Abilities.PROTEAN,
[Species.CHIKORITA]: Abilities.THICK_FAT,
[Species.CYNDAQUIL]: Abilities.DROUGHT,
[Species.TOTODILE]: Abilities.TOUGH_CLAWS,
[Species.SENTRET]: Abilities.PICKUP,
[Species.HOOTHOOT]: Abilities.AERILATE,
[Species.LEDYBA]: Abilities.PRANKSTER,
[Species.SPINARAK]: Abilities.PRANKSTER,
[Species.CHINCHOU]: Abilities.WATER_BUBBLE,
[Species.PICHU]: Abilities.ELECTRIC_SURGE,
[Species.CLEFFA]: Abilities.ANALYTIC,
[Species.IGGLYBUFF]: Abilities.HUGE_POWER,
[Species.TOGEPI]: Abilities.PIXILATE,
[Species.NATU]: Abilities.TINTED_LENS,
[Species.MAREEP]: Abilities.ELECTROMORPHOSIS,
[Species.HOPPIP]: Abilities.FLUFFY,
[Species.AIPOM]: Abilities.SCRAPPY,
[Species.SUNKERN]: Abilities.DROUGHT,
[Species.YANMA]: Abilities.SHEER_FORCE,
[Species.WOOPER]: Abilities.COMATOSE,
[Species.MURKROW]: Abilities.DARK_AURA,
[Species.MISDREAVUS]: Abilities.BEADS_OF_RUIN,
[Species.UNOWN]: Abilities.PICKUP,
[Species.GIRAFARIG]: Abilities.PARENTAL_BOND,
[Species.PINECO]: Abilities.IRON_BARBS,
[Species.DUNSPARCE]: Abilities.UNAWARE,
[Species.GLIGAR]: Abilities.TOXIC_BOOST,
[Species.SNUBBULL]: Abilities.PIXILATE,
[Species.QWILFISH]: Abilities.TOXIC_DEBRIS,
[Species.SHUCKLE]: Abilities.HARVEST,
[Species.HERACROSS]: Abilities.TECHNICIAN,
[Species.SNEASEL]: Abilities.TOUGH_CLAWS,
[Species.TEDDIURSA]: Abilities.THICK_FAT,
[Species.SLUGMA]: Abilities.DESOLATE_LAND,
[Species.SWINUB]: Abilities.SLUSH_RUSH,
[Species.CORSOLA]: Abilities.STORM_DRAIN,
[Species.REMORAID]: Abilities.SIMPLE,
[Species.DELIBIRD]: Abilities.HUGE_POWER,
[Species.SKARMORY]: Abilities.LIGHTNING_ROD,
[Species.HOUNDOUR]: Abilities.DROUGHT,
[Species.PHANPY]: Abilities.SPEED_BOOST,
[Species.STANTLER]: Abilities.SPEED_BOOST,
[Species.SMEARGLE]: Abilities.PRANKSTER,
[Species.TYROGUE]: Abilities.MOXIE,
[Species.SMOOCHUM]: Abilities.PSYCHIC_SURGE,
[Species.ELEKID]: Abilities.SHEER_FORCE,
[Species.MAGBY]: Abilities.CONTRARY,
[Species.MILTANK]: Abilities.STAMINA,
[Species.RAIKOU]: Abilities.TRANSISTOR,
[Species.ENTEI]: Abilities.MOXIE,
[Species.SUICUNE]: Abilities.UNAWARE,
[Species.LARVITAR]: Abilities.SAND_RUSH,
[Species.LUGIA]: Abilities.DELTA_STREAM,
[Species.HO_OH]: Abilities.MAGIC_GUARD,
[Species.CELEBI]: Abilities.PSYCHIC_SURGE,
[Species.TREECKO]: Abilities.TINTED_LENS,
[Species.TORCHIC]: Abilities.RECKLESS,
[Species.MUDKIP]: Abilities.DRIZZLE,
[Species.POOCHYENA]: Abilities.TOUGH_CLAWS,
[Species.ZIGZAGOON]: Abilities.RUN_AWAY,
[Species.WURMPLE]: Abilities.SIMPLE,
[Species.LOTAD]: Abilities.DRIZZLE,
[Species.SEEDOT]: Abilities.SHARPNESS,
[Species.TAILLOW]: Abilities.AERILATE,
[Species.WINGULL]: Abilities.SWIFT_SWIM,
[Species.RALTS]: Abilities.PSYCHIC_SURGE,
[Species.SURSKIT]: Abilities.WATER_BUBBLE,
[Species.SHROOMISH]: Abilities.GUTS,
[Species.SLAKOTH]: Abilities.GUTS,
[Species.NINCADA]: Abilities.MAGIC_GUARD,
[Species.WHISMUR]: Abilities.PUNK_ROCK,
[Species.MAKUHITA]: Abilities.STAMINA,
[Species.AZURILL]: Abilities.MISTY_SURGE,
[Species.NOSEPASS]: Abilities.LEVITATE,
[Species.SKITTY]: Abilities.SCRAPPY,
[Species.SABLEYE]: Abilities.UNNERVE,
[Species.MAWILE]: Abilities.UNNERVE,
[Species.ARON]: Abilities.EARTH_EATER,
[Species.MEDITITE]: Abilities.MINDS_EYE,
[Species.ELECTRIKE]: Abilities.ELECTRIC_SURGE,
[Species.PLUSLE]: Abilities.POWER_SPOT,
[Species.MINUN]: Abilities.POWER_SPOT,
[Species.VOLBEAT]: Abilities.HONEY_GATHER,
[Species.ILLUMISE]: Abilities.HONEY_GATHER,
[Species.GULPIN]: Abilities.EARTH_EATER,
[Species.CARVANHA]: Abilities.SHEER_FORCE,
[Species.WAILMER]: Abilities.LEVITATE,
[Species.NUMEL]: Abilities.FUR_COAT,
[Species.TORKOAL]: Abilities.ANALYTIC,
[Species.SPOINK]: Abilities.PSYCHIC_SURGE,
[Species.SPINDA]: Abilities.SIMPLE,
[Species.TRAPINCH]: Abilities.ADAPTABILITY,
[Species.CACNEA]: Abilities.SAND_RUSH,
[Species.SWABLU]: Abilities.ADAPTABILITY,
[Species.ZANGOOSE]: Abilities.POISON_HEAL,
[Species.SEVIPER]: Abilities.MULTISCALE,
[Species.LUNATONE]: Abilities.SHADOW_SHIELD,
[Species.SOLROCK]: Abilities.DROUGHT,
[Species.BARBOACH]: Abilities.SIMPLE,
[Species.CORPHISH]: Abilities.TOUGH_CLAWS,
[Species.BALTOY]: Abilities.WELL_BAKED_BODY,
[Species.LILEEP]: Abilities.SEED_SOWER,
[Species.ANORITH]: Abilities.WATER_ABSORB,
[Species.FEEBAS]: Abilities.MAGIC_GUARD,
[Species.CASTFORM]: Abilities.ADAPTABILITY,
[Species.KECLEON]: Abilities.ADAPTABILITY,
[Species.SHUPPET]: Abilities.SHADOW_SHIELD,
[Species.DUSKULL]: Abilities.UNNERVE,
[Species.TROPIUS]: Abilities.RIPEN,
[Species.ABSOL]: Abilities.SHARPNESS,
[Species.WYNAUT]: Abilities.STURDY,
[Species.SNORUNT]: Abilities.SNOW_WARNING,
[Species.SPHEAL]: Abilities.UNAWARE,
[Species.CLAMPERL]: Abilities.DRIZZLE,
[Species.RELICANTH]: Abilities.PRIMORDIAL_SEA,
[Species.LUVDISC]: Abilities.MULTISCALE,
[Species.BAGON]: Abilities.DRAGONS_MAW,
[Species.BELDUM]: Abilities.LEVITATE,
[Species.REGIROCK]: Abilities.SAND_STREAM,
[Species.REGICE]: Abilities.SNOW_WARNING,
[Species.REGISTEEL]: Abilities.FILTER,
[Species.LATIAS]: Abilities.PRISM_ARMOR,
[Species.LATIOS]: Abilities.TINTED_LENS,
[Species.KYOGRE]: Abilities.MOLD_BREAKER,
[Species.GROUDON]: Abilities.TURBOBLAZE,
[Species.RAYQUAZA]: Abilities.UNNERVE,
[Species.JIRACHI]: Abilities.COMATOSE,
[Species.DEOXYS]: Abilities.PROTEAN,
[Species.TURTWIG]: Abilities.THICK_FAT,
[Species.CHIMCHAR]: Abilities.BEAST_BOOST,
[Species.PIPLUP]: Abilities.DRIZZLE,
[Species.STARLY]: Abilities.ROCK_HEAD,
[Species.BIDOOF]: Abilities.SAP_SIPPER,
[Species.KRICKETOT]: Abilities.SHARPNESS,
[Species.SHINX]: Abilities.SPEED_BOOST,
[Species.BUDEW]: Abilities.GRASSY_SURGE,
[Species.CRANIDOS]: Abilities.ROCK_HEAD,
[Species.SHIELDON]: Abilities.EARTH_EATER,
[Species.BURMY]: Abilities.STURDY,
[Species.COMBEE]: Abilities.INTIMIDATE,
[Species.PACHIRISU]: Abilities.HONEY_GATHER,
[Species.BUIZEL]: Abilities.MOXIE,
[Species.CHERUBI]: Abilities.ORICHALCUM_PULSE,
[Species.SHELLOS]: Abilities.REGENERATOR,
[Species.DRIFLOON]: Abilities.MAGIC_GUARD,
[Species.BUNEARY]: Abilities.ADAPTABILITY,
[Species.GLAMEOW]: Abilities.INTIMIDATE,
[Species.CHINGLING]: Abilities.PUNK_ROCK,
[Species.STUNKY]: Abilities.NEUTRALIZING_GAS,
[Species.BRONZOR]: Abilities.BULLETPROOF,
[Species.BONSLY]: Abilities.SAP_SIPPER,
[Species.MIME_JR]: Abilities.OPPORTUNIST,
[Species.HAPPINY]: Abilities.FUR_COAT,
[Species.CHATOT]: Abilities.PUNK_ROCK,
[Species.SPIRITOMB]: Abilities.VESSEL_OF_RUIN,
[Species.GIBLE]: Abilities.SAND_STREAM,
[Species.MUNCHLAX]: Abilities.RIPEN,
[Species.RIOLU]: Abilities.MINDS_EYE,
[Species.HIPPOPOTAS]: Abilities.UNAWARE,
[Species.SKORUPI]: Abilities.SUPER_LUCK,
[Species.CROAGUNK]: Abilities.MOXIE,
[Species.CARNIVINE]: Abilities.ARENA_TRAP,
[Species.FINNEON]: Abilities.WATER_BUBBLE,
[Species.MANTYKE]: Abilities.UNAWARE,
[Species.SNOVER]: Abilities.THICK_FAT,
[Species.ROTOM]: Abilities.HADRON_ENGINE,
[Species.UXIE]: Abilities.UNAWARE,
[Species.MESPRIT]: Abilities.MOODY,
[Species.AZELF]: Abilities.NEUROFORCE,
[Species.DIALGA]: Abilities.LEVITATE,
[Species.PALKIA]: Abilities.SPEED_BOOST,
[Species.HEATRAN]: Abilities.EARTH_EATER,
[Species.REGIGIGAS]: Abilities.SCRAPPY,
[Species.GIRATINA]: Abilities.SHADOW_SHIELD,
[Species.CRESSELIA]: Abilities.SHADOW_SHIELD,
[Species.PHIONE]: Abilities.SIMPLE,
[Species.MANAPHY]: Abilities.PRIMORDIAL_SEA,
[Species.DARKRAI]: Abilities.UNNERVE,
[Species.SHAYMIN]: Abilities.WIND_RIDER,
[Species.ARCEUS]: Abilities.ADAPTABILITY,
[Species.VICTINI]: Abilities.SHEER_FORCE,
[Species.SNIVY]: Abilities.MULTISCALE,
[Species.TEPIG]: Abilities.ROCK_HEAD,
[Species.OSHAWOTT]: Abilities.INTREPID_SWORD,
[Species.PATRAT]: Abilities.NO_GUARD,
[Species.LILLIPUP]: Abilities.FUR_COAT,
[Species.PURRLOIN]: Abilities.PICKUP,
[Species.PANSAGE]: Abilities.WELL_BAKED_BODY,
[Species.PANSEAR]: Abilities.WATER_ABSORB,
[Species.PANPOUR]: Abilities.SAP_SIPPER,
[Species.MUNNA]: Abilities.NEUTRALIZING_GAS,
[Species.PIDOVE]: Abilities.SNIPER,
[Species.BLITZLE]: Abilities.ELECTRIC_SURGE,
[Species.ROGGENROLA]: Abilities.SOLID_ROCK,
[Species.WOOBAT]: Abilities.OPPORTUNIST,
[Species.DRILBUR]: Abilities.SAND_STREAM,
[Species.AUDINO]: Abilities.FRIEND_GUARD,
[Species.TIMBURR]: Abilities.ROCKY_PAYLOAD,
[Species.TYMPOLE]: Abilities.POISON_HEAL,
[Species.THROH]: Abilities.STAMINA,
[Species.SAWK]: Abilities.SCRAPPY,
[Species.SEWADDLE]: Abilities.SHARPNESS,
[Species.VENIPEDE]: Abilities.STAMINA,
[Species.COTTONEE]: Abilities.FLUFFY,
[Species.PETILIL]: Abilities.SIMPLE,
[Species.BASCULIN]: Abilities.SUPREME_OVERLORD,
[Species.SANDILE]: Abilities.TOUGH_CLAWS,
[Species.DARUMAKA]: Abilities.GORILLA_TACTICS,
[Species.MARACTUS]: Abilities.WELL_BAKED_BODY,
[Species.DWEBBLE]: Abilities.ROCKY_PAYLOAD,
[Species.SCRAGGY]: Abilities.PROTEAN,
[Species.SIGILYPH]: Abilities.FLARE_BOOST,
[Species.YAMASK]: Abilities.PURIFYING_SALT,
[Species.TIRTOUGA]: Abilities.WATER_ABSORB,
[Species.ARCHEN]: Abilities.MULTISCALE,
[Species.TRUBBISH]: Abilities.NEUTRALIZING_GAS,
[Species.ZORUA]: Abilities.DARK_AURA,
[Species.MINCCINO]: Abilities.FUR_COAT,
[Species.GOTHITA]: Abilities.UNNERVE,
[Species.SOLOSIS]: Abilities.PSYCHIC_SURGE,
[Species.DUCKLETT]: Abilities.DRIZZLE,
[Species.VANILLITE]: Abilities.SLUSH_RUSH,
[Species.DEERLING]: Abilities.FUR_COAT,
[Species.EMOLGA]: Abilities.TRANSISTOR,
[Species.KARRABLAST]: Abilities.QUICK_DRAW,
[Species.FOONGUS]: Abilities.THICK_FAT,
[Species.FRILLISH]: Abilities.POISON_HEAL,
[Species.ALOMOMOLA]: Abilities.MULTISCALE,
[Species.JOLTIK]: Abilities.TRANSISTOR,
[Species.FERROSEED]: Abilities.ROUGH_SKIN,
[Species.KLINK]: Abilities.STEELY_SPIRIT,
[Species.TYNAMO]: Abilities.POISON_HEAL,
[Species.ELGYEM]: Abilities.PRISM_ARMOR,
[Species.LITWICK]: Abilities.SOUL_HEART,
[Species.AXEW]: Abilities.DRAGONS_MAW,
[Species.CUBCHOO]: Abilities.TOUGH_CLAWS,
[Species.CRYOGONAL]: Abilities.SNOW_WARNING,
[Species.SHELMET]: Abilities.PROTEAN,
[Species.STUNFISK]: Abilities.STORM_DRAIN,
[Species.MIENFOO]: Abilities.NO_GUARD,
[Species.DRUDDIGON]: Abilities.INTIMIDATE,
[Species.GOLETT]: Abilities.SHADOW_SHIELD,
[Species.PAWNIARD]: Abilities.SWORD_OF_RUIN,
[Species.BOUFFALANT]: Abilities.ROCK_HEAD,
[Species.RUFFLET]: Abilities.SPEED_BOOST,
[Species.VULLABY]: Abilities.THICK_FAT,
[Species.HEATMOR]: Abilities.CONTRARY,
[Species.DURANT]: Abilities.COMPOUND_EYES,
[Species.DEINO]: Abilities.PARENTAL_BOND,
[Species.LARVESTA]: Abilities.DROUGHT,
[Species.COBALION]: Abilities.INTREPID_SWORD,
[Species.TERRAKION]: Abilities.ROCKY_PAYLOAD,
[Species.VIRIZION]: Abilities.SHARPNESS,
[Species.TORNADUS]: Abilities.DRIZZLE,
[Species.THUNDURUS]: Abilities.DRIZZLE,
[Species.RESHIRAM]: Abilities.ORICHALCUM_PULSE,
[Species.ZEKROM]: Abilities.HADRON_ENGINE,
[Species.LANDORUS]: Abilities.STORM_DRAIN,
[Species.KYUREM]: Abilities.SNOW_WARNING,
[Species.KELDEO]: Abilities.GRIM_NEIGH,
[Species.MELOETTA]: Abilities.MINDS_EYE,
[Species.GENESECT]: Abilities.PROTEAN,
[Species.CHESPIN]: Abilities.DAUNTLESS_SHIELD,
[Species.FENNEKIN]: Abilities.PSYCHIC_SURGE,
[Species.FROAKIE]: Abilities.STAKEOUT,
[Species.BUNNELBY]: Abilities.GUTS,
[Species.FLETCHLING]: Abilities.MAGIC_GUARD,
[Species.SCATTERBUG]: Abilities.PRANKSTER,
[Species.LITLEO]: Abilities.BEAST_BOOST,
[Species.FLABEBE]: Abilities.GRASSY_SURGE,
[Species.SKIDDO]: Abilities.SEED_SOWER,
[Species.PANCHAM]: Abilities.FUR_COAT,
[Species.FURFROU]: Abilities.FLUFFY,
[Species.ESPURR]: Abilities.FUR_COAT,
[Species.HONEDGE]: Abilities.SHARPNESS,
[Species.SPRITZEE]: Abilities.FUR_COAT,
[Species.SWIRLIX]: Abilities.WELL_BAKED_BODY,
[Species.INKAY]: Abilities.UNNERVE,
[Species.BINACLE]: Abilities.SAP_SIPPER,
[Species.SKRELP]: Abilities.DRAGONS_MAW,
[Species.CLAUNCHER]: Abilities.SWIFT_SWIM,
[Species.HELIOPTILE]: Abilities.PROTEAN,
[Species.TYRUNT]: Abilities.RECKLESS,
[Species.AMAURA]: Abilities.ICE_SCALES,
[Species.HAWLUCHA]: Abilities.MOXIE,
[Species.DEDENNE]: Abilities.PIXILATE,
[Species.CARBINK]: Abilities.SOLID_ROCK,
[Species.GOOMY]: Abilities.REGENERATOR,
[Species.KLEFKI]: Abilities.LEVITATE,
[Species.PHANTUMP]: Abilities.SHADOW_TAG,
[Species.PUMPKABOO]: Abilities.WELL_BAKED_BODY,
[Species.BERGMITE]: Abilities.ICE_SCALES,
[Species.NOIBAT]: Abilities.PUNK_ROCK,
[Species.XERNEAS]: Abilities.HARVEST,
[Species.YVELTAL]: Abilities.SOUL_HEART,
[Species.ZYGARDE]: Abilities.HUGE_POWER,
[Species.DIANCIE]: Abilities.LEVITATE,
[Species.HOOPA]: Abilities.OPPORTUNIST,
[Species.VOLCANION]: Abilities.FILTER,
[Species.ROWLET]: Abilities.SNIPER,
[Species.LITTEN]: Abilities.OPPORTUNIST,
[Species.POPPLIO]: Abilities.PUNK_ROCK,
[Species.PIKIPEK]: Abilities.TECHNICIAN,
[Species.YUNGOOS]: Abilities.TOUGH_CLAWS,
[Species.GRUBBIN]: Abilities.SPEED_BOOST,
[Species.CRABRAWLER]: Abilities.WATER_BUBBLE,
[Species.ORICORIO]: Abilities.ADAPTABILITY,
[Species.CUTIEFLY]: Abilities.TINTED_LENS,
[Species.ROCKRUFF]: Abilities.ROCKY_PAYLOAD,
[Species.WISHIWASHI]: Abilities.REGENERATOR,
[Species.MAREANIE]: Abilities.TOXIC_DEBRIS,
[Species.MUDBRAY]: Abilities.CUD_CHEW,
[Species.DEWPIDER]: Abilities.TINTED_LENS,
[Species.FOMANTIS]: Abilities.SHARPNESS,
[Species.MORELULL]: Abilities.TRIAGE,
[Species.SALANDIT]: Abilities.DRAGONS_MAW,
[Species.STUFFUL]: Abilities.SCRAPPY,
[Species.BOUNSWEET]: Abilities.MOXIE,
[Species.COMFEY]: Abilities.FRIEND_GUARD,
[Species.ORANGURU]: Abilities.POWER_SPOT,
[Species.PASSIMIAN]: Abilities.LIBERO,
[Species.WIMPOD]: Abilities.REGENERATOR,
[Species.SANDYGAST]: Abilities.SAND_SPIT,
[Species.PYUKUMUKU]: Abilities.PURIFYING_SALT,
[Species.TYPE_NULL]: Abilities.ADAPTABILITY,
[Species.MINIOR]: Abilities.STURDY,
[Species.KOMALA]: Abilities.GUTS,
[Species.TURTONATOR]: Abilities.DAUNTLESS_SHIELD,
[Species.TOGEDEMARU]: Abilities.ROUGH_SKIN,
[Species.MIMIKYU]: Abilities.TOUGH_CLAWS,
[Species.BRUXISH]: Abilities.MULTISCALE,
[Species.DRAMPA]: Abilities.THICK_FAT,
[Species.DHELMISE]: Abilities.WATER_BUBBLE,
[Species.JANGMO_O]: Abilities.DAUNTLESS_SHIELD,
[Species.TAPU_KOKO]: Abilities.TRANSISTOR,
[Species.TAPU_LELE]: Abilities.SHEER_FORCE,
[Species.TAPU_BULU]: Abilities.TRIAGE,
[Species.TAPU_FINI]: Abilities.FAIRY_AURA,
[Species.COSMOG]: Abilities.BEAST_BOOST,
[Species.NIHILEGO]: Abilities.LEVITATE,
[Species.BUZZWOLE]: Abilities.MOXIE,
[Species.PHEROMOSA]: Abilities.TINTED_LENS,
[Species.XURKITREE]: Abilities.TRANSISTOR,
[Species.CELESTEELA]: Abilities.HEATPROOF,
[Species.KARTANA]: Abilities.SHARPNESS,
[Species.GUZZLORD]: Abilities.POISON_HEAL,
[Species.NECROZMA]: Abilities.BEAST_BOOST,
[Species.MAGEARNA]: Abilities.STEELY_SPIRIT,
[Species.MARSHADOW]: Abilities.IRON_FIST,
[Species.POIPOLE]: Abilities.SHEER_FORCE,
[Species.STAKATAKA]: Abilities.SOLID_ROCK,
[Species.BLACEPHALON]: Abilities.MAGIC_GUARD,
[Species.ZERAORA]: Abilities.TOUGH_CLAWS,
[Species.MELTAN]: Abilities.STEELY_SPIRIT,
[Species.GROOKEY]: Abilities.GRASS_PELT,
[Species.SCORBUNNY]: Abilities.NO_GUARD,
[Species.SOBBLE]: Abilities.SUPER_LUCK,
[Species.SKWOVET]: Abilities.HARVEST,
[Species.ROOKIDEE]: Abilities.IRON_BARBS,
[Species.BLIPBUG]: Abilities.PSYCHIC_SURGE,
[Species.NICKIT]: Abilities.MAGICIAN,
[Species.GOSSIFLEUR]: Abilities.GRASSY_SURGE,
[Species.WOOLOO]: Abilities.SIMPLE,
[Species.CHEWTLE]: Abilities.ROCKY_PAYLOAD,
[Species.YAMPER]: Abilities.SHEER_FORCE,
[Species.ROLYCOLY]: Abilities.SOLID_ROCK,
[Species.APPLIN]: Abilities.DRAGONS_MAW,
[Species.SILICOBRA]: Abilities.SAND_RUSH,
[Species.CRAMORANT]: Abilities.LIGHTNING_ROD,
[Species.ARROKUDA]: Abilities.INTIMIDATE,
[Species.TOXEL]: Abilities.ELECTRIC_SURGE,
[Species.SIZZLIPEDE]: Abilities.SPEED_BOOST,
[Species.CLOBBOPUS]: Abilities.WATER_BUBBLE,
[Species.SINISTEA]: Abilities.SHADOW_SHIELD,
[Species.HATENNA]: Abilities.FAIRY_AURA,
[Species.IMPIDIMP]: Abilities.FUR_COAT,
[Species.MILCERY]: Abilities.REGENERATOR,
[Species.FALINKS]: Abilities.PARENTAL_BOND,
[Species.PINCURCHIN]: Abilities.ELECTROMORPHOSIS,
[Species.SNOM]: Abilities.SNOW_WARNING,
[Species.STONJOURNER]: Abilities.STURDY,
[Species.EISCUE]: Abilities.ICE_SCALES,
[Species.INDEEDEE]: Abilities.FRIEND_GUARD,
[Species.MORPEKO]: Abilities.MOODY,
[Species.CUFANT]: Abilities.EARTH_EATER,
[Species.DRACOZOLT]: Abilities.NO_GUARD,
[Species.ARCTOZOLT]: Abilities.TRANSISTOR,
[Species.DRACOVISH]: Abilities.SWIFT_SWIM,
[Species.ARCTOVISH]: Abilities.STRONG_JAW,
[Species.DURALUDON]: Abilities.STEELWORKER,
[Species.DREEPY]: Abilities.PARENTAL_BOND,
[Species.ZACIAN]: Abilities.UNNERVE,
[Species.ZAMAZENTA]: Abilities.UNNERVE,
[Species.ETERNATUS]: Abilities.NEUTRALIZING_GAS,
[Species.KUBFU]: Abilities.IRON_FIST,
[Species.ZARUDE]: Abilities.TOUGH_CLAWS,
[Species.REGIELEKI]: Abilities.ELECTRIC_SURGE,
[Species.REGIDRAGO]: Abilities.MULTISCALE,
[Species.GLASTRIER]: Abilities.FILTER,
[Species.SPECTRIER]: Abilities.SHADOW_SHIELD,
[Species.CALYREX]: Abilities.HARVEST,
[Species.ENAMORUS]: Abilities.FAIRY_AURA,
[Species.SPRIGATITO]: Abilities.MAGICIAN,
[Species.FUECOCO]: Abilities.PUNK_ROCK,
[Species.QUAXLY]: Abilities.OPPORTUNIST,
[Species.LECHONK]: Abilities.SIMPLE,
[Species.TAROUNTULA]: Abilities.HONEY_GATHER,
[Species.NYMBLE]: Abilities.GUTS,
[Species.PAWMI]: Abilities.TRANSISTOR,
[Species.TANDEMAUS]: Abilities.SCRAPPY,
[Species.FIDOUGH]: Abilities.WATER_ABSORB,
[Species.SMOLIV]: Abilities.RIPEN,
[Species.SQUAWKABILLY]: Abilities.MOXIE,
[Species.NACLI]: Abilities.SOLID_ROCK,
[Species.CHARCADET]: Abilities.PRISM_ARMOR,
[Species.TADBULB]: Abilities.STAMINA,
[Species.WATTREL]: Abilities.SHEER_FORCE,
[Species.MASCHIFF]: Abilities.STRONG_JAW,
[Species.SHROODLE]: Abilities.CORROSION,
[Species.BRAMBLIN]: Abilities.SHADOW_SHIELD,
[Species.TOEDSCOOL]: Abilities.PRANKSTER,
[Species.KLAWF]: Abilities.WATER_ABSORB,
[Species.CAPSAKID]: Abilities.PARENTAL_BOND,
[Species.RELLOR]: Abilities.PRANKSTER,
[Species.FLITTLE]: Abilities.DAZZLING,
[Species.TINKATINK]: Abilities.STEELWORKER,
[Species.WIGLETT]: Abilities.STURDY,
[Species.BOMBIRDIER]: Abilities.UNBURDEN,
[Species.FINIZEN]: Abilities.IRON_FIST,
[Species.VAROOM]: Abilities.LEVITATE,
[Species.CYCLIZAR]: Abilities.PROTEAN,
[Species.ORTHWORM]: Abilities.REGENERATOR,
[Species.GLIMMET]: Abilities.LEVITATE,
[Species.GREAVARD]: Abilities.FUR_COAT,
[Species.FLAMIGO]: Abilities.MOXIE,
[Species.CETODDLE]: Abilities.ICE_SCALES,
[Species.VELUZA]: Abilities.SUPER_LUCK,
[Species.DONDOZO]: Abilities.PARENTAL_BOND,
[Species.TATSUGIRI]: Abilities.ADAPTABILITY,
[Species.GREAT_TUSK]: Abilities.INTIMIDATE,
[Species.SCREAM_TAIL]: Abilities.UNAWARE,
[Species.BRUTE_BONNET]: Abilities.CHLOROPHYLL,
[Species.FLUTTER_MANE]: Abilities.DAZZLING,
[Species.SLITHER_WING]: Abilities.SCRAPPY,
[Species.SANDY_SHOCKS]: Abilities.EARTH_EATER,
[Species.IRON_TREADS]: Abilities.STEELY_SPIRIT,
[Species.IRON_BUNDLE]: Abilities.SNOW_WARNING,
[Species.IRON_HANDS]: Abilities.IRON_FIST,
[Species.IRON_JUGULIS]: Abilities.LIGHTNING_ROD,
[Species.IRON_MOTH]: Abilities.LEVITATE,
[Species.IRON_THORNS]: Abilities.SAND_STREAM,
[Species.FRIGIBAX]: Abilities.SNOW_WARNING,
[Species.GIMMIGHOUL]: Abilities.HONEY_GATHER,
[Species.WO_CHIEN]: Abilities.VESSEL_OF_RUIN,
[Species.CHIEN_PAO]: Abilities.INTIMIDATE,
[Species.TING_LU]: Abilities.STAMINA,
[Species.CHI_YU]: Abilities.BERSERK,
[Species.ROARING_MOON]: Abilities.TOUGH_CLAWS,
[Species.IRON_VALIANT]: Abilities.ADAPTABILITY,
[Species.KORAIDON]: Abilities.OPPORTUNIST,
[Species.MIRAIDON]: Abilities.OPPORTUNIST,
[Species.WALKING_WAKE]: Abilities.BEAST_BOOST,
[Species.IRON_LEAVES]: Abilities.SHARPNESS,
[Species.POLTCHAGEIST]: Abilities.TRIAGE,
[Species.OKIDOGI]: Abilities.FUR_COAT,
[Species.MUNKIDORI]: Abilities.NEUROFORCE,
[Species.FEZANDIPITI]: Abilities.LEVITATE,
[Species.OGERPON]: Abilities.OPPORTUNIST,
[Species.GOUGING_FIRE]: Abilities.BEAST_BOOST,
[Species.RAGING_BOLT]: Abilities.BEAST_BOOST,
[Species.IRON_BOULDER]: Abilities.SHARPNESS,
[Species.IRON_CROWN]: Abilities.SHARPNESS,
[Species.TERAPAGOS]: Abilities.SOUL_HEART,
[Species.PECHARUNT]: Abilities.TOXIC_CHAIN,
[Species.ALOLA_RATTATA]: Abilities.ADAPTABILITY,
[Species.ALOLA_SANDSHREW]: Abilities.ICE_SCALES,
[Species.ALOLA_VULPIX]: Abilities.SHEER_FORCE,
[Species.ALOLA_DIGLETT]: Abilities.STURDY,
[Species.ALOLA_MEOWTH]: Abilities.DARK_AURA,
[Species.ALOLA_GEODUDE]: Abilities.DRY_SKIN,
[Species.ALOLA_GRIMER]: Abilities.TOXIC_DEBRIS,
[Species.ETERNAL_FLOETTE]: Abilities.MAGIC_GUARD,
[Species.GALAR_MEOWTH]: Abilities.STEELWORKER,
[Species.GALAR_PONYTA]: Abilities.MOXIE,
[Species.GALAR_SLOWPOKE]: Abilities.UNAWARE,
[Species.GALAR_FARFETCHD]: Abilities.INTREPID_SWORD,
[Species.GALAR_ARTICUNO]: Abilities.SERENE_GRACE,
[Species.GALAR_ZAPDOS]: Abilities.TOUGH_CLAWS,
[Species.GALAR_MOLTRES]: Abilities.DARK_AURA,
[Species.GALAR_CORSOLA]: Abilities.SHADOW_SHIELD,
[Species.GALAR_ZIGZAGOON]: Abilities.POISON_HEAL,
[Species.GALAR_DARUMAKA]: Abilities.FLASH_FIRE,
[Species.GALAR_YAMASK]: Abilities.TABLETS_OF_RUIN,
[Species.GALAR_STUNFISK]: Abilities.ARENA_TRAP,
[Species.HISUI_GROWLITHE]: Abilities.RECKLESS,
[Species.HISUI_VOLTORB]: Abilities.TRANSISTOR,
[Species.HISUI_QWILFISH]: Abilities.MERCILESS,
[Species.HISUI_SNEASEL]: Abilities.SCRAPPY,
[Species.HISUI_ZORUA]: Abilities.ADAPTABILITY,
[Species.PALDEA_TAUROS]: Abilities.ADAPTABILITY,
[Species.PALDEA_WOOPER]: Abilities.THICK_FAT,
[Species.BLOODMOON_URSALUNA]: Abilities.BERSERK
};

View File

@ -1,11 +1,11 @@
import { Gender } from "./gender";
import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon";
import { Gender } from "#app/data/gender";
import { PokeballType } from "#app/data/pokeball";
import Pokemon from "#app/field/pokemon";
import { Stat } from "#enums/stat";
import { Type } from "./type";
import * as Utils from "../utils";
import { WeatherType } from "./weather";
import { Nature } from "./nature";
import { Type } from "#app/data/type";
import * as Utils from "#app/utils";
import { WeatherType } from "#app/data/weather";
import { Nature } from "#app/data/nature";
import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";

53
src/data/balance/rates.ts Normal file
View File

@ -0,0 +1,53 @@
/**
* Rates for shinies and other random properties are defined in this file.
* CHANCE is defined as x/65536
* RATE is defined as 1/x
*/
// #region Encounterable properties
/** `64/65536 -> 1/1024` */
export const BASE_SHINY_CHANCE = 64;
/** `256/65536 -> 1/256` */
export const BASE_HIDDEN_ABILITY_CHANCE = 256;
// #region Egg properties
// Threshold x at which a gacha egg is determined to be a certain tier
// Specifically, the tier is determined by the highest threshold a random value between 0-255 meets or exceeds
// Legendary Up Gacha raises these thresholds by 1, thereby giving Legendary eggs 2/256 chance
export const GACHA_DEFAULT_COMMON_EGG_THRESHOLD = 52; // Default 204/256 chance, 203/256 chance in Legendary Up Gacha
export const GACHA_DEFAULT_RARE_EGG_THRESHOLD = 8; // Default 44/256 chance
export const GACHA_DEFAULT_EPIC_EGG_THRESHOLD = 1; // Default 7/256 chance, leaving Legendary as 1/256 chance
export const GACHA_LEGENDARY_UP_THRESHOLD_OFFSET = 1; // The offset to threshold for Legendary Up gacha eggs. +x/256 Legendary Egg chance, -x/256 Common Egg chance
// The number of eggs without finding a certain tier egg it takes for egg pity to kick in and that tier to be forced
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
export const EGG_PITY_LEGENDARY_THRESHOLD = 412;
export const EGG_PITY_EPIC_THRESHOLD = 59;
export const EGG_PITY_RARE_THRESHOLD = 9;
// Waves to hatch an egg of a given tier
export const HATCH_WAVES_COMMON_EGG = 10;
export const HATCH_WAVES_RARE_EGG = 25;
export const HATCH_WAVES_EPIC_EGG = 50;
export const HATCH_WAVES_LEGENDARY_EGG = 100;
export const HATCH_WAVES_MANAPHY_EGG = 50;
// Rates for specific random properties in 1/x
export const GACHA_DEFAULT_SHINY_RATE = 128;
export const GACHA_SHINY_UP_SHINY_RATE = 64;
export const SAME_SPECIES_EGG_SHINY_RATE = 12;
export const SAME_SPECIES_EGG_HA_RATE = 8;
export const MANAPHY_EGG_MANAPHY_RATE = 8;
export const GACHA_EGG_HA_RATE = 192;
// 1/x for legendary eggs, 1/x*2 for epic eggs, 1/x*4 for rare eggs, and 1/x*8 for common eggs
export const GACHA_DEFAULT_RARE_EGGMOVE_RATE = 6;
export const SAME_SPECIES_EGG_RARE_EGGMOVE_RATE = 3;
export const GACHA_MOVE_UP_RARE_EGGMOVE_RATE = 3;
// #region Variant properties
// The chance x/10 of a shiny being a variant, then of being specifically an epic variant
export const SHINY_VARIANT_CHANCE = 4;
export const SHINY_EPIC_CHANCE = 1;

View File

@ -0,0 +1,671 @@
import { Species } from "#enums/species";
export const POKERUS_STARTER_COUNT = 5;
/**
* Function to get the cumulative friendship threshold at which a candy is earned
* @param starterCost The cost of the starter, found in {@linkcode speciesStarterCosts}
* @returns aforementioned threshold
*/
export function getStarterValueFriendshipCap(starterCost: number): number {
switch (starterCost) {
case 1:
return 20;
case 2:
return 40;
case 3:
return 60;
case 4:
return 100;
case 5:
return 140;
case 6:
return 200;
case 7:
return 280;
case 8:
case 9:
return 450;
default:
return 600;
}
}
export const speciesStarterCosts = {
[Species.BULBASAUR]: 3,
[Species.CHARMANDER]: 3,
[Species.SQUIRTLE]: 3,
[Species.CATERPIE]: 2,
[Species.WEEDLE]: 1,
[Species.PIDGEY]: 1,
[Species.RATTATA]: 1,
[Species.SPEAROW]: 1,
[Species.EKANS]: 2,
[Species.PIKACHU]: 3,
[Species.SANDSHREW]: 2,
[Species.NIDORAN_F]: 3,
[Species.NIDORAN_M]: 3,
[Species.CLEFAIRY]: 3,
[Species.VULPIX]: 3,
[Species.JIGGLYPUFF]: 2,
[Species.ZUBAT]: 3,
[Species.ODDISH]: 3,
[Species.PARAS]: 2,
[Species.VENONAT]: 2,
[Species.DIGLETT]: 2,
[Species.MEOWTH]: 3,
[Species.PSYDUCK]: 2,
[Species.MANKEY]: 4,
[Species.GROWLITHE]: 4,
[Species.POLIWAG]: 2,
[Species.ABRA]: 4,
[Species.MACHOP]: 3,
[Species.BELLSPROUT]: 2,
[Species.TENTACOOL]: 3,
[Species.GEODUDE]: 3,
[Species.PONYTA]: 2,
[Species.SLOWPOKE]: 3,
[Species.MAGNEMITE]: 4,
[Species.FARFETCHD]: 2,
[Species.DODUO]: 3,
[Species.SEEL]: 1,
[Species.GRIMER]: 2,
[Species.SHELLDER]: 5,
[Species.GASTLY]: 4,
[Species.ONIX]: 3,
[Species.DROWZEE]: 2,
[Species.KRABBY]: 3,
[Species.VOLTORB]: 2,
[Species.EXEGGCUTE]: 3,
[Species.CUBONE]: 3,
[Species.HITMONLEE]: 4,
[Species.HITMONCHAN]: 4,
[Species.LICKITUNG]: 3,
[Species.KOFFING]: 2,
[Species.RHYHORN]: 3,
[Species.CHANSEY]: 3,
[Species.TANGELA]: 3,
[Species.KANGASKHAN]: 4,
[Species.HORSEA]: 3,
[Species.GOLDEEN]: 2,
[Species.STARYU]: 3,
[Species.MR_MIME]: 3,
[Species.SCYTHER]: 5,
[Species.JYNX]: 4,
[Species.ELECTABUZZ]: 4,
[Species.MAGMAR]: 4,
[Species.PINSIR]: 4,
[Species.TAUROS]: 4,
[Species.MAGIKARP]: 4,
[Species.LAPRAS]: 4,
[Species.DITTO]: 2,
[Species.EEVEE]: 3,
[Species.PORYGON]: 4,
[Species.OMANYTE]: 3,
[Species.KABUTO]: 3,
[Species.AERODACTYL]: 5,
[Species.SNORLAX]: 5,
[Species.ARTICUNO]: 6,
[Species.ZAPDOS]: 6,
[Species.MOLTRES]: 6,
[Species.DRATINI]: 4,
[Species.MEWTWO]: 8,
[Species.MEW]: 6,
[Species.CHIKORITA]: 2,
[Species.CYNDAQUIL]: 3,
[Species.TOTODILE]: 3,
[Species.SENTRET]: 1,
[Species.HOOTHOOT]: 2,
[Species.LEDYBA]: 1,
[Species.SPINARAK]: 1,
[Species.CHINCHOU]: 2,
[Species.PICHU]: 2,
[Species.CLEFFA]: 2,
[Species.IGGLYBUFF]: 1,
[Species.TOGEPI]: 3,
[Species.NATU]: 2,
[Species.MAREEP]: 2,
[Species.MARILL]: 4,
[Species.SUDOWOODO]: 3,
[Species.HOPPIP]: 2,
[Species.AIPOM]: 2,
[Species.SUNKERN]: 1,
[Species.YANMA]: 3,
[Species.WOOPER]: 2,
[Species.MURKROW]: 3,
[Species.MISDREAVUS]: 2,
[Species.UNOWN]: 1,
[Species.WOBBUFFET]: 2,
[Species.GIRAFARIG]: 3,
[Species.PINECO]: 2,
[Species.DUNSPARCE]: 3,
[Species.GLIGAR]: 3,
[Species.SNUBBULL]: 2,
[Species.QWILFISH]: 3,
[Species.SHUCKLE]: 3,
[Species.HERACROSS]: 5,
[Species.SNEASEL]: 4,
[Species.TEDDIURSA]: 4,
[Species.SLUGMA]: 2,
[Species.SWINUB]: 3,
[Species.CORSOLA]: 2,
[Species.REMORAID]: 2,
[Species.DELIBIRD]: 2,
[Species.MANTINE]: 3,
[Species.SKARMORY]: 4,
[Species.HOUNDOUR]: 3,
[Species.PHANPY]: 3,
[Species.STANTLER]: 3,
[Species.SMEARGLE]: 1,
[Species.TYROGUE]: 3,
[Species.SMOOCHUM]: 3,
[Species.ELEKID]: 3,
[Species.MAGBY]: 3,
[Species.MILTANK]: 4,
[Species.RAIKOU]: 6,
[Species.ENTEI]: 6,
[Species.SUICUNE]: 6,
[Species.LARVITAR]: 4,
[Species.LUGIA]: 8,
[Species.HO_OH]: 8,
[Species.CELEBI]: 6,
[Species.TREECKO]: 3,
[Species.TORCHIC]: 4,
[Species.MUDKIP]: 3,
[Species.POOCHYENA]: 2,
[Species.ZIGZAGOON]: 2,
[Species.WURMPLE]: 1,
[Species.LOTAD]: 3,
[Species.SEEDOT]: 2,
[Species.TAILLOW]: 3,
[Species.WINGULL]: 2,
[Species.RALTS]: 3,
[Species.SURSKIT]: 2,
[Species.SHROOMISH]: 3,
[Species.SLAKOTH]: 4,
[Species.NINCADA]: 4,
[Species.WHISMUR]: 2,
[Species.MAKUHITA]: 3,
[Species.AZURILL]: 4,
[Species.NOSEPASS]: 2,
[Species.SKITTY]: 1,
[Species.SABLEYE]: 2,
[Species.MAWILE]: 3,
[Species.ARON]: 3,
[Species.MEDITITE]: 3,
[Species.ELECTRIKE]: 2,
[Species.PLUSLE]: 2,
[Species.MINUN]: 2,
[Species.VOLBEAT]: 2,
[Species.ILLUMISE]: 2,
[Species.ROSELIA]: 3,
[Species.GULPIN]: 1,
[Species.CARVANHA]: 3,
[Species.WAILMER]: 2,
[Species.NUMEL]: 2,
[Species.TORKOAL]: 3,
[Species.SPOINK]: 2,
[Species.SPINDA]: 1,
[Species.TRAPINCH]: 3,
[Species.CACNEA]: 2,
[Species.SWABLU]: 2,
[Species.ZANGOOSE]: 4,
[Species.SEVIPER]: 3,
[Species.LUNATONE]: 3,
[Species.SOLROCK]: 3,
[Species.BARBOACH]: 2,
[Species.CORPHISH]: 3,
[Species.BALTOY]: 2,
[Species.LILEEP]: 3,
[Species.ANORITH]: 3,
[Species.FEEBAS]: 4,
[Species.CASTFORM]: 1,
[Species.KECLEON]: 2,
[Species.SHUPPET]: 2,
[Species.DUSKULL]: 3,
[Species.TROPIUS]: 3,
[Species.CHIMECHO]: 3,
[Species.ABSOL]: 4,
[Species.WYNAUT]: 2,
[Species.SNORUNT]: 2,
[Species.SPHEAL]: 2,
[Species.CLAMPERL]: 3,
[Species.RELICANTH]: 3,
[Species.LUVDISC]: 1,
[Species.BAGON]: 4,
[Species.BELDUM]: 4,
[Species.REGIROCK]: 6,
[Species.REGICE]: 6,
[Species.REGISTEEL]: 6,
[Species.LATIAS]: 7,
[Species.LATIOS]: 7,
[Species.KYOGRE]: 9,
[Species.GROUDON]: 9,
[Species.RAYQUAZA]: 9,
[Species.JIRACHI]: 7,
[Species.DEOXYS]: 7,
[Species.TURTWIG]: 3,
[Species.CHIMCHAR]: 3,
[Species.PIPLUP]: 3,
[Species.STARLY]: 3,
[Species.BIDOOF]: 2,
[Species.KRICKETOT]: 1,
[Species.SHINX]: 2,
[Species.BUDEW]: 3,
[Species.CRANIDOS]: 3,
[Species.SHIELDON]: 3,
[Species.BURMY]: 2,
[Species.COMBEE]: 2,
[Species.PACHIRISU]: 2,
[Species.BUIZEL]: 2,
[Species.CHERUBI]: 1,
[Species.SHELLOS]: 3,
[Species.DRIFLOON]: 2,
[Species.BUNEARY]: 2,
[Species.GLAMEOW]: 2,
[Species.CHINGLING]: 2,
[Species.STUNKY]: 2,
[Species.BRONZOR]: 3,
[Species.BONSLY]: 2,
[Species.MIME_JR]: 2,
[Species.HAPPINY]: 2,
[Species.CHATOT]: 2,
[Species.SPIRITOMB]: 4,
[Species.GIBLE]: 4,
[Species.MUNCHLAX]: 4,
[Species.RIOLU]: 3,
[Species.HIPPOPOTAS]: 3,
[Species.SKORUPI]: 3,
[Species.CROAGUNK]: 2,
[Species.CARNIVINE]: 2,
[Species.FINNEON]: 1,
[Species.MANTYKE]: 2,
[Species.SNOVER]: 2,
[Species.ROTOM]: 5,
[Species.UXIE]: 6,
[Species.MESPRIT]: 6,
[Species.AZELF]: 6,
[Species.DIALGA]: 8,
[Species.PALKIA]: 8,
[Species.HEATRAN]: 6,
[Species.REGIGIGAS]: 7,
[Species.GIRATINA]: 8,
[Species.CRESSELIA]: 6,
[Species.PHIONE]: 4,
[Species.MANAPHY]: 7,
[Species.DARKRAI]: 7,
[Species.SHAYMIN]: 6,
[Species.ARCEUS]: 9,
[Species.VICTINI]: 7,
[Species.SNIVY]: 3,
[Species.TEPIG]: 3,
[Species.OSHAWOTT]: 3,
[Species.PATRAT]: 1,
[Species.LILLIPUP]: 3,
[Species.PURRLOIN]: 2,
[Species.PANSAGE]: 2,
[Species.PANSEAR]: 2,
[Species.PANPOUR]: 2,
[Species.MUNNA]: 2,
[Species.PIDOVE]: 1,
[Species.BLITZLE]: 2,
[Species.ROGGENROLA]: 3,
[Species.WOOBAT]: 3,
[Species.DRILBUR]: 4,
[Species.AUDINO]: 3,
[Species.TIMBURR]: 4,
[Species.TYMPOLE]: 3,
[Species.THROH]: 4,
[Species.SAWK]: 4,
[Species.SEWADDLE]: 2,
[Species.VENIPEDE]: 3,
[Species.COTTONEE]: 3,
[Species.PETILIL]: 3,
[Species.BASCULIN]: 4,
[Species.SANDILE]: 4,
[Species.DARUMAKA]: 4,
[Species.MARACTUS]: 2,
[Species.DWEBBLE]: 2,
[Species.SCRAGGY]: 3,
[Species.SIGILYPH]: 4,
[Species.YAMASK]: 3,
[Species.TIRTOUGA]: 3,
[Species.ARCHEN]: 3,
[Species.TRUBBISH]: 2,
[Species.ZORUA]: 3,
[Species.MINCCINO]: 3,
[Species.GOTHITA]: 3,
[Species.SOLOSIS]: 3,
[Species.DUCKLETT]: 2,
[Species.VANILLITE]: 3,
[Species.DEERLING]: 2,
[Species.EMOLGA]: 2,
[Species.KARRABLAST]: 3,
[Species.FOONGUS]: 2,
[Species.FRILLISH]: 3,
[Species.ALOMOMOLA]: 4,
[Species.JOLTIK]: 3,
[Species.FERROSEED]: 3,
[Species.KLINK]: 3,
[Species.TYNAMO]: 2,
[Species.ELGYEM]: 2,
[Species.LITWICK]: 3,
[Species.AXEW]: 4,
[Species.CUBCHOO]: 2,
[Species.CRYOGONAL]: 4,
[Species.SHELMET]: 2,
[Species.STUNFISK]: 3,
[Species.MIENFOO]: 3,
[Species.DRUDDIGON]: 4,
[Species.GOLETT]: 3,
[Species.PAWNIARD]: 4,
[Species.BOUFFALANT]: 4,
[Species.RUFFLET]: 3,
[Species.VULLABY]: 3,
[Species.HEATMOR]: 3,
[Species.DURANT]: 4,
[Species.DEINO]: 4,
[Species.LARVESTA]: 4,
[Species.COBALION]: 6,
[Species.TERRAKION]: 6,
[Species.VIRIZION]: 6,
[Species.TORNADUS]: 7,
[Species.THUNDURUS]: 7,
[Species.RESHIRAM]: 8,
[Species.ZEKROM]: 8,
[Species.LANDORUS]: 7,
[Species.KYUREM]: 8,
[Species.KELDEO]: 6,
[Species.MELOETTA]: 7,
[Species.GENESECT]: 6,
[Species.CHESPIN]: 3,
[Species.FENNEKIN]: 3,
[Species.FROAKIE]: 4,
[Species.BUNNELBY]: 3,
[Species.FLETCHLING]: 3,
[Species.SCATTERBUG]: 2,
[Species.LITLEO]: 2,
[Species.FLABEBE]: 3,
[Species.SKIDDO]: 2,
[Species.PANCHAM]: 3,
[Species.FURFROU]: 3,
[Species.ESPURR]: 2,
[Species.HONEDGE]: 4,
[Species.SPRITZEE]: 2,
[Species.SWIRLIX]: 3,
[Species.INKAY]: 3,
[Species.BINACLE]: 3,
[Species.SKRELP]: 2,
[Species.CLAUNCHER]: 3,
[Species.HELIOPTILE]: 3,
[Species.TYRUNT]: 3,
[Species.AMAURA]: 3,
[Species.HAWLUCHA]: 4,
[Species.DEDENNE]: 2,
[Species.CARBINK]: 2,
[Species.GOOMY]: 4,
[Species.KLEFKI]: 3,
[Species.PHANTUMP]: 2,
[Species.PUMPKABOO]: 2,
[Species.BERGMITE]: 3,
[Species.NOIBAT]: 3,
[Species.XERNEAS]: 8,
[Species.YVELTAL]: 8,
[Species.ZYGARDE]: 8,
[Species.DIANCIE]: 7,
[Species.HOOPA]: 7,
[Species.VOLCANION]: 6,
[Species.ETERNAL_FLOETTE]: 4,
[Species.ROWLET]: 3,
[Species.LITTEN]: 3,
[Species.POPPLIO]: 4,
[Species.PIKIPEK]: 2,
[Species.YUNGOOS]: 2,
[Species.GRUBBIN]: 3,
[Species.CRABRAWLER]: 3,
[Species.ORICORIO]: 3,
[Species.CUTIEFLY]: 3,
[Species.ROCKRUFF]: 3,
[Species.WISHIWASHI]: 2,
[Species.MAREANIE]: 2,
[Species.MUDBRAY]: 3,
[Species.DEWPIDER]: 3,
[Species.FOMANTIS]: 2,
[Species.MORELULL]: 2,
[Species.SALANDIT]: 3,
[Species.STUFFUL]: 3,
[Species.BOUNSWEET]: 3,
[Species.COMFEY]: 4,
[Species.ORANGURU]: 4,
[Species.PASSIMIAN]: 4,
[Species.WIMPOD]: 3,
[Species.SANDYGAST]: 3,
[Species.PYUKUMUKU]: 2,
[Species.TYPE_NULL]: 5,
[Species.MINIOR]: 4,
[Species.KOMALA]: 3,
[Species.TURTONATOR]: 4,
[Species.TOGEDEMARU]: 3,
[Species.MIMIKYU]: 4,
[Species.BRUXISH]: 4,
[Species.DRAMPA]: 4,
[Species.DHELMISE]: 4,
[Species.JANGMO_O]: 4,
[Species.TAPU_KOKO]: 6,
[Species.TAPU_LELE]: 6,
[Species.TAPU_BULU]: 6,
[Species.TAPU_FINI]: 6,
[Species.COSMOG]: 7,
[Species.NIHILEGO]: 6,
[Species.BUZZWOLE]: 6,
[Species.PHEROMOSA]: 7,
[Species.XURKITREE]: 6,
[Species.CELESTEELA]: 6,
[Species.KARTANA]: 7,
[Species.GUZZLORD]: 6,
[Species.NECROZMA]: 8,
[Species.MAGEARNA]: 7,
[Species.MARSHADOW]: 7,
[Species.POIPOLE]: 7,
[Species.STAKATAKA]: 6,
[Species.BLACEPHALON]: 7,
[Species.ZERAORA]: 6,
[Species.MELTAN]: 6,
[Species.ALOLA_RATTATA]: 1,
[Species.ALOLA_SANDSHREW]: 2,
[Species.ALOLA_VULPIX]: 3,
[Species.ALOLA_DIGLETT]: 2,
[Species.ALOLA_MEOWTH]: 3,
[Species.ALOLA_GEODUDE]: 3,
[Species.ALOLA_GRIMER]: 3,
[Species.GROOKEY]: 3,
[Species.SCORBUNNY]: 4,
[Species.SOBBLE]: 3,
[Species.SKWOVET]: 2,
[Species.ROOKIDEE]: 3,
[Species.BLIPBUG]: 2,
[Species.NICKIT]: 1,
[Species.GOSSIFLEUR]: 2,
[Species.WOOLOO]: 2,
[Species.CHEWTLE]: 3,
[Species.YAMPER]: 2,
[Species.ROLYCOLY]: 3,
[Species.APPLIN]: 3,
[Species.SILICOBRA]: 3,
[Species.CRAMORANT]: 3,
[Species.ARROKUDA]: 3,
[Species.TOXEL]: 3,
[Species.SIZZLIPEDE]: 3,
[Species.CLOBBOPUS]: 2,
[Species.SINISTEA]: 3,
[Species.HATENNA]: 3,
[Species.IMPIDIMP]: 3,
[Species.MILCERY]: 3,
[Species.FALINKS]: 4,
[Species.PINCURCHIN]: 3,
[Species.SNOM]: 3,
[Species.STONJOURNER]: 3,
[Species.EISCUE]: 3,
[Species.INDEEDEE]: 4,
[Species.MORPEKO]: 3,
[Species.CUFANT]: 3,
[Species.DRACOZOLT]: 5,
[Species.ARCTOZOLT]: 4,
[Species.DRACOVISH]: 5,
[Species.ARCTOVISH]: 4,
[Species.DURALUDON]: 5,
[Species.DREEPY]: 4,
[Species.ZACIAN]: 9,
[Species.ZAMAZENTA]: 8,
[Species.ETERNATUS]: 10,
[Species.KUBFU]: 6,
[Species.ZARUDE]: 6,
[Species.REGIELEKI]: 6,
[Species.REGIDRAGO]: 6,
[Species.GLASTRIER]: 6,
[Species.SPECTRIER]: 7,
[Species.CALYREX]: 8,
[Species.GALAR_MEOWTH]: 3,
[Species.GALAR_PONYTA]: 2,
[Species.GALAR_SLOWPOKE]: 3,
[Species.GALAR_FARFETCHD]: 3,
[Species.GALAR_CORSOLA]: 3,
[Species.GALAR_ZIGZAGOON]: 3,
[Species.GALAR_DARUMAKA]: 4,
[Species.GALAR_YAMASK]: 3,
[Species.GALAR_STUNFISK]: 2,
[Species.GALAR_MR_MIME]: 3,
[Species.GALAR_ARTICUNO]: 6,
[Species.GALAR_ZAPDOS]: 6,
[Species.GALAR_MOLTRES]: 6,
[Species.HISUI_GROWLITHE]: 4,
[Species.HISUI_VOLTORB]: 3,
[Species.HISUI_QWILFISH]: 4,
[Species.HISUI_SNEASEL]: 5,
[Species.HISUI_ZORUA]: 3,
[Species.ENAMORUS]: 7,
[Species.SPRIGATITO]: 4,
[Species.FUECOCO]: 4,
[Species.QUAXLY]: 4,
[Species.LECHONK]: 2,
[Species.TAROUNTULA]: 1,
[Species.NYMBLE]: 3,
[Species.PAWMI]: 3,
[Species.TANDEMAUS]: 4,
[Species.FIDOUGH]: 2,
[Species.SMOLIV]: 3,
[Species.SQUAWKABILLY]: 2,
[Species.NACLI]: 4,
[Species.CHARCADET]: 4,
[Species.TADBULB]: 3,
[Species.WATTREL]: 3,
[Species.MASCHIFF]: 3,
[Species.SHROODLE]: 2,
[Species.BRAMBLIN]: 3,
[Species.TOEDSCOOL]: 3,
[Species.KLAWF]: 3,
[Species.CAPSAKID]: 3,
[Species.RELLOR]: 2,
[Species.FLITTLE]: 3,
[Species.TINKATINK]: 4,
[Species.WIGLETT]: 2,
[Species.BOMBIRDIER]: 3,
[Species.FINIZEN]: 3,
[Species.VAROOM]: 4,
[Species.CYCLIZAR]: 4,
[Species.ORTHWORM]: 4,
[Species.GLIMMET]: 4,
[Species.GREAVARD]: 3,
[Species.FLAMIGO]: 4,
[Species.CETODDLE]: 3,
[Species.VELUZA]: 4,
[Species.DONDOZO]: 4,
[Species.TATSUGIRI]: 4,
[Species.GREAT_TUSK]: 6,
[Species.SCREAM_TAIL]: 6,
[Species.BRUTE_BONNET]: 6,
[Species.FLUTTER_MANE]: 7,
[Species.SLITHER_WING]: 6,
[Species.SANDY_SHOCKS]: 6,
[Species.IRON_TREADS]: 6,
[Species.IRON_BUNDLE]: 6,
[Species.IRON_HANDS]: 6,
[Species.IRON_JUGULIS]: 6,
[Species.IRON_MOTH]: 6,
[Species.IRON_THORNS]: 6,
[Species.FRIGIBAX]: 4,
[Species.GIMMIGHOUL]: 4,
[Species.WO_CHIEN]: 6,
[Species.CHIEN_PAO]: 7,
[Species.TING_LU]: 6,
[Species.CHI_YU]: 7,
[Species.ROARING_MOON]: 6,
[Species.IRON_VALIANT]: 6,
[Species.KORAIDON]: 9,
[Species.MIRAIDON]: 9,
[Species.WALKING_WAKE]: 6,
[Species.IRON_LEAVES]: 6,
[Species.POLTCHAGEIST]: 4,
[Species.OKIDOGI]: 6,
[Species.MUNKIDORI]: 6,
[Species.FEZANDIPITI]: 6,
[Species.OGERPON]: 7,
[Species.GOUGING_FIRE]: 7,
[Species.RAGING_BOLT]: 6,
[Species.IRON_BOULDER]: 7,
[Species.IRON_CROWN]: 6,
[Species.TERAPAGOS]: 8,
[Species.PECHARUNT]: 6,
[Species.PALDEA_TAUROS]: 5,
[Species.PALDEA_WOOPER]: 3,
[Species.BLOODMOON_URSALUNA]: 6,
};
const starterCandyCosts: { passive: number; costReduction: [number, number]; egg: number; }[] = [
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 1 Cost
{ passive: 40, costReduction: [ 25, 60 ], egg: 30 }, // 2 Cost
{ passive: 35, costReduction: [ 20, 50 ], egg: 25 }, // 3 Cost
{ passive: 30, costReduction: [ 15, 40 ], egg: 20 }, // 4 Cost
{ passive: 25, costReduction: [ 12, 35 ], egg: 18 }, // 5 Cost
{ passive: 20, costReduction: [ 10, 30 ], egg: 15 }, // 6 Cost
{ passive: 15, costReduction: [ 8, 20 ], egg: 12 }, // 7 Cost
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 8 Cost
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 9 Cost
{ passive: 10, costReduction: [ 5, 15 ], egg: 10 }, // 10 Cost
];
/**
* Getter for {@linkcode starterCandyCosts} for passive unlock candy cost based on initial point cost
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
* @returns the candy cost for passive unlock
*/
export function getPassiveCandyCount(starterCost: number): number {
return starterCandyCosts[starterCost - 1].passive;
}
/**
* Getter for {@linkcode starterCandyCosts} for value reduction unlock candy cost based on initial point cost
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
* @returns respective candy cost for the two cost reductions as an array 2 numbers
*/
export function getValueReductionCandyCounts(starterCost: number): [number, number] {
return starterCandyCosts[starterCost - 1].costReduction;
}
/**
* Getter for {@linkcode starterCandyCosts} for egg purchase candy cost based on initial point cost
* @param starterCost the default point cost of the starter found in {@linkcode speciesStarterCosts}
* @returns the candy cost for the purchasable egg
*/
export function getSameSpeciesEggCandyCounts(starterCost: number): number {
return starterCandyCosts[starterCost - 1].egg;
}

View File

@ -1,4 +1,4 @@
import { ModifierTier } from "../modifier/modifier-tier";
import { ModifierTier } from "#app/modifier/modifier-tier";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";

View File

@ -556,7 +556,7 @@ function logMissingMoveAnim(move: Moves, ...optionalParams: any[]) {
* @param encounterAnim one or more animations to fetch
*/
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim];
const anims = Array.isArray(encounterAnim) ? encounterAnim : [ encounterAnim ];
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
const encounterAnimFetches: Promise<Map<EncounterAnim, AnimConfig>>[] = [];
for (const anim of anims) {
@ -774,9 +774,9 @@ export abstract class BattleAnim {
private getGraphicFrameData(scene: BattleScene, frames: AnimFrame[], onSubstitute?: boolean): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
[AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
[AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
[AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
[ AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
[ AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
[ AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
]);
const isOppAnim = this.isOppAnim();
@ -1093,9 +1093,9 @@ export abstract class BattleAnim {
private getGraphicFrameDataWithoutTarget(frames: AnimFrame[], targetInitialX: number, targetInitialY: number): Map<integer, Map<AnimFrameTarget, GraphicFrameData>> {
const ret: Map<integer, Map<AnimFrameTarget, GraphicFrameData>> = new Map([
[AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
[AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
[AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
[ AnimFrameTarget.GRAPHIC, new Map<AnimFrameTarget, GraphicFrameData>() ],
[ AnimFrameTarget.USER, new Map<AnimFrameTarget, GraphicFrameData>() ],
[ AnimFrameTarget.TARGET, new Map<AnimFrameTarget, GraphicFrameData>() ]
]);
let g = 0;

View File

@ -363,7 +363,7 @@ export class RechargingTag extends BattlerTag {
super.onAdd(pokemon);
// Queue a placeholder move for the Pokemon to "use" next turn
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: [] });
pokemon.getMoveQueue().push({ move: Moves.NONE, targets: []});
}
/** Cancels the source's move this turn and queues a "__ must recharge!" message */
@ -569,7 +569,7 @@ export class InterruptedTag extends BattlerTag {
super.onAdd(pokemon);
pokemon.getMoveQueue().shift();
pokemon.pushMoveHistory({move: Moves.NONE, result: MoveResult.OTHER});
pokemon.pushMoveHistory({ move: Moves.NONE, result: MoveResult.OTHER });
}
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
@ -1935,10 +1935,10 @@ export class RoostedTag extends BattlerTag {
modifiedTypes = currentTypes.filter(type => type !== Type.NORMAL);
modifiedTypes.push(Type.FLYING);
} else {
modifiedTypes = [Type.FLYING];
modifiedTypes = [ Type.FLYING ];
}
} else {
modifiedTypes = [...currentTypes];
modifiedTypes = [ ...currentTypes ];
modifiedTypes.push(Type.FLYING);
}
pokemon.summonData.types = modifiedTypes;
@ -1958,10 +1958,10 @@ export class RoostedTag extends BattlerTag {
if (this.isBaseFlying) {
let modifiedTypes: Type[];
if (this.isBasePureFlying && !isCurrentlyDualType) {
modifiedTypes = [Type.NORMAL];
modifiedTypes = [ Type.NORMAL ];
} else {
if (!!pokemon.getTag(RemovedTypeTag) && isOriginallyDualType && !isCurrentlyDualType) {
modifiedTypes = [Type.UNKNOWN];
modifiedTypes = [ Type.UNKNOWN ];
} else {
modifiedTypes = currentTypes.filter(type => type !== Type.FLYING);
}
@ -2067,8 +2067,8 @@ export class StockpilingTag extends BattlerTag {
super.loadTag(source);
this.stockpiledCount = source.stockpiledCount || 0;
this.statChangeCounts = {
[ Stat.DEF ]: source.statChangeCounts?.[ Stat.DEF ] ?? 0,
[ Stat.SPDEF ]: source.statChangeCounts?.[ Stat.SPDEF ] ?? 0,
[Stat.DEF]: source.statChangeCounts?.[Stat.DEF] ?? 0,
[Stat.SPDEF]: source.statChangeCounts?.[Stat.SPDEF] ?? 0,
};
}
@ -2090,7 +2090,7 @@ export class StockpilingTag extends BattlerTag {
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
pokemon.scene.unshiftPhase(new StatStageChangePhase(
pokemon.scene, pokemon.getBattlerIndex(), true,
[Stat.SPDEF, Stat.DEF], 1, true, false, true, this.onStatStagesChanged
[ Stat.SPDEF, Stat.DEF ], 1, true, false, true, this.onStatStagesChanged
));
}
}
@ -2267,7 +2267,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
* Uses DisabledTag's selectionDeniedText() message
*/
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
}
/**
@ -2277,7 +2277,7 @@ export class HealBlockTag extends MoveRestrictionBattlerTag {
* @returns {string} text to display when the move is interrupted
*/
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
return i18next.t("battle:moveDisabledHealBlock", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name, healBlockName: allMoves[Moves.HEAL_BLOCK].name });
}
override onRemove(pokemon: Pokemon): void {
@ -2354,7 +2354,7 @@ export class SubstituteTag extends BattlerTag {
public sourceInFocus: boolean;
constructor(sourceMove: Moves, sourceId: integer) {
super(BattlerTagType.SUBSTITUTE, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT], 0, sourceMove, sourceId, true);
super(BattlerTagType.SUBSTITUTE, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE, BattlerTagLapseType.HIT ], 0, sourceMove, sourceId, true);
}
/** Sets the Substitute's HP and queues an on-add battle animation that initializes the Substitute's sprite. */
@ -2378,7 +2378,7 @@ export class SubstituteTag extends BattlerTag {
onRemove(pokemon: Pokemon): void {
// Only play the animation if the cause of removal isn't from the source's own move
if (!this.sourceInFocus) {
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [this.sprite]);
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_REMOVE, [ this.sprite ]);
} else {
this.sprite.destroy();
}
@ -2402,13 +2402,13 @@ export class SubstituteTag extends BattlerTag {
/** Triggers an animation that brings the Pokemon into focus before it uses a move */
onPreMove(pokemon: Pokemon): void {
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [this.sprite]);
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_PRE_MOVE, [ this.sprite ]);
this.sourceInFocus = true;
}
/** Triggers an animation that brings the Pokemon out of focus after it uses a move */
onAfterMove(pokemon: Pokemon): void {
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [this.sprite]);
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.SUBSTITUTE_POST_MOVE, [ this.sprite ]);
this.sourceInFocus = false;
}
@ -2530,8 +2530,8 @@ export class TormentTag extends MoveRestrictionBattlerTag {
return false;
}
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
override selectionDeniedText(pokemon: Pokemon, _move: Moves): string {
return i18next.t("battle:moveDisabledTorment", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
}
}
@ -2542,7 +2542,7 @@ export class TormentTag extends MoveRestrictionBattlerTag {
*/
export class TauntTag extends MoveRestrictionBattlerTag {
constructor() {
super(BattlerTagType.TAUNT, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 4, Moves.TAUNT);
super(BattlerTagType.TAUNT, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 4, Moves.TAUNT);
}
override onAdd(pokemon: Pokemon) {
@ -2559,12 +2559,12 @@ export class TauntTag extends MoveRestrictionBattlerTag {
return allMoves[move].category === MoveCategory.STATUS;
}
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
return i18next.t("battle:moveDisabledTaunt", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
}
@ -2577,7 +2577,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
private source: Pokemon | null;
constructor(sourceId: number) {
super(BattlerTagType.IMPRISON, [BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE], 1, Moves.IMPRISON, sourceId);
super(BattlerTagType.IMPRISON, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.AFTER_MOVE ], 1, Moves.IMPRISON, sourceId);
}
override onAdd(pokemon: Pokemon) {
@ -2609,12 +2609,12 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
return false;
}
override selectionDeniedText(_pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveCannotBeSelected", { moveName: allMoves[move].name });
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
return i18next.t("battle:moveDisabledImprison", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
}
@ -2650,7 +2650,7 @@ export class SyrupBombTag extends BattlerTag {
pokemon.scene.queueMessage(i18next.t("battlerTags:syrupBombLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })); // Custom message in lieu of an animation in mainline
pokemon.scene.unshiftPhase(new StatStageChangePhase(
pokemon.scene, pokemon.getBattlerIndex(), true,
[Stat.SPD], -1, true, false, true
[ Stat.SPD ], -1, true, false, true
));
return --this.turnCount > 0;
}
@ -2803,9 +2803,9 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
case BattlerTagType.DISABLED:
return new DisabledTag(sourceId);
case BattlerTagType.IGNORE_GHOST:
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
return new ExposedTag(tagType, sourceMove, Type.GHOST, [ Type.NORMAL, Type.FIGHTING ]);
case BattlerTagType.IGNORE_DARK:
return new ExposedTag(tagType, sourceMove, Type.DARK, [Type.PSYCHIC]);
return new ExposedTag(tagType, sourceMove, Type.DARK, [ Type.PSYCHIC ]);
case BattlerTagType.GULP_MISSILE_ARROKUDA:
case BattlerTagType.GULP_MISSILE_PIKACHU:
return new GulpMissileTag(tagType, sourceMove);

View File

@ -1,20 +1,21 @@
import * as Utils from "../utils";
import * as Utils from "#app/utils";
import i18next from "i18next";
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data";
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import Pokemon, { PokemonMove } from "#app/field/pokemon";
import { BattleType, FixedBattleConfig } from "#app/battle";
import Trainer, { TrainerVariant } from "#app/field/trainer";
import { GameMode } from "#app/game-mode";
import { Type } from "./type";
import { Type } from "#app/data/type";
import { Challenges } from "#enums/challenges";
import { Species } from "#enums/species";
import { TrainerType } from "#enums/trainer-type";
import { Nature } from "./nature";
import { Moves } from "#app/enums/moves";
import { TypeColor, TypeShadow } from "#app/enums/color";
import { pokemonEvolutions } from "./pokemon-evolutions";
import { pokemonFormChanges } from "./pokemon-forms";
import { Nature } from "#app/data/nature";
import { Moves } from "#enums/moves";
import { TypeColor, TypeShadow } from "#enums/color";
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { pokemonFormChanges } from "#app/data/pokemon-forms";
/** A constant for the default max cost of the starting party before a run */
const DEFAULT_PARTY_MAX_COST = 10;
@ -184,7 +185,7 @@ export abstract class Challenge {
*/
getDescription(overrideValue?: number): string {
const value = overrideValue ?? this.value;
return `${i18next.t([`challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc`])}`;
return `${i18next.t([ `challenges:${this.geti18nKey()}.desc.${value}`, `challenges:${this.geti18nKey()}.desc` ])}`;
}
/**
@ -413,9 +414,9 @@ export class SingleGenerationChallenge extends Challenge {
}
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
const generations = [pokemon.generation];
const generations = [ pokemon.generation ];
if (soft) {
const speciesToCheck = [pokemon.speciesId];
const speciesToCheck = [ pokemon.speciesId ];
while (speciesToCheck.length) {
const checking = speciesToCheck.pop();
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
@ -454,7 +455,7 @@ export class SingleGenerationChallenge extends Challenge {
trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ];
break;
case 186:
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE]), TrainerType.LARRY_ELITE ];
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ];
break;
case 188:
trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ];
@ -527,10 +528,10 @@ interface monotypeOverride {
*/
export class SingleTypeChallenge extends Challenge {
private static TYPE_OVERRIDES: monotypeOverride[] = [
{species: Species.CASTFORM, type: Type.NORMAL, fusion: false},
{ species: Species.CASTFORM, type: Type.NORMAL, fusion: false },
];
// TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy
private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA];
private static SPECIES_OVERRIDES: Species[] = [ Species.MELOETTA ];
constructor() {
super(Challenges.SINGLE_TYPE, 18);
@ -538,9 +539,9 @@ export class SingleTypeChallenge extends Challenge {
override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps, soft: boolean = false): boolean {
const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex);
const types = [speciesForm.type1, speciesForm.type2];
const types = [ speciesForm.type1, speciesForm.type2 ];
if (soft && !SingleTypeChallenge.SPECIES_OVERRIDES.includes(pokemon.speciesId)) {
const speciesToCheck = [pokemon.speciesId];
const speciesToCheck = [ pokemon.speciesId ];
while (speciesToCheck.length) {
const checking = speciesToCheck.pop();
if (checking && pokemonEvolutions.hasOwnProperty(checking)) {
@ -605,9 +606,9 @@ export class SingleTypeChallenge extends Challenge {
overrideValue = this.value;
}
const type = i18next.t(`pokemonInfo:Type.${Type[this.value - 1]}`);
const typeColor = `[color=${TypeColor[Type[this.value-1]]}][shadow=${TypeShadow[Type[this.value-1]]}]${type}[/shadow][/color]`;
const typeColor = `[color=${TypeColor[Type[this.value - 1]]}][shadow=${TypeShadow[Type[this.value - 1]]}]${type}[/shadow][/color]`;
const defaultDesc = i18next.t("challenges:singleType.desc_default");
const typeDesc = i18next.t("challenges:singleType.desc", {type: typeColor});
const typeDesc = i18next.t("challenges:singleType.desc", { type: typeColor });
return this.value === 0 ? defaultDesc : typeDesc;
}
@ -637,7 +638,7 @@ export class FreshStartChallenge extends Challenge {
applyStarterCost(species: Species, cost: Utils.NumberHolder): boolean {
if (defaultStarterSpecies.includes(species)) {
cost.value = speciesStarters[species];
cost.value = speciesStarterCosts[species];
return true;
}
return false;
@ -652,7 +653,7 @@ export class FreshStartChallenge extends Challenge {
pokemon.shiny = false; // Not shiny
pokemon.variant = 0; // Not shiny
pokemon.formIndex = 0; // Froakie should be base form
pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats
pokemon.ivs = [ 10, 10, 10, 10, 10, 10 ]; // Default IVs of 10 for all stats
return true;
}
@ -719,7 +720,7 @@ export class LowerStarterMaxCostChallenge extends Challenge {
}
applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean {
if (speciesStarters[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) {
if (speciesStarterCosts[pokemon.speciesId] > DEFAULT_PARTY_MAX_COST - this.value) {
valid.value = false;
return true;
}

View File

@ -1,10 +1,11 @@
import { PartyMemberStrength } from "#enums/party-member-strength";
import { Species } from "#enums/species";
import BattleScene from "../battle-scene";
import { PlayerPokemon } from "../field/pokemon";
import { Starter } from "../ui/starter-select-ui-handler";
import * as Utils from "../utils";
import PokemonSpecies, { PokemonSpeciesForm, getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
import BattleScene from "#app/battle-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import { Starter } from "#app/ui/starter-select-ui-handler";
import * as Utils from "#app/utils";
import PokemonSpecies, { PokemonSpeciesForm, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
export interface DailyRunConfig {
seed: integer;
@ -46,9 +47,9 @@ export function getDailyRunStarters(scene: BattleScene, seed: string): Starter[]
for (let c = 0; c < starterCosts.length; c++) {
const cost = starterCosts[c];
const costSpecies = Object.keys(speciesStarters)
const costSpecies = Object.keys(speciesStarterCosts)
.map(s => parseInt(s) as Species)
.filter(s => speciesStarters[s] === cost);
.filter(s => speciesStarterCosts[s] === cost);
const randPkmSpecies = getPokemonSpecies(Utils.randSeedItem(costSpecies));
const starterSpecies = getPokemonSpecies(randPkmSpecies.getTrainerSpeciesForLevel(startingLevel, true, PartyMemberStrength.STRONGER));
starters.push(getDailyRunStarter(scene, starterSpecies, startingLevel));

View File

@ -3123,44 +3123,44 @@ export const trainerTypeDialogue: TrainerTypeDialogue = {
export const doubleBattleDialogue = {
"blue_red_double": {
encounter: ["doubleBattleDialogue:blue_red_double.encounter.1"],
victory: ["doubleBattleDialogue:blue_red_double.victory.1"]
encounter: [ "doubleBattleDialogue:blue_red_double.encounter.1" ],
victory: [ "doubleBattleDialogue:blue_red_double.victory.1" ]
},
"red_blue_double": {
encounter: ["doubleBattleDialogue:red_blue_double.encounter.1"],
victory: ["doubleBattleDialogue:red_blue_double.victory.1"]
encounter: [ "doubleBattleDialogue:red_blue_double.encounter.1" ],
victory: [ "doubleBattleDialogue:red_blue_double.victory.1" ]
},
"tate_liza_double": {
encounter: ["doubleBattleDialogue:tate_liza_double.encounter.1"],
victory: ["doubleBattleDialogue:tate_liza_double.victory.1"]
encounter: [ "doubleBattleDialogue:tate_liza_double.encounter.1" ],
victory: [ "doubleBattleDialogue:tate_liza_double.victory.1" ]
},
"liza_tate_double": {
encounter: ["doubleBattleDialogue:liza_tate_double.encounter.1"],
victory: [ "doubleBattleDialogue:liza_tate_double.victory.1"]
encounter: [ "doubleBattleDialogue:liza_tate_double.encounter.1" ],
victory: [ "doubleBattleDialogue:liza_tate_double.victory.1" ]
},
"wallace_steven_double": {
encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1"],
victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1"]
encounter: [ "doubleBattleDialogue:wallace_steven_double.encounter.1" ],
victory: [ "doubleBattleDialogue:wallace_steven_double.victory.1" ]
},
"steven_wallace_double": {
encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1"],
victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1"]
encounter: [ "doubleBattleDialogue:steven_wallace_double.encounter.1" ],
victory: [ "doubleBattleDialogue:steven_wallace_double.victory.1" ]
},
"alder_iris_double": {
encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1"],
victory: [ "doubleBattleDialogue:alder_iris_double.victory.1"]
encounter: [ "doubleBattleDialogue:alder_iris_double.encounter.1" ],
victory: [ "doubleBattleDialogue:alder_iris_double.victory.1" ]
},
"iris_alder_double": {
encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1"],
victory: [ "doubleBattleDialogue:iris_alder_double.victory.1"]
encounter: [ "doubleBattleDialogue:iris_alder_double.encounter.1" ],
victory: [ "doubleBattleDialogue:iris_alder_double.victory.1" ]
},
"marnie_piers_double": {
encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1"],
victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1"]
encounter: [ "doubleBattleDialogue:marnie_piers_double.encounter.1" ],
victory: [ "doubleBattleDialogue:marnie_piers_double.victory.1" ]
},
"piers_marnie_double": {
encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1"],
victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1"]
encounter: [ "doubleBattleDialogue:piers_marnie_double.encounter.1" ],
victory: [ "doubleBattleDialogue:piers_marnie_double.victory.1" ]
},
@ -3193,7 +3193,7 @@ export function initTrainerTypeDialogue(): void {
const trainerTypes = Object.keys(trainerTypeDialogue).map(t => parseInt(t) as TrainerType);
for (const trainerType of trainerTypes) {
const messages = trainerTypeDialogue[trainerType];
const messageTypes = ["encounter", "victory", "defeat"];
const messageTypes = [ "encounter", "victory", "defeat" ];
for (const messageType of messageTypes) {
if (Array.isArray(messages)) {
if (messages[0][messageType]) {

View File

@ -48,7 +48,7 @@ export class EggHatchData {
seenCount: currDexEntry.seenCount,
caughtCount: currDexEntry.caughtCount,
hatchedCount: currDexEntry.hatchedCount,
ivs: [...currDexEntry.ivs]
ivs: [ ...currDexEntry.ivs ]
};
this.starterDataEntryBeforeUpdate = {
moveset: currStarterDataEntry.moveset,

View File

@ -1,30 +1,19 @@
import BattleScene from "../battle-scene";
import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "./pokemon-species";
import { VariantTier } from "../enums/variant-tier";
import * as Utils from "../utils";
import BattleScene from "#app/battle-scene";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { VariantTier } from "#enums/variant-tier";
import * as Utils from "#app/utils";
import Overrides from "#app/overrides";
import { pokemonPrevolutions } from "./pokemon-evolutions";
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import { PlayerPokemon } from "#app/field/pokemon";
import i18next from "i18next";
import { EggTier } from "#enums/egg-type";
import { Species } from "#enums/species";
import { EggSourceType } from "#app/enums/egg-source-types";
import { EggSourceType } from "#enums/egg-source-types";
import { MANAPHY_EGG_MANAPHY_RATE, SAME_SPECIES_EGG_HA_RATE, GACHA_EGG_HA_RATE, GACHA_DEFAULT_RARE_EGGMOVE_RATE, SAME_SPECIES_EGG_RARE_EGGMOVE_RATE, GACHA_MOVE_UP_RARE_EGGMOVE_RATE, GACHA_DEFAULT_SHINY_RATE, GACHA_SHINY_UP_SHINY_RATE, SAME_SPECIES_EGG_SHINY_RATE, EGG_PITY_LEGENDARY_THRESHOLD, EGG_PITY_EPIC_THRESHOLD, EGG_PITY_RARE_THRESHOLD, SHINY_VARIANT_CHANCE, SHINY_EPIC_CHANCE, GACHA_DEFAULT_COMMON_EGG_THRESHOLD, GACHA_DEFAULT_RARE_EGG_THRESHOLD, GACHA_DEFAULT_EPIC_EGG_THRESHOLD, GACHA_LEGENDARY_UP_THRESHOLD_OFFSET, HATCH_WAVES_MANAPHY_EGG, HATCH_WAVES_COMMON_EGG, HATCH_WAVES_RARE_EGG, HATCH_WAVES_EPIC_EGG, HATCH_WAVES_LEGENDARY_EGG } from "#app/data/balance/rates";
export const EGG_SEED = 1073741824;
// Rates for specific random properties in 1/x
const DEFAULT_SHINY_RATE = 128;
const GACHA_SHINY_UP_SHINY_RATE = 64;
const SAME_SPECIES_EGG_SHINY_RATE = 12;
const SAME_SPECIES_EGG_HA_RATE = 8;
const MANAPHY_EGG_MANAPHY_RATE = 8;
const GACHA_EGG_HA_RATE = 192;
// 1/x for legendary eggs, 1/x*2 for epic eggs, 1/x*4 for rare eggs, and 1/x*8 for common eggs
const DEFAULT_RARE_EGGMOVE_RATE = 6;
const SAME_SPECIES_EGG_RARE_EGGMOVE_RATE = 3;
const GACHA_MOVE_UP_RARE_EGGMOVE_RATE = 3;
/** Egg options to override egg properties */
export interface IEggOptions {
/** Id. Used to check if egg type will be manaphy (id % 204 === 0) */
@ -299,7 +288,7 @@ export class Egg {
public getEggTypeDescriptor(scene: BattleScene): string {
switch (this.sourceType) {
case EggSourceType.SAME_SPECIES_EGG:
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName() });
case EggSourceType.GACHA_LEGENDARY:
return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
case EggSourceType.GACHA_SHINY:
@ -323,7 +312,7 @@ export class Egg {
////
private rollEggMoveIndex() {
let baseChance = DEFAULT_RARE_EGGMOVE_RATE;
let baseChance = GACHA_DEFAULT_RARE_EGGMOVE_RATE;
switch (this._sourceType) {
case EggSourceType.SAME_SPECIES_EGG:
baseChance = SAME_SPECIES_EGG_RARE_EGGMOVE_RATE;
@ -341,24 +330,24 @@ export class Egg {
private getEggTierDefaultHatchWaves(eggTier?: EggTier): number {
if (this._species === Species.PHIONE || this._species === Species.MANAPHY) {
return 50;
return HATCH_WAVES_MANAPHY_EGG;
}
switch (eggTier ?? this._tier) {
case EggTier.COMMON:
return 10;
return HATCH_WAVES_COMMON_EGG;
case EggTier.GREAT:
return 25;
return HATCH_WAVES_RARE_EGG;
case EggTier.ULTRA:
return 50;
return HATCH_WAVES_EPIC_EGG;
}
return 100;
return HATCH_WAVES_LEGENDARY_EGG;
}
private rollEggTier(): EggTier {
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0;
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
const tierValue = Utils.randInt(256);
return tierValue >= 52 + tierValueOffset ? EggTier.COMMON : tierValue >= 8 + tierValueOffset ? EggTier.GREAT : tierValue >= 1 + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER;
return tierValue >= GACHA_DEFAULT_COMMON_EGG_THRESHOLD + tierValueOffset ? EggTier.COMMON : tierValue >= GACHA_DEFAULT_RARE_EGG_THRESHOLD + tierValueOffset ? EggTier.GREAT : tierValue >= GACHA_DEFAULT_EPIC_EGG_THRESHOLD + tierValueOffset ? EggTier.ULTRA : EggTier.MASTER;
}
private rollSpecies(scene: BattleScene): Species | null {
@ -407,10 +396,10 @@ export class Egg {
break;
}
const ignoredSpecies = [Species.PHIONE, Species.MANAPHY, Species.ETERNATUS];
const ignoredSpecies = [ Species.PHIONE, Species.MANAPHY, Species.ETERNATUS ];
let speciesPool = Object.keys(speciesStarters)
.filter(s => speciesStarters[s] >= minStarterValue && speciesStarters[s] <= maxStarterValue)
let speciesPool = Object.keys(speciesStarterCosts)
.filter(s => speciesStarterCosts[s] >= minStarterValue && speciesStarterCosts[s] <= maxStarterValue)
.map(s => parseInt(s) as Species)
.filter(s => !pokemonPrevolutions.hasOwnProperty(s) && getPokemonSpecies(s).isObtainable() && ignoredSpecies.indexOf(s) === -1);
@ -441,7 +430,7 @@ export class Egg {
let totalWeight = 0;
const speciesWeights : number[] = [];
for (const speciesId of speciesPool) {
let weight = Math.floor((((maxStarterValue - speciesStarters[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
let weight = Math.floor((((maxStarterValue - speciesStarterCosts[speciesId]) / ((maxStarterValue - minStarterValue) + 1)) * 1.5 + 1) * 100);
const species = getPokemonSpecies(speciesId);
if (species.isRegional()) {
weight = Math.floor(weight / 2);
@ -475,7 +464,7 @@ export class Egg {
* @returns True if the egg is shiny
**/
private rollShiny(): boolean {
let shinyChance = DEFAULT_SHINY_RATE;
let shinyChance = GACHA_DEFAULT_SHINY_RATE;
switch (this._sourceType) {
case EggSourceType.GACHA_SHINY:
shinyChance = GACHA_SHINY_UP_SHINY_RATE;
@ -498,9 +487,9 @@ export class Egg {
}
const rand = Utils.randSeedInt(10);
if (rand >= 4) {
if (rand >= SHINY_VARIANT_CHANCE) {
return VariantTier.STANDARD; // 6/10
} else if (rand >= 1) {
} else if (rand >= SHINY_EPIC_CHANCE) {
return VariantTier.RARE; // 3/10
} else {
return VariantTier.EPIC; // 1/10
@ -508,16 +497,16 @@ export class Egg {
}
private checkForPityTierOverrides(scene: BattleScene): void {
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? 1 : 0;
const tierValueOffset = this._sourceType === EggSourceType.GACHA_LEGENDARY ? GACHA_LEGENDARY_UP_THRESHOLD_OFFSET : 0;
scene.gameData.eggPity[EggTier.GREAT] += 1;
scene.gameData.eggPity[EggTier.ULTRA] += 1;
scene.gameData.eggPity[EggTier.MASTER] += 1 + tierValueOffset;
// These numbers are roughly the 80% mark. That is, 80% of the time you'll get an egg before this gets triggered.
if (scene.gameData.eggPity[EggTier.MASTER] >= 412 && this._tier === EggTier.COMMON) {
if (scene.gameData.eggPity[EggTier.MASTER] >= EGG_PITY_LEGENDARY_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.MASTER;
} else if (scene.gameData.eggPity[EggTier.ULTRA] >= 59 && this._tier === EggTier.COMMON) {
} else if (scene.gameData.eggPity[EggTier.ULTRA] >= EGG_PITY_EPIC_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.ULTRA;
} else if (scene.gameData.eggPity[EggTier.GREAT] >= 9 && this._tier === EggTier.COMMON) {
} else if (scene.gameData.eggPity[EggTier.GREAT] >= EGG_PITY_RARE_THRESHOLD && this._tier === EggTier.COMMON) {
this._tier = EggTier.GREAT;
}
scene.gameData.eggPity[this._tier] = 0;
@ -544,7 +533,7 @@ export class Egg {
}
private getEggTierFromSpeciesStarterValue(): EggTier {
const speciesStartValue = speciesStarters[this.species];
const speciesStartValue = speciesStarterCosts[this.species];
if (speciesStartValue >= 1 && speciesStartValue <= 3) {
return EggTier.COMMON;
}
@ -567,7 +556,7 @@ export class Egg {
}
export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timestamp: number): Species {
const legendarySpecies = Object.entries(speciesStarters)
const legendarySpecies = Object.entries(speciesStarterCosts)
.filter(s => s[1] >= 8 && s[1] <= 9)
.map(s => parseInt(s[0]))
.filter(s => getPokemonSpecies(s).isObtainable());
@ -594,7 +583,7 @@ export function getLegendaryGachaSpeciesForTimestamp(scene: BattleScene, timesta
* @returns The egg tier of a given pokemon species
*/
export function getEggTierForSpecies(pokemonSpecies :PokemonSpecies): EggTier {
const speciesBaseValue = speciesStarters[pokemonSpecies.getRootSpeciesId()];
const speciesBaseValue = speciesStarterCosts[pokemonSpecies.getRootSpeciesId()];
if (speciesBaseValue <= 3) {
return EggTier.COMMON;
} else if (speciesBaseValue <= 5) {

File diff suppressed because it is too large Load Diff

View File

@ -152,7 +152,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
tier: EggTier.ULTRA
};
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.epic`));
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SACRED_ASH], guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA], fillRemaining: true }, [eggOptions]);
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SACRED_ASH ], guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ULTRA ], fillRemaining: true }, [ eggOptions ]);
return initBattleWithEnemyConfig(scene, config);
}
)
@ -174,7 +174,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
tier: EggTier.GREAT
};
encounter.setDialogueToken("eggType", i18next.t(`${namespace}:eggTypes.rare`));
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [eggOptions]);
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [ eggOptions ]);
leaveEncounterWithoutBattle(scene);
}
)

View File

@ -195,7 +195,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// Can't define stack count on a ModifierType, have to just create separate instances for each stack
// Overflow berries will be "lost" on the boss, but it's un-catchable anyway
for (let i = 0; i < berryMod.stackCount; i++) {
const modifierType = generateModifierType(scene, modifierTypes.BERRY, [berryMod.berryType]) as PokemonHeldItemModifierType;
const modifierType = generateModifierType(scene, modifierTypes.BERRY, [ berryMod.berryType ]) as PokemonHeldItemModifierType;
bossModifierConfigs.push({ modifier: modifierType });
}
});
@ -204,8 +204,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// SpDef buff below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
[Stat.SPDEF] :
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
[ Stat.SPDEF ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
// Calculate boss mon
const config: EnemyPartyConfig = {
@ -215,9 +215,9 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
species: getPokemonSpecies(Species.GREEDENT),
isBoss: true,
bossSegments: 3,
moveSet: [Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH],
moveSet: [ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ],
modifierConfigs: bossModifierConfigs,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
@ -226,7 +226,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
encounter.setDialogueToken("greedentName", getPokemonSpecies(Species.GREEDENT).getName());
return true;
@ -280,7 +280,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY],
targets: [ BattlerIndex.ENEMY ],
move: new PokemonMove(Moves.STUFF_CHEEKS),
ignorePp: true
});
@ -320,7 +320,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
Phaser.Math.RND.shuffle(berryTypesAsArray);
const randBerryType = berryTypesAsArray.pop();
const berryModType = generateModifierType(scene, modifierTypes.BERRY, [randBerryType]) as BerryModifierType;
const berryModType = generateModifierType(scene, modifierTypes.BERRY, [ randBerryType ]) as BerryModifierType;
applyModifierTypeToPlayerPokemon(scene, pokemon, berryModType);
}
}
@ -355,7 +355,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
// Greedent joins the team, level equal to 2 below highest party member
const level = getHighestLevelPlayerPokemon(scene, false, true).level - 2;
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
greedent.moveset = [ new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF) ];
greedent.passive = true;
transitionMysteryEncounterIntroVisuals(scene, true, true, 500);
@ -472,7 +472,7 @@ function doGreedentEatBerries(scene: BattleScene) {
*/
function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
const berryAddDelay = 150;
let animationOrder = ["starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa"];
let animationOrder = [ "starf", "sitrus", "lansat", "salac", "apicot", "enigma", "liechi", "ganlon", "lum", "petaya", "leppa" ];
if (isEat) {
animationOrder = animationOrder.reverse();
}
@ -496,7 +496,7 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
// Animate Petaya berry falling off the pile
if (berry === "petaya" && sprite && tintSprite && !isEat) {
scene.time.delayedCall(200, () => {
doBerryBounce(scene, [sprite, tintSprite], 30, 500);
doBerryBounce(scene, [ sprite, tintSprite ], 30, 500);
});
}
});

View File

@ -8,7 +8,8 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
import { AbilityRequirement, CombinationPokemonRequirement, MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
import { getHighestStatTotalPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { EXTORTION_ABILITIES, EXTORTION_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
@ -71,7 +72,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
const pokemon = getHighestStatTotalPlayerPokemon(scene, true, true);
const baseSpecies = pokemon.getSpeciesForm().getRootSpeciesId();
const starterValue: number = speciesStarters[baseSpecies] ?? 1;
const starterValue: number = speciesStarterCosts[baseSpecies] ?? 1;
const multiplier = Math.max(MONEY_MAXIMUM_MULTIPLIER / 10 * starterValue, MONEY_MINIMUM_MULTIPLIER);
const price = scene.getWaveMoneyAmount(multiplier);

View File

@ -69,7 +69,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
isBoss: true
}],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
// Calculate the number of extra berries that player receives
// 10-40: 2, 40-120: 4, 120-160: 5, 160-180: 7
@ -193,11 +193,11 @@ export const BerriesAboundEncounter: MysteryEncounter =
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
const config = scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0];
config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
config.pokemonConfigs![0].tags = [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ];
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.boss_enraged`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
@ -208,7 +208,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
return;
} else {
// Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.08), numBerries), 2);
const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1) / 0.08), numBerries), 2);
encounter.setDialogueToken("numBerries", String(numBerriesGrabbed));
const doFasterBerryRewards = () => {
const berryText = i18next.t(`${namespace}:berries`);
@ -250,7 +250,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
function tryGiveBerry(scene: BattleScene, prioritizedPokemon?: PlayerPokemon) {
const berryType = randSeedInt(Object.keys(BerryType).filter(s => !isNaN(Number(s))).length) as BerryType;
const berry = generateModifierType(scene, modifierTypes.BERRY, [berryType]) as BerryModifierType;
const berry = generateModifierType(scene, modifierTypes.BERRY, [ berryType ]) as BerryModifierType;
const party = scene.getParty();

View File

@ -181,7 +181,7 @@ const MISC_TUTOR_MOVES = [
/**
* Wave breakpoints that determine how strong to make the Bug-Type Superfan's team
*/
const WAVE_LEVEL_BREAKPOINTS = [30, 50, 70, 100, 120, 140, 160];
const WAVE_LEVEL_BREAKPOINTS = [ 30, 50, 70, 100, 120, 140, 160 ];
/**
* Bug Type Superfan encounter.
@ -193,7 +193,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
.withEncounterTier(MysteryEncounterTier.GREAT)
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
// Must have at least 1 Bug type on team, OR have a bug item somewhere on the team
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
new TypeRequirement(Type.BUG, false, 1)
))
@ -268,7 +268,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
const requiredItems = [
generateModifierType(scene, modifierTypes.QUICK_CLAW),
generateModifierType(scene, modifierTypes.GRIP_CLAW),
generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.BUG]),
generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.BUG ]),
];
const requiredItemString = requiredItems.map(m => m?.name ?? "unknown").join("/");
@ -331,7 +331,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
encounter.setDialogueToken("numBugTypes", numBugTypesText);
if (numBugTypes < 2) {
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SUPER_LURE, modifierTypes.GREAT_BALL ], fillRemaining: false });
encounter.selectedOption!.dialogue!.selected = [
{
speaker: `${namespace}:speaker`,
@ -339,7 +339,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
},
];
} else if (numBugTypes < 4) {
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.QUICK_CLAW, modifierTypes.MAX_LURE, modifierTypes.ULTRA_BALL ], fillRemaining: false });
encounter.selectedOption!.dialogue!.selected = [
{
speaker: `${namespace}:speaker`,
@ -347,7 +347,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
},
];
} else if (numBugTypes < 6) {
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.GRIP_CLAW, modifierTypes.MAX_LURE, modifierTypes.ROGUE_BALL ], fillRemaining: false });
encounter.selectedOption!.dialogue!.selected = [
{
speaker: `${namespace}:speaker`,
@ -356,7 +356,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
];
} else {
// If player has any evolution/form change items that are valid for their party, will spawn one of those items in addition to a Master Ball
const modifierOptions: ModifierTypeOption[] = [generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)!];
const modifierOptions: ModifierTypeOption[] = [ generateModifierTypeOption(scene, modifierTypes.MASTER_BALL)!, generateModifierTypeOption(scene, modifierTypes.MAX_LURE)! ];
const specialOptions: ModifierTypeOption[] = [];
const nonRareEvolutionModifier = generateModifierTypeOption(scene, modifierTypes.EVOLUTION_ITEM);
@ -397,7 +397,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
// Meets one or both of the below reqs
new HeldItemRequirement(["BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier"], 1),
new HeldItemRequirement([ "BypassSpeedChanceModifier", "ContactHeldItemTransferChanceModifier" ], 1),
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1)
))
.withDialogue({
@ -474,7 +474,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
const bugNet = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET)!;
bugNet.type.tier = ModifierTier.ROGUE;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [bugNet], guaranteedModifierTypeFuncs: [modifierTypes.REVIVER_SEED], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ bugNet ], guaranteedModifierTypeFuncs: [ modifierTypes.REVIVER_SEED ], fillRemaining: false });
leaveEncounterWithoutBattle(scene, true);
})
.build())
@ -535,7 +535,7 @@ function getTrainerConfigForWave(waveIndex: number) {
}))
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
.setPartyMemberFunc(3, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon.formIndex)) {
p.formIndex = pool3Mon.formIndex;
p.generateAndPopulateMoveset();
@ -558,14 +558,14 @@ function getTrainerConfigForWave(waveIndex: number) {
p.generateName();
}))
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon.formIndex)) {
p.formIndex = pool3Mon.formIndex;
p.generateAndPopulateMoveset();
p.generateName();
}
}))
.setPartyMemberFunc(4, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(4, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
p.formIndex = pool3Mon2.formIndex;
p.generateAndPopulateMoveset();
@ -586,7 +586,7 @@ function getTrainerConfigForWave(waveIndex: number) {
p.generateName();
}))
.setPartyMemberFunc(2, getRandomPartyMemberFunc(POOL_2_POKEMON, TrainerSlot.TRAINER, true))
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon.formIndex)) {
p.formIndex = pool3Mon.formIndex;
p.generateAndPopulateMoveset();
@ -611,14 +611,14 @@ function getTrainerConfigForWave(waveIndex: number) {
p.generateAndPopulateMoveset();
p.generateName();
}))
.setPartyMemberFunc(2, getRandomPartyMemberFunc([pool3Mon.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(2, getRandomPartyMemberFunc([ pool3Mon.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon.formIndex)) {
p.formIndex = pool3Mon.formIndex;
p.generateAndPopulateMoveset();
p.generateName();
}
}))
.setPartyMemberFunc(3, getRandomPartyMemberFunc([pool3Mon2.species], TrainerSlot.TRAINER, true, p => {
.setPartyMemberFunc(3, getRandomPartyMemberFunc([ pool3Mon2.species ], TrainerSlot.TRAINER, true, p => {
if (!isNullOrUndefined(pool3Mon2.formIndex)) {
p.formIndex = pool3Mon2.formIndex;
p.generateAndPopulateMoveset();

View File

@ -129,20 +129,20 @@ export const ClowningAroundEncounter: MysteryEncounter =
{
species: getPokemonSpecies(Species.MR_MIME),
isBoss: true,
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC]
moveSet: [ Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC ]
},
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
species: getPokemonSpecies(Species.BLACEPHALON),
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [randSeedInt(18), randSeedInt(18)] }),
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ ability: ability, types: [ randSeedInt(18), randSeedInt(18) ]}),
isBoss: true,
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
moveSet: [ Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN ]
},
],
doubleBattle: true
});
// Load animations/sfx for start of fight moves
loadCustomMovesForEncounter(scene, [Moves.ROLE_PLAY, Moves.TAUNT]);
loadCustomMovesForEncounter(scene, [ Moves.ROLE_PLAY, Moves.TAUNT ]);
encounter.setDialogueToken("blacephalonName", getPokemonSpecies(Species.BLACEPHALON).getName());
@ -175,19 +175,19 @@ export const ClowningAroundEncounter: MysteryEncounter =
encounter.startOfBattleEffects.push(
{ // Mr. Mime copies the Blacephalon's random ability
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY_2],
targets: [ BattlerIndex.ENEMY_2 ],
move: new PokemonMove(Moves.ROLE_PLAY),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.TAUNT),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER_2],
targets: [ BattlerIndex.PLAYER_2 ],
move: new PokemonMove(Moves.TAUNT),
ignorePp: true
});
@ -336,11 +336,11 @@ export const ClowningAroundEncounter: MysteryEncounter =
.filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
.map(move => move!.getMove().type);
if (priorityTypes?.length > 0) {
priorityTypes = [...new Set(priorityTypes)].sort();
priorityTypes = [ ...new Set(priorityTypes) ].sort();
priorityTypes = randSeedShuffle(priorityTypes);
}
const newTypes = [originalTypes[0]];
const newTypes = [ originalTypes[0] ];
let secondType: Type | null = null;
while (secondType === null || secondType === newTypes[0] || originalTypes.includes(secondType)) {
if (priorityTypes.length > 0) {
@ -453,37 +453,37 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
// Pools have instances of the modifier type equal to the max stacks that modifier can be applied to any one pokemon
// This is to prevent "over-generating" a random item of a certain type during item swaps
const ultraPool = [
[modifierTypes.REVIVER_SEED, 1],
[modifierTypes.GOLDEN_PUNCH, 5],
[modifierTypes.ATTACK_TYPE_BOOSTER, 99],
[modifierTypes.QUICK_CLAW, 3],
[modifierTypes.WIDE_LENS, 3]
[ modifierTypes.REVIVER_SEED, 1 ],
[ modifierTypes.GOLDEN_PUNCH, 5 ],
[ modifierTypes.ATTACK_TYPE_BOOSTER, 99 ],
[ modifierTypes.QUICK_CLAW, 3 ],
[ modifierTypes.WIDE_LENS, 3 ]
];
const roguePool = [
[modifierTypes.LEFTOVERS, 4],
[modifierTypes.SHELL_BELL, 4],
[modifierTypes.SOUL_DEW, 10],
[modifierTypes.SOOTHE_BELL, 3],
[modifierTypes.SCOPE_LENS, 1],
[modifierTypes.BATON, 1],
[modifierTypes.FOCUS_BAND, 5],
[modifierTypes.KINGS_ROCK, 3],
[modifierTypes.GRIP_CLAW, 5]
[ modifierTypes.LEFTOVERS, 4 ],
[ modifierTypes.SHELL_BELL, 4 ],
[ modifierTypes.SOUL_DEW, 10 ],
[ modifierTypes.SOOTHE_BELL, 3 ],
[ modifierTypes.SCOPE_LENS, 1 ],
[ modifierTypes.BATON, 1 ],
[ modifierTypes.FOCUS_BAND, 5 ],
[ modifierTypes.KINGS_ROCK, 3 ],
[ modifierTypes.GRIP_CLAW, 5 ]
];
const berryPool = [
[BerryType.APICOT, 3],
[BerryType.ENIGMA, 2],
[BerryType.GANLON, 3],
[BerryType.LANSAT, 3],
[BerryType.LEPPA, 2],
[BerryType.LIECHI, 3],
[BerryType.LUM, 2],
[BerryType.PETAYA, 3],
[BerryType.SALAC, 2],
[BerryType.SITRUS, 2],
[BerryType.STARF, 3]
[ BerryType.APICOT, 3 ],
[ BerryType.ENIGMA, 2 ],
[ BerryType.GANLON, 3 ],
[ BerryType.LANSAT, 3 ],
[ BerryType.LEPPA, 2 ],
[ BerryType.LIECHI, 3 ],
[ BerryType.LUM, 2 ],
[ BerryType.PETAYA, 3 ],
[ BerryType.SALAC, 2 ],
[ BerryType.SITRUS, 2 ],
[ BerryType.STARF, 3 ]
];
let pool: any[];
@ -502,7 +502,7 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
const newItemType = pool[randIndex];
let newMod: PokemonHeldItemModifierType;
if (tier === "Berries") {
newMod = generateModifierType(scene, modifierTypes.BERRY, [newItemType[0]]) as PokemonHeldItemModifierType;
newMod = generateModifierType(scene, modifierTypes.BERRY, [ newItemType[0] ]) as PokemonHeldItemModifierType;
} else {
newMod = generateModifierType(scene, newItemType[0]) as PokemonHeldItemModifierType;
}

View File

@ -141,7 +141,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
scene.getEnemyParty().forEach(enemyPokemon => {
scene.field.remove(enemyPokemon, true);
});
scene.currentBattle.enemyParty = [oricorio];
scene.currentBattle.enemyParty = [ oricorio ];
scene.field.add(oricorio);
// Spawns on offscreen field
oricorio.x -= 300;
@ -153,14 +153,14 @@ export const DancingLessonsEncounter: MysteryEncounter =
dataSource: oricorioData,
isBoss: true,
// Gets +1 to all stats except SPD on battle start
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.boss_enraged`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF], 1));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF ], 1));
}
}],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
encounter.misc = {
oricorioData
};
@ -187,13 +187,13 @@ export const DancingLessonsEncounter: MysteryEncounter =
encounter.startOfBattleEffects.push({
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.REVELATION_DANCE),
ignorePp: true
});
await hideOricorioPokemon(scene);
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.BATON], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.BATON ], fillRemaining: true });
await initBattleWithEnemyConfig(scene, encounter.enemyPartyConfigs[0]);
})
.build()

View File

@ -164,7 +164,7 @@ export const DarkDealEncounter: MysteryEncounter =
// Starter egg tier, 35/50/10/5 %odds for tiers 6/7/8/9+
const roll = randSeedInt(100);
const starterTier: number | [number, number] =
roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [9, 10];
roll >= 65 ? 6 : roll >= 15 ? 7 : roll >= 5 ? 8 : [ 9, 10 ];
const bossSpecies = getPokemonSpecies(getRandomSpeciesByStarterTier(starterTier, excludedBosses, bossTypes));
const pokemonConfig: EnemyPokemonConfig = {
species: bossSpecies,
@ -179,7 +179,7 @@ export const DarkDealEncounter: MysteryEncounter =
pokemonConfig.formIndex = 0;
}
const config: EnemyPartyConfig = {
pokemonConfigs: [pokemonConfig],
pokemonConfigs: [ pokemonConfig ],
};
return initBattleWithEnemyConfig(scene, config);
})

View File

@ -22,7 +22,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
const namespace = "mysteryEncounters/delibirdy";
/** Berries only */
const OPTION_2_ALLOWED_MODIFIERS = ["BerryModifier", "PokemonInstantReviveModifier"];
const OPTION_2_ALLOWED_MODIFIERS = [ "BerryModifier", "PokemonInstantReviveModifier" ];
/** Disallowed items are berries, Reviver Seeds, and Vitamins (form change items and fusion items are not PokemonHeldItemModifiers) */
const OPTION_3_DISALLOWED_MODIFIERS = [

View File

@ -87,9 +87,9 @@ export const FieldTripEncounter: MysteryEncounter =
const encounter = scene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ATK])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ATK ])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.DEF ])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
];
@ -133,9 +133,9 @@ export const FieldTripEncounter: MysteryEncounter =
const encounter = scene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPATK])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPATK ])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPDEF ])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
];
@ -179,8 +179,8 @@ export const FieldTripEncounter: MysteryEncounter =
const encounter = scene.currentBattle.mysteryEncounter!;
if (encounter.misc.correctMove) {
const modifiers = [
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.ACC])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.ACC ])!,
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [ Stat.SPD ])!,
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
@ -227,7 +227,7 @@ function pokemonAndMoveChosen(scene: BattleScene, pokemon: PlayerPokemon, move:
text: `${namespace}:correct_exp`,
},
];
setEncounterExp(scene, [pokemon.id], 100);
setEncounterExp(scene, [ pokemon.id ], 100);
}
encounter.misc = {
correctMove: correctMove,

View File

@ -73,7 +73,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
doubleBattle: true,
disableSwitch: true
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
// Load hidden Volcarona sprites
encounter.spriteConfigs = [
@ -99,7 +99,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
];
// Load animations/sfx for Volcarona moves
loadCustomMovesForEncounter(scene, [Moves.FIRE_SPIN, Moves.QUIVER_DANCE]);
loadCustomMovesForEncounter(scene, [ Moves.FIRE_SPIN, Moves.QUIVER_DANCE ]);
scene.arena.trySetWeather(WeatherType.SUNNY, true);
@ -143,25 +143,25 @@ export const FieryFalloutEncounter: MysteryEncounter =
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.FIRE_SPIN),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.PLAYER_2],
targets: [ BattlerIndex.PLAYER_2 ],
move: new PokemonMove(Moves.FIRE_SPIN),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY],
targets: [ BattlerIndex.ENEMY ],
move: new PokemonMove(Moves.QUIVER_DANCE),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY_2,
targets: [BattlerIndex.ENEMY_2],
targets: [ BattlerIndex.ENEMY_2 ],
move: new PokemonMove(Moves.QUIVER_DANCE),
ignorePp: true
});
@ -237,7 +237,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
const primary = encounter.options[2].primaryPokemon!;
const secondary = encounter.options[2].secondaryPokemon![0];
setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
setEncounterExp(scene, [ primary.id, secondary.id ], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
leaveEncounterWithoutBattle(scene);
})
.build()
@ -248,7 +248,7 @@ function giveLeadPokemonCharcoal(scene: BattleScene) {
// Give first party pokemon Charcoal for free at end of battle
const leadPokemon = scene.getParty()?.[0];
if (leadPokemon) {
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]) as AttackTypeBoosterModifierType;
const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FIRE ]) as AttackTypeBoosterModifierType;
applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal);
scene.currentBattle.mysteryEncounter!.setDialogueToken("leadPokemon", leadPokemon.getNameToRender());
queueEncounterMessage(scene, `${namespace}:found_charcoal`);

View File

@ -65,16 +65,16 @@ export const FightOrFlightEncounter: MysteryEncounter =
species: bossSpecies,
dataSource: new PokemonData(bossPokemon),
isBoss: true,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
// Randomly boost 1 stat 2 stages
// Cannot boost Spd, Acc, or Evasion
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [randSeedInt(4, 1)], 2));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randSeedInt(4, 1) ], 2));
}
}],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
// Calculate item
// Waves 10-40 GREAT, 60-120 ULTRA, 120-160 ROGUE, 160-180 MASTER
@ -90,7 +90,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
let item: ModifierTypeOption | null = null;
// TMs and Candy Jar excluded from possible rewards as they're too swingy in value for a singular item reward
while (!item || item.type.id.includes("TM_") || item.type.id === "CANDY_JAR") {
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
}
encounter.setDialogueToken("itemName", item.type.name);
encounter.misc = item;
@ -137,7 +137,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
// Pick battle
// Pokemon will randomly boost 1 stat by 2 stages
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0]);
}
)
@ -159,7 +159,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
// Pick steal
const encounter = scene.currentBattle.mysteryEncounter!;
const item = scene.currentBattle.mysteryEncounter!.misc as ModifierTypeOption;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
// Use primaryPokemon to execute the thievery
const primaryPokemon = encounter.options[1].primaryPokemon!;

View File

@ -197,7 +197,7 @@ async function summonPlayerPokemon(scene: BattleScene) {
const enemySpecies = getPokemonSpecies(Species.WOBBUFFET);
scene.currentBattle.enemyParty = [];
const wobbuffet = scene.addEnemyPokemon(enemySpecies, encounter.misc.playerPokemon.level, TrainerSlot.NONE, false);
wobbuffet.ivs = [0, 0, 0, 0, 0, 0];
wobbuffet.ivs = [ 0, 0, 0, 0, 0, 0 ];
wobbuffet.setNature(Nature.MILD);
wobbuffet.setAlpha(0);
wobbuffet.setVisible(false);
@ -256,15 +256,15 @@ function handleNextTurn(scene: BattleScene) {
let isHealPhase = false;
if (healthRatio < 0.03) {
// Grand prize
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MULTI_LENS], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MULTI_LENS ], fillRemaining: false });
resultMessageKey = `${namespace}:best_result`;
} else if (healthRatio < 0.15) {
// 2nd prize
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SCOPE_LENS], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SCOPE_LENS ], fillRemaining: false });
resultMessageKey = `${namespace}:great_result`;
} else if (healthRatio < 0.33) {
// 3rd prize
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.WIDE_LENS], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.WIDE_LENS ], fillRemaining: false });
resultMessageKey = `${namespace}:good_result`;
} else {
// No prize
@ -411,7 +411,7 @@ function hideShowmanIntroSprite(scene: BattleScene) {
// Slide the Wobbuffet and Game over slightly
scene.tweens.add({
targets: [wobbuffet, carnivalGame],
targets: [ wobbuffet, carnivalGame ],
x: "+=16",
ease: "Sine.easeInOut",
duration: 750

View File

@ -35,15 +35,15 @@ const WONDER_TRADE_SHINY_CHANCE = 512;
const MAX_WONDER_TRADE_SHINY_CHANCE = 4096;
const LEGENDARY_TRADE_POOLS = {
1: [Species.RATTATA, Species.PIDGEY, Species.WEEDLE],
2: [Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA],
3: [Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW],
4: [Species.BIDOOF, Species.STARLY, Species.KRICKETOT],
5: [Species.PATRAT, Species.PURRLOIN, Species.PIDOVE],
6: [Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG],
7: [Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF],
8: [Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE],
9: [Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA]
1: [ Species.RATTATA, Species.PIDGEY, Species.WEEDLE ],
2: [ Species.SENTRET, Species.HOOTHOOT, Species.LEDYBA ],
3: [ Species.POOCHYENA, Species.ZIGZAGOON, Species.TAILLOW ],
4: [ Species.BIDOOF, Species.STARLY, Species.KRICKETOT ],
5: [ Species.PATRAT, Species.PURRLOIN, Species.PIDOVE ],
6: [ Species.BUNNELBY, Species.LITLEO, Species.SCATTERBUG ],
7: [ Species.PIKIPEK, Species.YUNGOOS, Species.ROCKRUFF ],
8: [ Species.SKWOVET, Species.WOOLOO, Species.ROOKIDEE ],
9: [ Species.LECHONK, Species.FIDOUGH, Species.TAROUNTULA ]
};
/** Exclude Paradox mons as they aren't considered legendary/mythical */
@ -387,11 +387,11 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
let item: ModifierTypeOption | null = null;
// TMs excluded from possible rewards
while (!item || item.type.id.includes("TM_")) {
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [ tier ], allowLuckUpgrades: false })[0];
}
encounter.setDialogueToken("itemName", item.type.name);
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ item ], fillRemaining: false });
// Remove the chosen modifier if its stacks go to 0
modifier.stackCount -= 1;
@ -650,7 +650,7 @@ function doPokemonTradeSequence(scene: BattleScene, tradedPokemon: PlayerPokemon
// addPokeballOpenParticles(scene, tradedPokemon.x, tradedPokemon.y, tradedPokemon.pokeball);
scene.tweens.add({
targets: [tradedPokemonTintSprite, tradedPokemonSprite],
targets: [ tradedPokemonTintSprite, tradedPokemonSprite ],
duration: 500,
ease: "Sine.easeIn",
scale: 0.25,
@ -726,7 +726,7 @@ function doPokemonTradeFlyBySequence(scene: BattleScene, tradedPokemonSprite: Ph
duration: FADE_DELAY,
onComplete: () => {
scene.tweens.add({
targets: [receivedPokemonSprite, tradedPokemonSprite],
targets: [ receivedPokemonSprite, tradedPokemonSprite ],
y: tradeBaseBg.displayWidth / 2 - 100,
ease: "Cubic.easeInOut",
duration: BASE_ANIM_DURATION * 3,

View File

@ -10,7 +10,7 @@ import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encount
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import {PokemonMove} from "#app/field/pokemon";
import { PokemonMove } from "#app/field/pokemon";
const OPTION_1_REQUIRED_MOVE = Moves.SURF;
const OPTION_2_REQUIRED_MOVE = Moves.FLY;

View File

@ -143,7 +143,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Spawn standard trainer battle with memory mushroom reward
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0];
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.TM_COMMON, modifierTypes.TM_GREAT, modifierTypes.MEMORY_MUSHROOM ], fillRemaining: true });
// Seed offsets to remove possibility of different trainers having exact same teams
let ret;
@ -168,7 +168,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// Spawn hard fight
const config: EnemyPartyConfig = encounter.enemyPartyConfigs[1];
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], fillRemaining: true });
// Seed offsets to remove possibility of different trainers having exact same teams
let ret;
@ -196,7 +196,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
// To avoid player level snowballing from picking this option
encounter.expMultiplier = 0.9;
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true });
// Seed offsets to remove possibility of different trainers having exact same teams
let ret;

View File

@ -76,12 +76,12 @@ export const MysteriousChestEncounter: MysteryEncounter =
species: getPokemonSpecies(Species.GIMMIGHOUL),
formIndex: 0,
isBoss: true,
moveSet: [Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF]
moveSet: [ Moves.NASTY_PLOT, Moves.SHADOW_BALL, Moves.POWER_GEM, Moves.THIEF ]
}
],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
encounter.setDialogueToken("gimmighoulName", getPokemonSpecies(Species.GIMMIGHOUL).getName());
encounter.setDialogueToken("trapPercent", TRAP_PERCENT.toString());
@ -157,13 +157,13 @@ export const MysteriousChestEncounter: MysteryEncounter =
leaveEncounterWithoutBattle(scene);
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT) {
// Choose between 2 ROGUE tier items (10%)
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE] });
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE ]});
// Display result message then proceed to rewards
queueEncounterMessage(scene, `${namespace}:option.1.great`);
leaveEncounterWithoutBattle(scene);
} else if (roll >= RAND_LENGTH - COMMON_REWARDS_PERCENT - ULTRA_REWARDS_PERCENT - ROGUE_REWARDS_PERCENT - MASTER_REWARDS_PERCENT) {
// Choose 1 MASTER tier item (5%)
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.MASTER] });
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.MASTER ]});
// Display result message then proceed to rewards
queueEncounterMessage(scene, `${namespace}:option.1.amazing`);
leaveEncounterWithoutBattle(scene);

View File

@ -94,7 +94,7 @@ export const PartTimerEncounter: MysteryEncounter =
// Calculation from Pokemon.calculateStats
const baselineValue = Math.floor(((2 * 90 + 16) * pokemon.level) * 0.01) + 5;
const percentDiff = (pokemon.getStat(Stat.SPD) - baselineValue) / baselineValue;
const moneyMultiplier = Math.min(Math.max(2.5 * (1+ percentDiff), 1), 4);
const moneyMultiplier = Math.min(Math.max(2.5 * (1 + percentDiff), 1), 4);
encounter.misc = {
moneyMultiplier

View File

@ -23,7 +23,7 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
/** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/safariZone";
const TRAINER_THROW_ANIMATION_TIMES = [512, 184, 768];
const TRAINER_THROW_ANIMATION_TIMES = [ 512, 184, 768 ];
const SAFARI_MONEY_MULTIPLIER = 2;
@ -260,7 +260,7 @@ async function summonSafariPokemon(scene: BattleScene) {
let enemySpecies;
let pokemon;
scene.executeWithSeedOffset(() => {
enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
enemySpecies = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
const level = scene.currentBattle.getLevelForWave();
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, scene.gameMode));
pokemon = scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);

View File

@ -33,7 +33,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
.withEncounterTier(MysteryEncounterTier.COMMON)
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
.withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal
.withPrimaryPokemonHealthRatioRequirement([0.51, 1]) // At least 1 Pokemon must have above half HP
.withPrimaryPokemonHealthRatioRequirement([ 0.51, 1 ]) // At least 1 Pokemon must have above half HP
.withIntroSpriteConfigs([
{
spriteKey: Species.KROOKODILE.toString(),
@ -140,7 +140,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
chosenPokemon.nature = newNature;
encounter.setDialogueToken("newNature", getNatureName(newNature));
queueEncounterMessage(scene, `${namespace}:cheap_side_effects`);
setEncounterExp(scene, [chosenPokemon.id], 100);
setEncounterExp(scene, [ chosenPokemon.id ], 100);
chosenPokemon.updateInfo();
})
.build()
@ -201,7 +201,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
const chosenPokemon = encounter.misc.chosenPokemon;
queueEncounterMessage(scene, `${namespace}:no_bad_effects`);
setEncounterExp(scene, [chosenPokemon.id], 100);
setEncounterExp(scene, [ chosenPokemon.id ], 100);
chosenPokemon.updateInfo();
})

View File

@ -60,15 +60,15 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
const pokemonConfig: EnemyPokemonConfig = {
species: bossSpecies,
isBoss: true,
status: [StatusEffect.SLEEP, 5], // Extra turns on timer for Snorlax's start of fight moves
moveSet: [Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT],
status: [ StatusEffect.SLEEP, 5 ], // Extra turns on timer for Snorlax's start of fight moves
moveSet: [ Moves.REST, Moves.SLEEP_TALK, Moves.CRUNCH, Moves.GIGA_IMPACT ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType,
stackCount: 2
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType,
stackCount: 2
},
],
@ -77,12 +77,12 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
};
const config: EnemyPartyConfig = {
levelAdditiveModifier: 0.5,
pokemonConfigs: [pokemonConfig],
pokemonConfigs: [ pokemonConfig ],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
// Load animations/sfx for Snorlax fight start moves
loadCustomMovesForEncounter(scene, [Moves.SNORE]);
loadCustomMovesForEncounter(scene, [ Moves.SNORE ]);
encounter.setDialogueToken("snorlaxName", getPokemonSpecies(Species.SNORLAX).getName());
@ -104,17 +104,17 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
async (scene: BattleScene) => {
// Pick battle
const encounter = scene.currentBattle.mysteryEncounter!;
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: true});
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: true });
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.SNORE),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.SNORE),
ignorePp: true
});
@ -156,7 +156,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
.withOptionPhase(async (scene: BattleScene) => {
// Steal the Snorlax's Leftovers
const instance = scene.currentBattle.mysteryEncounter!;
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.LEFTOVERS ], fillRemaining: false });
// Snorlax exp to Pokemon that did the stealing
setEncounterExp(scene, instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp);
leaveEncounterWithoutBattle(scene);

View File

@ -26,8 +26,8 @@ import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIF
const namespace = "mysteryEncounters/teleportingHijinks";
const MONEY_COST_MULTIPLIER = 1.75;
const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO];
const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
const BIOME_CANDIDATES = [ Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND, Biome.WASTELAND, Biome.DOJO ];
const MACHINE_INTERFACING_TYPES = [ Type.ELECTRIC, Type.STEEL ];
/**
* Teleporting Hijinks encounter.
@ -38,7 +38,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
.withEncounterTier(MysteryEncounterTier.COMMON)
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
.withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave
.withSceneRequirement(new WaveModulusRequirement([ 1, 2, 3 ], 10)) // Must be in first 3 waves after boss wave
.withSceneRequirement(new MoneyRequirement(0, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost
.withAutoHideIntroVisuals(false)
.withCatchAllowed(true)
@ -145,9 +145,9 @@ export const TeleportingHijinksEncounter: MysteryEncounter =
}],
};
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL])!;
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC])!;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true });
const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.STEEL ])!;
const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.ELECTRIC ])!;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ magnet, metalCoat ], fillRemaining: true });
transitionMysteryEncounterIntroVisuals(scene, true, true);
await initBattleWithEnemyConfig(scene, config);
}
@ -163,7 +163,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
// Show dialogue and transition biome
await showEncounterText(scene, `${namespace}:transport`);
await Promise.all([animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene)]);
await Promise.all([ animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene) ]);
scene.playBgm();
await showEncounterText(scene, `${namespace}:attacked`);
@ -175,8 +175,8 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
const config: EnemyPartyConfig = {
pokemonConfigs: [{
@ -184,7 +184,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
species: bossSpecies,
dataSource: new PokemonData(bossPokemon),
isBoss: true,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:boss_enraged`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
@ -198,7 +198,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) {
async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) {
return new Promise<void>(resolve => {
scene.tweens.add({
targets: [scene.arenaEnemy, scene.lastEnemyTrainer],
targets: [ scene.arenaEnemy, scene.lastEnemyTrainer ],
x: "+=300",
duration: 2000,
onComplete: () => {
@ -214,7 +214,7 @@ async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) {
scene.arenaPlayerTransition.setVisible(true);
scene.tweens.add({
targets: [scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition],
targets: [ scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition ],
duration: 1000,
ease: "Sine.easeInOut",
alpha: (target: any) => target === scene.arenaPlayer ? 0 : 1,

View File

@ -10,7 +10,8 @@ import { Biome } from "#enums/biome";
import { TrainerType } from "#enums/trainer-type";
import i18next from "i18next";
import { Species } from "#enums/species";
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { Nature } from "#enums/nature";
import { Moves } from "#enums/moves";
import { PlayerPokemon } from "#app/field/pokemon";
@ -47,29 +48,29 @@ class BreederSpeciesEvolution {
}
const POOL_1_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
[Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE)]
[ Species.MUNCHLAX, new BreederSpeciesEvolution(Species.SNORLAX, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.HAPPINY, new BreederSpeciesEvolution(Species.CHANSEY, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.BLISSEY, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.MAGBY, new BreederSpeciesEvolution(Species.MAGMAR, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MAGMORTAR, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.ELEKID, new BreederSpeciesEvolution(Species.ELECTABUZZ, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ELECTIVIRE, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.RIOLU, new BreederSpeciesEvolution(Species.LUCARIO, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.BUDEW, new BreederSpeciesEvolution(Species.ROSELIA, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ROSERADE, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.TOXEL, new BreederSpeciesEvolution(Species.TOXTRICITY, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.MIME_JR, new BreederSpeciesEvolution(Species.GALAR_MR_MIME, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.MR_RIME, FINAL_STAGE_EVOLUTION_WAVE) ]
];
const POOL_2_POKEMON: (Species | BreederSpeciesEvolution)[][] = [
[Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.JYNX],
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE)],
[Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE)],
[Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE)]
[ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.PICHU, new BreederSpeciesEvolution(Species.PIKACHU, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.ALOLA_RAICHU, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.JYNX ],
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONLEE, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONCHAN, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.TYROGUE, new BreederSpeciesEvolution(Species.HITMONTOP, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.IGGLYBUFF, new BreederSpeciesEvolution(Species.JIGGLYPUFF, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.WIGGLYTUFF, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.AZURILL, new BreederSpeciesEvolution(Species.MARILL, FIRST_STAGE_EVOLUTION_WAVE), new BreederSpeciesEvolution(Species.AZUMARILL, FINAL_STAGE_EVOLUTION_WAVE) ],
[ Species.WYNAUT, new BreederSpeciesEvolution(Species.WOBBUFFET, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.CHINGLING, new BreederSpeciesEvolution(Species.CHIMECHO, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.BONSLY, new BreederSpeciesEvolution(Species.SUDOWOODO, SECOND_STAGE_EVOLUTION_WAVE) ],
[ Species.MANTYKE, new BreederSpeciesEvolution(Species.MANTINE, SECOND_STAGE_EVOLUTION_WAVE) ]
];
/**
@ -137,7 +138,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.setDialogueToken("pokemon3Name", pokemon3.getNameToRender());
// Dialogue and egg calcs for Pokemon 1
const [pokemon1CommonEggs, pokemon1RareEggs] = calculateEggRewardsForPokemon(pokemon1);
const [ pokemon1CommonEggs, pokemon1RareEggs ] = calculateEggRewardsForPokemon(pokemon1);
let pokemon1Tooltip = getEncounterText(scene, `${namespace}:option.1.tooltip_base`)!;
if (pokemon1RareEggs > 0) {
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon1RareEggs, rarity: i18next.t("egg:greatTier") });
@ -152,7 +153,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.options[0].dialogue!.buttonTooltip = pokemon1Tooltip;
// Dialogue and egg calcs for Pokemon 2
const [pokemon2CommonEggs, pokemon2RareEggs] = calculateEggRewardsForPokemon(pokemon2);
const [ pokemon2CommonEggs, pokemon2RareEggs ] = calculateEggRewardsForPokemon(pokemon2);
let pokemon2Tooltip = getEncounterText(scene, `${namespace}:option.2.tooltip_base`)!;
if (pokemon2RareEggs > 0) {
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon2RareEggs, rarity: i18next.t("egg:greatTier") });
@ -167,7 +168,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.options[1].dialogue!.buttonTooltip = pokemon2Tooltip;
// Dialogue and egg calcs for Pokemon 3
const [pokemon3CommonEggs, pokemon3RareEggs] = calculateEggRewardsForPokemon(pokemon3);
const [ pokemon3CommonEggs, pokemon3RareEggs ] = calculateEggRewardsForPokemon(pokemon3);
let pokemon3Tooltip = getEncounterText(scene, `${namespace}:option.3.tooltip_base`)!;
if (pokemon3RareEggs > 0) {
const eggsText = i18next.t(`${namespace}:numEggs`, { count: pokemon3RareEggs, rarity: i18next.t("egg:greatTier") });
@ -380,11 +381,11 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
abilityIndex: 1, // Magic Guard
shiny: false,
nature: Nature.ADAMANT,
moveSet: [Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH],
ivs: [31, 31, 31, 31, 31, 31],
moveSet: [ Moves.METEOR_MASH, Moves.FIRE_PUNCH, Moves.ICE_PUNCH, Moves.THUNDER_PUNCH ],
ivs: [ 31, 31, 31, 31, 31, 31 ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [Type.STEEL]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.TERA_SHARD, [ Type.STEEL ]) as PokemonHeldItemModifierType,
}
]
}
@ -401,8 +402,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
shiny: true,
variant: 1,
nature: Nature.MODEST,
moveSet: [Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT],
ivs: [31, 31, 31, 31, 31, 31]
moveSet: [ Moves.MOONBLAST, Moves.MYSTICAL_FIRE, Moves.ICE_BEAM, Moves.THUNDERBOLT ],
ivs: [ 31, 31, 31, 31, 31, 31 ]
},
{
nickname: i18next.t(`${namespace}:cleffa_3_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
@ -412,8 +413,8 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
shiny: true,
variant: 2,
nature: Nature.BOLD,
moveSet: [Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT],
ivs: [31, 31, 31, 31, 31, 31]
moveSet: [ Moves.TRI_ATTACK, Moves.STORED_POWER, Moves.TAKE_HEART, Moves.MOONLIGHT ],
ivs: [ 31, 31, 31, 31, 31, 31 ]
});
} else {
// Second member from pool 1
@ -424,12 +425,12 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
baseConfig.pokemonConfigs!.push({
species: getPokemonSpecies(pool1Species),
isBoss: false,
ivs: [31, 31, 31, 31, 31, 31]
ivs: [ 31, 31, 31, 31, 31, 31 ]
},
{
species: getPokemonSpecies(pool2Species),
isBoss: false,
ivs: [31, 31, 31, 31, 31, 31]
ivs: [ 31, 31, 31, 31, 31, 31 ]
});
}
@ -454,8 +455,8 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number]
const rootSpecies = pokemon.species.getRootSpeciesId();
let pointsFromStarterTier = 0;
// 2 points for every 1 below 7 that the pokemon's starter tier is (max 12, min 0)
if (speciesStarters.hasOwnProperty(rootSpecies)) {
const starterTier = speciesStarters[rootSpecies];
if (speciesStarterCosts.hasOwnProperty(rootSpecies)) {
const starterTier = speciesStarterCosts[rootSpecies];
pointsFromStarterTier = Math.min(Math.max(Math.floor(7 - starterTier) * 2, 0), 12);
}
@ -467,7 +468,7 @@ function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number]
// 1 Common egg for every point leftover
const numCommons = totalPoints % 6;
return [numCommons, numRares];
return [ numCommons, numRares ];
}
function getEggOptions(scene: BattleScene, commonEggs: number, rareEggs: number) {

View File

@ -5,7 +5,8 @@ import BattleScene from "#app/battle-scene";
import MysteryEncounter, { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MoneyRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
import { catchPokemon, getRandomSpeciesByStarterTier, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { Species } from "#enums/species";
import { PokeballType } from "#app/data/pokeball";
import { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
@ -58,12 +59,12 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
.withOnInit((scene: BattleScene) => {
const encounter = scene.currentBattle.mysteryEncounter!;
let species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
let species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
let tries = 0;
// Reroll any species that don't have HAs
while ((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) && tries < 5) {
species = getPokemonSpecies(getRandomSpeciesByStarterTier([0, 5], undefined, undefined, false, false, false));
species = getPokemonSpecies(getRandomSpeciesByStarterTier([ 0, 5 ], undefined, undefined, false, false, false));
tries++;
}
@ -88,7 +89,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
isPokemon: true
});
const starterTier = speciesStarters[species.speciesId];
const starterTier = speciesStarterCosts[species.speciesId];
// Prices decrease by starter tier less than 5, but only reduces cost by half at max
let priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER * (Math.max(starterTier, 2.5) / 5);
if (pokemon.shiny) {

View File

@ -81,37 +81,37 @@ export const TheStrongStuffEncounter: MysteryEncounter =
bossSegments: 5,
mysteryEncounterPokemonData: new MysteryEncounterPokemonData({ spriteScale: 1.25 }),
nature: Nature.BOLD,
moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER],
moveSet: [ Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
stackCount: 2
}
],
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.2.stat_boost`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [Stat.DEF, Stat.SPDEF], 2));
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF, Stat.SPDEF ], 2));
}
}
],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
loadCustomMovesForEncounter(scene, [Moves.GASTRO_ACID, Moves.STEALTH_ROCK]);
loadCustomMovesForEncounter(scene, [ Moves.GASTRO_ACID, Moves.STEALTH_ROCK ]);
encounter.setDialogueToken("shuckleName", getPokemonSpecies(Species.SHUCKLE).getName());
@ -184,17 +184,17 @@ export const TheStrongStuffEncounter: MysteryEncounter =
async (scene: BattleScene) => {
// Pick battle
const encounter = scene.currentBattle.mysteryEncounter!;
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.SOUL_DEW], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.SOUL_DEW ], fillRemaining: true });
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.GASTRO_ACID),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.STEALTH_ROCK),
ignorePp: true
});

View File

@ -131,7 +131,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter =
async (scene: BattleScene) => {
// Refuse the challenge, they full heal the party and give the player a Rarer Candy
scene.unshiftPhase(new PartyHealPhase(scene, true));
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.RARER_CANDY], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.RARER_CANDY ], fillRemaining: false });
leaveEncounterWithoutBattle(scene);
}
)
@ -154,7 +154,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
scene.ui.clearText(); // Clears "Winstrate" title from screen as rewards get animated in
const machoBrace = generateModifierTypeOption(scene, modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE)!;
machoBrace.type.tier = ModifierTier.MASTER;
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [machoBrace], fillRemaining: false });
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [ machoBrace ], fillRemaining: false });
encounter.doContinueEncounter = undefined;
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.NO_BATTLE);
} else {
@ -232,7 +232,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Guts
nature: Nature.ADAMANT,
moveSet: [Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK],
moveSet: [ Moves.FACADE, Moves.BRAVE_BIRD, Moves.PROTECT, Moves.QUICK_ATTACK ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -250,7 +250,7 @@ function getVictorTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 1, // Guts
nature: Nature.ADAMANT,
moveSet: [Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH],
moveSet: [ Moves.FACADE, Moves.OBSTRUCT, Moves.NIGHT_SLASH, Moves.FIRE_PUNCH ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.FLAME_ORB) as PokemonHeldItemModifierType,
@ -276,7 +276,7 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Natural Cure
nature: Nature.CALM,
moveSet: [Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER],
moveSet: [ Moves.SYNTHESIS, Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.SLEEP_POWDER ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType,
@ -294,15 +294,15 @@ function getVictoriaTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
nature: Nature.TIMID,
moveSet: [Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP],
moveSet: [ Moves.PSYSHOCK, Moves.MOONBLAST, Moves.SHADOW_BALL, Moves.WILL_O_WISP ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.PSYCHIC]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.PSYCHIC ]) as PokemonHeldItemModifierType,
stackCount: 1,
isTransferable: false
},
{
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FAIRY]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [ Type.FAIRY ]) as PokemonHeldItemModifierType,
stackCount: 1,
isTransferable: false
}
@ -321,15 +321,15 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 3, // Lightning Rod
nature: Nature.ADAMANT,
moveSet: [Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST],
moveSet: [ Moves.WATERFALL, Moves.MEGAHORN, Moves.KNOCK_OFF, Moves.REST ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
stackCount: 2,
isTransferable: false
},
{
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType,
stackCount: 4,
isTransferable: false
}
@ -340,10 +340,10 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 1, // Poison Heal
nature: Nature.JOLLY,
moveSet: [Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH],
moveSet: [ Moves.SPORE, Moves.SWORDS_DANCE, Moves.SEED_BOMB, Moves.DRAIN_PUNCH ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.HP]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.HP ]) as PokemonHeldItemModifierType,
stackCount: 4,
isTransferable: false
},
@ -358,7 +358,7 @@ function getViviTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
nature: Nature.CALM,
moveSet: [Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT],
moveSet: [ Moves.EARTH_POWER, Moves.FIRE_BLAST, Moves.YAWN, Moves.PROTECT ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,
@ -380,7 +380,7 @@ function getVickyTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
nature: Nature.IMPISH,
moveSet: [Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH],
moveSet: [ Moves.AXE_KICK, Moves.ICE_PUNCH, Moves.ZEN_HEADBUTT, Moves.BULLET_PUNCH ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType,
@ -401,10 +401,10 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Soundproof
nature: Nature.MODEST,
moveSet: [Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE],
moveSet: [ Moves.THUNDERBOLT, Moves.GIGA_DRAIN, Moves.FOUL_PLAY, Moves.THUNDER_WAVE ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [Stat.SPD]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BASE_STAT_BOOSTER, [ Stat.SPD ]) as PokemonHeldItemModifierType,
stackCount: 2,
isTransferable: false
}
@ -415,50 +415,50 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 2, // Gluttony
nature: Nature.QUIET,
moveSet: [Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE],
moveSet: [ Moves.SLUDGE_BOMB, Moves.GIGA_DRAIN, Moves.ICE_BEAM, Moves.EARTHQUAKE ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SITRUS ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.APICOT]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.APICOT ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.GANLON ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.STARF]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.STARF ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.SALAC]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.SALAC ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LUM]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LUM ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LANSAT]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LANSAT ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LIECHI]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LIECHI ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.PETAYA]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.PETAYA ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.ENIGMA]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.ENIGMA ]) as PokemonHeldItemModifierType,
stackCount: 2,
},
{
modifier: generateModifierType(scene, modifierTypes.BERRY, [BerryType.LEPPA]) as PokemonHeldItemModifierType,
modifier: generateModifierType(scene, modifierTypes.BERRY, [ BerryType.LEPPA ]) as PokemonHeldItemModifierType,
stackCount: 2,
}
]
@ -468,7 +468,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 2, // Tangled Feet
nature: Nature.JOLLY,
moveSet: [Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF],
moveSet: [ Moves.DRILL_PECK, Moves.QUICK_ATTACK, Moves.THRASH, Moves.KNOCK_OFF ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.KINGS_ROCK) as PokemonHeldItemModifierType,
@ -482,7 +482,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
formIndex: 1,
nature: Nature.BOLD,
moveSet: [Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT],
moveSet: [ Moves.PSYCHIC, Moves.SHADOW_BALL, Moves.FOCUS_BLAST, Moves.THUNDERBOLT ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.WIDE_LENS) as PokemonHeldItemModifierType,
@ -496,7 +496,7 @@ function getVitoTrainerConfig(scene: BattleScene): EnemyPartyConfig {
isBoss: false,
abilityIndex: 0, // Sheer Force
nature: Nature.IMPISH,
moveSet: [Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE],
moveSet: [ Moves.EARTHQUAKE, Moves.U_TURN, Moves.FLARE_BLITZ, Moves.ROCK_SLIDE ],
modifierConfigs: [
{
modifier: generateModifierType(scene, modifierTypes.QUICK_CLAW) as PokemonHeldItemModifierType,

View File

@ -1,7 +1,7 @@
import { Ability, allAbilities } from "#app/data/ability";
import { EnemyPartyConfig, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, selectPokemonForOption, setEncounterRewards, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
import { getNatureName, Nature } from "#app/data/nature";
import { speciesStarters } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
import { AbilityAttr } from "#app/system/game-data";
@ -326,7 +326,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
// Only update the fusion's dex data if the Pokemon is already caught in dex (ignore rentals)
const rootFusionSpecies = playerPokemon.fusionSpecies?.getRootSpeciesId();
if (!isNullOrUndefined(rootFusionSpecies)
&& speciesStarters.hasOwnProperty(rootFusionSpecies)
&& speciesStarterCosts.hasOwnProperty(rootFusionSpecies)
&& !!scene.gameData.dexData[rootFusionSpecies].caughtAttr) {
scene.gameData.starterData[rootFusionSpecies].abilityAttr |= playerPokemon.fusionAbilityIndex !== 1 || playerPokemon.fusionSpecies?.ability2
? 1 << playerPokemon.fusionAbilityIndex

View File

@ -67,17 +67,17 @@ export const TrashToTreasureEncounter: MysteryEncounter =
isBoss: true,
formIndex: 1, // Gmax
bossSegmentModifier: 1, // +1 Segment from normal
moveSet: [Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH]
moveSet: [ Moves.PAYBACK, Moves.GUNK_SHOT, Moves.STOMPING_TANTRUM, Moves.DRAIN_PUNCH ]
};
const config: EnemyPartyConfig = {
levelAdditiveModifier: 1,
pokemonConfigs: [pokemonConfig],
pokemonConfigs: [ pokemonConfig ],
disableSwitch: true
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
// Load animations/sfx for Garbodor fight start moves
loadCustomMovesForEncounter(scene, [Moves.TOXIC, Moves.AMNESIA]);
loadCustomMovesForEncounter(scene, [ Moves.TOXIC, Moves.AMNESIA ]);
scene.loadSe("PRSFX- Dig2", "battle_anims", "PRSFX- Dig2.wav");
scene.loadSe("PRSFX- Venom Drench", "battle_anims", "PRSFX- Venom Drench.wav");
@ -107,7 +107,7 @@ export const TrashToTreasureEncounter: MysteryEncounter =
transitionMysteryEncounterIntroVisuals(scene);
await tryApplyDigRewardItems(scene);
const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [SHOP_ITEM_COST_MULTIPLIER]);
const blackSludge = generateModifierType(scene, modifierTypes.MYSTERY_ENCOUNTER_BLACK_SLUDGE, [ SHOP_ITEM_COST_MULTIPLIER ]);
const modifier = blackSludge?.newModifier();
if (modifier) {
await scene.addModifier(modifier, false, false, false, true);
@ -139,17 +139,17 @@ export const TrashToTreasureEncounter: MysteryEncounter =
const encounter = scene.currentBattle.mysteryEncounter!;
setEncounterRewards(scene, { guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT], fillRemaining: true });
setEncounterRewards(scene, { guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT ], fillRemaining: true });
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.PLAYER],
targets: [ BattlerIndex.PLAYER ],
move: new PokemonMove(Moves.TOXIC),
ignorePp: true
},
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [BattlerIndex.ENEMY],
targets: [ BattlerIndex.ENEMY ],
move: new PokemonMove(Moves.AMNESIA),
ignorePp: true
});

View File

@ -74,8 +74,8 @@ export const UncommonBreedEncounter: MysteryEncounter =
// Defense/Spd buffs below wave 50, +1 to all stats otherwise
const statChangesForBattle: (Stat.ATK | Stat.DEF | Stat.SPATK | Stat.SPDEF | Stat.SPD | Stat.ACC | Stat.EVA)[] = scene.currentBattle.waveIndex < 50 ?
[Stat.DEF, Stat.SPDEF, Stat.SPD] :
[Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD];
[ Stat.DEF, Stat.SPDEF, Stat.SPD ] :
[ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ];
const config: EnemyPartyConfig = {
pokemonConfigs: [{
@ -83,14 +83,14 @@ export const UncommonBreedEncounter: MysteryEncounter =
species: species,
dataSource: new PokemonData(pokemon),
isBoss: false,
tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON],
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
mysteryEncounterBattleEffects: (pokemon: Pokemon) => {
queueEncounterMessage(pokemon.scene, `${namespace}:option.1.stat_boost`);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, statChangesForBattle, 1));
}
}],
};
encounter.enemyPartyConfigs = [config];
encounter.enemyPartyConfigs = [ config ];
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
encounter.spriteConfigs = [
@ -152,7 +152,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
encounter.startOfBattleEffects.push(
{
sourceBattlerIndex: BattlerIndex.ENEMY,
targets: [target],
targets: [ target ],
move: pokemonMove,
ignorePp: true
});
@ -181,7 +181,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
// Remove 4 random berries from player's party
// Get all player berry items, remove from party, and store reference
const berryItems: BerryModifier[]= scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
const berryItems: BerryModifier[] = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
for (let i = 0; i < 4; i++) {
const index = randSeedInt(berryItems.length);
const randBerry = berryItems[index];

View File

@ -89,12 +89,12 @@ const PERCENT_LEVEL_LOSS_ON_REFUSE = 12.5;
* Value ranges of the resulting species BST transformations after adding values to original species
* 2 Pokemon in the party use this range
*/
const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [90, 110];
const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 90, 110 ];
/**
* Value ranges of the resulting species BST transformations after adding values to original species
* All remaining Pokemon in the party use this range
*/
const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [40, 50];
const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [ 40, 50 ];
/**
* Weird Dream encounter.
@ -192,7 +192,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
await showEncounterText(scene, `${namespace}:option.1.dream_complete`);
await doNewTeamPostProcess(scene, transformations);
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT]});
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [ modifierTypes.MEMORY_MUSHROOM, modifierTypes.ROGUE_BALL, modifierTypes.MINT, modifierTypes.MINT ]});
leaveEncounterWithoutBattle(scene, true);
})
.build()
@ -372,7 +372,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
// Randomize the second type of the pokemon
// If the pokemon does not normally have a second type, it will gain 1
const newTypes = [newPokemon.getTypes()[0]];
const newTypes = [ newPokemon.getTypes()[0] ];
let newType = randSeedInt(18) as Type;
while (newType === newTypes[0]) {
newType = randSeedInt(18) as Type;
@ -390,14 +390,14 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
// Any pokemon that is at or below 450 BST gets +20 permanent BST to 3 stats: HP (halved, +10), lowest of Atk/SpAtk, and lowest of Def/SpDef
if (newPokemon.getSpeciesForm().getBaseStatTotal() <= GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD) {
const stats: Stat[] = [Stat.HP];
const stats: Stat[] = [ Stat.HP ];
const baseStats = newPokemon.getSpeciesForm().baseStats.slice(0);
// Attack or SpAtk
stats.push(baseStats[Stat.ATK] < baseStats[Stat.SPATK] ? Stat.ATK : Stat.SPATK);
// Def or SpDef
stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF);
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU()
.generateType(scene.getParty(), [20, stats])
.generateType(scene.getParty(), [ 20, stats ])
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU);
const modifier = modType?.newModifier(newPokemon);
if (modifier) {
@ -553,7 +553,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla
let eggMoveIndex: null | number = null;
const eggMoves = newPokemon.getEggMoves()?.slice(0);
if (eggMoves) {
const eggMoveIndices = randSeedShuffle([0, 1, 2, 3]);
const eggMoveIndices = randSeedShuffle([ 0, 1, 2, 3 ]);
let randomEggMoveIndex = eggMoveIndices.pop();
let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
let retries = 0;

View File

@ -5,12 +5,12 @@ import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import { TimeOfDay } from "#enums/time-of-day";
import { Nature } from "../nature";
import { EvolutionItem, pokemonEvolutions } from "../pokemon-evolutions";
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeItemTrigger } from "../pokemon-forms";
import { StatusEffect } from "../status-effect";
import { Type } from "../type";
import { WeatherType } from "../weather";
import { Nature } from "#app/data/nature";
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms";
import { StatusEffect } from "#app/data/status-effect";
import { Type } from "#app/data/type";
import { WeatherType } from "#app/data/weather";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { AttackTypeBoosterModifier } from "#app/modifier/modifier";
import { AttackTypeBoosterModifierType } from "#app/modifier/modifier-type";
@ -147,7 +147,7 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""];
return [ "previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? "" ];
}
}
@ -175,7 +175,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
return [ "waveIndex", scene.currentBattle.waveIndex.toString() ];
}
}
@ -204,7 +204,7 @@ export class WaveModulusRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
return [ "waveIndex", scene.currentBattle.waveIndex.toString() ];
}
}
@ -213,7 +213,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
constructor(timeOfDay: TimeOfDay | TimeOfDay[]) {
super();
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay];
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [ timeOfDay ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -226,7 +226,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()];
return [ "timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase() ];
}
}
@ -235,7 +235,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
constructor(weather: WeatherType | WeatherType[]) {
super();
this.requiredWeather = Array.isArray(weather) ? weather : [weather];
this.requiredWeather = Array.isArray(weather) ? weather : [ weather ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -253,7 +253,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
if (!isNullOrUndefined(currentWeather)) {
token = WeatherType[currentWeather].replace("_", " ").toLocaleLowerCase();
}
return ["weather", token];
return [ "weather", token ];
}
}
@ -285,7 +285,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["partySize", scene.getParty().length.toString()];
return [ "partySize", scene.getParty().length.toString() ];
}
}
@ -296,7 +296,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
constructor(heldItem: string | string[], minNumberOfItems: number = 1) {
super();
this.minNumberOfItems = minNumberOfItems;
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -318,7 +318,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["requiredItem", this.requiredHeldItemModifiers[0]];
return [ "requiredItem", this.requiredHeldItemModifiers[0] ];
}
}
@ -346,7 +346,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
return ["money", value];
return [ "money", value ];
}
}
@ -359,7 +359,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredSpecies = Array.isArray(species) ? species : [species];
this.requiredSpecies = Array.isArray(species) ? species : [ species ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -381,9 +381,9 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) {
return ["species", Species[pokemon.species.speciesId]];
return [ "species", Species[pokemon.species.speciesId] ];
}
return ["species", ""];
return [ "species", "" ];
}
}
@ -397,7 +397,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredNature = Array.isArray(nature) ? nature : [nature];
this.requiredNature = Array.isArray(nature) ? nature : [ nature ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -419,9 +419,9 @@ export class NatureRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon.nature)) {
return ["nature", Nature[pokemon.nature]];
return [ "nature", Nature[pokemon.nature] ];
}
return ["nature", ""];
return [ "nature", "" ];
}
}
@ -436,7 +436,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
this.excludeFainted = excludeFainted;
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredType = Array.isArray(type) ? type : [type];
this.requiredType = Array.isArray(type) ? type : [ type ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -465,9 +465,9 @@ export class TypeRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty));
if (includedTypes.length > 0) {
return ["type", Type[includedTypes[0]]];
return [ "type", Type[includedTypes[0]] ];
}
return ["type", ""];
return [ "type", "" ];
}
}
@ -481,7 +481,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredMoves = Array.isArray(moves) ? moves : [moves];
this.requiredMoves = Array.isArray(moves) ? moves : [ moves ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -504,9 +504,9 @@ export class MoveRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId));
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
return ["move", includedMoves[0].getName()];
return [ "move", includedMoves[0].getName() ];
}
return ["move", ""];
return [ "move", "" ];
}
}
@ -525,7 +525,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove];
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [ learnableMove ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -548,9 +548,9 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
if (includedCompatMoves.length > 0) {
return ["compatibleMove", Moves[includedCompatMoves[0]]];
return [ "compatibleMove", Moves[includedCompatMoves[0]] ];
}
return ["compatibleMove", ""];
return [ "compatibleMove", "" ];
}
}
@ -564,7 +564,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities];
this.requiredAbilities = Array.isArray(abilities) ? abilities : [ abilities ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -586,9 +586,9 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) {
return ["ability", pokemon.getAbility().name];
return [ "ability", pokemon.getAbility().name ];
}
return ["ability", ""];
return [ "ability", "" ];
}
}
@ -601,7 +601,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect];
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [ statusEffect ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -649,9 +649,9 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
return pokemon!.status?.effect === a;
});
if (reqStatus.length > 0) {
return ["status", StatusEffect[reqStatus[0]]];
return [ "status", StatusEffect[reqStatus[0]] ];
}
return ["status", ""];
return [ "status", "" ];
}
}
@ -670,7 +670,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem];
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [ formChangeItem ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -706,9 +706,9 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem));
if (requiredItems.length > 0) {
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
return [ "formChangeItem", FormChangeItem[requiredItems[0]] ];
}
return ["formChangeItem", ""];
return [ "formChangeItem", "" ];
}
}
@ -722,7 +722,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems];
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [ evolutionItems ];
}
override meetsRequirement(scene: BattleScene): boolean {
@ -756,9 +756,9 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem));
if (requiredItems.length > 0) {
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
return [ "evolutionItem", EvolutionItem[requiredItems[0]] ];
}
return ["evolutionItem", ""];
return [ "evolutionItem", "" ];
}
}
@ -772,7 +772,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [ heldItem ];
this.requireTransferable = requireTransferable;
}
@ -807,9 +807,9 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
&& (!this.requireTransferable || it.isTransferable);
});
if (requiredItems && requiredItems.length > 0) {
return ["heldItem", requiredItems[0].type.name];
return [ "heldItem", requiredItems[0].type.name ];
}
return ["heldItem", ""];
return [ "heldItem", "" ];
}
}
@ -823,7 +823,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
super();
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [ heldItemTypes ];
this.requireTransferable = requireTransferable;
}
@ -864,9 +864,9 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
&& (!this.requireTransferable || it.isTransferable);
});
if (requiredItems && requiredItems.length > 0) {
return ["heldItem", requiredItems[0].type.name];
return [ "heldItem", requiredItems[0].type.name ];
}
return ["heldItem", ""];
return [ "heldItem", "" ];
}
}
@ -904,7 +904,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["level", pokemon?.level.toString() ?? ""];
return [ "level", pokemon?.level.toString() ?? "" ];
}
}
@ -942,7 +942,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["friendship", pokemon?.friendship.toString() ?? ""];
return [ "friendship", pokemon?.friendship.toString() ?? "" ];
}
}
@ -989,9 +989,9 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
const hpRatio = pokemon?.getHpRatio();
if (!isNullOrUndefined(hpRatio)) {
return ["healthRatio", Math.floor(hpRatio * 100).toString() + "%"];
return [ "healthRatio", Math.floor(hpRatio * 100).toString() + "%" ];
}
return ["healthRatio", ""];
return [ "healthRatio", "" ];
}
}
@ -1029,8 +1029,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
}
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
return ["weight", pokemon?.getWeight().toString() ?? ""];
return [ "weight", pokemon?.getWeight().toString() ?? "" ];
}
}

View File

@ -265,7 +265,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
}
this.encounterTier = this.encounterTier ?? MysteryEncounterTier.COMMON;
this.dialogue = this.dialogue ?? {};
this.spriteConfigs = this.spriteConfigs ? [...this.spriteConfigs] : [];
this.spriteConfigs = this.spriteConfigs ? [ ...this.spriteConfigs ] : [];
// Default max is 1 for ROGUE encounters, 2 for others
this.maxAllowedEncounters = this.maxAllowedEncounters ?? this.encounterTier === MysteryEncounterTier.ROGUE ? DEFAULT_MAX_ALLOWED_ROGUE_ENCOUNTERS : DEFAULT_MAX_ALLOWED_ENCOUNTERS;
this.encounterMode = MysteryEncounterMode.DEFAULT;
@ -573,7 +573,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
*/
withOption(option: MysteryEncounterOption): this & Pick<IMysteryEncounter, "options"> {
if (!this.options) {
const options = [option];
const options = [ option ];
return Object.assign(this, { options });
} else {
this.options.push(option);
@ -624,11 +624,11 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
}
withIntroDialogue(dialogue: MysteryEncounterDialogue["intro"] = []): this {
this.dialogue = {...this.dialogue, intro: dialogue };
this.dialogue = { ...this.dialogue, intro: dialogue };
return this;
}
withIntro({spriteConfigs, dialogue} : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) {
withIntro({ spriteConfigs, dialogue } : {spriteConfigs: MysteryEncounterSpriteConfig[], dialogue?: MysteryEncounterDialogue["intro"]}) {
return this.withIntroSpriteConfigs(spriteConfigs).withIntroDialogue(dialogue);
}
@ -660,7 +660,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @returns
*/
withAnimations(...encounterAnimations: EncounterAnim[]): this & Required<Pick<IMysteryEncounter, "encounterAnimations">> {
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [encounterAnimations];
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [ encounterAnimations ];
return Object.assign(this, { encounterAnimations: animations });
}
@ -670,7 +670,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @param disallowedGameModes
*/
withDisallowedGameModes(...disallowedGameModes: GameModes[]): this & Required<Pick<IMysteryEncounter, "disallowedGameModes">> {
const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [disallowedGameModes];
const gameModes = Array.isArray(disallowedGameModes) ? disallowedGameModes : [ disallowedGameModes ];
return Object.assign(this, { disallowedGameModes: gameModes });
}
@ -680,7 +680,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @param disallowedChallenges
*/
withDisallowedChallenges(...disallowedChallenges: Challenges[]): this & Required<Pick<IMysteryEncounter, "disallowedChallenges">> {
const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [disallowedChallenges];
const challenges = Array.isArray(disallowedChallenges) ? disallowedChallenges : [ disallowedChallenges ];
return Object.assign(this, { disallowedChallenges: challenges });
}
@ -755,7 +755,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @returns
*/
withSceneWaveRangeRequirement(min: number, max?: number): this & Required<Pick<IMysteryEncounter, "requirements">> {
return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min]));
return this.withSceneRequirement(new WaveRangeRequirement([ min, max ?? min ]));
}
/**
@ -767,7 +767,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @returns
*/
withScenePartySizeRequirement(min: number, max?: number, excludeDisallowedPokemon: boolean = false): this & Required<Pick<IMysteryEncounter, "requirements">> {
return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeDisallowedPokemon));
return this.withSceneRequirement(new PartySizeRequirement([ min, max ?? min ], excludeDisallowedPokemon));
}
/**
@ -982,7 +982,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
* @returns
*/
withOutroDialogue(dialogue: MysteryEncounterDialogue["outro"] = []): this {
this.dialogue = {...this.dialogue, outro: dialogue };
this.dialogue = { ...this.dialogue, outro: dialogue };
return this;
}

View File

@ -32,7 +32,7 @@ import { FunAndGamesEncounter } from "#app/data/mystery-encounters/encounters/fu
import { UncommonBreedEncounter } from "#app/data/mystery-encounters/encounters/uncommon-breed-encounter";
import { GlobalTradeSystemEncounter } from "#app/data/mystery-encounters/encounters/global-trade-system-encounter";
import { TheExpertPokemonBreederEncounter } from "#app/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter";
import { getBiomeName } from "#app/data/biomes";
import { getBiomeName } from "#app/data/balance/biomes";
/**
* Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * <number of missed spawns>) / MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT
@ -224,72 +224,72 @@ const anyBiomeEncounters: MysteryEncounterType[] = [
* that biome groups do not cover
*/
export const mysteryEncountersByBiome = new Map<Biome, MysteryEncounterType[]>([
[Biome.TOWN, []],
[Biome.PLAINS, [
[ Biome.TOWN, []],
[ Biome.PLAINS, [
MysteryEncounterType.SLUMBERING_SNORLAX,
MysteryEncounterType.ABSOLUTE_AVARICE
]],
[Biome.GRASS, [
[ Biome.GRASS, [
MysteryEncounterType.SLUMBERING_SNORLAX,
MysteryEncounterType.ABSOLUTE_AVARICE
]],
[Biome.TALL_GRASS, [
[ Biome.TALL_GRASS, [
MysteryEncounterType.ABSOLUTE_AVARICE
]],
[Biome.METROPOLIS, []],
[Biome.FOREST, [
[ Biome.METROPOLIS, []],
[ Biome.FOREST, [
MysteryEncounterType.SAFARI_ZONE,
MysteryEncounterType.ABSOLUTE_AVARICE
]],
[Biome.SEA, [
[ Biome.SEA, [
MysteryEncounterType.LOST_AT_SEA
]],
[Biome.SWAMP, [
[ Biome.SWAMP, [
MysteryEncounterType.SAFARI_ZONE
]],
[Biome.BEACH, []],
[Biome.LAKE, []],
[Biome.SEABED, []],
[Biome.MOUNTAIN, []],
[Biome.BADLANDS, [
[ Biome.BEACH, []],
[ Biome.LAKE, []],
[ Biome.SEABED, []],
[ Biome.MOUNTAIN, []],
[ Biome.BADLANDS, [
MysteryEncounterType.DANCING_LESSONS
]],
[Biome.CAVE, [
[ Biome.CAVE, [
MysteryEncounterType.THE_STRONG_STUFF
]],
[Biome.DESERT, [
[ Biome.DESERT, [
MysteryEncounterType.DANCING_LESSONS
]],
[Biome.ICE_CAVE, []],
[Biome.MEADOW, []],
[Biome.POWER_PLANT, []],
[Biome.VOLCANO, [
[ Biome.ICE_CAVE, []],
[ Biome.MEADOW, []],
[ Biome.POWER_PLANT, []],
[ Biome.VOLCANO, [
MysteryEncounterType.FIERY_FALLOUT,
MysteryEncounterType.DANCING_LESSONS
]],
[Biome.GRAVEYARD, []],
[Biome.DOJO, []],
[Biome.FACTORY, []],
[Biome.RUINS, []],
[Biome.WASTELAND, [
[ Biome.GRAVEYARD, []],
[ Biome.DOJO, []],
[ Biome.FACTORY, []],
[ Biome.RUINS, []],
[ Biome.WASTELAND, [
MysteryEncounterType.DANCING_LESSONS
]],
[Biome.ABYSS, [
[ Biome.ABYSS, [
MysteryEncounterType.DANCING_LESSONS
]],
[Biome.SPACE, [
[ Biome.SPACE, [
MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER
]],
[Biome.CONSTRUCTION_SITE, []],
[Biome.JUNGLE, [
[ Biome.CONSTRUCTION_SITE, []],
[ Biome.JUNGLE, [
MysteryEncounterType.SAFARI_ZONE
]],
[Biome.FAIRY_CAVE, []],
[Biome.TEMPLE, []],
[Biome.SLUM, []],
[Biome.SNOWY_FOREST, []],
[Biome.ISLAND, []],
[Biome.LABORATORY, []]
[ Biome.FAIRY_CAVE, []],
[ Biome.TEMPLE, []],
[ Biome.SLUM, []],
[ Biome.SNOWY_FOREST, []],
[ Biome.ISLAND, []],
[ Biome.LABORATORY, []]
]);
export function initMysteryEncounters() {
@ -363,6 +363,7 @@ export function initMysteryEncounters() {
});
// Add ANY biome encounters to biome map
// eslint-disable-next-line
let encounterBiomeTableLog = "";
mysteryEncountersByBiome.forEach((biomeEncounters, biome) => {
anyBiomeEncounters.forEach(encounter => {
@ -374,5 +375,5 @@ export function initMysteryEncounters() {
encounterBiomeTableLog += `${getBiomeName(biome).toUpperCase()}: [${biomeEncounters.map(type => MysteryEncounterType[type].toString().toLowerCase()).sort().join(", ")}]\n`;
});
console.debug("All Mystery Encounters by Biome:\n" + encounterBiomeTableLog);
//console.debug("All Mystery Encounters by Biome:\n" + encounterBiomeTableLog);
}

View File

@ -28,7 +28,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
constructor(requiredMoves: Moves | Moves[], options: CanLearnMoveRequirementOptions = {}) {
super();
this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [requiredMoves];
this.requiredMoves = Array.isArray(requiredMoves) ? requiredMoves : [ requiredMoves ];
this.excludeLevelMoves = options.excludeLevelMoves ?? false;
this.excludeTmMoves = options.excludeTmMoves ?? false;
@ -64,11 +64,11 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
}
override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] {
return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")];
return [ "requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ") ];
}
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
return pkm.getLevelMoves().map(([_level, move]) => move);
return pkm.getLevelMoves().map(([ _level, move ]) => move);
}
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {

View File

@ -1,5 +1,5 @@
import Battle, { BattlerIndex, BattleType } from "#app/battle";
import { biomeLinks, BiomePoolTier } from "#app/data/biomes";
import { biomeLinks, BiomePoolTier } from "#app/data/balance/biomes";
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
import { AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
@ -373,7 +373,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
* @param moves
*/
export function loadCustomMovesForEncounter(scene: BattleScene, moves: Moves | Moves[]) {
moves = Array.isArray(moves) ? moves : [moves];
moves = Array.isArray(moves) ? moves : [ moves ];
return Promise.all(moves.map(move => initMoveAnim(scene, move)))
.then(() => loadMoveAnimAssets(scene, moves));
}
@ -663,7 +663,7 @@ export function setEncounterRewards(scene: BattleScene, customShopRewards?: Cust
* @param useWaveIndex - set to false when directly passing the the full exp value instead of baseExpValue
*/
export function setEncounterExp(scene: BattleScene, participantId: number | number[], baseExpValue: number, useWaveIndex: boolean = true) {
const participantIds = Array.isArray(participantId) ? participantId : [participantId];
const participantIds = Array.isArray(participantId) ? participantId : [ participantId ];
scene.currentBattle.mysteryEncounter!.doEncounterExp = (scene: BattleScene) => {
scene.unshiftPhase(new PartyExpPhase(scene, baseExpValue, useWaveIndex, new Set(participantIds)));
@ -800,8 +800,8 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide:
// Transition
scene.tweens.add({
targets: [introVisuals, enemyPokemon],
x: `${hide? "+" : "-"}=16`,
targets: [ introVisuals, enemyPokemon ],
x: `${hide ? "+" : "-"}=16`,
y: `${hide ? "-" : "+"}=16`,
alpha: hide ? 0 : 1,
ease: "Sine.easeInOut",
@ -888,14 +888,14 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
const numRuns = 1000;
let run = 0;
const biomes = Object.keys(Biome).filter(key => isNaN(Number(key)));
const alwaysPickTheseBiomes = [Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND];
const alwaysPickTheseBiomes = [ Biome.ISLAND, Biome.ABYSS, Biome.WASTELAND, Biome.FAIRY_CAVE, Biome.TEMPLE, Biome.LABORATORY, Biome.SPACE, Biome.WASTELAND ];
const calculateNumEncounters = (): any[] => {
let encounterRate = baseSpawnWeight; // BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT
const numEncounters = [0, 0, 0, 0];
const numEncounters = [ 0, 0, 0, 0 ];
let mostRecentEncounterWave = 0;
const encountersByBiome = new Map<string, number>(biomes.map(b => [b, 0]));
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [b, 0]));
const encountersByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
const validMEfloorsByBiome = new Map<string, number>(biomes.map(b => [ b, 0 ]));
let currentBiome = Biome.TOWN;
let currentArena = scene.newArena(currentBiome);
scene.setSeed(Utils.randomString(24));
@ -968,7 +968,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
// Calculate encounter rarity
// Common / Uncommon / Rare / Super Rare (base is out of 128)
const tierWeights = [66, 40, 19, 3];
const tierWeights = [ 66, 40, 19, 3 ];
// Adjust tier weights by currently encountered events (pity system that lowers odds of multiple Common/Great)
tierWeights[0] = tierWeights[0] - 6 * numEncounters[0];
@ -987,7 +987,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
}
}
return [numEncounters, encountersByBiome, validMEfloorsByBiome];
return [ numEncounters, encountersByBiome, validMEfloorsByBiome ];
};
const encounterRuns: number[][] = [];
@ -995,7 +995,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
const validFloorsByBiome: Map<string, number>[] = [];
while (run < numRuns) {
scene.executeWithSeedOffset(() => {
const [numEncounters, encountersByBiome, validMEfloorsByBiome] = calculateNumEncounters();
const [ numEncounters, encountersByBiome, validMEfloorsByBiome ] = calculateNumEncounters();
encounterRuns.push(numEncounters);
encountersByBiomeRuns.push(encountersByBiome);
validFloorsByBiome.push(validMEfloorsByBiome);
@ -1036,7 +1036,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
let stats = `Starting weight: ${baseSpawnWeight}\nAverage MEs per run: ${totalMean}\nStandard Deviation: ${totalStd}\nAvg Commons: ${commonMean}\nAvg Greats: ${uncommonMean}\nAvg Ultras: ${rareMean}\nAvg Rogues: ${superRareMean}\n`;
const meanEncountersPerRunPerBiomeSorted = [...meanEncountersPerRunPerBiome.entries()].sort((e1, e2) => e2[1] - e1[1]);
const meanEncountersPerRunPerBiomeSorted = [ ...meanEncountersPerRunPerBiome.entries() ].sort((e1, e2) => e2[1] - e1[1]);
meanEncountersPerRunPerBiomeSorted.forEach(value => stats = stats + `${value[0]}: avg valid floors ${meanMEFloorsPerRunPerBiome.get(value[0])}, avg MEs ${value[1]},\n`);
console.log(stats);
@ -1054,7 +1054,7 @@ export function calculateRareSpawnAggregateStats(scene: BattleScene, luckValue:
let run = 0;
const calculateNumRareEncounters = (): any[] => {
const bossEncountersByRarity = [0, 0, 0, 0];
const bossEncountersByRarity = [ 0, 0, 0, 0 ];
scene.setSeed(Utils.randomString(24));
scene.resetSeed();
// There are 12 wild boss floors

View File

@ -12,7 +12,8 @@ import { Mode } from "#app/ui/ui";
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
import { Species } from "#enums/species";
import { Type } from "#app/data/type";
import PokemonSpecies, { getPokemonSpecies, speciesStarters } from "#app/data/pokemon-species";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { getEncounterText, queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
import { getPokemonNameWithAffix } from "#app/messages";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
@ -206,8 +207,8 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
let min = Array.isArray(starterTiers) ? starterTiers[0] : starterTiers;
let max = Array.isArray(starterTiers) ? starterTiers[1] : starterTiers;
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarters)
.map(s => [parseInt(s) as Species, speciesStarters[s] as number])
let filteredSpecies: [PokemonSpecies, number][] = Object.keys(speciesStarterCosts)
.map(s => [ parseInt(s) as Species, speciesStarterCosts[s] as number ])
.filter(s => {
const pokemonSpecies = getPokemonSpecies(s[0]);
return pokemonSpecies && (!excludedSpecies || !excludedSpecies.includes(s[0]))
@ -215,7 +216,7 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
&& (allowLegendary || !pokemonSpecies.legendary)
&& (allowMythical || !pokemonSpecies.mythical);
})
.map(s => [getPokemonSpecies(s[0]), s[1]]);
.map(s => [ getPokemonSpecies(s[0]), s[1] ]);
if (types && types.length > 0) {
filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2)));
@ -312,7 +313,7 @@ export function applyHealToPokemon(scene: BattleScene, pokemon: PlayerPokemon, h
*/
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE()
.generateType(pokemon.scene.getParty(), [value])
.generateType(pokemon.scene.getParty(), [ value ])
?.withIdFromFunc(modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE);
const modifier = modType?.newModifier(pokemon);
if (modifier) {
@ -601,7 +602,7 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
}
});
};
Promise.all([pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon)]).then(() => {
Promise.all([ pokemon.hideInfo(), scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (scene.getParty().length === 6) {
const promptRelease = () => {
scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {
@ -727,33 +728,33 @@ export function doPlayerFlee(scene: BattleScene, pokemon: EnemyPokemon): Promise
* Bug Species and their corresponding weights
*/
const GOLDEN_BUG_NET_SPECIES_POOL: [Species, number][] = [
[Species.SCYTHER, 40],
[Species.SCIZOR, 40],
[Species.KLEAVOR, 40],
[Species.PINSIR, 40],
[Species.HERACROSS, 40],
[Species.YANMA, 40],
[Species.YANMEGA, 40],
[Species.SHUCKLE, 40],
[Species.ANORITH, 40],
[Species.ARMALDO, 40],
[Species.ESCAVALIER, 40],
[Species.ACCELGOR, 40],
[Species.JOLTIK, 40],
[Species.GALVANTULA, 40],
[Species.DURANT, 40],
[Species.LARVESTA, 40],
[Species.VOLCARONA, 40],
[Species.DEWPIDER, 40],
[Species.ARAQUANID, 40],
[Species.WIMPOD, 40],
[Species.GOLISOPOD, 40],
[Species.SIZZLIPEDE, 40],
[Species.CENTISKORCH, 40],
[Species.NYMBLE, 40],
[Species.LOKIX, 40],
[Species.BUZZWOLE, 1],
[Species.PHEROMOSA, 1],
[ Species.SCYTHER, 40 ],
[ Species.SCIZOR, 40 ],
[ Species.KLEAVOR, 40 ],
[ Species.PINSIR, 40 ],
[ Species.HERACROSS, 40 ],
[ Species.YANMA, 40 ],
[ Species.YANMEGA, 40 ],
[ Species.SHUCKLE, 40 ],
[ Species.ANORITH, 40 ],
[ Species.ARMALDO, 40 ],
[ Species.ESCAVALIER, 40 ],
[ Species.ACCELGOR, 40 ],
[ Species.JOLTIK, 40 ],
[ Species.GALVANTULA, 40 ],
[ Species.DURANT, 40 ],
[ Species.LARVESTA, 40 ],
[ Species.VOLCARONA, 40 ],
[ Species.DEWPIDER, 40 ],
[ Species.ARAQUANID, 40 ],
[ Species.WIMPOD, 40 ],
[ Species.GOLISOPOD, 40 ],
[ Species.SIZZLIPEDE, 40 ],
[ Species.CENTISKORCH, 40 ],
[ Species.NYMBLE, 40 ],
[ Species.LOKIX, 40 ],
[ Species.BUZZWOLE, 1 ],
[ Species.PHEROMOSA, 1 ],
];
/**

View File

@ -640,18 +640,18 @@ export const pokemonFormChanges: PokemonFormChanges = {
new SpeciesFormChange(Species.ALTARIA, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.ALTARIANITE))
],
[Species.CASTFORM]: [
new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.SUNNY, WeatherType.HARSH_SUN]), true),
new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.RAIN, WeatherType.HEAVY_RAIN]), true),
new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [WeatherType.HAIL, WeatherType.SNOW]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG]), true),
new SpeciesFormChange(Species.CASTFORM, "", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "sunny", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.SUNNY, WeatherType.HARSH_SUN ]), true),
new SpeciesFormChange(Species.CASTFORM, "", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "rainy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.RAIN, WeatherType.HEAVY_RAIN ]), true),
new SpeciesFormChange(Species.CASTFORM, "", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "snowy", new SpeciesFormChangeWeatherTrigger(Abilities.FORECAST, [ WeatherType.HAIL, WeatherType.SNOW ]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeRevertWeatherFormTrigger(Abilities.FORECAST, [ WeatherType.NONE, WeatherType.SANDSTORM, WeatherType.STRONG_WINDS, WeatherType.FOG ]), true),
new SpeciesFormChange(Species.CASTFORM, "sunny", "", new SpeciesFormChangeActiveTrigger(), true),
new SpeciesFormChange(Species.CASTFORM, "rainy", "", new SpeciesFormChangeActiveTrigger(), true),
new SpeciesFormChange(Species.CASTFORM, "snowy", "", new SpeciesFormChangeActiveTrigger(), true)

File diff suppressed because it is too large Load Diff

View File

@ -185,26 +185,26 @@ const seasonalSplashMessages: Season[] = [
name: "Halloween",
start: "09-15",
end: "10-31",
messages: ["halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever"],
messages: [ "halloween.pumpkabooAbout", "halloween.mayContainSpiders", "halloween.spookyScarySkeledirge", "halloween.gourgeistUsedTrickOrTreat", "halloween.letsSnuggleForever" ],
},
{
name: "XMAS",
start: "12-01",
end: "12-26",
messages: ["xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded"],
messages: [ "xmas.happyHolidays", "xmas.unaffilicatedWithDelibirdServices", "xmas.delibirdSeason", "xmas.diamondsFromTheSky", "xmas.holidayStylePikachuNotIncluded" ],
},
{
name: "New Year's",
start: "01-01",
end: "01-31",
messages: ["newYears.happyNewYear"],
messages: [ "newYears.happyNewYear" ],
},
];
//#endregion
export function getSplashMessages(): string[] {
const splashMessages: string[] = [...commonSplashMessages];
const splashMessages: string[] = [ ...commonSplashMessages ];
console.log("use seasonal splash messages", USE_SEASONAL_SPLASH_MESSAGES);
if (USE_SEASONAL_SPLASH_MESSAGES) {
// add seasonal splash messages if the season is active

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -171,9 +171,9 @@ export function getWeatherLapseMessage(weatherType: WeatherType): string | null
export function getWeatherDamageMessage(weatherType: WeatherType, pokemon: Pokemon): string | null {
switch (weatherType) {
case WeatherType.SANDSTORM:
return i18next.t("weather:sandstormDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
return i18next.t("weather:sandstormDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
case WeatherType.HAIL:
return i18next.t("weather:hailDamageMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
return i18next.t("weather:hailDamageMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
}
return null;
@ -238,9 +238,9 @@ export function getTerrainClearMessage(terrainType: TerrainType): string | null
export function getTerrainBlockMessage(pokemon: Pokemon, terrainType: TerrainType): string {
if (terrainType === TerrainType.MISTY) {
return i18next.t("terrain:mistyBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon)});
return i18next.t("terrain:mistyBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) });
}
return i18next.t("terrain:defaultBlockMessage", {pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType)});
return i18next.t("terrain:defaultBlockMessage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), terrainName: getTerrainName(terrainType) });
}
interface WeatherPoolEntry {

View File

@ -1,4 +1,3 @@
export enum ArenaTagType {
NONE = "NONE",
MUD_SPORT = "MUD_SPORT",

View File

@ -1,4 +1,3 @@
export enum BattlerTagType {
NONE = "NONE",
RECHARGING = "RECHARGING",

View File

@ -1,4 +1,3 @@
export enum BerryType {
SITRUS,
LUM,

View File

@ -1,4 +1,3 @@
export enum Biome {
TOWN,
PLAINS,

View File

@ -1,4 +1,3 @@
export enum TimeOfDay {
ALL = -1,
DAWN,

View File

@ -1,26 +1,26 @@
import BattleScene from "../battle-scene";
import { biomePokemonPools, BiomePoolTier, BiomeTierTrainerPools, biomeTrainerPools, PokemonPools } from "../data/biomes";
import BattleScene from "#app/battle-scene";
import { biomePokemonPools, BiomePoolTier, BiomeTierTrainerPools, biomeTrainerPools, PokemonPools } from "#app/data/balance/biomes";
import { Constructor } from "#app/utils";
import * as Utils from "../utils";
import PokemonSpecies, { getPokemonSpecies } from "../data/pokemon-species";
import { getTerrainClearMessage, getTerrainStartMessage, getWeatherClearMessage, getWeatherStartMessage, Weather, WeatherType } from "../data/weather";
import { CommonAnim } from "../data/battle-anims";
import { Type } from "../data/type";
import Move from "../data/move";
import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "../data/arena-tag";
import { BattlerIndex } from "../battle";
import { Terrain, TerrainType } from "../data/terrain";
import { applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs, PostTerrainChangeAbAttr, PostWeatherChangeAbAttr } from "../data/ability";
import Pokemon from "./pokemon";
import * as Utils from "#app/utils";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import { getTerrainClearMessage, getTerrainStartMessage, getWeatherClearMessage, getWeatherStartMessage, Weather, WeatherType } from "#app/data/weather";
import { CommonAnim } from "#app/data/battle-anims";
import { Type } from "#app/data/type";
import Move from "#app/data/move";
import { ArenaTag, ArenaTagSide, ArenaTrapTag, getArenaTag } from "#app/data/arena-tag";
import { BattlerIndex } from "#app/battle";
import { Terrain, TerrainType } from "#app/data/terrain";
import { applyPostTerrainChangeAbAttrs, applyPostWeatherChangeAbAttrs, PostTerrainChangeAbAttr, PostWeatherChangeAbAttr } from "#app/data/ability";
import Pokemon from "#app/field/pokemon";
import Overrides from "#app/overrides";
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "../events/arena";
import { TagAddedEvent, TagRemovedEvent, TerrainChangedEvent, WeatherChangedEvent } from "#app/events/arena";
import { ArenaTagType } from "#enums/arena-tag-type";
import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import { TimeOfDay } from "#enums/time-of-day";
import { TrainerType } from "#enums/trainer-type";
import { Abilities } from "#app/enums/abilities";
import { Abilities } from "#enums/abilities";
import { SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "#app/data/pokemon-forms";
import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";

View File

@ -101,14 +101,14 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
const getSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
const ret = this.scene.addFieldSprite(0, 0, spriteKey);
ret.setOrigin(0.5, 1);
ret.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
return ret;
};
const getItemSprite = (spriteKey: string, hasShadow?: boolean, yShadow?: number) => {
const icon = this.scene.add.sprite(-19, 2, "items", spriteKey);
icon.setOrigin(0.5, 1);
icon.setPipeline(this.scene.spritePipeline, { tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
icon.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow, yShadowOffset: yShadow ?? 0 });
return icon;
};

View File

@ -36,7 +36,7 @@ export default class PokemonSpriteSparkleHandler {
const ratioY = s.height / height;
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 [ 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.setName("sprite-tera-sparkle");

View File

@ -1,43 +1,45 @@
import Phaser from "phaser";
import BattleScene, { AnySound } from "../battle-scene";
import BattleScene, { AnySound } from "#app/battle-scene";
import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
import { variantData } from "#app/data/variant";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "#app/ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget } from "#app/data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
import { starterPassiveAbilities } from "#app/data/balance/passives";
import { Constructor, isNullOrUndefined, randSeedInt } from "#app/utils";
import * as Utils from "../utils";
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
import { getLevelTotalExp } from "../data/exp";
import * as Utils from "#app/utils";
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "#app/data/type";
import { getLevelTotalExp } from "#app/data/exp";
import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "../modifier/modifier";
import { PokeballType } from "../data/pokeball";
import { Gender } from "../data/gender";
import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms";
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonIncrementingStatModifier, EvoTrackerModifier } from "#app/modifier/modifier";
import { PokeballType } from "#app/data/pokeball";
import { Gender } from "#app/data/gender";
import { initMoveAnim, loadMoveAnimAssets } from "#app/data/battle-anims";
import { Status, StatusEffect, getRandomStatus } from "#app/data/status-effect";
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "#app/data/balance/pokemon-evolutions";
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "#app/data/balance/tms";
import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, SubstituteTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag, TarShotTag, AutotomizedTag } from "../data/battler-tags";
import { WeatherType } from "../data/weather";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "../data/ability";
import PokemonData from "../system/pokemon-data";
import { BattlerIndex } from "../battle";
import { Mode } from "../ui/ui";
import PartyUiHandler, { PartyOption, PartyUiMode } from "../ui/party-ui-handler";
import { WeatherType } from "#app/data/weather";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "#app/data/arena-tag";
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr, PostSetStatusAbAttr, applyPostSetStatusAbAttrs } from "#app/data/ability";
import PokemonData from "#app/system/pokemon-data";
import { BattlerIndex } from "#app/battle";
import { Mode } from "#app/ui/ui";
import PartyUiHandler, { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
import { LevelMoves } from "../data/pokemon-level-moves";
import { DamageAchv, achvs } from "../system/achv";
import { DexAttr, StarterDataEntry, StarterMoveset } from "../system/game-data";
import { LevelMoves } from "#app/data/balance/pokemon-level-moves";
import { DamageAchv, achvs } from "#app/system/achv";
import { DexAttr, StarterDataEntry, StarterMoveset } from "#app/system/game-data";
import { QuantizerCelebi, argbFromRgba, rgbaFromArgb } from "@material/material-color-utilities";
import { Nature, getNatureStatMultiplier } from "../data/nature";
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "../data/pokemon-forms";
import { TerrainType } from "../data/terrain";
import { TrainerSlot } from "../data/trainer-config";
import { Nature, getNatureStatMultiplier } from "#app/data/nature";
import { SpeciesFormChange, SpeciesFormChangeActiveTrigger, SpeciesFormChangeMoveLearnedTrigger, SpeciesFormChangePostMoveTrigger, SpeciesFormChangeStatusEffectTrigger } from "#app/data/pokemon-forms";
import { TerrainType } from "#app/data/terrain";
import { TrainerSlot } from "#app/data/trainer-config";
import Overrides from "#app/overrides";
import i18next from "i18next";
import { speciesEggMoves } from "../data/egg-moves";
import { ModifierTier } from "../modifier/modifier-tier";
import { speciesEggMoves } from "#app/data/balance/egg-moves";
import { ModifierTier } from "#app/modifier/modifier-tier";
import { applyChallenges, ChallengeType } from "#app/data/challenge";
import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type";
@ -58,17 +60,12 @@ import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
import { Challenges } from "#enums/challenges";
import { PokemonAnimType } from "#app/enums/pokemon-anim-type";
import { PokemonAnimType } from "#enums/pokemon-anim-type";
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
import { SwitchType } from "#enums/switch-type";
import { SpeciesFormKey } from "#enums/species-form-key";
/** `64/65536 -> 1/1024` */
const BASE_SHINY_CHANCE = 64;
/** `1/256` */
const BASE_HIDDEN_ABILITY_CHANCE = 256;
import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE, SHINY_EPIC_CHANCE, SHINY_VARIANT_CHANCE } from "#app/data/balance/rates";
export enum FieldPosition {
CENTER,
@ -699,7 +696,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @see {@linkcode getFieldPositionOffset}
*/
getSubstituteOffset(): [ number, number ] {
return this.isPlayer() ? [-30, 10] : [30, -10];
return this.isPlayer() ? [ -30, 10 ] : [ 30, -10 ];
}
/**
@ -1090,6 +1087,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return !!this.fusionSpecies;
}
/**
* Checks if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}.
* @param species the pokemon {@linkcode Species} to check
* @returns `true` if the {@linkcode Pokemon} has a fusion with the specified {@linkcode Species}, `false` otherwise
*/
hasFusionSpecies(species: Species): boolean {
return this.fusionSpecies?.speciesId === species;
}
abstract isBoss(): boolean;
getMoveset(ignoreOverride?: boolean): (PokemonMove | null)[] {
@ -1100,7 +1106,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
// Overrides moveset based on arrays specified in overrides.ts
let overrideArray: Moves | Array<Moves> = this.isPlayer() ? Overrides.MOVESET_OVERRIDE : Overrides.OPP_MOVESET_OVERRIDE;
if (!Array.isArray(overrideArray)) {
overrideArray = [overrideArray];
overrideArray = [ overrideArray ];
}
if (overrideArray.length > 0) {
if (!this.isPlayer()) {
@ -1386,10 +1392,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const suppressed = new Utils.BooleanHolder(false);
this.scene.getField(true).filter(p => p !== this).map(p => {
if (p.getAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility()) {
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ability]));
p.getAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, false, false, suppressed, [ ability ]));
}
if (p.getPassiveAbility().hasAttr(SuppressFieldAbilitiesAbAttr) && p.canApplyAbility(true)) {
p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ability]));
p.getPassiveAbility().getAttrs(SuppressFieldAbilitiesAbAttr).map(a => a.apply(this, true, false, suppressed, [ ability ]));
}
});
if (suppressed.value) {
@ -1525,7 +1531,6 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
/**
* Calculates the effectiveness of a move against the Pokémon.
* This includes modifiers from move and ability attributes.
@ -1930,9 +1935,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.executeWithSeedOffset(() => {
rand.value = Utils.randSeedInt(10);
}, this.id, this.scene.waveSeed);
if (rand.value >= 4) {
if (rand.value >= SHINY_VARIANT_CHANCE) {
return 0; // 6/10
} else if (rand.value >= 1) {
} else if (rand.value >= SHINY_EPIC_CHANCE) {
return 1; // 3/10
} else {
return 2; // 1/10
@ -1959,7 +1964,15 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
&& species.speciesId !== this.species.speciesId;
};
this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
let fusionOverride: PokemonSpecies | undefined = undefined;
if (forStarter && this instanceof PlayerPokemon && Overrides.STARTER_FUSION_SPECIES_OVERRIDE) {
fusionOverride = getPokemonSpecies(Overrides.STARTER_FUSION_SPECIES_OVERRIDE);
} else if (this instanceof EnemyPokemon && Overrides.OPP_FUSION_SPECIES_OVERRIDE) {
fusionOverride = getPokemonSpecies(Overrides.OPP_FUSION_SPECIES_OVERRIDE);
}
this.fusionSpecies = fusionOverride ?? this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0);
this.fusionShiny = this.shiny;
this.fusionVariant = this.variant;
@ -2020,7 +2033,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
weight /= 100;
} // Unimplemented level up moves are possible to generate, but 1% of their normal chance.
if (!movePool.some(m => m[0] === levelMove[1])) {
movePool.push([levelMove[1], weight]);
movePool.push([ levelMove[1], weight ]);
}
}
@ -2042,11 +2055,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
if (compatible && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
if (tmPoolTiers[moveId] === ModifierTier.COMMON && this.level >= 15) {
movePool.push([moveId, 4]);
movePool.push([ moveId, 4 ]);
} else if (tmPoolTiers[moveId] === ModifierTier.GREAT && this.level >= 30) {
movePool.push([moveId, 8]);
movePool.push([ moveId, 8 ]);
} else if (tmPoolTiers[moveId] === ModifierTier.ULTRA && this.level >= 50) {
movePool.push([moveId, 14]);
movePool.push([ moveId, 14 ]);
}
}
}
@ -2055,23 +2068,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
for (let i = 0; i < 3; i++) {
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][i];
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
movePool.push([moveId, 40]);
movePool.push([ moveId, 40 ]);
}
}
const moveId = speciesEggMoves[this.species.getRootSpeciesId()][3];
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) { // No rare egg moves before e4
movePool.push([moveId, 30]);
movePool.push([ moveId, 30 ]);
}
if (this.fusionSpecies) {
for (let i = 0; i < 3; i++) {
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][i];
if (!movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)")) {
movePool.push([moveId, 40]);
movePool.push([ moveId, 40 ]);
}
}
const moveId = speciesEggMoves[this.fusionSpecies.getRootSpeciesId()][3];
if (this.level >= 170 && !movePool.some(m => m[0] === moveId) && !allMoves[moveId].name.endsWith(" (N)") && !this.isBoss()) {// No rare egg moves before e4
movePool.push([moveId, 30]);
movePool.push([ moveId, 30 ]);
}
}
}
@ -2085,26 +2098,26 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
// Trainers never get OHKO moves
movePool = movePool.filter(m => !allMoves[m[0]].hasAttr(OneHitKOAttr));
// Half the weight of self KO moves
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1)]);
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1)]);
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1) ]);
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1) ]);
// Trainers get a weight bump to stat buffing moves
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1)]);
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1) ]);
// Trainers get a weight decrease to multiturn moves
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1)]);
movePool = movePool.map(m => [ m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1) ]);
}
// Weight towards higher power moves, by reducing the power of moves below the highest power.
// Caps max power at 90 to avoid something like hyper beam ruining the stats.
// This is a pretty soft weighting factor, although it is scaled with the weight multiplier.
const maxPower = Math.min(movePool.reduce((v, m) => Math.max(allMoves[m[0]].power, v), 40), 90);
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power/maxPower, 1), 0.5))]);
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power / maxPower, 1), 0.5)) ]);
// Weight damaging moves against the lower stat
const atk = this.getStat(Stat.ATK);
const spAtk = this.getStat(Stat.SPATK);
const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL;
const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk;
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1)]);
movePool = movePool.map(m => [ m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1) ]);
let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight.
if (this.hasTrainer()) {
@ -2113,7 +2126,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.isBoss()) {
weightMultiplier += 0.4;
}
const baseWeights: [Moves, number][] = movePool.map(m => [m[0], Math.ceil(Math.pow(m[1], weightMultiplier)*100)]);
const baseWeights: [Moves, number][] = movePool.map(m => [ m[0], Math.ceil(Math.pow(m[1], weightMultiplier) * 100) ]);
if (this.hasTrainer() || this.isBoss()) { // Trainers and bosses always force a stab move
const stabMovePool = baseWeights.filter(m => allMoves[m[0]].category !== MoveCategory.STATUS && this.isOfType(allMoves[m[0]].type));
@ -2145,7 +2158,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
// Sqrt the weight of any damaging moves with overlapping types. This is about a 0.05 - 0.1 multiplier.
// Other damaging moves 2x weight if 0-1 damaging moves, 0.5x if 2, 0.125x if 3. These weights double if STAB.
// Status moves remain unchanged on weight, this encourages 1-2
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1]/Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length)/8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1]]); // TODO: is this bang correct?
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId)).map(m => [ m[0], this.moveset.some(mo => mo?.getMove().category !== MoveCategory.STATUS && mo?.getMove().type === allMoves[m[0]].type) ? Math.ceil(Math.sqrt(m[1])) : allMoves[m[0]].category !== MoveCategory.STATUS ? Math.ceil(m[1] / Math.max(Math.pow(4, this.moveset.filter(mo => (mo?.getMove().power!) > 1).length) / 8, 0.5) * (this.isOfType(allMoves[m[0]].type) ? 2 : 1)) : m[1] ]); // TODO: is this bang correct?
} else { // Non-trainer pokemon just use normal weights
movePool = baseWeights.filter(m => !this.moveset.some(mo => m[0] === mo?.moveId));
}
@ -2683,7 +2696,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (critOnly.value || critAlways) {
isCritical = true;
} else {
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(this.getCritStage(source, move), 3))];
const critChance = [ 24, 8, 2, 1 ][Math.max(0, Math.min(this.getCritStage(source, move), 3))];
isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance);
}
@ -2868,7 +2881,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
isMax(): boolean {
const maxForms = [SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX] as string[];
const maxForms = [ SpeciesFormKey.GIGANTAMAX, SpeciesFormKey.GIGANTAMAX_RAPID, SpeciesFormKey.GIGANTAMAX_SINGLE, SpeciesFormKey.ETERNAMAX ] as string[];
return maxForms.includes(this.getFormKey()) || (!!this.getFusionFormKey() && maxForms.includes(this.getFusionFormKey()!));
}
@ -3356,7 +3369,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
break;
case StatusEffect.FREEZE:
if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType &&[WeatherType.SUNNY, WeatherType.HARSH_SUN].includes(this.scene.arena.weather.weatherType))) {
if (this.isOfType(Type.ICE) || (this.scene?.arena?.weather?.weatherType && [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(this.scene.arena.weather.weatherType))) {
return false;
}
break;
@ -3649,7 +3662,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const pixel = pixelData[f].slice(i, i + 4);
let [ r, g, b, a ] = pixel;
if (variantColors) {
const color = Utils.rgbaToInt([r, g, b, a]);
const color = Utils.rgbaToInt([ r, g, b, a ]);
if (variantColorSet.has(color)) {
const mappedPixel = variantColorSet.get(color);
if (mappedPixel) {
@ -3693,7 +3706,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
let [ r, g, b, a ] = [ pixelData[2 + f][i], pixelData[2 + f][i + 1], pixelData[2 + f][i + 2], pixelData[2 + f][i + 3] ];
if (variantColors) {
const color = Utils.rgbaToInt([r, g, b, a]);
const color = Utils.rgbaToInt([ r, g, b, a ]);
if (variantColorSet.has(color)) {
const mappedPixel = variantColorSet.get(color);
if (mappedPixel) {
@ -3988,7 +4001,7 @@ export class PlayerPokemon extends Pokemon {
let compatible = false;
for (const p of tmSpecies[tm]) {
if (Array.isArray(p)) {
const [pkm, form] = p;
const [ pkm, form ] = p;
if ((pkm === this.species.speciesId || this.fusionSpecies && pkm === this.fusionSpecies.speciesId) && form === this.getFormKey()) {
compatible = true;
break;
@ -4057,7 +4070,7 @@ export class PlayerPokemon extends Pokemon {
starterData.forEach((sd: StarterDataEntry, i: integer) => {
const speciesId = !i ? starterSpeciesId : fusionStarterSpeciesId as Species;
sd.friendship = (sd.friendship || 0) + starterAmount.value;
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarters[speciesId])) {
if (sd.friendship >= getStarterValueFriendshipCap(speciesStarterCosts[speciesId])) {
this.scene.gameData.addStarterCandy(getPokemonSpecies(speciesId), 1);
sd.friendship = 0;
}
@ -4077,7 +4090,7 @@ export class PlayerPokemon extends Pokemon {
revivalBlessing(): Promise<void> {
return new Promise(resolve => {
this.scene.ui.setMode(Mode.PARTY, PartyUiMode.REVIVAL_BLESSING, this.getFieldIndex(), (slotIndex:integer, option: PartyOption) => {
if (slotIndex >= 0 && slotIndex<6) {
if (slotIndex >= 0 && slotIndex < 6) {
const pokemon = this.scene.getParty()[slotIndex];
if (!pokemon || !pokemon.isFainted()) {
resolve();
@ -4086,11 +4099,11 @@ export class PlayerPokemon extends Pokemon {
pokemon.resetTurnData();
pokemon.resetStatus();
pokemon.heal(Math.min(Utils.toDmgValue(0.5 * pokemon.getMaxHp()), pokemon.getMaxHp()));
this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", {pokemonName: pokemon.name}), 0, true);
this.scene.queueMessage(i18next.t("moveTriggers:revivalBlessing", { pokemonName: pokemon.name }), 0, true);
if (this.scene.currentBattle.double && this.scene.getParty().length > 1) {
const allyPokemon = this.getAlly();
if (slotIndex<=1) {
if (slotIndex <= 1) {
// Revived ally pokemon
this.scene.unshiftPhase(new SwitchSummonPhase(this.scene, SwitchType.SWITCH, pokemon.getFieldIndex(), slotIndex, false, true));
this.scene.unshiftPhase(new ToggleDoublePositionPhase(this.scene, true));
@ -4157,7 +4170,7 @@ export class PlayerPokemon extends Pokemon {
if (!isFusion) {
const abilityCount = this.getSpeciesForm().getAbilityCount();
const preEvoAbilityCount = preEvolution.getAbilityCount();
if ([0, 1, 2].includes(this.abilityIndex)) {
if ([ 0, 1, 2 ].includes(this.abilityIndex)) {
// Handles cases where a Pokemon with 3 abilities evolves into a Pokemon with 2 abilities (ie: Eevee -> any Eeveelution)
if (this.abilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
this.abilityIndex = 1;
@ -4170,7 +4183,7 @@ export class PlayerPokemon extends Pokemon {
} else { // Do the same as above, but for fusions
const abilityCount = this.getFusionSpeciesForm().getAbilityCount();
const preEvoAbilityCount = preEvolution.getAbilityCount();
if ([0, 1, 2].includes(this.fusionAbilityIndex)) {
if ([ 0, 1, 2 ].includes(this.fusionAbilityIndex)) {
if (this.fusionAbilityIndex === 2 && preEvoAbilityCount === 3 && abilityCount === 2) {
this.fusionAbilityIndex = 1;
}
@ -4561,7 +4574,7 @@ export class EnemyPokemon extends Pokemon {
return move.category !== MoveCategory.STATUS
&& moveTargets.some(p => {
const doesNotFail = move.applyConditions(this, p, move) || [Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id);
const doesNotFail = move.applyConditions(this, p, move) || [ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id);
return doesNotFail && p.getAttackDamage(this, move, !p.battleData.abilityRevealed, false, isCritical).damage >= p.hp;
});
}, this);
@ -4604,7 +4617,7 @@ export class EnemyPokemon extends Pokemon {
* If this move is unimplemented, or the move is known to fail when used, set its
* target score to -20
*/
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP].includes(move.id)) {
if ((move.name.endsWith(" (N)") || !move.applyConditions(this, target, move)) && ![ Moves.SUCKER_PUNCH, Moves.UPPER_HAND, Moves.THUNDERCLAP ].includes(move.id)) {
targetScore = -20;
} else if (move instanceof AttackMove) {
/**
@ -4700,7 +4713,7 @@ export class EnemyPokemon extends Pokemon {
// Set target to BattlerIndex.ATTACKER when using a counter move
// This is the same as when the player does so
if (move.hasAttr(CounterDamageAttr)) {
return [BattlerIndex.ATTACKER];
return [ BattlerIndex.ATTACKER ];
}
return [];

View File

@ -1,6 +1,6 @@
import BattleScene from "../battle-scene";
import {pokemonPrevolutions} from "../data/pokemon-evolutions";
import PokemonSpecies, {getPokemonSpecies} from "../data/pokemon-species";
import BattleScene from "#app/battle-scene";
import { pokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import PokemonSpecies, { getPokemonSpecies } from "#app/data/pokemon-species";
import {
TrainerConfig,
TrainerPartyCompoundTemplate,
@ -10,13 +10,13 @@ import {
trainerConfigs,
trainerPartyTemplates,
signatureSpecies
} from "../data/trainer-config";
import {EnemyPokemon} from "./pokemon";
import * as Utils from "../utils";
import {PersistentModifier} from "../modifier/modifier";
import {trainerNamePools} from "../data/trainer-names";
import {ArenaTagSide, ArenaTrapTag} from "#app/data/arena-tag";
import {getIsInitialized, initI18n} from "#app/plugins/i18n";
} from "#app/data/trainer-config";
import { EnemyPokemon } from "#app/field/pokemon";
import * as Utils from "#app/utils";
import { PersistentModifier } from "#app/modifier/modifier";
import { trainerNamePools } from "#app/data/trainer-names";
import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import { getIsInitialized, initI18n } from "#app/plugins/i18n";
import i18next from "i18next";
import { PartyMemberStrength } from "#enums/party-member-strength";
import { Species } from "#enums/species";
@ -56,7 +56,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
if (partnerName) {
this.partnerName = partnerName;
} else {
[this.name, this.partnerName] = this.name.split(" & ");
[ this.name, this.partnerName ] = this.name.split(" & ");
}
} else {
this.partnerName = partnerName || Utils.randSeedItem(Array.isArray(namePool[0]) ? namePool[1] : namePool);
@ -82,7 +82,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
const getSprite = (hasShadow?: boolean, forceFemale?: boolean) => {
const ret = this.scene.addFieldSprite(0, 0, this.config.getSpriteKey(variant === TrainerVariant.FEMALE || forceFemale, this.isDouble()));
ret.setOrigin(0.5, 1);
ret.setPipeline(this.scene.spritePipeline, {tone: [0.0, 0.0, 0.0, 0.0], hasShadow: !!hasShadow});
ret.setPipeline(this.scene.spritePipeline, { tone: [ 0.0, 0.0, 0.0, 0.0 ], hasShadow: !!hasShadow });
return ret;
};
@ -126,7 +126,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
// Determine the title to include based on the configuration and includeTitle flag.
let title = includeTitle && this.config.title ? this.config.title : null;
const evilTeamTitles = ["grunt"];
const evilTeamTitles = [ "grunt" ];
if (this.name === "" && evilTeamTitles.some(t => name.toLocaleLowerCase().includes(t))) {
// This is a evil team grunt so we localize it by only using the "name" as the title
title = i18next.t(`trainerClasses:${name.toLowerCase().replace(/\s/g, "_")}`);
@ -336,9 +336,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
if (!(index % 2)) {
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.TATE])) {
newSpeciesPool = [Species.SOLROCK];
newSpeciesPool = [ Species.SOLROCK ];
} else if (index === 0 && (TrainerType[this.config.trainerType] === TrainerType[TrainerType.LIZA])) {
newSpeciesPool = [Species.LUNATONE];
newSpeciesPool = [ Species.LUNATONE ];
} else {
newSpeciesPool = speciesPoolFiltered;
}
@ -346,9 +346,9 @@ export default class Trainer extends Phaser.GameObjects.Container {
// If the index is odd, use the species pool for the partner trainer (that way he only uses his own pokemon in battle)
// Since the only currently allowed double battle with named trainers is Tate & Liza, we need to make sure that Solrock is the first pokemon in the party for Tate and Lunatone for Liza
if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.TATE])) {
newSpeciesPool = [Species.SOLROCK];
newSpeciesPool = [ Species.SOLROCK ];
} else if (index === 1 && (TrainerType[this.config.trainerTypeDouble] === TrainerType[TrainerType.LIZA])) {
newSpeciesPool = [Species.LUNATONE];
newSpeciesPool = [ Species.LUNATONE ];
} else {
newSpeciesPool = speciesPoolPartnerFiltered;
}
@ -475,7 +475,7 @@ export default class Trainer extends Phaser.GameObjects.Container {
}
}
return [party.indexOf(p), score];
return [ party.indexOf(p), score ];
}) as [integer, integer][];
return partyMemberScores;

View File

@ -33,8 +33,8 @@ interface GameModeConfig {
}
// Describes min and max waves for MEs in specific game modes
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ];
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [ 10, 180 ];
export class GameMode implements GameModeConfig {
public modeId: GameModes;
@ -330,7 +330,7 @@ export class GameMode implements GameModeConfig {
getMysteryEncounterLegalWaves(): [number, number] {
switch (this.modeId) {
default:
return [0, 0];
return [ 0, 0 ];
case GameModes.CLASSIC:
return CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES;
case GameModes.CHALLENGE:

View File

@ -1,12 +1,12 @@
import Phaser from "phaser";
import * as Utils from "./utils";
import {deepCopy} from "./utils";
import { deepCopy } from "./utils";
import pad_generic from "./configs/inputs/pad_generic";
import pad_unlicensedSNES from "./configs/inputs/pad_unlicensedSNES";
import pad_xbox360 from "./configs/inputs/pad_xbox360";
import pad_dualshock from "./configs/inputs/pad_dualshock";
import pad_procon from "./configs/inputs/pad_procon";
import {Mode} from "./ui/ui";
import { Mode } from "./ui/ui";
import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler";
import SettingsKeyboardUiHandler from "./ui/settings/settings-keyboard-ui-handler";
import cfg_keyboard_qwerty from "./configs/inputs/cfg_keyboard_qwerty";
@ -16,8 +16,8 @@ import {
getIconForLatestInput, swap,
} from "#app/configs/inputs/configHandler";
import BattleScene from "./battle-scene";
import {SettingGamepad} from "#app/system/settings/settings-gamepad";
import {SettingKeyboard} from "#app/system/settings/settings-keyboard";
import { SettingGamepad } from "#app/system/settings/settings-gamepad";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
import TouchControl from "#app/touch-controls";
import { Button } from "#enums/buttons";
import { Device } from "#enums/devices";
@ -294,7 +294,7 @@ export class InputsController {
this.setChosenGamepad(gamepadID);
}
const config = deepCopy(this.getConfig(gamepadID)) as InterfaceConfig;
config.custom = this.configs[gamepadID]?.custom || {...config.default};
config.custom = this.configs[gamepadID]?.custom || { ...config.default };
this.configs[gamepadID] = config;
this.scene.gameData?.saveMappingConfigs(gamepadID, this.configs[gamepadID]);
}
@ -307,9 +307,9 @@ export class InputsController {
* Initializes or updates configurations for connected keyboards.
*/
setupKeyboard(): void {
for (const layout of ["default"]) {
for (const layout of [ "default" ]) {
const config = deepCopy(this.getConfigKeyboard(layout)) as InterfaceConfig;
config.custom = this.configs[layout]?.custom || {...config.default};
config.custom = this.configs[layout]?.custom || { ...config.default };
this.configs[layout] = config;
this.scene.gameData?.saveMappingConfigs(this.selectedDevice[Device.KEYBOARD], this.configs[layout]);
}
@ -330,7 +330,7 @@ export class InputsController {
return el !== null;
}) ?? [];
for (const [index, thisGamepad] of this.gamepads.entries()) {
for (const [ index, thisGamepad ] of this.gamepads.entries()) {
thisGamepad.index = index; // Overwrite the gamepad index, in case we had undefined gamepads earlier
}
}

View File

@ -1,25 +1,25 @@
import { GachaType } from "./enums/gacha-types";
import { getBiomeHasProps } from "./field/arena";
import CacheBustedLoaderPlugin from "./plugins/cache-busted-loader-plugin";
import { SceneBase } from "./scene-base";
import { WindowVariant, getWindowVariantSuffix } from "./ui/ui-theme";
import { isMobile } from "./touch-controls";
import * as Utils from "./utils";
import { initPokemonPrevolutions } from "#app/data/pokemon-evolutions";
import { initBiomes } from "#app/data/biomes";
import { initEggMoves } from "#app/data/egg-moves";
import { GachaType } from "#enums/gacha-types";
import { getBiomeHasProps } from "#app/field/arena";
import CacheBustedLoaderPlugin from "#app/plugins/cache-busted-loader-plugin";
import { SceneBase } from "#app/scene-base";
import { WindowVariant, getWindowVariantSuffix } from "#app/ui/ui-theme";
import { isMobile } from "#app/touch-controls";
import * as Utils from "#app/utils";
import { initPokemonPrevolutions } from "#app/data/balance/pokemon-evolutions";
import { initBiomes } from "#app/data/balance/biomes";
import { initEggMoves } from "#app/data/balance/egg-moves";
import { initPokemonForms } from "#app/data/pokemon-forms";
import { initSpecies } from "#app/data/pokemon-species";
import { initMoves } from "#app/data/move";
import { initAbilities } from "#app/data/ability";
import { initAchievements } from "#app/system/achv";
import { initTrainerTypeDialogue } from "#app/data/dialogue";
import { initChallenges } from "./data/challenge";
import { initChallenges } from "#app/data/challenge";
import i18next from "i18next";
import { initStatsKeys } from "./ui/game-stats-ui-handler";
import { initVouchers } from "./system/voucher";
import { initStatsKeys } from "#app/ui/game-stats-ui-handler";
import { initVouchers } from "#app/system/voucher";
import { Biome } from "#enums/biome";
import {initMysteryEncounters} from "#app/data/mystery-encounters/mystery-encounters";
import { initMysteryEncounters } from "#app/data/mystery-encounters/mystery-encounters";
export class LoadingScene extends SceneBase {
public static readonly KEY = "loading";
@ -44,6 +44,8 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("prompt", "ui");
this.loadImage("candy", "ui");
this.loadImage("candy_overlay", "ui");
this.loadImage("friendship", "ui");
this.loadImage("friendship_overlay", "ui");
this.loadImage("cursor", "ui");
this.loadImage("cursor_reverse", "ui");
for (const wv of Utils.getEnumValues(WindowVariant)) {
@ -240,9 +242,9 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("statuses", "");
this.loadAtlas("types", "");
}
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"];
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN" ];
if (lang && availableLangs.includes(lang)) {
this.loadImage("egg-update_"+lang, "events");
this.loadImage("egg-update_" + lang, "events");
} else {
this.loadImage("egg-update_en", "events");
}

View File

@ -1,38 +1,35 @@
import * as Modifiers from "./modifier";
import { MoneyMultiplierModifier } from "./modifier";
import { allMoves, AttackMove, selfStatLowerMoves } from "../data/move";
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "../data/pokeball";
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "../field/pokemon";
import { EvolutionItem, pokemonEvolutions } from "../data/pokemon-evolutions";
import { tmPoolTiers, tmSpecies } from "../data/tms";
import { Type } from "../data/type";
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "../ui/party-ui-handler";
import * as Utils from "../utils";
import { getBerryEffectDescription, getBerryName } from "../data/berry";
import { Unlockables } from "../system/unlockables";
import { getStatusEffectDescriptor, StatusEffect } from "../data/status-effect";
import BattleScene from "../battle-scene";
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "../system/voucher";
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger } from "../data/pokemon-forms";
import { ModifierTier } from "./modifier-tier";
import BattleScene from "#app/battle-scene";
import { EvolutionItem, pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
import { tmPoolTiers, tmSpecies } from "#app/data/balance/tms";
import { getBerryEffectDescription, getBerryName } from "#app/data/berry";
import { allMoves, AttackMove, selfStatLowerMoves } from "#app/data/move";
import { getNatureName, getNatureStatMultiplier, Nature } from "#app/data/nature";
import i18next from "i18next";
import { getModifierTierTextTint } from "#app/ui/text";
import { getPokeballCatchMultiplier, getPokeballName, MAX_PER_TYPE_POKEBALLS, PokeballType } from "#app/data/pokeball";
import { FormChangeItem, pokemonFormChanges, SpeciesFormChangeCondition, SpeciesFormChangeItemTrigger } from "#app/data/pokemon-forms";
import { getStatusEffectDescriptor, StatusEffect } from "#app/data/status-effect";
import { Type } from "#app/data/type";
import Pokemon, { EnemyPokemon, PlayerPokemon, PokemonMove } from "#app/field/pokemon";
import { getPokemonNameWithAffix } from "#app/messages";
import { AddPokeballModifier, AddVoucherModifier, AttackTypeBoosterModifier, BaseStatModifier, BerryModifier, BoostBugSpawnModifier, BypassSpeedChanceModifier, ContactHeldItemTransferChanceModifier, CritBoosterModifier, DamageMoneyRewardModifier, DoubleBattleChanceBoosterModifier, EnemyAttackStatusEffectChanceModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, EvolutionItemModifier, EvolutionStatBoosterModifier, EvoTrackerModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, FusePokemonModifier, GigantamaxAccessModifier, HealingBoosterModifier, HealShopCostModifier, HiddenAbilityRateBoosterModifier, HitHealModifier, IvScannerModifier, LevelIncrementBoosterModifier, LockModifierTiersModifier, MapModifier, MegaEvolutionAccessModifier, MoneyInterestModifier, MoneyMultiplierModifier, MoneyRewardModifier, MultipleParticipantExpBonusModifier, PokemonAllMovePpRestoreModifier, PokemonBaseStatFlatModifier, PokemonBaseStatTotalModifier, PokemonExpBoosterModifier, PokemonFormChangeItemModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonHpRestoreModifier, PokemonIncrementingStatModifier, PokemonInstantReviveModifier, PokemonLevelIncrementModifier, PokemonMoveAccuracyBoosterModifier, PokemonMultiHitModifier, PokemonNatureChangeModifier, PokemonNatureWeightModifier, PokemonPpRestoreModifier, PokemonPpUpModifier, PokemonStatusHealModifier, PreserveBerryModifier, RememberMoveModifier, ResetNegativeStatStageModifier, ShinyRateBoosterModifier, SpeciesCritBoosterModifier, SpeciesStatBoosterModifier, SurviveDamageModifier, SwitchEffectTransferModifier, TempCritBoosterModifier, TempStatStageBoosterModifier, TerastallizeAccessModifier, TerastallizeModifier, TmModifier, TurnHealModifier, TurnHeldItemTransferModifier, TurnStatusEffectModifier, type EnemyPersistentModifier, type Modifier, type PersistentModifier } from "#app/modifier/modifier";
import { ModifierTier } from "#app/modifier/modifier-tier";
import Overrides from "#app/overrides";
import { Unlockables } from "#app/system/unlockables";
import { getVoucherTypeIcon, getVoucherTypeName, VoucherType } from "#app/system/voucher";
import PartyUiHandler, { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party-ui-handler";
import { getModifierTierTextTint } from "#app/ui/text";
import { formatMoney, getEnumKeys, getEnumValues, IntegerHolder, NumberHolder, padInt, randSeedInt, randSeedItem } from "#app/utils";
import { Abilities } from "#enums/abilities";
import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import { getPokemonNameWithAffix } from "#app/messages";
import { PermanentStat, TEMP_BATTLE_STATS, TempBattleStat, Stat, getStatKey } from "#app/enums/stat";
import { SpeciesFormKey } from "#enums/species-form-key";
import { getStatKey, PermanentStat, Stat, TEMP_BATTLE_STATS, TempBattleStat } from "#enums/stat";
import i18next from "i18next";
const outputModifierData = false;
const useMaxWeightForOutput = false;
type Modifier = Modifiers.Modifier;
export enum ModifierPoolType {
PLAYER,
WILD,
@ -97,7 +94,7 @@ export class ModifierType {
// Try multiple pool types in case of stolen items
for (const type of poolTypes) {
const pool = getModifierPoolForType(type);
for (const tier of Utils.getEnumValues(ModifierTier)) {
for (const tier of getEnumValues(ModifierTier)) {
if (!pool.hasOwnProperty(tier)) {
continue;
}
@ -171,7 +168,7 @@ class AddPokeballModifierType extends ModifierType {
private count: integer;
constructor(iconImage: string, pokeballType: PokeballType, count: integer) {
super("", iconImage, (_type, _args) => new Modifiers.AddPokeballModifier(this, pokeballType, count), "pb", "se/pb_bounce_1");
super("", iconImage, (_type, _args) => new AddPokeballModifier(this, pokeballType, count), "pb", "se/pb_bounce_1");
this.pokeballType = pokeballType;
this.count = count;
}
@ -198,7 +195,7 @@ class AddVoucherModifierType extends ModifierType {
private count: integer;
constructor(voucherType: VoucherType, count: integer) {
super("", getVoucherTypeIcon(voucherType), (_type, _args) => new Modifiers.AddVoucherModifier(this, voucherType, count), "voucher");
super("", getVoucherTypeIcon(voucherType), (_type, _args) => new AddVoucherModifier(this, voucherType, count), "voucher");
this.count = count;
this.voucherType = voucherType;
}
@ -232,7 +229,7 @@ export class PokemonHeldItemModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string, newModifierFunc: NewModifierFunc, group?: string, soundName?: string) {
super(localeKey, iconImage, newModifierFunc, (pokemon: PlayerPokemon) => {
const dummyModifier = this.newModifier(pokemon);
const matchingModifier = pokemon.scene.findModifier(m => m instanceof Modifiers.PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as Modifiers.PokemonHeldItemModifier;
const matchingModifier = pokemon.scene.findModifier(m => m instanceof PokemonHeldItemModifier && m.pokemonId === pokemon.id && m.matchType(dummyModifier)) as PokemonHeldItemModifier;
const maxStackCount = dummyModifier.getMaxStackCount(pokemon.scene);
if (!maxStackCount) {
return i18next.t("modifierType:ModifierType.PokemonHeldItemModifierType.extra.inoperable", { "pokemonName": getPokemonNameWithAffix(pokemon) });
@ -244,8 +241,8 @@ export class PokemonHeldItemModifierType extends PokemonModifierType {
}, group, soundName);
}
newModifier(...args: any[]): Modifiers.PokemonHeldItemModifier {
return super.newModifier(...args) as Modifiers.PokemonHeldItemModifier;
newModifier(...args: any[]): PokemonHeldItemModifier {
return super.newModifier(...args) as PokemonHeldItemModifier;
}
}
@ -255,7 +252,7 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType {
protected healStatus: boolean;
constructor(localeKey: string, iconImage: string, restorePoints: integer, restorePercent: integer, healStatus: boolean = false, newModifierFunc?: NewModifierFunc, selectFilter?: PokemonSelectFilter, group?: string) {
super(localeKey, iconImage, newModifierFunc || ((_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)),
super(localeKey, iconImage, newModifierFunc || ((_type, args) => new PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints, this.restorePercent, this.healStatus, false)),
selectFilter || ((pokemon: PlayerPokemon) => {
if (!pokemon.hp || (pokemon.isFullHp() && (!this.healStatus || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))))) {
return PartyUiHandler.NoEffectMessage;
@ -282,7 +279,7 @@ export class PokemonHpRestoreModifierType extends PokemonModifierType {
export class PokemonReviveModifierType extends PokemonHpRestoreModifierType {
constructor(localeKey: string, iconImage: string, restorePercent: integer) {
super(localeKey, iconImage, 0, restorePercent, false, (_type, args) => new Modifiers.PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, false, true),
super(localeKey, iconImage, 0, restorePercent, false, (_type, args) => new PokemonHpRestoreModifier(this, (args[0] as PlayerPokemon).id, 0, this.restorePercent, false, true),
((pokemon: PlayerPokemon) => {
if (!pokemon.isFainted()) {
return PartyUiHandler.NoEffectMessage;
@ -305,7 +302,7 @@ export class PokemonReviveModifierType extends PokemonHpRestoreModifierType {
export class PokemonStatusHealModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, ((_type, args) => new Modifiers.PokemonStatusHealModifier(this, (args[0] as PlayerPokemon).id)),
super(localeKey, iconImage, ((_type, args) => new PokemonStatusHealModifier(this, (args[0] as PlayerPokemon).id)),
((pokemon: PlayerPokemon) => {
if (!pokemon.hp || (!pokemon.status && !pokemon.getTag(BattlerTagType.CONFUSED))) {
return PartyUiHandler.NoEffectMessage;
@ -333,7 +330,7 @@ export class PokemonPpRestoreModifierType extends PokemonMoveModifierType {
protected restorePoints: integer;
constructor(localeKey: string, iconImage: string, restorePoints: integer) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints),
super(localeKey, iconImage, (_type, args) => new PokemonPpRestoreModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.restorePoints),
(_pokemon: PlayerPokemon) => {
return null;
}, (pokemonMove: PokemonMove) => {
@ -358,7 +355,7 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType {
protected restorePoints: integer;
constructor(localeKey: string, iconImage: string, restorePoints: integer) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints),
super(localeKey, iconImage, (_type, args) => new PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints),
(pokemon: PlayerPokemon) => {
if (!pokemon.getMoveset().filter(m => m?.ppUsed).length) {
return PartyUiHandler.NoEffectMessage;
@ -381,7 +378,7 @@ export class PokemonPpUpModifierType extends PokemonMoveModifierType {
protected upPoints: integer;
constructor(localeKey: string, iconImage: string, upPoints: integer) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints),
super(localeKey, iconImage, (_type, args) => new PokemonPpUpModifier(this, (args[0] as PlayerPokemon).id, (args[1] as integer), this.upPoints),
(_pokemon: PlayerPokemon) => {
return null;
}, (pokemonMove: PokemonMove) => {
@ -403,7 +400,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType {
protected nature: Nature;
constructor(nature: Nature) {
super("", `mint_${Utils.getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || "neutral" }`, ((_type, args) => new Modifiers.PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)),
super("", `mint_${getEnumKeys(Stat).find(s => getNatureStatMultiplier(nature, Stat[s]) > 1)?.toLowerCase() || "neutral" }`, ((_type, args) => new PokemonNatureChangeModifier(this, (args[0] as PlayerPokemon).id, this.nature)),
((pokemon: PlayerPokemon) => {
if (pokemon.getNature() === this.nature) {
return PartyUiHandler.NoEffectMessage;
@ -425,7 +422,7 @@ export class PokemonNatureChangeModifierType extends PokemonModifierType {
export class RememberMoveModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string, group?: string) {
super(localeKey, iconImage, (type, args) => new Modifiers.RememberMoveModifier(type, (args[0] as PlayerPokemon).id, (args[1] as integer)),
super(localeKey, iconImage, (type, args) => new RememberMoveModifier(type, (args[0] as PlayerPokemon).id, (args[1] as integer)),
(pokemon: PlayerPokemon) => {
if (!pokemon.getLearnableLevelMoves().length) {
return PartyUiHandler.NoEffectMessage;
@ -439,7 +436,7 @@ export class DoubleBattleChanceBoosterModifierType extends ModifierType {
private maxBattles: number;
constructor(localeKey: string, iconImage: string, maxBattles: number) {
super(localeKey, iconImage, (_type, _args) => new Modifiers.DoubleBattleChanceBoosterModifier(this, maxBattles), "lure");
super(localeKey, iconImage, (_type, _args) => new DoubleBattleChanceBoosterModifier(this, maxBattles), "lure");
this.maxBattles = maxBattles;
}
@ -458,7 +455,7 @@ export class TempStatStageBoosterModifierType extends ModifierType implements Ge
constructor(stat: TempBattleStat) {
const nameKey = TempStatStageBoosterModifierTypeGenerator.items[stat];
super("", nameKey, (_type, _args) => new Modifiers.TempStatStageBoosterModifier(this, this.stat, 5));
super("", nameKey, (_type, _args) => new TempStatStageBoosterModifier(this, this.stat, 5));
this.stat = stat;
this.nameKey = nameKey;
@ -485,7 +482,7 @@ export class BerryModifierType extends PokemonHeldItemModifierType implements Ge
private berryType: BerryType;
constructor(berryType: BerryType) {
super("", `${BerryType[berryType].toLowerCase()}_berry`, (type, args) => new Modifiers.BerryModifier(type, (args[0] as Pokemon).id, berryType), "berry");
super("", `${BerryType[berryType].toLowerCase()}_berry`, (type, args) => new BerryModifier(type, (args[0] as Pokemon).id, berryType), "berry");
this.berryType = berryType;
}
@ -550,7 +547,7 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i
constructor(moveType: Type, boostPercent: integer) {
super("", `${getAttackTypeBoosterItemName(moveType)?.replace(/[ \-]/g, "_").toLowerCase()}`,
(_type, args) => new Modifiers.AttackTypeBoosterModifier(this, (args[0] as Pokemon).id, moveType, boostPercent));
(_type, args) => new AttackTypeBoosterModifier(this, (args[0] as Pokemon).id, moveType, boostPercent));
this.moveType = moveType;
this.boostPercent = boostPercent;
@ -573,7 +570,7 @@ export class AttackTypeBoosterModifierType extends PokemonHeldItemModifierType i
export type SpeciesStatBoosterItem = keyof typeof SpeciesStatBoosterModifierTypeGenerator.items;
/**
* Modifier type for {@linkcode Modifiers.SpeciesStatBoosterModifier}
* Modifier type for {@linkcode SpeciesStatBoosterModifier}
* @extends PokemonHeldItemModifierType
* @implements GeneratedPersistentModifierType
*/
@ -582,7 +579,7 @@ export class SpeciesStatBoosterModifierType extends PokemonHeldItemModifierType
constructor(key: SpeciesStatBoosterItem) {
const item = SpeciesStatBoosterModifierTypeGenerator.items[key];
super(`modifierType:SpeciesBoosterItem.${key}`, key.toLowerCase(), (type, args) => new Modifiers.SpeciesStatBoosterModifier(type, (args[0] as Pokemon).id, item.stats, item.multiplier, item.species));
super(`modifierType:SpeciesBoosterItem.${key}`, key.toLowerCase(), (type, args) => new SpeciesStatBoosterModifier(type, (args[0] as Pokemon).id, item.stats, item.multiplier, item.species));
this.key = key;
}
@ -594,12 +591,12 @@ export class SpeciesStatBoosterModifierType extends PokemonHeldItemModifierType
export class PokemonLevelIncrementModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonLevelIncrementModifier(this, (args[0] as PlayerPokemon).id), (_pokemon: PlayerPokemon) => null);
super(localeKey, iconImage, (_type, args) => new PokemonLevelIncrementModifier(this, (args[0] as PlayerPokemon).id), (_pokemon: PlayerPokemon) => null);
}
getDescription(scene: BattleScene): string {
let levels = 1;
const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof Modifiers.LevelIncrementBoosterModifier);
const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
if (hasCandyJar) {
levels += hasCandyJar.stackCount;
}
@ -609,12 +606,12 @@ export class PokemonLevelIncrementModifierType extends PokemonModifierType {
export class AllPokemonLevelIncrementModifierType extends ModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, (_type, _args) => new Modifiers.PokemonLevelIncrementModifier(this, -1));
super(localeKey, iconImage, (_type, _args) => new PokemonLevelIncrementModifier(this, -1));
}
getDescription(scene: BattleScene): string {
let levels = 1;
const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof Modifiers.LevelIncrementBoosterModifier);
const hasCandyJar = scene.modifiers.find(modifier => modifier instanceof LevelIncrementBoosterModifier);
if (hasCandyJar) {
levels += hasCandyJar.stackCount;
}
@ -628,7 +625,7 @@ export class BaseStatBoosterModifierType extends PokemonHeldItemModifierType imp
constructor(stat: PermanentStat) {
const key = BaseStatBoosterModifierTypeGenerator.items[stat];
super("", key, (_type, args) => new Modifiers.BaseStatModifier(this, (args[0] as Pokemon).id, this.stat));
super("", key, (_type, args) => new BaseStatModifier(this, (args[0] as Pokemon).id, this.stat));
this.stat = stat;
this.key = key;
@ -654,7 +651,7 @@ export class PokemonBaseStatTotalModifierType extends PokemonHeldItemModifierTyp
private readonly statModifier: integer;
constructor(statModifier: integer) {
super("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE", "berry_juice", (_type, args) => new Modifiers.PokemonBaseStatTotalModifier(this, (args[0] as Pokemon).id, this.statModifier));
super("modifierType:ModifierType.MYSTERY_ENCOUNTER_SHUCKLE_JUICE", "berry_juice", (_type, args) => new PokemonBaseStatTotalModifier(this, (args[0] as Pokemon).id, this.statModifier));
this.statModifier = statModifier;
}
@ -679,7 +676,7 @@ export class PokemonBaseStatFlatModifierType extends PokemonHeldItemModifierType
private readonly stats: Stat[];
constructor(statModifier: integer, stats: Stat[]) {
super("modifierType:ModifierType.MYSTERY_ENCOUNTER_OLD_GATEAU", "old_gateau", (_type, args) => new Modifiers.PokemonBaseStatFlatModifier(this, (args[0] as Pokemon).id, this.statModifier, this.stats));
super("modifierType:ModifierType.MYSTERY_ENCOUNTER_OLD_GATEAU", "old_gateau", (_type, args) => new PokemonBaseStatFlatModifier(this, (args[0] as Pokemon).id, this.statModifier, this.stats));
this.statModifier = statModifier;
this.stats = stats;
}
@ -700,7 +697,7 @@ class AllPokemonFullHpRestoreModifierType extends ModifierType {
private descriptionKey: string;
constructor(localeKey: string, iconImage: string, descriptionKey?: string, newModifierFunc?: NewModifierFunc) {
super(localeKey, iconImage, newModifierFunc || ((_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false)));
super(localeKey, iconImage, newModifierFunc || ((_type, _args) => new PokemonHpRestoreModifier(this, -1, 0, 100, false)));
this.descriptionKey = descriptionKey!; // TODO: is this bang correct?
}
@ -712,7 +709,7 @@ class AllPokemonFullHpRestoreModifierType extends ModifierType {
class AllPokemonFullReviveModifierType extends AllPokemonFullHpRestoreModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, "modifierType:ModifierType.AllPokemonFullReviveModifierType", (_type, _args) => new Modifiers.PokemonHpRestoreModifier(this, -1, 0, 100, false, true));
super(localeKey, iconImage, "modifierType:ModifierType.AllPokemonFullReviveModifierType", (_type, _args) => new PokemonHpRestoreModifier(this, -1, 0, 100, false, true));
}
}
@ -721,16 +718,16 @@ export class MoneyRewardModifierType extends ModifierType {
private moneyMultiplierDescriptorKey: string;
constructor(localeKey: string, iconImage: string, moneyMultiplier: number, moneyMultiplierDescriptorKey: string) {
super(localeKey, iconImage, (_type, _args) => new Modifiers.MoneyRewardModifier(this, moneyMultiplier), "money", "se/buy");
super(localeKey, iconImage, (_type, _args) => new MoneyRewardModifier(this, moneyMultiplier), "money", "se/buy");
this.moneyMultiplier = moneyMultiplier;
this.moneyMultiplierDescriptorKey = moneyMultiplierDescriptorKey;
}
getDescription(scene: BattleScene): string {
const moneyAmount = new Utils.IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier));
const moneyAmount = new IntegerHolder(scene.getWaveMoneyAmount(this.moneyMultiplier));
scene.applyModifiers(MoneyMultiplierModifier, true, moneyAmount);
const formattedMoney = Utils.formatMoney(scene.moneyFormat, moneyAmount.value);
const formattedMoney = formatMoney(scene.moneyFormat, moneyAmount.value);
return i18next.t("modifierType:ModifierType.MoneyRewardModifierType.description", {
moneyMultiplier: i18next.t(this.moneyMultiplierDescriptorKey as any),
@ -743,7 +740,7 @@ export class ExpBoosterModifierType extends ModifierType {
private boostPercent: integer;
constructor(localeKey: string, iconImage: string, boostPercent: integer) {
super(localeKey, iconImage, () => new Modifiers.ExpBoosterModifier(this, boostPercent));
super(localeKey, iconImage, () => new ExpBoosterModifier(this, boostPercent));
this.boostPercent = boostPercent;
}
@ -757,7 +754,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType {
private boostPercent: integer;
constructor(localeKey: string, iconImage: string, boostPercent: integer) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonExpBoosterModifier(this, (args[0] as Pokemon).id, boostPercent));
super(localeKey, iconImage, (_type, args) => new PokemonExpBoosterModifier(this, (args[0] as Pokemon).id, boostPercent));
this.boostPercent = boostPercent;
}
@ -769,7 +766,7 @@ export class PokemonExpBoosterModifierType extends PokemonHeldItemModifierType {
export class PokemonFriendshipBoosterModifierType extends PokemonHeldItemModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id));
super(localeKey, iconImage, (_type, args) => new PokemonFriendshipBoosterModifier(this, (args[0] as Pokemon).id));
}
getDescription(scene: BattleScene): string {
@ -781,7 +778,7 @@ export class PokemonMoveAccuracyBoosterModifierType extends PokemonHeldItemModif
private amount: integer;
constructor(localeKey: string, iconImage: string, amount: integer, group?: string, soundName?: string) {
super(localeKey, iconImage, (_type, args) => new Modifiers.PokemonMoveAccuracyBoosterModifier(this, (args[0] as Pokemon).id, amount), group, soundName);
super(localeKey, iconImage, (_type, args) => new PokemonMoveAccuracyBoosterModifier(this, (args[0] as Pokemon).id, amount), group, soundName);
this.amount = amount;
}
@ -793,7 +790,7 @@ export class PokemonMoveAccuracyBoosterModifierType extends PokemonHeldItemModif
export class PokemonMultiHitModifierType extends PokemonHeldItemModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, (type, args) => new Modifiers.PokemonMultiHitModifier(type as PokemonMultiHitModifierType, (args[0] as Pokemon).id));
super(localeKey, iconImage, (type, args) => new PokemonMultiHitModifier(type as PokemonMultiHitModifierType, (args[0] as Pokemon).id));
}
getDescription(scene: BattleScene): string {
@ -805,7 +802,7 @@ export class TmModifierType extends PokemonModifierType {
public moveId: Moves;
constructor(moveId: Moves) {
super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new Modifiers.TmModifier(this, (args[0] as PlayerPokemon).id),
super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new TmModifier(this, (args[0] as PlayerPokemon).id),
(pokemon: PlayerPokemon) => {
if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.getMoveset().filter(m => m?.moveId === moveId).length) {
return PartyUiHandler.NoEffectMessage;
@ -818,7 +815,7 @@ export class TmModifierType extends PokemonModifierType {
get name(): string {
return i18next.t("modifierType:ModifierType.TmModifierType.name", {
moveId: Utils.padInt(Object.keys(tmSpecies).indexOf(this.moveId.toString()) + 1, 3),
moveId: padInt(Object.keys(tmSpecies).indexOf(this.moveId.toString()) + 1, 3),
moveName: allMoves[this.moveId].name,
});
}
@ -832,7 +829,7 @@ export class EvolutionItemModifierType extends PokemonModifierType implements Ge
public evolutionItem: EvolutionItem;
constructor(evolutionItem: EvolutionItem) {
super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new Modifiers.EvolutionItemModifier(this, (args[0] as PlayerPokemon).id),
super("", EvolutionItem[evolutionItem].toLowerCase(), (_type, args) => new EvolutionItemModifier(this, (args[0] as PlayerPokemon).id),
(pokemon: PlayerPokemon) => {
if (pokemonEvolutions.hasOwnProperty(pokemon.species.speciesId) && pokemonEvolutions[pokemon.species.speciesId].filter(e => e.item === this.evolutionItem
&& (!e.condition || e.condition.predicate(pokemon)) && (e.preFormKey === null || e.preFormKey === pokemon.getFormKey())).length && (pokemon.getFormKey() !== SpeciesFormKey.GIGANTAMAX)) {
@ -868,7 +865,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G
public formChangeItem: FormChangeItem;
constructor(formChangeItem: FormChangeItem) {
super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new Modifiers.PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true),
super("", FormChangeItem[formChangeItem].toLowerCase(), (_type, args) => new PokemonFormChangeItemModifier(this, (args[0] as PlayerPokemon).id, formChangeItem, true),
(pokemon: PlayerPokemon) => {
// Make sure the Pokemon has alternate forms
if (pokemonFormChanges.hasOwnProperty(pokemon.species.speciesId)
@ -902,7 +899,7 @@ export class FormChangeItemModifierType extends PokemonModifierType implements G
export class FusePokemonModifierType extends PokemonModifierType {
constructor(localeKey: string, iconImage: string) {
super(localeKey, iconImage, (_type, args) => new Modifiers.FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id),
super(localeKey, iconImage, (_type, args) => new FusePokemonModifier(this, (args[0] as PlayerPokemon).id, (args[1] as PlayerPokemon).id),
(pokemon: PlayerPokemon) => {
if (pokemon.isFusion()) {
return PartyUiHandler.NoEffectMessage;
@ -949,7 +946,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
let type: Type;
const randInt = Utils.randSeedInt(totalWeight);
const randInt = randSeedInt(totalWeight);
let weight = 0;
for (const t of attackMoveTypeWeights.keys()) {
@ -981,7 +978,7 @@ class BaseStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
if (pregenArgs) {
return new BaseStatBoosterModifierType(pregenArgs[0]);
}
const randStat: PermanentStat = Utils.randSeedInt(Stat.SPD + 1);
const randStat: PermanentStat = randSeedInt(Stat.SPD + 1);
return new BaseStatBoosterModifierType(randStat);
});
}
@ -1002,7 +999,7 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator {
if (pregenArgs && (pregenArgs.length === 1) && TEMP_BATTLE_STATS.includes(pregenArgs[0])) {
return new TempStatStageBoosterModifierType(pregenArgs[0]);
}
const randStat: TempBattleStat = Utils.randSeedInt(Stat.ACC, Stat.ATK);
const randStat: TempBattleStat = randSeedInt(Stat.ACC, Stat.ATK);
return new TempStatStageBoosterModifierType(randStat);
});
}
@ -1017,10 +1014,10 @@ class TempStatStageBoosterModifierTypeGenerator extends ModifierTypeGenerator {
class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
/** Object comprised of the currently available species-based stat boosting held items */
public static readonly items = {
LIGHT_BALL: { stats: [Stat.ATK, Stat.SPATK], multiplier: 2, species: [Species.PIKACHU] },
THICK_CLUB: { stats: [Stat.ATK], multiplier: 2, species: [Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK] },
METAL_POWDER: { stats: [Stat.DEF], multiplier: 2, species: [Species.DITTO] },
QUICK_POWDER: { stats: [Stat.SPD], multiplier: 2, species: [Species.DITTO] },
LIGHT_BALL: { stats: [ Stat.ATK, Stat.SPATK ], multiplier: 2, species: [ Species.PIKACHU ]},
THICK_CLUB: { stats: [ Stat.ATK ], multiplier: 2, species: [ Species.CUBONE, Species.MAROWAK, Species.ALOLA_MAROWAK ]},
METAL_POWDER: { stats: [ Stat.DEF ], multiplier: 2, species: [ Species.DITTO ]},
QUICK_POWDER: { stats: [ Stat.SPD ], multiplier: 2, species: [ Species.DITTO ]},
};
constructor() {
@ -1044,8 +1041,8 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
const checkedStats = values[i].stats;
// If party member already has the item being weighted currently, skip to the next item
const hasItem = p.getHeldItems().some(m => m instanceof Modifiers.SpeciesStatBoosterModifier
&& (m as Modifiers.SpeciesStatBoosterModifier).contains(checkedSpecies[0], checkedStats[0]));
const hasItem = p.getHeldItems().some(m => m instanceof SpeciesStatBoosterModifier
&& (m as SpeciesStatBoosterModifier).contains(checkedSpecies[0], checkedStats[0]));
if (!hasItem) {
if (checkedSpecies.includes(speciesId) || (!!fusionSpeciesId && checkedSpecies.includes(fusionSpeciesId))) {
@ -1065,7 +1062,7 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
}
if (totalWeight !== 0) {
const randInt = Utils.randSeedInt(totalWeight, 1);
const randInt = randSeedInt(totalWeight, 1);
let weight = 0;
for (const i in weights) {
@ -1095,7 +1092,7 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator {
if (!tierUniqueCompatibleTms.length) {
return null;
}
const randTmIndex = Utils.randSeedInt(tierUniqueCompatibleTms.length);
const randTmIndex = randSeedInt(tierUniqueCompatibleTms.length);
return new TmModifierType(tierUniqueCompatibleTms[randTmIndex]);
});
}
@ -1123,7 +1120,7 @@ class EvolutionItemModifierTypeGenerator extends ModifierTypeGenerator {
return null;
}
return new EvolutionItemModifierType(evolutionItemPool[Utils.randSeedInt(evolutionItemPool.length)]!); // TODO: is the bang correct?
return new EvolutionItemModifierType(evolutionItemPool[randSeedInt(evolutionItemPool.length)]!); // TODO: is the bang correct?
});
}
}
@ -1135,14 +1132,14 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
return new FormChangeItemModifierType(pregenArgs[0] as FormChangeItem);
}
const formChangeItemPool = [...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChangeItemPool = [ ...new Set(party.filter(p => pokemonFormChanges.hasOwnProperty(p.species.speciesId)).map(p => {
const formChanges = pokemonFormChanges[p.species.speciesId];
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(Modifiers.MegaEvolutionAccessModifier).length)
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(Modifiers.GigantamaxAccessModifier).length)
let formChangeItemTriggers = formChanges.filter(fc => ((fc.formKey.indexOf(SpeciesFormKey.MEGA) === -1 && fc.formKey.indexOf(SpeciesFormKey.PRIMAL) === -1) || party[0].scene.getModifiers(MegaEvolutionAccessModifier).length)
&& ((fc.formKey.indexOf(SpeciesFormKey.GIGANTAMAX) === -1 && fc.formKey.indexOf(SpeciesFormKey.ETERNAMAX) === -1) || party[0].scene.getModifiers(GigantamaxAccessModifier).length)
&& (!fc.conditions.length || fc.conditions.filter(cond => cond instanceof SpeciesFormChangeCondition && cond.predicate(p)).length)
&& (fc.preFormKey === p.getFormKey()))
.map(fc => fc.findTrigger(SpeciesFormChangeItemTrigger) as SpeciesFormChangeItemTrigger)
.filter(t => t && t.active && !p.scene.findModifier(m => m instanceof Modifiers.PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item));
.filter(t => t && t.active && !p.scene.findModifier(m => m instanceof PokemonFormChangeItemModifier && m.pokemonId === p.id && m.formChangeItem === t.item));
if (p.species.speciesId === Species.NECROZMA) {
// technically we could use a simplified version and check for formChanges.length > 3, but in case any code changes later, this might break...
@ -1177,7 +1174,7 @@ class FormChangeItemModifierTypeGenerator extends ModifierTypeGenerator {
return null;
}
return new FormChangeItemModifierType(formChangeItemPool[Utils.randSeedInt(formChangeItemPool.length)]);
return new FormChangeItemModifierType(formChangeItemPool[randSeedInt(formChangeItemPool.length)]);
});
}
}
@ -1186,7 +1183,7 @@ export class TerastallizeModifierType extends PokemonHeldItemModifierType implem
private teraType: Type;
constructor(teraType: Type) {
super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new Modifiers.TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard");
super("", `${Type[teraType].toLowerCase()}_tera_shard`, (type, args) => new TerastallizeModifier(type as TerastallizeModifierType, (args[0] as Pokemon).id, teraType), "tera_shard");
this.teraType = teraType;
}
@ -1208,7 +1205,7 @@ export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemMo
private chancePercent: integer;
constructor(localeKey: string, iconImage: string, chancePercent: integer, group?: string, soundName?: string) {
super(localeKey, iconImage, (type, args) => new Modifiers.ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), group, soundName);
super(localeKey, iconImage, (type, args) => new ContactHeldItemTransferChanceModifier(type, (args[0] as Pokemon).id, chancePercent), group, soundName);
this.chancePercent = chancePercent;
}
@ -1220,7 +1217,7 @@ export class ContactHeldItemTransferChanceModifierType extends PokemonHeldItemMo
export class TurnHeldItemTransferModifierType extends PokemonHeldItemModifierType {
constructor(localeKey: string, iconImage: string, group?: string, soundName?: string) {
super(localeKey, iconImage, (type, args) => new Modifiers.TurnHeldItemTransferModifier(type, (args[0] as Pokemon).id), group, soundName);
super(localeKey, iconImage, (type, args) => new TurnHeldItemTransferModifier(type, (args[0] as Pokemon).id), group, soundName);
}
getDescription(scene: BattleScene): string {
@ -1233,7 +1230,7 @@ export class EnemyAttackStatusEffectChanceModifierType extends ModifierType {
private effect: StatusEffect;
constructor(localeKey: string, iconImage: string, chancePercent: integer, effect: StatusEffect, stackCount?: integer) {
super(localeKey, iconImage, (type, args) => new Modifiers.EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance");
super(localeKey, iconImage, (type, args) => new EnemyAttackStatusEffectChanceModifier(type, effect, chancePercent, stackCount), "enemy_status_chance");
this.chancePercent = chancePercent;
this.effect = effect;
@ -1251,7 +1248,7 @@ export class EnemyEndureChanceModifierType extends ModifierType {
private chancePercent: number;
constructor(localeKey: string, iconImage: string, chancePercent: number) {
super(localeKey, iconImage, (type, _args) => new Modifiers.EnemyEndureChanceModifier(type, chancePercent), "enemy_endure");
super(localeKey, iconImage, (type, _args) => new EnemyEndureChanceModifier(type, chancePercent), "enemy_endure");
this.chancePercent = chancePercent;
}
@ -1298,7 +1295,7 @@ function skipInLastClassicWaveOrDefault(defaultWeight: integer) : WeightedModifi
*/
function lureWeightFunc(maxBattles: number, weight: number): WeightedModifierTypeWeightFunc {
return (party: Pokemon[]) => {
const lures = party[0].scene.getModifiers(Modifiers.DoubleBattleChanceBoosterModifier);
const lures = party[0].scene.getModifiers(DoubleBattleChanceBoosterModifier);
return !(party[0].scene.gameMode.isClassic && party[0].scene.currentBattle.waveIndex === 199) && (lures.length === 0 || lures.filter(m => m.getMaxBattles() === maxBattles && m.getBattleCount() >= maxBattles * 0.6).length === 0) ? weight : 0;
};
}
@ -1388,13 +1385,13 @@ export const modifierTypes = {
RARE_FORM_CHANGE_ITEM: () => new FormChangeItemModifierTypeGenerator(true),
EVOLUTION_TRACKER_GIMMIGHOUL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVOLUTION_TRACKER_GIMMIGHOUL", "relic_gold",
(type, args) => new Modifiers.EvoTrackerModifier(type, (args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)),
(type, args) => new EvoTrackerModifier(type, (args[0] as Pokemon).id, Species.GIMMIGHOUL, 10)),
MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new Modifiers.MegaEvolutionAccessModifier(type)),
DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new Modifiers.GigantamaxAccessModifier(type)),
TERA_ORB: () => new ModifierType("modifierType:ModifierType.TERA_ORB", "tera_orb", (type, _args) => new Modifiers.TerastallizeAccessModifier(type)),
MEGA_BRACELET: () => new ModifierType("modifierType:ModifierType.MEGA_BRACELET", "mega_bracelet", (type, _args) => new MegaEvolutionAccessModifier(type)),
DYNAMAX_BAND: () => new ModifierType("modifierType:ModifierType.DYNAMAX_BAND", "dynamax_band", (type, _args) => new GigantamaxAccessModifier(type)),
TERA_ORB: () => new ModifierType("modifierType:ModifierType.TERA_ORB", "tera_orb", (type, _args) => new TerastallizeAccessModifier(type)),
MAP: () => new ModifierType("modifierType:ModifierType.MAP", "map", (type, _args) => new Modifiers.MapModifier(type)),
MAP: () => new ModifierType("modifierType:ModifierType.MAP", "map", (type, _args) => new MapModifier(type)),
POTION: () => new PokemonHpRestoreModifierType("modifierType:ModifierType.POTION", "potion", 20, 10),
SUPER_POTION: () => new PokemonHpRestoreModifierType("modifierType:ModifierType.SUPER_POTION", "super_potion", 50, 25),
@ -1409,8 +1406,8 @@ export const modifierTypes = {
SACRED_ASH: () => new AllPokemonFullReviveModifierType("modifierType:ModifierType.SACRED_ASH", "sacred_ash"),
REVIVER_SEED: () => new PokemonHeldItemModifierType("modifierType:ModifierType.REVIVER_SEED", "reviver_seed", (type, args) => new Modifiers.PokemonInstantReviveModifier(type, (args[0] as Pokemon).id)),
WHITE_HERB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.WHITE_HERB", "white_herb", (type, args) => new Modifiers.ResetNegativeStatStageModifier(type, (args[0] as Pokemon).id)),
REVIVER_SEED: () => new PokemonHeldItemModifierType("modifierType:ModifierType.REVIVER_SEED", "reviver_seed", (type, args) => new PokemonInstantReviveModifier(type, (args[0] as Pokemon).id)),
WHITE_HERB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.WHITE_HERB", "white_herb", (type, args) => new ResetNegativeStatStageModifier(type, (args[0] as Pokemon).id)),
ETHER: () => new PokemonPpRestoreModifierType("modifierType:ModifierType.ETHER", "ether", 10),
MAX_ETHER: () => new PokemonPpRestoreModifierType("modifierType:ModifierType.MAX_ETHER", "max_ether", -1),
@ -1440,7 +1437,7 @@ export const modifierTypes = {
amount: i18next.t("modifierType:ModifierType.TempStatStageBoosterModifierType.extra.stage")
});
}
}("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new Modifiers.TempCritBoosterModifier(type, 5)),
}("modifierType:ModifierType.DIRE_HIT", "dire_hit", (type, _args) => new TempCritBoosterModifier(type, 5)),
BASE_STAT_BOOSTER: () => new BaseStatBoosterModifierTypeGenerator(),
@ -1450,22 +1447,22 @@ export const modifierTypes = {
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Nature)) {
return new PokemonNatureChangeModifierType(pregenArgs[0] as Nature);
}
return new PokemonNatureChangeModifierType(Utils.randSeedInt(Utils.getEnumValues(Nature).length) as Nature);
return new PokemonNatureChangeModifierType(randSeedInt(getEnumValues(Nature).length) as Nature);
}),
TERA_SHARD: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Type)) {
return new TerastallizeModifierType(pregenArgs[0] as Type);
}
if (!party[0].scene.getModifiers(Modifiers.TerastallizeAccessModifier).length) {
if (!party[0].scene.getModifiers(TerastallizeAccessModifier).length) {
return null;
}
let type: Type;
if (!Utils.randSeedInt(3)) {
if (!randSeedInt(3)) {
const partyMemberTypes = party.map(p => p.getTypes(false, false, true)).flat();
type = Utils.randSeedItem(partyMemberTypes);
type = randSeedItem(partyMemberTypes);
} else {
type = Utils.randSeedInt(64) ? Utils.randSeedInt(18) as Type : Type.STELLAR;
type = randSeedInt(64) ? randSeedInt(18) as Type : Type.STELLAR;
}
return new TerastallizeModifierType(type);
}),
@ -1474,9 +1471,9 @@ export const modifierTypes = {
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in BerryType)) {
return new BerryModifierType(pregenArgs[0] as BerryType);
}
const berryTypes = Utils.getEnumValues(BerryType);
const berryTypes = getEnumValues(BerryType);
let randBerryType: BerryType;
const rand = Utils.randSeedInt(12);
const rand = randSeedInt(12);
if (rand < 2) {
randBerryType = BerryType.SITRUS;
} else if (rand < 4) {
@ -1484,7 +1481,7 @@ export const modifierTypes = {
} else if (rand < 6) {
randBerryType = BerryType.LEPPA;
} else {
randBerryType = berryTypes[Utils.randSeedInt(berryTypes.length - 3) + 2];
randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2];
}
return new BerryModifierType(randBerryType);
}),
@ -1495,10 +1492,10 @@ export const modifierTypes = {
MEMORY_MUSHROOM: () => new RememberMoveModifierType("modifierType:ModifierType.MEMORY_MUSHROOM", "big_mushroom"),
EXP_SHARE: () => new ModifierType("modifierType:ModifierType.EXP_SHARE", "exp_share", (type, _args) => new Modifiers.ExpShareModifier(type)),
EXP_BALANCE: () => new ModifierType("modifierType:ModifierType.EXP_BALANCE", "exp_balance", (type, _args) => new Modifiers.ExpBalanceModifier(type)),
EXP_SHARE: () => new ModifierType("modifierType:ModifierType.EXP_SHARE", "exp_share", (type, _args) => new ExpShareModifier(type)),
EXP_BALANCE: () => new ModifierType("modifierType:ModifierType.EXP_BALANCE", "exp_balance", (type, _args) => new ExpBalanceModifier(type)),
OVAL_CHARM: () => new ModifierType("modifierType:ModifierType.OVAL_CHARM", "oval_charm", (type, _args) => new Modifiers.MultipleParticipantExpBonusModifier(type)),
OVAL_CHARM: () => new ModifierType("modifierType:ModifierType.OVAL_CHARM", "oval_charm", (type, _args) => new MultipleParticipantExpBonusModifier(type)),
EXP_CHARM: () => new ExpBoosterModifierType("modifierType:ModifierType.EXP_CHARM", "exp_charm", 25),
SUPER_EXP_CHARM: () => new ExpBoosterModifierType("modifierType:ModifierType.SUPER_EXP_CHARM", "super_exp_charm", 60),
@ -1509,51 +1506,51 @@ export const modifierTypes = {
SOOTHE_BELL: () => new PokemonFriendshipBoosterModifierType("modifierType:ModifierType.SOOTHE_BELL", "soothe_bell"),
SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new Modifiers.CritBoosterModifier(type, (args[0] as Pokemon).id, 1)),
LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new Modifiers.SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD])),
SCOPE_LENS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SCOPE_LENS", "scope_lens", (type, args) => new CritBoosterModifier(type, (args[0] as Pokemon).id, 1)),
LEEK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEEK", "leek", (type, args) => new SpeciesCritBoosterModifier(type, (args[0] as Pokemon).id, 2, [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ])),
EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new Modifiers.EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [Stat.DEF, Stat.SPDEF], 1.5)),
EVIOLITE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.EVIOLITE", "eviolite", (type, args) => new EvolutionStatBoosterModifier(type, (args[0] as Pokemon).id, [ Stat.DEF, Stat.SPDEF ], 1.5)),
SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new Modifiers.PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)),
SOUL_DEW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SOUL_DEW", "soul_dew", (type, args) => new PokemonNatureWeightModifier(type, (args[0] as Pokemon).id)),
NUGGET: () => new MoneyRewardModifierType("modifierType:ModifierType.NUGGET", "nugget", 1, "modifierType:ModifierType.MoneyRewardModifierType.extra.small"),
BIG_NUGGET: () => new MoneyRewardModifierType("modifierType:ModifierType.BIG_NUGGET", "big_nugget", 2.5, "modifierType:ModifierType.MoneyRewardModifierType.extra.moderate"),
RELIC_GOLD: () => new MoneyRewardModifierType("modifierType:ModifierType.RELIC_GOLD", "relic_gold", 10, "modifierType:ModifierType.MoneyRewardModifierType.extra.large"),
AMULET_COIN: () => new ModifierType("modifierType:ModifierType.AMULET_COIN", "amulet_coin", (type, _args) => new Modifiers.MoneyMultiplierModifier(type)),
GOLDEN_PUNCH: () => new PokemonHeldItemModifierType("modifierType:ModifierType.GOLDEN_PUNCH", "golden_punch", (type, args) => new Modifiers.DamageMoneyRewardModifier(type, (args[0] as Pokemon).id)),
COIN_CASE: () => new ModifierType("modifierType:ModifierType.COIN_CASE", "coin_case", (type, _args) => new Modifiers.MoneyInterestModifier(type)),
AMULET_COIN: () => new ModifierType("modifierType:ModifierType.AMULET_COIN", "amulet_coin", (type, _args) => new MoneyMultiplierModifier(type)),
GOLDEN_PUNCH: () => new PokemonHeldItemModifierType("modifierType:ModifierType.GOLDEN_PUNCH", "golden_punch", (type, args) => new DamageMoneyRewardModifier(type, (args[0] as Pokemon).id)),
COIN_CASE: () => new ModifierType("modifierType:ModifierType.COIN_CASE", "coin_case", (type, _args) => new MoneyInterestModifier(type)),
LOCK_CAPSULE: () => new ModifierType("modifierType:ModifierType.LOCK_CAPSULE", "lock_capsule", (type, _args) => new Modifiers.LockModifierTiersModifier(type)),
LOCK_CAPSULE: () => new ModifierType("modifierType:ModifierType.LOCK_CAPSULE", "lock_capsule", (type, _args) => new LockModifierTiersModifier(type)),
GRIP_CLAW: () => new ContactHeldItemTransferChanceModifierType("modifierType:ModifierType.GRIP_CLAW", "grip_claw", 10),
WIDE_LENS: () => new PokemonMoveAccuracyBoosterModifierType("modifierType:ModifierType.WIDE_LENS", "wide_lens", 5),
MULTI_LENS: () => new PokemonMultiHitModifierType("modifierType:ModifierType.MULTI_LENS", "zoom_lens"),
HEALING_CHARM: () => new ModifierType("modifierType:ModifierType.HEALING_CHARM", "healing_charm", (type, _args) => new Modifiers.HealingBoosterModifier(type, 1.1)),
CANDY_JAR: () => new ModifierType("modifierType:ModifierType.CANDY_JAR", "candy_jar", (type, _args) => new Modifiers.LevelIncrementBoosterModifier(type)),
HEALING_CHARM: () => new ModifierType("modifierType:ModifierType.HEALING_CHARM", "healing_charm", (type, _args) => new HealingBoosterModifier(type, 1.1)),
CANDY_JAR: () => new ModifierType("modifierType:ModifierType.CANDY_JAR", "candy_jar", (type, _args) => new LevelIncrementBoosterModifier(type)),
BERRY_POUCH: () => new ModifierType("modifierType:ModifierType.BERRY_POUCH", "berry_pouch", (type, _args) => new Modifiers.PreserveBerryModifier(type)),
BERRY_POUCH: () => new ModifierType("modifierType:ModifierType.BERRY_POUCH", "berry_pouch", (type, _args) => new PreserveBerryModifier(type)),
FOCUS_BAND: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FOCUS_BAND", "focus_band", (type, args) => new Modifiers.SurviveDamageModifier(type, (args[0] as Pokemon).id)),
FOCUS_BAND: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FOCUS_BAND", "focus_band", (type, args) => new SurviveDamageModifier(type, (args[0] as Pokemon).id)),
QUICK_CLAW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.QUICK_CLAW", "quick_claw", (type, args) => new Modifiers.BypassSpeedChanceModifier(type, (args[0] as Pokemon).id)),
QUICK_CLAW: () => new PokemonHeldItemModifierType("modifierType:ModifierType.QUICK_CLAW", "quick_claw", (type, args) => new BypassSpeedChanceModifier(type, (args[0] as Pokemon).id)),
KINGS_ROCK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.KINGS_ROCK", "kings_rock", (type, args) => new Modifiers.FlinchChanceModifier(type, (args[0] as Pokemon).id)),
KINGS_ROCK: () => new PokemonHeldItemModifierType("modifierType:ModifierType.KINGS_ROCK", "kings_rock", (type, args) => new FlinchChanceModifier(type, (args[0] as Pokemon).id)),
LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new Modifiers.TurnHealModifier(type, (args[0] as Pokemon).id)),
SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new Modifiers.HitHealModifier(type, (args[0] as Pokemon).id)),
LEFTOVERS: () => new PokemonHeldItemModifierType("modifierType:ModifierType.LEFTOVERS", "leftovers", (type, args) => new TurnHealModifier(type, (args[0] as Pokemon).id)),
SHELL_BELL: () => new PokemonHeldItemModifierType("modifierType:ModifierType.SHELL_BELL", "shell_bell", (type, args) => new HitHealModifier(type, (args[0] as Pokemon).id)),
TOXIC_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.TOXIC_ORB", "toxic_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
FLAME_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FLAME_ORB", "flame_orb", (type, args) => new Modifiers.TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
TOXIC_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.TOXIC_ORB", "toxic_orb", (type, args) => new TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
FLAME_ORB: () => new PokemonHeldItemModifierType("modifierType:ModifierType.FLAME_ORB", "flame_orb", (type, args) => new TurnStatusEffectModifier(type, (args[0] as Pokemon).id)),
BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "baton", (type, args) => new Modifiers.SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)),
BATON: () => new PokemonHeldItemModifierType("modifierType:ModifierType.BATON", "baton", (type, args) => new SwitchEffectTransferModifier(type, (args[0] as Pokemon).id)),
SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new Modifiers.ShinyRateBoosterModifier(type)),
ABILITY_CHARM: () => new ModifierType("modifierType:ModifierType.ABILITY_CHARM", "ability_charm", (type, _args) => new Modifiers.HiddenAbilityRateBoosterModifier(type)),
SHINY_CHARM: () => new ModifierType("modifierType:ModifierType.SHINY_CHARM", "shiny_charm", (type, _args) => new ShinyRateBoosterModifier(type)),
ABILITY_CHARM: () => new ModifierType("modifierType:ModifierType.ABILITY_CHARM", "ability_charm", (type, _args) => new HiddenAbilityRateBoosterModifier(type)),
IV_SCANNER: () => new ModifierType("modifierType:ModifierType.IV_SCANNER", "scanner", (type, _args) => new Modifiers.IvScannerModifier(type)),
IV_SCANNER: () => new ModifierType("modifierType:ModifierType.IV_SCANNER", "scanner", (type, _args) => new IvScannerModifier(type)),
DNA_SPLICERS: () => new FusePokemonModifierType("modifierType:ModifierType.DNA_SPLICERS", "dna_splicers"),
@ -1563,39 +1560,39 @@ export const modifierTypes = {
VOUCHER_PLUS: () => new AddVoucherModifierType(VoucherType.PLUS, 1),
VOUCHER_PREMIUM: () => new AddVoucherModifierType(VoucherType.PREMIUM, 1),
GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new Modifiers.ExtraModifierModifier(type), undefined, "se/pb_bounce_1"),
GOLDEN_POKEBALL: () => new ModifierType("modifierType:ModifierType.GOLDEN_POKEBALL", "pb_gold", (type, _args) => new ExtraModifierModifier(type), undefined, "se/pb_bounce_1"),
ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new Modifiers.EnemyDamageBoosterModifier(type, 5)),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new Modifiers.EnemyDamageReducerModifier(type, 2.5)),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new Modifiers.EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new Modifiers.EnemyTurnHealModifier(type, 2, 10)),
ENEMY_DAMAGE_BOOSTER: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_BOOSTER", "wl_item_drop", (type, _args) => new EnemyDamageBoosterModifier(type, 5)),
ENEMY_DAMAGE_REDUCTION: () => new ModifierType("modifierType:ModifierType.ENEMY_DAMAGE_REDUCTION", "wl_guard_spec", (type, _args) => new EnemyDamageReducerModifier(type, 2.5)),
//ENEMY_SUPER_EFFECT_BOOSTER: () => new ModifierType('Type Advantage Token', 'Increases damage of super effective attacks by 30%', (type, _args) => new EnemySuperEffectiveDamageBoosterModifier(type, 30), 'wl_custom_super_effective'),
ENEMY_HEAL: () => new ModifierType("modifierType:ModifierType.ENEMY_HEAL", "wl_potion", (type, _args) => new EnemyTurnHealModifier(type, 2, 10)),
ENEMY_ATTACK_POISON_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_POISON_CHANCE", "wl_antidote", 5, StatusEffect.POISON, 10),
ENEMY_ATTACK_PARALYZE_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_PARALYZE_CHANCE", "wl_paralyze_heal", 2.5, StatusEffect.PARALYSIS, 10),
ENEMY_ATTACK_BURN_CHANCE: () => new EnemyAttackStatusEffectChanceModifierType("modifierType:ModifierType.ENEMY_ATTACK_BURN_CHANCE", "wl_burn_heal", 5, StatusEffect.BURN, 10),
ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new Modifiers.EnemyStatusEffectHealChanceModifier(type, 2.5, 10)),
ENEMY_STATUS_EFFECT_HEAL_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_STATUS_EFFECT_HEAL_CHANCE", "wl_full_heal", (type, _args) => new EnemyStatusEffectHealChanceModifier(type, 2.5, 10)),
ENEMY_ENDURE_CHANCE: () => new EnemyEndureChanceModifierType("modifierType:ModifierType.ENEMY_ENDURE_CHANCE", "wl_reset_urge", 2),
ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new Modifiers.EnemyFusionChanceModifier(type, 1)),
ENEMY_FUSED_CHANCE: () => new ModifierType("modifierType:ModifierType.ENEMY_FUSED_CHANCE", "wl_custom_spliced", (type, _args) => new EnemyFusionChanceModifier(type, 1)),
MYSTERY_ENCOUNTER_SHUCKLE_JUICE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs) {
return new PokemonBaseStatTotalModifierType(pregenArgs[0] as number);
}
return new PokemonBaseStatTotalModifierType(Utils.randSeedInt(20));
return new PokemonBaseStatTotalModifierType(randSeedInt(20));
}),
MYSTERY_ENCOUNTER_OLD_GATEAU: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs) {
return new PokemonBaseStatFlatModifierType(pregenArgs[0] as number, pregenArgs[1] as Stat[]);
}
return new PokemonBaseStatFlatModifierType(Utils.randSeedInt(20), [Stat.HP, Stat.ATK, Stat.DEF]);
return new PokemonBaseStatFlatModifierType(randSeedInt(20), [ Stat.HP, Stat.ATK, Stat.DEF ]);
}),
MYSTERY_ENCOUNTER_BLACK_SLUDGE: () => new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
if (pregenArgs) {
return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.HealShopCostModifier(type, pregenArgs[0] as number));
return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new HealShopCostModifier(type, pregenArgs[0] as number));
}
return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new Modifiers.HealShopCostModifier(type, 2.5));
return new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_BLACK_SLUDGE", "black_sludge", (type, _args) => new HealShopCostModifier(type, 2.5));
}),
MYSTERY_ENCOUNTER_MACHO_BRACE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_MACHO_BRACE", "macho_brace", (type, args) => new Modifiers.PokemonIncrementingStatModifier(type, (args[0] as Pokemon).id)),
MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new Modifiers.BoostBugSpawnModifier(type)),
MYSTERY_ENCOUNTER_MACHO_BRACE: () => new PokemonHeldItemModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_MACHO_BRACE", "macho_brace", (type, args) => new PokemonIncrementingStatModifier(type, (args[0] as Pokemon).id)),
MYSTERY_ENCOUNTER_GOLDEN_BUG_NET: () => new ModifierType("modifierType:ModifierType.MYSTERY_ENCOUNTER_GOLDEN_BUG_NET", "golden_net", (type, _args) => new BoostBugSpawnModifier(type)),
};
interface ModifierPool {
@ -1644,8 +1641,8 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.PP_UP, 2),
new WeightedModifierType(modifierTypes.FULL_HEAL, (party: Pokemon[]) => {
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => {
if (i instanceof Modifiers.TurnStatusEffectModifier) {
return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status?.effect;
if (i instanceof TurnStatusEffectModifier) {
return (i as TurnStatusEffectModifier).getStatusEffect() === p.status?.effect;
}
return false;
})).length, 3);
@ -1672,8 +1669,8 @@ const modifierPool: ModifierPool = {
}, 3),
new WeightedModifierType(modifierTypes.FULL_RESTORE, (party: Pokemon[]) => {
const statusEffectPartyMemberCount = Math.min(party.filter(p => p.hp && !!p.status && !p.getHeldItems().some(i => {
if (i instanceof Modifiers.TurnStatusEffectModifier) {
return (i as Modifiers.TurnStatusEffectModifier).getStatusEffect() === p.status?.effect;
if (i instanceof TurnStatusEffectModifier) {
return (i as TurnStatusEffectModifier).getStatusEffect() === p.status?.effect;
}
return false;
})).length, 3);
@ -1723,7 +1720,7 @@ const modifierPool: ModifierPool = {
const { gameMode, gameData } = party[0].scene;
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
return party.some(p => ((p.getSpeciesForm(true).speciesId in pokemonEvolutions) || (p.isFusion() && (p.getFusionSpeciesForm(true).speciesId in pokemonEvolutions)))
&& !p.getHeldItems().some(i => i instanceof Modifiers.EvolutionStatBoosterModifier) && !p.isMax()) ? 10 : 0;
&& !p.getHeldItems().some(i => i instanceof EvolutionStatBoosterModifier) && !p.isMax()) ? 10 : 0;
}
return 0;
}),
@ -1731,29 +1728,29 @@ const modifierPool: ModifierPool = {
new WeightedModifierType(modifierTypes.LEEK, (party: Pokemon[]) => {
const checkedSpecies = [ Species.FARFETCHD, Species.GALAR_FARFETCHD, Species.SIRFETCHD ];
// If a party member doesn't already have a Leek and is one of the relevant species, Leek can appear
return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.SpeciesCritBoosterModifier)
return party.some(p => !p.getHeldItems().some(i => i instanceof SpeciesCritBoosterModifier)
&& (checkedSpecies.includes(p.getSpeciesForm(true).speciesId)
|| (p.isFusion() && checkedSpecies.includes(p.getFusionSpeciesForm(true).speciesId)))) ? 12 : 0;
}, 12),
new WeightedModifierType(modifierTypes.TOXIC_ORB, (party: Pokemon[]) => {
const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD];
const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.TOXIC_BOOST, Abilities.POISON_HEAL, Abilities.MAGIC_GUARD ];
const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ];
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier)
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
&& (checkedAbilities.some(a => p.hasAbility(a, false, true))
|| p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
}, 10),
new WeightedModifierType(modifierTypes.FLAME_ORB, (party: Pokemon[]) => {
const checkedAbilities = [Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD];
const checkedMoves = [Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT];
const checkedAbilities = [ Abilities.QUICK_FEET, Abilities.GUTS, Abilities.MARVEL_SCALE, Abilities.FLARE_BOOST, Abilities.MAGIC_GUARD ];
const checkedMoves = [ Moves.FACADE, Moves.TRICK, Moves.FLING, Moves.SWITCHEROO, Moves.PSYCHO_SHIFT ];
// If a party member doesn't already have one of these two orbs and has one of the above moves or abilities, the orb can appear
return party.some(p => !p.getHeldItems().some(i => i instanceof Modifiers.TurnStatusEffectModifier)
return party.some(p => !p.getHeldItems().some(i => i instanceof TurnStatusEffectModifier)
&& (checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && checkedMoves.includes(m.moveId)))) ? 10 : 0;
}, 10),
new WeightedModifierType(modifierTypes.WHITE_HERB, (party: Pokemon[]) => {
const checkedAbilities = [Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT];
const checkedAbilities = [ Abilities.WEAK_ARMOR, Abilities.CONTRARY, Abilities.MOODY, Abilities.ANGER_SHELL, Abilities.COMPETITIVE, Abilities.DEFIANT ];
const weightMultiplier = party.filter(
p => !p.getHeldItems().some(i => i instanceof Modifiers.ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) &&
p => !p.getHeldItems().some(i => i instanceof ResetNegativeStatStageModifier && i.stackCount >= i.getMaxHeldItemCount(p)) &&
(checkedAbilities.some(a => p.hasAbility(a, false, true)) || p.getMoveset(true).some(m => m && selfStatLowerMoves.includes(m.moveId)))).length;
// If a party member has one of the above moves or abilities and doesn't have max herbs, the herb will appear more frequently
return 0 * (weightMultiplier ? 2 : 1) + (weightMultiplier ? weightMultiplier * 0 : 0);
@ -2199,7 +2196,7 @@ export function overridePlayerModifierTypeOptions(options: ModifierTypeOption[],
let modifierType: ModifierType | null = modifierFunc();
if (modifierType instanceof ModifierTypeGenerator) {
const pregenArgs = ("type" in override) && (override.type !== null) ? [override.type] : undefined;
const pregenArgs = ("type" in override) && (override.type !== null) ? [ override.type ] : undefined;
modifierType = modifierType.generateType(party, pregenArgs);
}
@ -2246,7 +2243,7 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: integer, base
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
}
export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: Modifiers.PersistentModifier[], scene: BattleScene): Modifiers.EnemyPersistentModifier {
export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers: PersistentModifier[], scene: BattleScene): EnemyPersistentModifier {
let tierStackCount: number;
switch (tier) {
case ModifierTier.ULTRA:
@ -2263,30 +2260,30 @@ export function getEnemyBuffModifierForWave(tier: ModifierTier, enemyModifiers:
const retryCount = 50;
let candidate = getNewModifierTypeOption([], ModifierPoolType.ENEMY_BUFF, tier);
let r = 0;
let matchingModifier: Modifiers.PersistentModifier | undefined;
let matchingModifier: PersistentModifier | undefined;
while (++r < retryCount && (matchingModifier = enemyModifiers.find(m => m.type.id === candidate?.type?.id)) && matchingModifier.getMaxStackCount(scene) < matchingModifier.stackCount + (r < 10 ? tierStackCount : 1)) {
candidate = getNewModifierTypeOption([], ModifierPoolType.ENEMY_BUFF, tier);
}
const modifier = candidate?.type?.newModifier() as Modifiers.EnemyPersistentModifier;
const modifier = candidate?.type?.newModifier() as EnemyPersistentModifier;
modifier.stackCount = tierStackCount;
return modifier;
}
export function getEnemyModifierTypesForWave(waveIndex: integer, count: integer, party: EnemyPokemon[], poolType: ModifierPoolType.WILD | ModifierPoolType.TRAINER, upgradeChance: integer = 0): PokemonHeldItemModifierType[] {
const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !Utils.randSeedInt(upgradeChance) ? 1 : 0)?.type as PokemonHeldItemModifierType);
const ret = new Array(count).fill(0).map(() => getNewModifierTypeOption(party, poolType, undefined, upgradeChance && !randSeedInt(upgradeChance) ? 1 : 0)?.type as PokemonHeldItemModifierType);
if (!(waveIndex % 1000)) {
ret.push(getModifierType(modifierTypes.MINI_BLACK_HOLE) as PokemonHeldItemModifierType);
}
return ret;
}
export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.PokemonHeldItemModifier[] {
const ret: Modifiers.PokemonHeldItemModifier[] = [];
export function getDailyRunStarterModifiers(party: PlayerPokemon[]): PokemonHeldItemModifier[] {
const ret: PokemonHeldItemModifier[] = [];
for (const p of party) {
for (let m = 0; m < 3; m++) {
const tierValue = Utils.randSeedInt(64);
const tierValue = randSeedInt(64);
let tier: ModifierTier;
if (tierValue > 25) {
@ -2301,7 +2298,7 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P
tier = ModifierTier.MASTER;
}
const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier)?.type?.newModifier(p) as Modifiers.PokemonHeldItemModifier;
const modifier = getNewModifierTypeOption(party, ModifierPoolType.DAILY_STARTER, tier)?.type?.newModifier(p) as PokemonHeldItemModifier;
ret.push(modifier);
}
}
@ -2340,7 +2337,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
break;
}
if (tier === undefined) {
const tierValue = Utils.randSeedInt(1024);
const tierValue = randSeedInt(1024);
if (!upgradeCount) {
upgradeCount = 0;
}
@ -2349,7 +2346,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4));
let upgraded = false;
do {
upgraded = Utils.randSeedInt(upgradeOdds) < 4;
upgraded = randSeedInt(upgradeOdds) < 4;
if (upgraded) {
upgradeCount++;
}
@ -2381,7 +2378,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
const partyShinyCount = party.filter(p => p.isShiny() && !p.isFainted()).length;
const upgradeOdds = Math.floor(32 / ((partyShinyCount + 2) / 2));
while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) {
if (!Utils.randSeedInt(upgradeOdds)) {
if (!randSeedInt(upgradeOdds)) {
upgradeCount++;
} else {
break;
@ -2396,7 +2393,7 @@ function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType,
const tierThresholds = Object.keys(thresholds[tier]);
const totalWeight = parseInt(tierThresholds[tierThresholds.length - 1]);
const value = Utils.randSeedInt(totalWeight);
const value = randSeedInt(totalWeight);
let index: integer | undefined;
for (const t of tierThresholds) {
const threshold = parseInt(t);
@ -2456,9 +2453,9 @@ export class ModifierTypeOption {
*/
export function getPartyLuckValue(party: Pokemon[]): integer {
if (party[0].scene.gameMode.isDaily) {
const DailyLuck = new Utils.NumberHolder(0);
const DailyLuck = new NumberHolder(0);
party[0].scene.executeWithSeedOffset(() => {
DailyLuck.value = Utils.randSeedInt(15); // Random number between 0 and 14
DailyLuck.value = randSeedInt(15); // Random number between 0 and 14
}, 0, party[0].scene.seed);
return DailyLuck.value;
}

File diff suppressed because it is too large Load Diff

View File

@ -100,6 +100,14 @@ class DefaultOverrides {
* @example SPECIES_OVERRIDE = Species.Bulbasaur;
*/
readonly STARTER_SPECIES_OVERRIDE: Species | number = 0;
/**
* This will force your starter to be a random fusion
*/
readonly STARTER_FUSION_OVERRIDE: boolean = false;
/**
* This will override the species of the fusion
*/
readonly STARTER_FUSION_SPECIES_OVERRIDE: Species | integer = 0;
readonly ABILITY_OVERRIDE: Abilities = Abilities.NONE;
readonly PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
readonly STATUS_OVERRIDE: StatusEffect = StatusEffect.NONE;
@ -112,6 +120,14 @@ class DefaultOverrides {
// OPPONENT / ENEMY OVERRIDES
// --------------------------
readonly OPP_SPECIES_OVERRIDE: Species | number = 0;
/**
* This will make all opponents fused Pokemon
*/
readonly OPP_FUSION_OVERRIDE: boolean = false;
/**
* This will override the species of the fusion only when the opponent is already a fusion
*/
readonly OPP_FUSION_SPECIES_OVERRIDE: Species | integer = 0;
readonly OPP_LEVEL_OVERRIDE: number = 0;
readonly OPP_ABILITY_OVERRIDE: Abilities = Abilities.NONE;
readonly OPP_PASSIVE_ABILITY_OVERRIDE: Abilities = Abilities.NONE;

View File

@ -248,7 +248,7 @@ export class AttemptCapturePhase extends PokemonPhase {
}
});
};
Promise.all([pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon)]).then(() => {
Promise.all([ pokemon.hideInfo(), this.scene.gameData.setPokemonCaught(pokemon) ]).then(() => {
if (this.scene.getParty().length === 6) {
const promptRelease = () => {
this.scene.ui.showText(i18next.t("battle:partyFull", { pokemonName: pokemon.getNameToRender() }), null, () => {

View File

@ -33,7 +33,7 @@ export class AttemptRunPhase extends PokemonPhase {
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
this.scene.tweens.add({
targets: [this.scene.arenaEnemy, enemyField].flat(),
targets: [ this.scene.arenaEnemy, enemyField ].flat(),
alpha: 0,
duration: 250,
ease: "Sine.easeIn",

View File

@ -57,7 +57,7 @@ export class BattleEndPhase extends BattlePhase {
if (m instanceof LapsingPokemonHeldItemModifier) {
args.push(this.scene.getPokemonById(m.pokemonId));
}
if (!m.lapse(args)) {
if (!m.lapse(...args)) {
this.scene.removeModifier(m);
}
}

View File

@ -12,7 +12,7 @@ export class BattlePhase extends Phase {
const tintSprites = this.scene.currentBattle.trainer?.getTintSprites()!; // TODO: is this bang correct?
for (let i = 0; i < sprites.length; i++) {
const visible = !trainerSlot || !i === (trainerSlot === TrainerSlot.TRAINER) || sprites.length < 2;
[sprites[i], tintSprites[i]].map(sprite => {
[ sprites[i], tintSprites[i] ].map(sprite => {
if (visible) {
sprite.x = trainerSlot || sprites.length < 2 ? 0 : i ? 16 : -16;
}

View File

@ -15,7 +15,7 @@ export class BerryPhase extends FieldPhase {
this.executeForAll((pokemon) => {
const hasUsableBerry = !!this.scene.findModifier((m) => {
return m instanceof BerryModifier && m.shouldApply([pokemon]);
return m instanceof BerryModifier && m.shouldApply(pokemon);
}, pokemon.isPlayer());
if (hasUsableBerry) {
@ -29,7 +29,7 @@ export class BerryPhase extends FieldPhase {
new CommonAnimPhase(this.scene, pokemon.getBattlerIndex(), pokemon.getBattlerIndex(), CommonAnim.USE_ITEM)
);
for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon) as BerryModifier[]) {
for (const berryModifier of this.scene.applyModifiers(BerryModifier, pokemon.isPlayer(), pokemon)) {
if (berryModifier.consumed) {
if (!--berryModifier.stackCount) {
this.scene.removeModifier(berryModifier);

View File

@ -2,7 +2,7 @@ import BattleScene from "#app/battle-scene";
import { TurnCommand, BattleType } from "#app/battle";
import { TrappedTag, EncoreTag } from "#app/data/battler-tags";
import { MoveTargetSet, getMoveTargets } from "#app/data/move";
import { speciesStarters } from "#app/data/pokemon-species";
import { speciesStarterCosts } from "#app/data/balance/starters";
import { Abilities } from "#app/enums/abilities";
import { BattlerTagType } from "#app/enums/battler-tag-type";
import { Biome } from "#app/enums/biome";
@ -93,7 +93,7 @@ export class CommandPhase extends FieldPhase {
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
if (!moveId) {
turnCommand.targets = [this.fieldIndex];
turnCommand.targets = [ this.fieldIndex ];
}
console.log(moveTargets, getPokemonNameWithAffix(playerPokemon));
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
@ -126,7 +126,7 @@ export class CommandPhase extends FieldPhase {
}
break;
case Command.BALL:
const notInDex = (this.scene.getEnemyField().filter(p => p.isActive(true)).some(p => !p.scene.gameData.dexData[p.species.speciesId].caughtAttr) && this.scene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarters).length - 1);
const notInDex = (this.scene.getEnemyField().filter(p => p.isActive(true)).some(p => !p.scene.gameData.dexData[p.species.speciesId].caughtAttr) && this.scene.gameData.getStarterCount(d => !!d.caughtAttr) < Object.keys(speciesStarterCosts).length - 1);
if (this.scene.arena.biomeType === Biome.END && (!this.scene.gameMode.isClassic || this.scene.gameMode.isFreshStartChallenge() || notInDex )) {
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
this.scene.ui.setMode(Mode.MESSAGE);

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