mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-12-15 06:15:20 +01:00
Merge branch 'beta' into cached-fetch
This commit is contained in:
commit
f2f8cc67ba
4
.gitignore
vendored
4
.gitignore
vendored
@ -20,6 +20,7 @@ build
|
||||
# Editor directories and files (excluding `extensions.json` for devcontainer)
|
||||
*.code-workspace
|
||||
.vscode/*
|
||||
.zed
|
||||
!.vscode/extensions.json
|
||||
!.vscode/spdx.code-snippets
|
||||
.idea
|
||||
@ -50,6 +51,5 @@ coverage
|
||||
/dependency-graph.svg
|
||||
/.vs
|
||||
|
||||
|
||||
# Script outputs
|
||||
./*.csv
|
||||
./*.csv
|
||||
|
||||
2
assets
2
assets
@ -1 +1 @@
|
||||
Subproject commit c5d6e54c2c8c0ba3d6c11fd6f3a1c1d07efd2c16
|
||||
Subproject commit d2d9309cd1acfcebeefbf4c1c63e1104a1294ed8
|
||||
@ -8,9 +8,9 @@ pre-commit:
|
||||
- rebase
|
||||
commands:
|
||||
biome-lint:
|
||||
# Disable colors as certain IDEs don't support it in the output pane.
|
||||
# Disable colors as certain IDEs (such as VSCode) don't support it in the output pane.
|
||||
# Summary mode looks decent in plain ASCII anyhow
|
||||
run: pnpm exec biome check --write --colors=off --reporter=summary --staged --no-errors-on-unmatched --diagnostic-level=error
|
||||
run: pnpm biome:staged --colors=off --reporter=summary
|
||||
stage_fixed: true
|
||||
ls-lint:
|
||||
run: pnpm exec ls-lint
|
||||
|
||||
2
locales
2
locales
@ -1 +1 @@
|
||||
Subproject commit 01a0aa4441b85221c61211eb1097d93e004f4334
|
||||
Subproject commit ddf9509e1c6abe8fc93b455d79bfaa0202e05ede
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "pokemon-rogue-battle",
|
||||
"private": true,
|
||||
"version": "1.10.7",
|
||||
"version": "1.11.2",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start:prod": "vite --mode production",
|
||||
@ -23,6 +23,7 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"typecheck:scripts": "tsc -p scripts/jsconfig.json",
|
||||
"biome": "biome check --write --changed --no-errors-on-unmatched --diagnostic-level=error",
|
||||
"biome:staged": "biome check --write --staged --no-errors-on-unmatched --diagnostic-level=error",
|
||||
"biome:all": "biome check --write --no-errors-on-unmatched --diagnostic-level=error",
|
||||
"biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched",
|
||||
"typedoc": "typedoc",
|
||||
@ -80,5 +81,5 @@
|
||||
"engines": {
|
||||
"node": ">=24.9.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.18.3"
|
||||
"packageManager": "pnpm@10.19.0"
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
onlyBuiltDependencies:
|
||||
- core-js
|
||||
- esbuild
|
||||
- msw
|
||||
- lefthook
|
||||
- msw
|
||||
|
||||
shellEmulator: true
|
||||
|
||||
98
src/@types/pokemon-common.ts
Normal file
98
src/@types/pokemon-common.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import type { PokemonSpecies, PokemonSpeciesFilter } from "#data/pokemon-species";
|
||||
import type { SpeciesId } from "#enums/species-id";
|
||||
import type { BooleanHolder } from "#utils/common";
|
||||
|
||||
/**
|
||||
* The type that {@linkcode PokemonSpeciesForm} is converted to when an object containing it serializes it.
|
||||
*/
|
||||
export type SerializedSpeciesForm = {
|
||||
id: SpeciesId;
|
||||
formIdx: number;
|
||||
};
|
||||
|
||||
export interface RandomEncounterParams {
|
||||
/** The level of the mon */
|
||||
level: number;
|
||||
|
||||
/** A custom function used to return the {@linkcode PokemonSpecies} to generate */
|
||||
speciesFunction?: () => PokemonSpecies;
|
||||
|
||||
/**
|
||||
* Whether the Pokemon should be a Boss.
|
||||
* @defaultValue `false`
|
||||
*/
|
||||
isBoss?: boolean;
|
||||
|
||||
/**
|
||||
* Whether Sub-legendaries can be encountered, mainly for event encounters
|
||||
* @defaultValue `true`
|
||||
*/
|
||||
includeSubLegendary?: boolean;
|
||||
|
||||
/**
|
||||
* Whether Legendaries can be encountered
|
||||
* @defaultValue `true`
|
||||
*/
|
||||
includeLegendary?: boolean;
|
||||
|
||||
/**
|
||||
* Whether Mythicals can be encountered
|
||||
* @defaultValue `true`
|
||||
*/
|
||||
includeMythical?: boolean;
|
||||
|
||||
/**
|
||||
* The chance out of 100 to pick an event encounter
|
||||
* @defaultValue `50`
|
||||
*/
|
||||
eventChance?: number;
|
||||
|
||||
/**
|
||||
* Number of rerolls for Hidden Ability (HA) that should be attempted
|
||||
* @defaultValue `0`
|
||||
*/
|
||||
hiddenRerolls?: number;
|
||||
|
||||
/**
|
||||
* Number of rerolls for shininess/variants that should be attempted
|
||||
* @defaultValue `0`
|
||||
*/
|
||||
shinyRerolls?: number;
|
||||
|
||||
/**
|
||||
* Number of extra HA rerolls for event mons
|
||||
* @defaultValue `0`
|
||||
*/
|
||||
eventHiddenRerolls?: number;
|
||||
|
||||
/**
|
||||
* Number of extra shiny rerolls for event mons
|
||||
* @defaultValue `0`
|
||||
*/
|
||||
eventShinyRerolls?: number;
|
||||
|
||||
/**
|
||||
* The overridden HA chance, defaults to base
|
||||
*/
|
||||
hiddenAbilityChance?: number;
|
||||
|
||||
/**
|
||||
* The overridden shiny chance, defaults to base
|
||||
*/
|
||||
shinyChance?: number;
|
||||
|
||||
/**
|
||||
* The max shiny threshold after modifiers are applied. Values below 1 mean no maximum
|
||||
* @defaultValue `0` (no maximum)
|
||||
*/
|
||||
maxShinyChance?: number;
|
||||
|
||||
/**
|
||||
* An optional filter for eligible mons, applied to the event encounter pool.
|
||||
* If omitted, no filter will be applied.
|
||||
*/
|
||||
speciesFilter?: PokemonSpeciesFilter;
|
||||
|
||||
/** An optional {@linkcode BooleanHolder} used to let the caller know if it pulled from an event. */
|
||||
isEventEncounter?: BooleanHolder;
|
||||
}
|
||||
@ -452,9 +452,17 @@ export class BattleScene extends SceneBase {
|
||||
true,
|
||||
);
|
||||
|
||||
//@ts-expect-error (the defined types in the package are incromplete...)
|
||||
// TODO: fix the typing in a `.d.ts` file so the `ts-ignore` is no longer necessary
|
||||
/* biome-ignore lint/suspicious/noTsIgnore: ts-ignore is necessary because `tsc` and `tsgo` require the directive to be on different lines,
|
||||
* meaning `@ts-expect-error` is guaranteed to emit a diagnostic on one of the lines depending on which one is used
|
||||
*/
|
||||
// @ts-ignore
|
||||
transition.transit({
|
||||
mode: "blinds",
|
||||
/* biome-ignore lint/suspicious/noTsIgnore: ts-ignore is necessary because `tsc` and `tsgo` require the directive to be on different lines,
|
||||
* meaning `@ts-expect-error` is guaranteed to emit a diagnostic on one of the lines depending on which one is used
|
||||
*/
|
||||
// @ts-ignore
|
||||
ease: "Cubic.easeInOut",
|
||||
duration: 1250,
|
||||
});
|
||||
@ -803,6 +811,10 @@ export class BattleScene extends SceneBase {
|
||||
* @param activeOnly - Whether to consider only active pokemon (as described by {@linkcode Pokemon.isActive()}); default `false`.
|
||||
* If `true`, will also remove all `null` values from the array.
|
||||
* @returns An array of {@linkcode Pokemon}, as described above.
|
||||
*
|
||||
* @remarks
|
||||
* This should *only* be used in instances where speed order is not relevant.
|
||||
* If speed order matters, use {@linkcode inSpeedOrder}.
|
||||
*/
|
||||
public getField(activeOnly = false): Pokemon[] {
|
||||
const ret: Pokemon[] = new Array(4).fill(null);
|
||||
@ -1621,6 +1633,7 @@ export class BattleScene extends SceneBase {
|
||||
case SpeciesId.UNOWN:
|
||||
case SpeciesId.SHELLOS:
|
||||
case SpeciesId.GASTRODON:
|
||||
case SpeciesId.ROTOM:
|
||||
case SpeciesId.BASCULIN:
|
||||
case SpeciesId.DEERLING:
|
||||
case SpeciesId.SAWSBUCK:
|
||||
@ -1640,11 +1653,10 @@ export class BattleScene extends SceneBase {
|
||||
case SpeciesId.TATSUGIRI:
|
||||
case SpeciesId.PALDEA_TAUROS:
|
||||
return randSeedInt(species.forms.length);
|
||||
case SpeciesId.MAUSHOLD:
|
||||
case SpeciesId.DUDUNSPARCE:
|
||||
return !randSeedInt(4) ? 1 : 0;
|
||||
case SpeciesId.SINISTEA:
|
||||
case SpeciesId.POLTEAGEIST:
|
||||
case SpeciesId.MAUSHOLD:
|
||||
case SpeciesId.DUDUNSPARCE:
|
||||
case SpeciesId.POLTCHAGEIST:
|
||||
case SpeciesId.SINISTCHA:
|
||||
return !randSeedInt(16) ? 1 : 0;
|
||||
@ -1714,7 +1726,6 @@ export class BattleScene extends SceneBase {
|
||||
switch (species.speciesId) {
|
||||
case SpeciesId.BURMY:
|
||||
case SpeciesId.WORMADAM:
|
||||
case SpeciesId.ROTOM:
|
||||
case SpeciesId.LYCANROC:
|
||||
return randSeedInt(species.forms.length);
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import { MoveCategory } from "#enums/move-category";
|
||||
import { MoveFlags } from "#enums/move-flags";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { MovePhaseTimingModifier } from "#enums/move-phase-timing-modifier";
|
||||
import { MovePriorityInBracket } from "#enums/move-priority-in-bracket";
|
||||
import { MoveResult } from "#enums/move-result";
|
||||
import { MoveTarget } from "#enums/move-target";
|
||||
import { MoveUseMode } from "#enums/move-use-mode";
|
||||
@ -66,6 +67,7 @@ import type { Constructor } from "#types/common";
|
||||
import type { Closed, Exact } from "#types/type-helpers";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import { BooleanHolder, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
@ -2857,7 +2859,7 @@ export class PostSummonStatStageChangeAbAttr extends PostSummonAbAttr {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
for (const opponent of pokemon.getOpponentsGenerator()) {
|
||||
const cancelled = new BooleanHolder(false);
|
||||
if (this.intimidate) {
|
||||
const params: AbAttrParamsWithCancel = { pokemon: opponent, cancelled, simulated };
|
||||
@ -3168,10 +3170,8 @@ export class PostSummonUserFieldRemoveStatusEffectAbAttr extends PostSummonAbAtt
|
||||
if (simulated) {
|
||||
return;
|
||||
}
|
||||
const party = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const allowedParty = party.filter(p => p.isAllowedInBattle());
|
||||
|
||||
for (const partyPokemon of allowedParty) {
|
||||
for (const partyPokemon of pokemon.getAlliesGenerator()) {
|
||||
if (partyPokemon.status && this.statusEffect.includes(partyPokemon.status.effect)) {
|
||||
globalScene.phaseManager.queueMessage(
|
||||
getStatusEffectHealText(partyPokemon.status.effect, getPokemonNameWithAffix(partyPokemon)),
|
||||
@ -4143,6 +4143,25 @@ export class ChangeMovePriorityAbAttr extends AbAttr {
|
||||
}
|
||||
}
|
||||
|
||||
export class ChangeMovePriorityInBracketAbAttr extends AbAttr {
|
||||
private readonly newModifier: MovePriorityInBracket;
|
||||
private readonly moveFunc: (pokemon: Pokemon, move: Move) => boolean;
|
||||
|
||||
constructor(moveFunc: (pokemon: Pokemon, move: Move) => boolean, newModifier: MovePriorityInBracket) {
|
||||
super(false);
|
||||
this.newModifier = newModifier;
|
||||
this.moveFunc = moveFunc;
|
||||
}
|
||||
|
||||
override canApply({ pokemon, move }: ChangeMovePriorityAbAttrParams): boolean {
|
||||
return this.moveFunc(pokemon, move);
|
||||
}
|
||||
|
||||
override apply({ priority }: ChangeMovePriorityAbAttrParams): void {
|
||||
priority.value = this.newModifier;
|
||||
}
|
||||
}
|
||||
|
||||
export class IgnoreContactAbAttr extends AbAttr {
|
||||
private declare readonly _: never;
|
||||
}
|
||||
@ -4214,28 +4233,26 @@ export class SuppressWeatherEffectAbAttr extends PreWeatherEffectAbAttr {
|
||||
/**
|
||||
* Condition function to applied to abilities related to Sheer Force.
|
||||
* Checks if last move used against target was affected by a Sheer Force user and:
|
||||
* Disables: Color Change, Pickpocket, Berserk, Anger Shell
|
||||
* Disables: Color Change, Pickpocket, Berserk, Anger Shell, Wimp Out, Emergency Exit
|
||||
* @returns An {@linkcode AbAttrCondition} to disable the ability under the proper conditions.
|
||||
*/
|
||||
function getSheerForceHitDisableAbCondition(): AbAttrCondition {
|
||||
return (pokemon: Pokemon) => {
|
||||
const lastReceivedAttack = pokemon.turnData.attacksReceived[0];
|
||||
if (!lastReceivedAttack) {
|
||||
return true;
|
||||
}
|
||||
const sheerForceHitDisableAbCondition: AbAttrCondition = (pokemon: Pokemon) => {
|
||||
const lastReceivedAttack = pokemon.turnData.attacksReceived[0];
|
||||
if (!lastReceivedAttack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const lastAttacker = pokemon.getOpponents().find(p => p.id === lastReceivedAttack.sourceId);
|
||||
if (!lastAttacker) {
|
||||
return true;
|
||||
}
|
||||
const lastAttacker = pokemon.getOpponents().find(p => p.id === lastReceivedAttack.sourceId);
|
||||
if (!lastAttacker) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** `true` if the last move's chance is above 0 and the last attacker's ability is sheer force */
|
||||
const SheerForceAffected =
|
||||
allMoves[lastReceivedAttack.move].chance >= 0 && lastAttacker.hasAbility(AbilityId.SHEER_FORCE);
|
||||
/** `true` if the last move's chance is above 0 and the last attacker's ability is sheer force */
|
||||
const sheerForceAffected =
|
||||
allMoves[lastReceivedAttack.move].chance >= 0 && lastAttacker.hasAbility(AbilityId.SHEER_FORCE);
|
||||
|
||||
return !SheerForceAffected;
|
||||
};
|
||||
}
|
||||
return !sheerForceAffected;
|
||||
};
|
||||
|
||||
function getWeatherCondition(...weatherTypes: WeatherType[]): AbAttrCondition {
|
||||
return () => {
|
||||
@ -4423,7 +4440,7 @@ export class FriskAbAttr extends PostSummonAbAttr {
|
||||
|
||||
override apply({ simulated, pokemon }: AbAttrBaseParams): void {
|
||||
if (!simulated) {
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
for (const opponent of pokemon.getOpponentsGenerator()) {
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("abilityTriggers:frisk", {
|
||||
pokemonNameWithAffix: getPokemonNameWithAffix(pokemon),
|
||||
@ -4992,7 +5009,7 @@ export class PostTurnHurtIfSleepingAbAttr extends PostTurnAbAttr {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const opp of pokemon.getOpponents()) {
|
||||
for (const opp of pokemon.getOpponentsGenerator()) {
|
||||
if ((opp.status?.effect !== StatusEffect.SLEEP && !opp.hasAbility(AbilityId.COMATOSE)) || opp.switchOutStatus) {
|
||||
continue;
|
||||
}
|
||||
@ -5545,10 +5562,9 @@ export class PostFaintContactDamageAbAttr extends PostFaintAbAttr {
|
||||
}
|
||||
|
||||
const cancelled = new BooleanHolder(false);
|
||||
// TODO: This should be in speed order
|
||||
globalScene
|
||||
.getField(true)
|
||||
.forEach(p => applyAbAttrs("FieldPreventExplosiveMovesAbAttr", { pokemon: p, cancelled, simulated }));
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
applyAbAttrs("FieldPreventExplosiveMovesAbAttr", { pokemon: p, cancelled, simulated });
|
||||
}
|
||||
|
||||
if (cancelled.value) {
|
||||
return false;
|
||||
@ -6725,6 +6741,7 @@ const AbilityAttrs = Object.freeze({
|
||||
BlockStatusDamageAbAttr,
|
||||
BlockOneHitKOAbAttr,
|
||||
ChangeMovePriorityAbAttr,
|
||||
ChangeMovePriorityInBracketAbAttr,
|
||||
IgnoreContactAbAttr,
|
||||
PreWeatherEffectAbAttr,
|
||||
PreWeatherDamageAbAttr,
|
||||
@ -6908,7 +6925,7 @@ export function initAbilities() {
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.COLOR_CHANGE, 3)
|
||||
.attr(PostDefendTypeChangeAbAttr)
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.IMMUNITY, 3)
|
||||
.attr(StatusEffectImmunityAbAttr, StatusEffect.POISON, StatusEffect.TOXIC)
|
||||
@ -7242,7 +7259,7 @@ export function initAbilities() {
|
||||
.attr(DoubleBattleChanceAbAttr)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.STALL, 4)
|
||||
.attr(ChangeMovePriorityAbAttr, (_pokemon, _move: Move) => true, -0.2)
|
||||
.attr(ChangeMovePriorityInBracketAbAttr, (_pokemon, _move: Move) => true, MovePriorityInBracket.LAST)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.TECHNICIAN, 4)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => {
|
||||
@ -7344,7 +7361,7 @@ export function initAbilities() {
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.PICKPOCKET, 5)
|
||||
.attr(PostDefendStealHeldItemAbAttr, (target, user, move) => move.doesFlagEffectApply({flag: MoveFlags.MAKES_CONTACT, user, target}))
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.SHEER_FORCE, 5)
|
||||
.attr(MovePowerBoostAbAttr, (_user, _target, move) => move.chance >= 1, 1.3)
|
||||
@ -7444,17 +7461,18 @@ export function initAbilities() {
|
||||
1.3)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.ILLUSION, 5)
|
||||
// The Pokemon generate an illusion if it's available
|
||||
.attr(IllusionPreSummonAbAttr, false)
|
||||
.attr(IllusionBreakAbAttr)
|
||||
// The Pokemon loses its illusion when damaged by a move
|
||||
.attr(PostDefendIllusionBreakAbAttr, true)
|
||||
// Disable Illusion in fusions
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
// Illusion is available again after a battle
|
||||
.conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false)
|
||||
// // The Pokemon generate an illusion if it's available
|
||||
// .attr(IllusionPreSummonAbAttr, false)
|
||||
// .attr(IllusionBreakAbAttr)
|
||||
// // The Pokemon loses its illusion when damaged by a move
|
||||
// .attr(PostDefendIllusionBreakAbAttr, true)
|
||||
// // Disable Illusion in fusions
|
||||
// .attr(NoFusionAbilityAbAttr)
|
||||
// // Illusion is available again after a battle
|
||||
// .conditionalAttr((pokemon) => pokemon.isAllowedInBattle(), IllusionPostBattleAbAttr, false)
|
||||
.uncopiable()
|
||||
.bypassFaint()
|
||||
// .bypassFaint()
|
||||
.unimplemented() // TODO reimplement Illusion properly
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.IMPOSTER, 5)
|
||||
.attr(PostSummonTransformAbAttr)
|
||||
@ -7658,10 +7676,12 @@ export function initAbilities() {
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.WIMP_OUT, 7)
|
||||
.attr(PostDamageForceSwitchAbAttr)
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.edgeCase() // Should not trigger when hurting itself in confusion, causes Fake Out to fail turn 1 and succeed turn 2 if pokemon is switched out before battle start via playing in Switch Mode
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.EMERGENCY_EXIT, 7)
|
||||
.attr(PostDamageForceSwitchAbAttr)
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.edgeCase() // Should not trigger when hurting itself in confusion, causes Fake Out to fail turn 1 and succeed turn 2 if pokemon is switched out before battle start via playing in Switch Mode
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.WATER_COMPACTION, 7)
|
||||
@ -7701,7 +7721,7 @@ export function initAbilities() {
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.BERSERK, 7)
|
||||
.attr(PostDefendHpGatedStatStageChangeAbAttr, (_target, _user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.SPATK ], 1)
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.SLUSH_RUSH, 7)
|
||||
.attr(StatMultiplierAbAttr, Stat.SPD, 2)
|
||||
@ -8061,7 +8081,7 @@ export function initAbilities() {
|
||||
new AbBuilder(AbilityId.ANGER_SHELL, 9)
|
||||
.attr(PostDefendHpGatedStatStageChangeAbAttr, (_target, _user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.ATK, Stat.SPATK, Stat.SPD ], 1)
|
||||
.attr(PostDefendHpGatedStatStageChangeAbAttr, (_target, _user, move) => move.category !== MoveCategory.STATUS, 0.5, [ Stat.DEF, Stat.SPDEF ], -1)
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.condition(sheerForceHitDisableAbCondition)
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.PURIFYING_SALT, 9)
|
||||
.attr(StatusEffectImmunityAbAttr)
|
||||
@ -8187,7 +8207,7 @@ export function initAbilities() {
|
||||
.ignorable()
|
||||
.build(),
|
||||
new AbBuilder(AbilityId.MYCELIUM_MIGHT, 9)
|
||||
.attr(ChangeMovePriorityAbAttr, (_pokemon, move) => move.category === MoveCategory.STATUS, -0.2)
|
||||
.attr(ChangeMovePriorityInBracketAbAttr, (_pokemon, move) => move.category === MoveCategory.STATUS, MovePriorityInBracket.LAST)
|
||||
.attr(PreventBypassSpeedChanceAbAttr, (_pokemon, move) => move.category === MoveCategory.STATUS)
|
||||
.attr(MoveAbilityBypassAbAttr, (_pokemon, move: Move) => move.category === MoveCategory.STATUS)
|
||||
.build(),
|
||||
|
||||
@ -78,6 +78,7 @@ import type {
|
||||
} from "#types/arena-tags";
|
||||
import type { Mutable } from "#types/type-helpers";
|
||||
import { BooleanHolder, type NumberHolder, toDmgValue } from "#utils/common";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
/** Interface containing the serializable fields of ArenaTagData. */
|
||||
@ -247,7 +248,7 @@ export abstract class ArenaTag implements BaseArenaTag {
|
||||
|
||||
/**
|
||||
* Helper function that retrieves the Pokemon affected.
|
||||
* @returns An array containing all {@linkcode Pokemon} affected by this Tag.
|
||||
* @returns An array containing all {@linkcode Pokemon} affected by this Tag, not in speed order.
|
||||
*/
|
||||
protected getAffectedPokemon(): Pokemon[] {
|
||||
switch (this.side) {
|
||||
@ -1204,7 +1205,7 @@ export class GravityTag extends SerializableArenaTag {
|
||||
|
||||
onAdd(quiet = false): void {
|
||||
super.onAdd(quiet);
|
||||
globalScene.getField(true).forEach(pokemon => {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (pokemon !== null) {
|
||||
pokemon.removeTag(BattlerTagType.FLOATING);
|
||||
pokemon.removeTag(BattlerTagType.TELEKINESIS);
|
||||
@ -1212,7 +1213,7 @@ export class GravityTag extends SerializableArenaTag {
|
||||
pokemon.addTag(BattlerTagType.INTERRUPTED);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1237,10 +1238,13 @@ class TailwindTag extends SerializableArenaTag {
|
||||
|
||||
onAdd(quiet = false): void {
|
||||
super.onAdd(quiet);
|
||||
const source = this.getSourcePokemon();
|
||||
|
||||
const field = this.getAffectedPokemon();
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const pokemon of field) {
|
||||
for (const pokemon of source.getAlliesGenerator()) {
|
||||
// Apply the CHARGED tag to party members with the WIND_POWER ability
|
||||
// TODO: This should not be handled here
|
||||
if (pokemon.hasAbility(AbilityId.WIND_POWER) && !pokemon.getTag(BattlerTagType.CHARGED)) {
|
||||
@ -1346,11 +1350,11 @@ class FireGrassPledgeTag extends SerializableArenaTag {
|
||||
}
|
||||
|
||||
override lapse(): boolean {
|
||||
const field = this.getAffectedPokemon().filter(
|
||||
pokemon => !pokemon.isOfType(PokemonType.FIRE, true, true) && !pokemon.switchOutStatus,
|
||||
);
|
||||
for (const pokemon of inSpeedOrder(this.side)) {
|
||||
if (pokemon.isOfType(PokemonType.FIRE) || pokemon.switchOutStatus) {
|
||||
continue;
|
||||
}
|
||||
|
||||
field.forEach(pokemon => {
|
||||
// "{pokemonNameWithAffix} was hurt by the sea of fire!"
|
||||
globalScene.phaseManager.queueMessage(
|
||||
i18next.t("arenaTag:fireGrassPledgeLapse", {
|
||||
@ -1365,7 +1369,7 @@ class FireGrassPledgeTag extends SerializableArenaTag {
|
||||
CommonAnim.MAGMA_STORM,
|
||||
);
|
||||
pokemon.damageAndUpdate(toDmgValue(pokemon.getMaxHp() / 8), { result: HitResult.INDIRECT });
|
||||
});
|
||||
}
|
||||
|
||||
return super.lapse();
|
||||
}
|
||||
@ -1497,7 +1501,7 @@ export class SuppressAbilitiesTag extends SerializableArenaTag {
|
||||
if (pokemon) {
|
||||
this.playActivationMessage(pokemon);
|
||||
|
||||
for (const fieldPokemon of globalScene.getField(true)) {
|
||||
for (const fieldPokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (fieldPokemon.id !== pokemon.id) {
|
||||
// TODO: investigate whether we can just remove the foreach and call `applyAbAttrs` directly, providing
|
||||
// the appropriate attributes (preLEaveField and IllusionBreak)
|
||||
@ -1539,7 +1543,7 @@ export class SuppressAbilitiesTag extends SerializableArenaTag {
|
||||
this.#beingRemoved = true;
|
||||
super.onRemove(quiet);
|
||||
|
||||
for (const pokemon of globalScene.getField(true)) {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
// There is only one pokemon with this attr on the field on removal, so its abilities are already active
|
||||
if (!pokemon.hasAbilityWithAttr("PreLeaveFieldRemoveSuppressAbilitiesSourceAbAttr", false)) {
|
||||
[true, false].forEach(passive => {
|
||||
|
||||
@ -51,6 +51,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.LEDYBA,
|
||||
SpeciesId.HOPPIP,
|
||||
SpeciesId.SUNKERN,
|
||||
SpeciesId.SILCOON,
|
||||
SpeciesId.STARLY,
|
||||
SpeciesId.PIDOVE,
|
||||
SpeciesId.COTTONEE,
|
||||
@ -61,6 +62,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [
|
||||
SpeciesId.CATERPIE,
|
||||
SpeciesId.SENTRET,
|
||||
SpeciesId.LEDYBA,
|
||||
SpeciesId.HOPPIP,
|
||||
SpeciesId.SUNKERN,
|
||||
SpeciesId.SILCOON,
|
||||
@ -71,20 +73,20 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.YUNGOOS,
|
||||
SpeciesId.SKWOVET
|
||||
],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.WEEDLE, SpeciesId.POOCHYENA, SpeciesId.PATRAT, SpeciesId.PURRLOIN, SpeciesId.BLIPBUG ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.WEEDLE, SpeciesId.HOOTHOOT, SpeciesId.SPINARAK, SpeciesId.POOCHYENA, SpeciesId.CASCOON, SpeciesId.PATRAT, SpeciesId.PURRLOIN, SpeciesId.BLIPBUG ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PIDGEY, SpeciesId.RATTATA, SpeciesId.SPEAROW, SpeciesId.ZIGZAGOON, SpeciesId.WURMPLE, SpeciesId.TAILLOW, SpeciesId.BIDOOF, SpeciesId.LILLIPUP, SpeciesId.FLETCHLING, SpeciesId.WOOLOO, SpeciesId.LECHONK ]
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.WEEDLE, SpeciesId.HOOTHOOT, SpeciesId.SPINARAK, SpeciesId.POOCHYENA, SpeciesId.CASCOON, SpeciesId.PURRLOIN, SpeciesId.BLIPBUG ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.WEEDLE, SpeciesId.HOOTHOOT, SpeciesId.SPINARAK, SpeciesId.POOCHYENA, SpeciesId.CASCOON, SpeciesId.PURRLOIN, SpeciesId.BLIPBUG ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PIDGEY, SpeciesId.RATTATA, SpeciesId.SPEAROW, SpeciesId.ZIGZAGOON, SpeciesId.WURMPLE, SpeciesId.TAILLOW, SpeciesId.BIDOOF, SpeciesId.PATRAT, SpeciesId.LILLIPUP, SpeciesId.FLETCHLING, SpeciesId.WOOLOO, SpeciesId.LECHONK ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.BELLSPROUT, SpeciesId.POOCHYENA, SpeciesId.LOTAD, SpeciesId.SKITTY, SpeciesId.COMBEE, SpeciesId.CHERUBI, SpeciesId.PATRAT, SpeciesId.MINCCINO, SpeciesId.PAWMI ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.NIDORAN_F, SpeciesId.NIDORAN_M, SpeciesId.BELLSPROUT, SpeciesId.POOCHYENA, SpeciesId.LOTAD, SpeciesId.SKITTY, SpeciesId.COMBEE, SpeciesId.CHERUBI, SpeciesId.PATRAT, SpeciesId.MINCCINO, SpeciesId.PAWMI ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.EKANS, SpeciesId.ODDISH, SpeciesId.MEOWTH, SpeciesId.SPINARAK, SpeciesId.SEEDOT, SpeciesId.SHROOMISH, SpeciesId.KRICKETOT, SpeciesId.VENIPEDE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.EKANS, SpeciesId.ODDISH, SpeciesId.PARAS, SpeciesId.VENONAT, SpeciesId.MEOWTH, SpeciesId.SEEDOT, SpeciesId.SHROOMISH, SpeciesId.KRICKETOT, SpeciesId.VENIPEDE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINCADA, SpeciesId.WHISMUR, SpeciesId.FIDOUGH ]
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.NIDORAN_F, SpeciesId.NIDORAN_M, SpeciesId.BELLSPROUT, SpeciesId.POOCHYENA, SpeciesId.LOTAD, SpeciesId.SKITTY, SpeciesId.COMBEE, SpeciesId.CHERUBI, SpeciesId.MINCCINO, SpeciesId.PAWMI ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.NIDORAN_F, SpeciesId.NIDORAN_M, SpeciesId.BELLSPROUT, SpeciesId.POOCHYENA, SpeciesId.LOTAD, SpeciesId.SKITTY, SpeciesId.COMBEE, SpeciesId.CHERUBI, SpeciesId.MINCCINO, SpeciesId.PAWMI ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.EKANS, SpeciesId.ODDISH, SpeciesId.PARAS, SpeciesId.VENONAT, SpeciesId.MEOWTH, SpeciesId.SHROOMISH, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.EKANS, SpeciesId.ODDISH, SpeciesId.PARAS, SpeciesId.VENONAT, SpeciesId.MEOWTH, SpeciesId.SHROOMISH, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SEEDOT, SpeciesId.WHISMUR, SpeciesId.VENIPEDE, SpeciesId.FIDOUGH ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.TANDEMAUS ], [TimeOfDay.DAY]: [ SpeciesId.TANDEMAUS ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ABRA, SpeciesId.SURSKIT, SpeciesId.ROOKIDEE ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.EEVEE, SpeciesId.RALTS ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ABRA, SpeciesId.CLEFFA, SpeciesId.IGGLYBUFF, SpeciesId.SURSKIT, SpeciesId.HAPPINY, SpeciesId.ROOKIDEE, SpeciesId.TANDEMAUS ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.EEVEE, SpeciesId.PICHU, SpeciesId.TOGEPI, SpeciesId.RALTS, SpeciesId.NINCADA, SpeciesId.RIOLU ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.MUNCHLAX, SpeciesId.ZORUA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
@ -94,7 +96,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SENTRET, SpeciesId.YUNGOOS, SpeciesId.SKWOVET ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SENTRET, SpeciesId.YUNGOOS, SpeciesId.SKWOVET ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.MEOWTH, SpeciesId.POOCHYENA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.ZUBAT, SpeciesId.MEOWTH, SpeciesId.POOCHYENA ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.ZUBAT, SpeciesId.MEOWTH, SpeciesId.POOCHYENA ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.ZIGZAGOON, SpeciesId.BIDOOF, SpeciesId.LECHONK ]
|
||||
},
|
||||
@ -104,6 +106,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.POOCHYENA,
|
||||
SpeciesId.STARLY,
|
||||
SpeciesId.PIDOVE,
|
||||
SpeciesId.ROCKRUFF,
|
||||
SpeciesId.PAWMI
|
||||
],
|
||||
[TimeOfDay.DAY]: [
|
||||
@ -114,8 +117,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.ROCKRUFF,
|
||||
SpeciesId.PAWMI
|
||||
],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.MANKEY ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.MANKEY ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.MANKEY, SpeciesId.NICKIT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.MANKEY, SpeciesId.NICKIT ],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.PIDGEY,
|
||||
SpeciesId.SPEAROW,
|
||||
@ -151,79 +154,79 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
},
|
||||
[BiomeId.GRASS]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.HOPPIP, SpeciesId.SUNKERN, SpeciesId.COTTONEE, SpeciesId.PETILIL ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.HOPPIP, SpeciesId.SUNKERN, SpeciesId.COTTONEE, SpeciesId.PETILIL ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SEEDOT, SpeciesId.SHROOMISH ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SEEDOT, SpeciesId.SHROOMISH ],
|
||||
[TimeOfDay.ALL]: []
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.HOPPIP, SpeciesId.SILCOON ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.HOPPIP, SpeciesId.SILCOON ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.CASCOON ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.CASCOON ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SHROOMISH, SpeciesId.VENIPEDE, SpeciesId.COTTONEE, SpeciesId.PETILIL ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.COMBEE, SpeciesId.CHERUBI ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.COMBEE, SpeciesId.CHERUBI ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.FOONGUS ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.FOONGUS ],
|
||||
[TimeOfDay.ALL]: []
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SUNKERN, SpeciesId.COMBEE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SUNKERN, SpeciesId.COMBEE ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SEEDOT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SEEDOT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.MILTANK, SpeciesId.CHERUBI, SpeciesId.FOONGUS, ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.BULBASAUR, SpeciesId.GROWLITHE, SpeciesId.TURTWIG ]
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.NOIBAT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.NOIBAT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.BULBASAUR, SpeciesId.GROWLITHE, SpeciesId.TURTWIG, SpeciesId.BONSLY ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SUDOWOODO ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.VIRIZION ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.JUMPLUFF, SpeciesId.SUNFLORA, SpeciesId.WHIMSICOTT ], [TimeOfDay.DAY]: [ SpeciesId.JUMPLUFF, SpeciesId.SUNFLORA, SpeciesId.WHIMSICOTT ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.VENUSAUR, SpeciesId.SUDOWOODO, SpeciesId.TORTERRA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.JUMPLUFF, SpeciesId.VESPIQUEN ], [TimeOfDay.DAY]: [ SpeciesId.JUMPLUFF, SpeciesId.VESPIQUEN ], [TimeOfDay.DUSK]: [ SpeciesId.NOIVERN ], [TimeOfDay.NIGHT]: [ SpeciesId.NOIVERN ], [TimeOfDay.ALL]: [ SpeciesId.MILTANK, SpeciesId.SCOLIPEDE, SpeciesId.WHIMSICOTT, SpeciesId.LILLIGANT ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.VENUSAUR, SpeciesId.ARCANINE, SpeciesId.SUDOWOODO, SpeciesId.TORTERRA ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.VIRIZION ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
[BiomeId.TALL_GRASS]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.BOUNSWEET ],
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.NIDORAN_F, SpeciesId.NIDORAN_M, SpeciesId.BOUNSWEET ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.NIDORAN_F, SpeciesId.NIDORAN_M, SpeciesId.BOUNSWEET ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.ODDISH, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.ODDISH, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINCADA, SpeciesId.FOMANTIS, SpeciesId.NYMBLE ]
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.ODDISH, SpeciesId.SPINARAK, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.ODDISH, SpeciesId.SPINARAK, SpeciesId.KRICKETOT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PARAS, SpeciesId.FOMANTIS, SpeciesId.NYMBLE, SpeciesId.SCATTERBUG ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.PARAS, SpeciesId.VENONAT, SpeciesId.SPINARAK ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.VULPIX ]
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.VULPIX, SpeciesId.VENONAT, SpeciesId.NINCADA, SpeciesId.ZANGOOSE, SpeciesId.SEVIPER ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PINSIR, SpeciesId.CHIKORITA, SpeciesId.GIRAFARIG, SpeciesId.ZANGOOSE, SpeciesId.KECLEON, SpeciesId.TROPIUS ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PINSIR, SpeciesId.CHIKORITA, SpeciesId.GIRAFARIG, SpeciesId.KECLEON, SpeciesId.TROPIUS, SpeciesId.AUDINO, SpeciesId.PAWNIARD ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SCYTHER, SpeciesId.SHEDINJA, SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SCYTHER, SpeciesId.SHEDINJA ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.TSAREENA ],
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.NIDOQUEEN, SpeciesId.NIDOKING, SpeciesId.TSAREENA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.NIDOQUEEN, SpeciesId.NIDOKING, SpeciesId.TSAREENA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.VILEPLUME, SpeciesId.KRICKETUNE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.VILEPLUME, SpeciesId.KRICKETUNE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINJASK, SpeciesId.ZANGOOSE, SpeciesId.KECLEON, SpeciesId.LURANTIS, SpeciesId.LOKIX ]
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.VILEPLUME, SpeciesId.ARIADOS, SpeciesId.KRICKETUNE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.VILEPLUME, SpeciesId.ARIADOS, SpeciesId.KRICKETUNE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINJASK, SpeciesId.ZANGOOSE, SpeciesId.SEVIPER, SpeciesId.KECLEON, SpeciesId.LURANTIS, SpeciesId.LOKIX ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.BELLOSSOM ], [TimeOfDay.DAY]: [ SpeciesId.BELLOSSOM ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PINSIR, SpeciesId.MEGANIUM, SpeciesId.FARIGIRAF ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.BELLOSSOM ], [TimeOfDay.DAY]: [ SpeciesId.BELLOSSOM ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SCYTHER, SpeciesId.PINSIR, SpeciesId.MEGANIUM, SpeciesId.FARIGIRAF, SpeciesId.KINGAMBIT ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
[BiomeId.METROPOLIS]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.YAMPER ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.YAMPER ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.PATRAT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.HOUNDOUR, SpeciesId.PATRAT ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.RATTATA, SpeciesId.ZIGZAGOON, SpeciesId.LILLIPUP ]
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.HOUNDOUR],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.HOUNDOUR ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.RATTATA, SpeciesId.ZIGZAGOON, SpeciesId.PATRAT, SpeciesId.LILLIPUP ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.PATRAT, SpeciesId.INDEEDEE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.PATRAT, SpeciesId.INDEEDEE ],
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.INDEEDEE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.INDEEDEE ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.ESPURR ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.ESPURR ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PIKACHU, SpeciesId.GLAMEOW, SpeciesId.FURFROU, SpeciesId.FIDOUGH, SpeciesId.SQUAWKABILLY ]
|
||||
@ -233,12 +236,12 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [ SpeciesId.TANDEMAUS ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.MORPEKO ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.MORPEKO ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.VAROOM ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SMEARGLE, SpeciesId.CASTFORM, SpeciesId.VAROOM ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.EEVEE, SpeciesId.SMEARGLE ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.CASTFORM ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.BOLTUND ], [TimeOfDay.DAY]: [ SpeciesId.BOLTUND ], [TimeOfDay.DUSK]: [ SpeciesId.MEOWSTIC ], [TimeOfDay.NIGHT]: [ SpeciesId.MEOWSTIC ], [TimeOfDay.ALL]: [ SpeciesId.STOUTLAND, SpeciesId.FURFROU, SpeciesId.DACHSBUN ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.MAUSHOLD ], [TimeOfDay.DAY]: [ SpeciesId.MAUSHOLD ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.CASTFORM, SpeciesId.REVAVROOM ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.EEVEE ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.BOLTUND ], [TimeOfDay.DAY]: [ SpeciesId.BOLTUND ], [TimeOfDay.DUSK]: [ SpeciesId.MEOWSTIC ], [TimeOfDay.NIGHT]: [ SpeciesId.MEOWSTIC ], [TimeOfDay.ALL]: [ SpeciesId.CASTFORM, SpeciesId.STOUTLAND, SpeciesId.FURFROU, SpeciesId.DACHSBUN ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.MAUSHOLD ], [TimeOfDay.DAY]: [ SpeciesId.MAUSHOLD ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.REVAVROOM ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
@ -263,6 +266,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
],
|
||||
[TimeOfDay.DUSK]: [
|
||||
SpeciesId.BEEDRILL,
|
||||
SpeciesId.SPINARAK,
|
||||
SpeciesId.PINECO,
|
||||
SpeciesId.SEEDOT,
|
||||
SpeciesId.SHROOMISH,
|
||||
@ -283,7 +287,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.ROSELIA, SpeciesId.MOTHIM, SpeciesId.SEWADDLE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.ROSELIA, SpeciesId.MOTHIM, SpeciesId.SEWADDLE ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SPINARAK, SpeciesId.DOTTLER ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.DOTTLER ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.HOOTHOOT, SpeciesId.ROCKRUFF, SpeciesId.DOTTLER ],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.EKANS,
|
||||
@ -332,9 +336,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SLOWPOKE, SpeciesId.WINGULL, SpeciesId.CRAMORANT, SpeciesId.FINIZEN ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SLOWPOKE, SpeciesId.WINGULL, SpeciesId.CRAMORANT, SpeciesId.FINIZEN ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.INKAY ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.FINNEON, SpeciesId.INKAY ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.FINNEON, SpeciesId.INKAY ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TENTACOOL, SpeciesId.MAGIKARP, SpeciesId.BUIZEL ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TENTACOOL, SpeciesId.WAILMER ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.STARYU ],
|
||||
@ -345,7 +349,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.POLIWAG,
|
||||
SpeciesId.HORSEA,
|
||||
SpeciesId.GOLDEEN,
|
||||
SpeciesId.WAILMER,
|
||||
SpeciesId.MAGIKARP,
|
||||
SpeciesId.BUIZEL,
|
||||
SpeciesId.PANPOUR,
|
||||
SpeciesId.WATTREL
|
||||
]
|
||||
@ -357,7 +362,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.LAPRAS, SpeciesId.PIPLUP, SpeciesId.POPPLIO ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KINGDRA, SpeciesId.ROTOM, SpeciesId.TIRTOUGA ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KINGDRA, SpeciesId.TIRTOUGA ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.PELIPPER, SpeciesId.CRAMORANT, SpeciesId.PALAFIN ],
|
||||
@ -366,8 +371,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SHARPEDO, SpeciesId.LUMINEON, SpeciesId.MALAMAR ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TENTACRUEL, SpeciesId.FLOATZEL, SpeciesId.SIMIPOUR, SpeciesId.KILOWATTREL ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KINGDRA, SpeciesId.EMPOLEON, SpeciesId.PRIMARINA ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GYARADOS, SpeciesId.KINGDRA, SpeciesId.EMPOLEON, SpeciesId.PRIMARINA ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.LUGIA ] }
|
||||
},
|
||||
[BiomeId.SWAMP]: {
|
||||
@ -473,8 +478,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.PSYDUCK,
|
||||
SpeciesId.GOLDEEN,
|
||||
SpeciesId.MAGIKARP,
|
||||
SpeciesId.CHEWTLE
|
||||
SpeciesId.WOOPER,
|
||||
SpeciesId.SURSKIT,
|
||||
SpeciesId.CHEWTLE,
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
@ -482,7 +488,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [ SpeciesId.DEWPIDER ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SLOWPOKE, SpeciesId.WOOPER, SpeciesId.SURSKIT, SpeciesId.WISHIWASHI, SpeciesId.FLAMIGO ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SLOWPOKE, SpeciesId.MAGIKARP, SpeciesId.WISHIWASHI ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
@ -493,7 +499,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.SQUIRTLE,
|
||||
SpeciesId.OSHAWOTT,
|
||||
SpeciesId.FROAKIE,
|
||||
SpeciesId.SOBBLE
|
||||
SpeciesId.SOBBLE,
|
||||
SpeciesId.FLAMIGO
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.VAPOREON, SpeciesId.SLOWKING ] },
|
||||
@ -503,9 +510,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SWANNA, SpeciesId.ARAQUANID ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.AZUMARILL ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.AZUMARILL ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.GOLDUCK, SpeciesId.SLOWBRO, SpeciesId.SEAKING, SpeciesId.GYARADOS, SpeciesId.MASQUERAIN, SpeciesId.WISHIWASHI, SpeciesId.DREDNAW ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.GOLDUCK, SpeciesId.SLOWBRO, SpeciesId.SEAKING, SpeciesId.MASQUERAIN, SpeciesId.WISHIWASHI, SpeciesId.DREDNAW ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BLASTOISE, SpeciesId.VAPOREON, SpeciesId.SLOWKING, SpeciesId.SAMUROTT, SpeciesId.GRENINJA, SpeciesId.INTELEON ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BLASTOISE, SpeciesId.GYARADOS, SpeciesId.VAPOREON, SpeciesId.SLOWKING, SpeciesId.SAMUROTT, SpeciesId.GRENINJA, SpeciesId.INTELEON ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SUICUNE, SpeciesId.MESPRIT ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
@ -546,7 +553,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.QWILFISH, SpeciesId.CORSOLA, SpeciesId.OCTILLERY, SpeciesId.MANTYKE, SpeciesId.ALOMOMOLA, SpeciesId.TYNAMO, SpeciesId.DHELMISE ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.QWILFISH, SpeciesId.CORSOLA, SpeciesId.OCTILLERY, SpeciesId.FEEBAS, SpeciesId.MANTYKE, SpeciesId.ALOMOMOLA, SpeciesId.TYNAMO, SpeciesId.DHELMISE ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
@ -563,7 +570,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.HISUI_QWILFISH
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.FEEBAS, SpeciesId.NIHILEGO ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.NIHILEGO ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
@ -576,9 +583,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.OMASTAR, SpeciesId.KABUTOPS, SpeciesId.RELICANTH, SpeciesId.EELEKTROSS, SpeciesId.PYUKUMUKU, SpeciesId.DHELMISE, SpeciesId.CURSOLA, SpeciesId.ARCTOVISH, SpeciesId.BASCULEGION, SpeciesId.OVERQWIL ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.OMASTAR, SpeciesId.KABUTOPS, SpeciesId.MILOTIC, SpeciesId.RELICANTH, SpeciesId.EELEKTROSS, SpeciesId.PYUKUMUKU, SpeciesId.DHELMISE, SpeciesId.CURSOLA, SpeciesId.ARCTOVISH, SpeciesId.BASCULEGION, SpeciesId.OVERQWIL ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MILOTIC, SpeciesId.NIHILEGO ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.NIHILEGO ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KYOGRE ] }
|
||||
},
|
||||
[BiomeId.MOUNTAIN]: {
|
||||
@ -626,8 +633,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.MACHOP,
|
||||
SpeciesId.GEODUDE,
|
||||
SpeciesId.NATU,
|
||||
SpeciesId.SLUGMA,
|
||||
SpeciesId.NACLI
|
||||
SpeciesId.SLUGMA
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
@ -635,7 +641,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.MURKROW ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SKARMORY, SpeciesId.TORCHIC, SpeciesId.SPOINK, SpeciesId.HAWLUCHA, SpeciesId.KLAWF ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SKARMORY, SpeciesId.TORCHIC, SpeciesId.SPOINK, SpeciesId.HAWLUCHA, SpeciesId.NACLI ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
@ -647,7 +653,6 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.CRANIDOS,
|
||||
SpeciesId.SHIELDON,
|
||||
SpeciesId.GIBLE,
|
||||
SpeciesId.ROTOM,
|
||||
SpeciesId.ARCHEOPS,
|
||||
SpeciesId.AXEW
|
||||
]
|
||||
@ -658,10 +663,10 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SWELLOW, SpeciesId.ALTARIA, SpeciesId.STARAPTOR, SpeciesId.UNFEZANT, SpeciesId.BRAVIARY, SpeciesId.TALONFLAME, SpeciesId.CORVIKNIGHT, SpeciesId.ESPATHRA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.MANDIBUZZ ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.MANDIBUZZ ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PIDGEOT, SpeciesId.FEAROW, SpeciesId.SKARMORY, SpeciesId.AGGRON, SpeciesId.GOGOAT, SpeciesId.GARGANACL ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PIDGEOT, SpeciesId.FEAROW, SpeciesId.SKARMORY, SpeciesId.AGGRON, SpeciesId.GOGOAT ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.HISUI_BRAVIARY ], [TimeOfDay.DAY]: [ SpeciesId.HISUI_BRAVIARY ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BLAZIKEN, SpeciesId.RAMPARDOS, SpeciesId.BASTIODON, SpeciesId.HAWLUCHA ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM, SpeciesId.TORNADUS, SpeciesId.TING_LU, SpeciesId.OGERPON ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [ SpeciesId.HISUI_BRAVIARY ], [TimeOfDay.DAY]: [ SpeciesId.HISUI_BRAVIARY ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BLAZIKEN, SpeciesId.RAMPARDOS, SpeciesId.BASTIODON, SpeciesId.HAWLUCHA, SpeciesId.GARGANACL ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TORNADUS, SpeciesId.TING_LU, SpeciesId.OGERPON ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HO_OH ] }
|
||||
},
|
||||
[BiomeId.BADLANDS]: {
|
||||
@ -690,7 +695,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.CUFANT
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.GLIGAR, SpeciesId.POLTCHAGEIST ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.GLIGAR, SpeciesId.KLAWF, SpeciesId.POLTCHAGEIST ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.LANDORUS, SpeciesId.OKIDOGI ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
@ -717,8 +722,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.WHISMUR,
|
||||
SpeciesId.ROGGENROLA,
|
||||
SpeciesId.WOOBAT,
|
||||
SpeciesId.BUNNELBY,
|
||||
SpeciesId.NACLI
|
||||
SpeciesId.BUNNELBY
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
@ -739,7 +743,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.FERROSEED, SpeciesId.CARBINK, SpeciesId.GLIMMET ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.FERROSEED, SpeciesId.CARBINK, SpeciesId.NACLI, SpeciesId.GLIMMET ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SHUCKLE ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UXIE ] },
|
||||
@ -748,44 +752,44 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PARASECT, SpeciesId.ONIX, SpeciesId.CROBAT, SpeciesId.URSARING, SpeciesId.EXPLOUD, SpeciesId.PROBOPASS, SpeciesId.GIGALITH, SpeciesId.SWOOBAT, SpeciesId.DIGGERSBY, SpeciesId.NOIVERN, SpeciesId.GOLISOPOD, SpeciesId.GARGANACL ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.PARASECT, SpeciesId.ONIX, SpeciesId.CROBAT, SpeciesId.URSARING, SpeciesId.EXPLOUD, SpeciesId.PROBOPASS, SpeciesId.GIGALITH, SpeciesId.SWOOBAT, SpeciesId.DIGGERSBY, SpeciesId.NOIVERN, SpeciesId.GOLISOPOD ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.LYCANROC ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SHUCKLE, SpeciesId.FERROTHORN, SpeciesId.GLIMMORA ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.LYCANROC ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SHUCKLE, SpeciesId.FERROTHORN, SpeciesId.GARGANACL, SpeciesId.GLIMMORA ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UXIE ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERAPAGOS ] }
|
||||
},
|
||||
[BiomeId.DESERT]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.TRAPINCH, SpeciesId.HIPPOPOTAS, SpeciesId.RELLOR ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.TRAPINCH, SpeciesId.HIPPOPOTAS, SpeciesId.RELLOR ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.CACNEA, SpeciesId.SANDILE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.CACNEA, SpeciesId.SANDILE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SANDSHREW, SpeciesId.SKORUPI, SpeciesId.SILICOBRA ]
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.TRAPINCH, SpeciesId.HELIOPTILE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.TRAPINCH, SpeciesId.HELIOPTILE ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.CACNEA ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.CACNEA ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SANDSHREW, SpeciesId.SKORUPI, SpeciesId.SILICOBRA, SpeciesId.BRAMBLIN, SpeciesId.RELLOR ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SANDILE, SpeciesId.HELIOPTILE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SANDILE, SpeciesId.HELIOPTILE ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.MARACTUS, SpeciesId.BRAMBLIN, SpeciesId.ORTHWORM ]
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.MARACTUS ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.MARACTUS ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.GLIGAR, SpeciesId.YAMASK ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.GLIGAR, SpeciesId.YAMASK ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NUMEL, SpeciesId.HIPPOPOTAS, SpeciesId.SANDILE, SpeciesId.ORTHWORM ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.VIBRAVA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.VIBRAVA ],
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.DARUMAKA ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.DODUO, SpeciesId.DARUMAKA, SpeciesId.SIGILYPH, SpeciesId.STONJOURNER ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.LILEEP, SpeciesId.ANORITH ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.LILEEP, SpeciesId.ANORITH, SpeciesId.GIBLE ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.REGIROCK, SpeciesId.TAPU_BULU, SpeciesId.PHEROMOSA ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.HIPPOWDON, SpeciesId.HELIOLISK, SpeciesId.RABSCA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.HIPPOWDON, SpeciesId.HELIOLISK, SpeciesId.RABSCA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.CACTURNE, SpeciesId.KROOKODILE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.CACTURNE, SpeciesId.KROOKODILE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SANDSLASH, SpeciesId.DRAPION, SpeciesId.DARMANITAN, SpeciesId.MARACTUS, SpeciesId.SANDACONDA, SpeciesId.BRAMBLEGHAST ]
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.MARACTUS, SpeciesId.HELIOLISK, SpeciesId.FLYGON ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.MARACTUS, SpeciesId.HELIOLISK, SpeciesId.FLYGON ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.GLISCOR, SpeciesId.CACTURNE, SpeciesId.COFAGRIGUS ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.GLISCOR, SpeciesId.CACTURNE, SpeciesId.COFAGRIGUS ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SANDSLASH, SpeciesId.HIPPOWDON, SpeciesId.DRAPION, SpeciesId.KROOKODILE, SpeciesId.DARMANITAN, SpeciesId.SANDACONDA, SpeciesId.BRAMBLEGHAST ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.CRADILY, SpeciesId.ARMALDO ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DODRIO, SpeciesId.CRADILY, SpeciesId.ARMALDO, SpeciesId.GARCHOMP, SpeciesId.SIGILYPH, SpeciesId.STONJOURNER ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.REGIROCK, SpeciesId.TAPU_BULU, SpeciesId.PHEROMOSA ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
@ -798,7 +802,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.SEEL,
|
||||
SpeciesId.SWINUB,
|
||||
SpeciesId.SNOVER,
|
||||
SpeciesId.SNORUNT,
|
||||
SpeciesId.VANILLITE,
|
||||
SpeciesId.CUBCHOO,
|
||||
SpeciesId.BERGMITE,
|
||||
@ -812,15 +816,16 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.SLOWKING,
|
||||
SpeciesId.SNEASEL,
|
||||
SpeciesId.SNORUNT,
|
||||
SpeciesId.SMOOCHUM,
|
||||
SpeciesId.SPHEAL,
|
||||
SpeciesId.EISCUE,
|
||||
SpeciesId.CETODDLE
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.JYNX, SpeciesId.LAPRAS, SpeciesId.FROSLASS, SpeciesId.CRYOGONAL ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DELIBIRD, SpeciesId.ROTOM, SpeciesId.AMAURA ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.LAPRAS, SpeciesId.DELIBIRD, SpeciesId.CRYOGONAL ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.AMAURA ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ARTICUNO, SpeciesId.REGICE ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
@ -830,13 +835,13 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.ALL]: [ SpeciesId.DEWGONG, SpeciesId.GLALIE, SpeciesId.WALREIN, SpeciesId.WEAVILE, SpeciesId.MAMOSWINE, SpeciesId.FROSLASS, SpeciesId.VANILLUXE, SpeciesId.BEARTIC, SpeciesId.CRYOGONAL, SpeciesId.AVALUGG, SpeciesId.CRABOMINABLE, SpeciesId.CETITAN ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.JYNX, SpeciesId.LAPRAS, SpeciesId.GLACEON, SpeciesId.AURORUS ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ARTICUNO, SpeciesId.REGICE, SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ARTICUNO, SpeciesId.REGICE ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KYUREM ] }
|
||||
},
|
||||
[BiomeId.MEADOW]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.LEDYBA, SpeciesId.ROSELIA, SpeciesId.COTTONEE, SpeciesId.MINCCINO ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.ROSELIA, SpeciesId.COTTONEE, SpeciesId.MINCCINO ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.LEDYBA, SpeciesId.ROSELIA, SpeciesId.COTTONEE, SpeciesId.MINCCINO ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
@ -873,9 +878,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.VOLBEAT, SpeciesId.ILLUMISE ],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.VOLBEAT, SpeciesId.ILLUMISE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.VOLBEAT, SpeciesId.ILLUMISE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TAUROS, SpeciesId.EEVEE, SpeciesId.MILTANK, SpeciesId.SPINDA, SpeciesId.APPLIN, SpeciesId.SPRIGATITO ]
|
||||
},
|
||||
@ -883,7 +888,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MELOETTA ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.LEDIAN, SpeciesId.GRANBULL, SpeciesId.DELCATTY, SpeciesId.ROSERADE, SpeciesId.CINCCINO, SpeciesId.BOUFFALANT, SpeciesId.ARBOLIVA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.GRANBULL, SpeciesId.DELCATTY, SpeciesId.ROSERADE, SpeciesId.CINCCINO, SpeciesId.BOUFFALANT, SpeciesId.ARBOLIVA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.LEDIAN, SpeciesId.GRANBULL, SpeciesId.DELCATTY, SpeciesId.ROSERADE, SpeciesId.CINCCINO, SpeciesId.BOUFFALANT, SpeciesId.ARBOLIVA ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TAUROS, SpeciesId.MILTANK, SpeciesId.GARDEVOIR, SpeciesId.PURUGLY, SpeciesId.ZEBSTRIKA, SpeciesId.FLORGES, SpeciesId.RIBOMBEE, SpeciesId.DUBWOOL ]
|
||||
@ -900,7 +905,6 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.PIKACHU,
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.VOLTORB,
|
||||
SpeciesId.ELECTRIKE,
|
||||
SpeciesId.SHINX,
|
||||
@ -910,8 +914,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.TADBULB
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ELECTABUZZ, SpeciesId.PLUSLE, SpeciesId.MINUN, SpeciesId.PACHIRISU, SpeciesId.EMOLGA, SpeciesId.TOGEDEMARU ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAREEP ] },
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAGNEMITE, SpeciesId.ELECTABUZZ, SpeciesId.PLUSLE, SpeciesId.MINUN, SpeciesId.PACHIRISU, SpeciesId.EMOLGA, SpeciesId.TOGEDEMARU ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAREEP, SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.JOLTEON, SpeciesId.HISUI_VOLTORB ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.RAIKOU, SpeciesId.THUNDURUS, SpeciesId.XURKITREE, SpeciesId.ZERAORA, SpeciesId.REGIELEKI ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
@ -936,12 +940,14 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.GROWLITHE,
|
||||
SpeciesId.PONYTA,
|
||||
SpeciesId.SLUGMA,
|
||||
SpeciesId.POOCHYENA,
|
||||
SpeciesId.NUMEL,
|
||||
SpeciesId.SALANDIT,
|
||||
SpeciesId.SPOINK,
|
||||
SpeciesId.SWABLU,
|
||||
SpeciesId.ROLYCOLY
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAGMAR, SpeciesId.TORKOAL, SpeciesId.PANSEAR, SpeciesId.HEATMOR, SpeciesId.TURTONATOR ] },
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAGMAR, SpeciesId.MEDITITE, SpeciesId.TORKOAL, SpeciesId.PANSEAR, SpeciesId.HEATMOR, SpeciesId.SALANDIT, SpeciesId.TURTONATOR, SpeciesId.ALOLA_DIGLETT ] },
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
@ -958,14 +964,14 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
SpeciesId.CHARCADET
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.FLAREON, SpeciesId.ROTOM, SpeciesId.LARVESTA, SpeciesId.HISUI_GROWLITHE ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.FLAREON, SpeciesId.LARVESTA, SpeciesId.HISUI_GROWLITHE ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ENTEI, SpeciesId.HEATRAN, SpeciesId.VOLCANION, SpeciesId.CHI_YU ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINETALES, SpeciesId.ARCANINE, SpeciesId.RAPIDASH, SpeciesId.MAGCARGO, SpeciesId.CAMERUPT, SpeciesId.TORKOAL, SpeciesId.MAGMORTAR, SpeciesId.SIMISEAR, SpeciesId.HEATMOR, SpeciesId.SALAZZLE, SpeciesId.TURTONATOR, SpeciesId.COALOSSAL ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.NINETALES, SpeciesId.ARCANINE, SpeciesId.RAPIDASH, SpeciesId.MAGCARGO, SpeciesId.CAMERUPT, SpeciesId.TORKOAL, SpeciesId.MAGMORTAR, SpeciesId.SIMISEAR, SpeciesId.HEATMOR, SpeciesId.SALAZZLE, SpeciesId.TURTONATOR, SpeciesId.COALOSSAL, SpeciesId.ALOLA_DUGTRIO ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
@ -974,7 +980,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.CHARIZARD, SpeciesId.FLAREON, SpeciesId.TYPHLOSION, SpeciesId.INFERNAPE, SpeciesId.EMBOAR, SpeciesId.VOLCARONA, SpeciesId.DELPHOX, SpeciesId.INCINEROAR, SpeciesId.CINDERACE, SpeciesId.ARMAROUGE, SpeciesId.HISUI_ARCANINE ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MOLTRES, SpeciesId.ENTEI, SpeciesId.ROTOM, SpeciesId.HEATRAN, SpeciesId.VOLCANION, SpeciesId.CHI_YU ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MOLTRES, SpeciesId.ENTEI, SpeciesId.HEATRAN, SpeciesId.VOLCANION, SpeciesId.CHI_YU ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.RESHIRAM ] }
|
||||
},
|
||||
[BiomeId.GRAVEYARD]: {
|
||||
@ -1047,8 +1053,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.ALL]: [ SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.HARIYAMA, SpeciesId.MEDICHAM, SpeciesId.LUCARIO, SpeciesId.TOXICROAK, SpeciesId.THROH, SpeciesId.SAWK, SpeciesId.SCRAFTY, SpeciesId.MIENSHAO, SpeciesId.BEWEAR, SpeciesId.GRAPPLOCT, SpeciesId.ANNIHILAPE ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.HITMONTOP, SpeciesId.GALLADE, SpeciesId.PANGORO, SpeciesId.SIRFETCHD, SpeciesId.HISUI_DECIDUEYE ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, SpeciesId.KUBFU ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZAMAZENTA, SpeciesId.GALAR_ZAPDOS ] }
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TERRAKION, SpeciesId.KUBFU, SpeciesId.GALAR_ZAPDOS ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZAMAZENTA ] }
|
||||
},
|
||||
[BiomeId.FACTORY]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
@ -1058,18 +1064,18 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.MACHOP,
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.VOLTORB,
|
||||
SpeciesId.BRONZOR,
|
||||
SpeciesId.TIMBURR,
|
||||
SpeciesId.KLINK
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BRONZOR, SpeciesId.KLEFKI ] },
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAGNEMITE, SpeciesId.ELEKID, SpeciesId.MAGBY, SpeciesId.KLEFKI ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PORYGON ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BELDUM ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GENESECT, SpeciesId.MAGEARNA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KLINKLANG, SpeciesId.KLEFKI ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BRONZONG, SpeciesId.ELECTIVIRE, SpeciesId.MAGMORTAR, SpeciesId.KLINKLANG, SpeciesId.KLEFKI ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.METAGROSS ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GENESECT, SpeciesId.MAGEARNA ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
@ -1163,44 +1169,42 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.MURKROW,
|
||||
SpeciesId.HOUNDOUR,
|
||||
SpeciesId.ZUBAT,
|
||||
SpeciesId.PARAS,
|
||||
SpeciesId.MISDREAVUS,
|
||||
SpeciesId.SABLEYE,
|
||||
SpeciesId.PURRLOIN,
|
||||
SpeciesId.PAWNIARD,
|
||||
SpeciesId.NICKIT,
|
||||
SpeciesId.IMPIDIMP,
|
||||
SpeciesId.MASCHIFF
|
||||
SpeciesId.WOOBAT,
|
||||
SpeciesId.IMPIDIMP
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GASTLY, SpeciesId.DUNSPARCE, SpeciesId.HOUNDOUR, SpeciesId.MAWILE, SpeciesId.WHISMUR ] },
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.ABSOL, SpeciesId.SPIRITOMB, SpeciesId.ZORUA, SpeciesId.DEINO ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.ABSOL, SpeciesId.SPIRITOMB, SpeciesId.FROSLASS, SpeciesId.ZORUA ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UMBREON ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UMBREON, SpeciesId.DEINO, SpeciesId.DREEPY ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DARKRAI, SpeciesId.GALAR_MOLTRES ] },
|
||||
[BiomePoolTier.BOSS]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.HOUNDOOM, SpeciesId.SABLEYE, SpeciesId.ABSOL, SpeciesId.HONCHKROW, SpeciesId.SPIRITOMB, SpeciesId.LIEPARD, SpeciesId.ZOROARK, SpeciesId.HYDREIGON, SpeciesId.THIEVUL, SpeciesId.GRIMMSNARL, SpeciesId.MABOSSTIFF, SpeciesId.KINGAMBIT ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.GENGAR, SpeciesId.CROBAT, SpeciesId.HOUNDOOM, SpeciesId.SABLEYE, SpeciesId.FROSLASS, SpeciesId.ZOROARK, SpeciesId.GRIMMSNARL ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UMBREON, SpeciesId.HISUI_SAMUROTT ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DARKRAI ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PALKIA, SpeciesId.YVELTAL, SpeciesId.GALAR_MOLTRES ] }
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.UMBREON, SpeciesId.SPIRITOMB, SpeciesId.HYDREIGON, SpeciesId.DRAGAPULT ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DARKRAI, SpeciesId.GALAR_MOLTRES ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PALKIA, SpeciesId.YVELTAL ] }
|
||||
},
|
||||
[BiomeId.SPACE]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SOLROCK ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SOLROCK ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.LUNATONE ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.LUNATONE ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.CLEFAIRY, SpeciesId.BRONZOR, SpeciesId.MUNNA, SpeciesId.MINIOR ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.CLEFFA, SpeciesId.BRONZOR, SpeciesId.MUNNA, SpeciesId.MINIOR ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.BALTOY, SpeciesId.ELGYEM ] },
|
||||
[BiomePoolTier.RARE]: {
|
||||
@ -1208,9 +1212,9 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.BELDUM, SpeciesId.SIGILYPH, SpeciesId.SOLOSIS ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.STARYU, SpeciesId.SIGILYPH, SpeciesId.SOLOSIS ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PORYGON ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PORYGON, SpeciesId.BELDUM ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.COSMOG, SpeciesId.CELESTEELA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [ SpeciesId.SOLROCK ], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [ SpeciesId.LUNATONE ], [TimeOfDay.ALL]: [ SpeciesId.CLEFABLE, SpeciesId.BRONZONG, SpeciesId.MUSHARNA, SpeciesId.REUNICLUS, SpeciesId.MINIOR ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.METAGROSS, SpeciesId.PORYGON_Z ] },
|
||||
@ -1224,9 +1228,12 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.DIGLETT,
|
||||
SpeciesId.MACHOP,
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.DRILBUR,
|
||||
SpeciesId.GRIMER,
|
||||
SpeciesId.PHANPY,
|
||||
SpeciesId.MAKUHITA,
|
||||
SpeciesId.NOSEPASS,
|
||||
SpeciesId.TIMBURR
|
||||
]
|
||||
},
|
||||
@ -1236,17 +1243,19 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.GRIMER,
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.KOFFING,
|
||||
SpeciesId.RHYHORN,
|
||||
SpeciesId.SCRAGGY
|
||||
SpeciesId.DRILBUR,
|
||||
SpeciesId.SCRAGGY,
|
||||
SpeciesId.ALOLA_GEODUDE,
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.GALAR_MEOWTH ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.HITMONLEE, SpeciesId.HITMONCHAN, SpeciesId.DURALUDON ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.HITMONTOP ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ONIX, SpeciesId.TYROGUE, SpeciesId.GALAR_MEOWTH ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.DURALUDON ] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.COBALION, SpeciesId.STAKATAKA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MACHAMP, SpeciesId.CONKELDURR ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.PERRSERKER ], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ARCHALUDON ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MACHAMP, SpeciesId.MAGNEZONE, SpeciesId.PROBOPASS, SpeciesId.CONKELDURR, SpeciesId.ALOLA_GOLEM ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PERRSERKER, SpeciesId.ARCHALUDON ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.COBALION, SpeciesId.STAKATAKA ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
@ -1254,14 +1263,14 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.VESPIQUEN, SpeciesId.CHERUBI, SpeciesId.SEWADDLE ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.VESPIQUEN, SpeciesId.CHERUBI, SpeciesId.SEWADDLE ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SHROOMISH, SpeciesId.PURRLOIN, SpeciesId.FOONGUS ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SPINARAK, SpeciesId.SHROOMISH, SpeciesId.PURRLOIN, SpeciesId.FOONGUS ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SPINARAK, SpeciesId.SHROOMISH, SpeciesId.PURRLOIN, SpeciesId.FOONGUS ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.AIPOM, SpeciesId.BLITZLE, SpeciesId.PIKIPEK ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.EXEGGCUTE, SpeciesId.TROPIUS, SpeciesId.COMBEE, SpeciesId.KOMALA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.EXEGGCUTE, SpeciesId.TROPIUS, SpeciesId.COMBEE, SpeciesId.KOMALA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.TANGELA, SpeciesId.SPINARAK, SpeciesId.PANCHAM ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.TANGELA, SpeciesId.PANCHAM ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.TANGELA, SpeciesId.PANCHAM ],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.PANSAGE,
|
||||
@ -1275,7 +1284,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.FOONGUS, SpeciesId.PASSIMIAN, SpeciesId.GALAR_PONYTA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.FOONGUS, SpeciesId.PASSIMIAN ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.FOONGUS, SpeciesId.PASSIMIAN, SpeciesId.GALAR_PONYTA ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.ORANGURU ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.ORANGURU ],
|
||||
[TimeOfDay.ALL]: [
|
||||
@ -1299,13 +1308,13 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
},
|
||||
[BiomePoolTier.BOSS_RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.AMOONGUSS, SpeciesId.GALAR_RAPIDASH ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.AMOONGUSS ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.AMOONGUSS, SpeciesId.GALAR_RAPIDASH ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.KANGASKHAN, SpeciesId.SCIZOR, SpeciesId.SLAKING, SpeciesId.LEAFEON, SpeciesId.SERPERIOR, SpeciesId.RILLABOOM ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.KANGASKHAN, SpeciesId.SCIZOR, SpeciesId.SLAKING, SpeciesId.LEAFEON, SpeciesId.SERPERIOR, SpeciesId.RILLABOOM, SpeciesId.KLEAVOR ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TAPU_LELE, SpeciesId.BUZZWOLE, SpeciesId.ZARUDE, SpeciesId.MUNKIDORI ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.KLEAVOR ] }
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
[BiomeId.FAIRY_CAVE]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
@ -1390,59 +1399,63 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
},
|
||||
[BiomeId.SLUM]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.PATRAT ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.PATRAT ],
|
||||
[TimeOfDay.DAWN]: [ ],
|
||||
[TimeOfDay.DAY]: [ ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SHUPPET ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SHUPPET ],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.RATTATA,
|
||||
SpeciesId.GRIMER,
|
||||
SpeciesId.DROWZEE,
|
||||
SpeciesId.KOFFING,
|
||||
SpeciesId.MURKROW,
|
||||
SpeciesId.GLAMEOW,
|
||||
SpeciesId.SCRAGGY,
|
||||
SpeciesId.TRUBBISH,
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.STUNKY ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.STUNKY ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.WORMADAM ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.HOUNDOUR, SpeciesId.WORMADAM, SpeciesId.STUNKY, SpeciesId.PANCHAM, SpeciesId.MASCHIFF, SpeciesId.ALOLA_RATTATA, SpeciesId.GALAR_ZIGZAGOON ],
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.TOXTRICITY, SpeciesId.GALAR_ZIGZAGOON ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.TOXTRICITY, SpeciesId.GALAR_ZIGZAGOON ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.VAROOM ]
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.SNEASEL, SpeciesId.GOTHITA, SpeciesId.PAWNIARD, SpeciesId.TOXEL, SpeciesId.SQUAWKABILLY, SpeciesId.VAROOM ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GUZZLORD ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.SKUNTANK, SpeciesId.WATCHOG ], [TimeOfDay.NIGHT]: [ SpeciesId.SKUNTANK, SpeciesId.WATCHOG ], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.WEEZING, SpeciesId.WORMADAM, SpeciesId.GARBODOR ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [ SpeciesId.TOXTRICITY, SpeciesId.OBSTAGOON ], [TimeOfDay.NIGHT]: [ SpeciesId.TOXTRICITY, SpeciesId.OBSTAGOON ], [TimeOfDay.ALL]: [ SpeciesId.REVAVROOM, SpeciesId.GALAR_WEEZING ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.WEEZING, SpeciesId.SKUNTANK, SpeciesId.SCRAFTY, SpeciesId.GARBODOR, SpeciesId.PANGORO, SpeciesId.ALOLA_RATICATE, SpeciesId.OBSTAGOON ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.WEAVILE, SpeciesId.TOXTRICITY, SpeciesId.REVAVROOM, SpeciesId.GALAR_WEEZING ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GUZZLORD ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] }
|
||||
},
|
||||
[BiomeId.SNOWY_FOREST]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SNEASEL, SpeciesId.TEDDIURSA, SpeciesId.SNOM ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SNEASEL, SpeciesId.TEDDIURSA, SpeciesId.SNOM ],
|
||||
[TimeOfDay.ALL]: [SpeciesId.PILOSWINE, SpeciesId.SNOVER, SpeciesId.EISCUE ]
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.GLALIE, SpeciesId.CUBCHOO ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.GLALIE, SpeciesId.CUBCHOO ],
|
||||
[TimeOfDay.DUSK]: [ SpeciesId.SNEASEL, SpeciesId.FROSLASS ],
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.SNEASEL, SpeciesId.FROSLASS ],
|
||||
[TimeOfDay.ALL]: [SpeciesId.SENTRET, SpeciesId.SWINUB, SpeciesId.SNOVER, SpeciesId.SNOM ]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SNEASEL, SpeciesId.TEDDIURSA, SpeciesId.STANTLER ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SNEASEL, SpeciesId.TEDDIURSA, SpeciesId.STANTLER ],
|
||||
[TimeOfDay.DAWN]: [],
|
||||
[TimeOfDay.DAY]: [],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: []
|
||||
[TimeOfDay.ALL]: [ SpeciesId.TEDDIURSA, SpeciesId.STANTLER, SpeciesId.SKIDDO, SpeciesId.EISCUE ]
|
||||
},
|
||||
[BiomePoolTier.RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.GALAR_DARUMAKA ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.GALAR_DARUMAKA ],
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.DELIBIRD, SpeciesId.ALOLA_SANDSHREW, SpeciesId.ALOLA_VULPIX ]
|
||||
[TimeOfDay.ALL]: [ SpeciesId.DELIBIRD, SpeciesId.CRYOGONAL, SpeciesId.AVALUGG, SpeciesId.ALOLA_SANDSHREW, SpeciesId.ALOLA_VULPIX ]
|
||||
},
|
||||
[BiomePoolTier.SUPER_RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.HISUI_SNEASEL ],
|
||||
@ -1452,7 +1465,7 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.ALL]: [ SpeciesId.GALAR_MR_MIME, SpeciesId.ARCTOZOLT, SpeciesId.HISUI_AVALUGG ]
|
||||
},
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GLASTRIER, SpeciesId.CHIEN_PAO, SpeciesId.GALAR_ARTICUNO ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.WYRDEER ], [TimeOfDay.DAY]: [ SpeciesId.WYRDEER ], [TimeOfDay.DUSK]: [ SpeciesId.FROSMOTH ], [TimeOfDay.NIGHT]: [ SpeciesId.FROSMOTH ], [TimeOfDay.ALL]: [ SpeciesId.ABOMASNOW, SpeciesId.URSALUNA ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [ SpeciesId.GLALIE, SpeciesId.BEARTIC ], [TimeOfDay.DAY]: [ SpeciesId.GLALIE, SpeciesId.BEARTIC ], [TimeOfDay.DUSK]: [ SpeciesId.WEAVILE, SpeciesId.FROSLASS ], [TimeOfDay.NIGHT]: [ SpeciesId.WEAVILE, SpeciesId.FROSLASS ], [TimeOfDay.ALL]: [ SpeciesId.ABOMASNOW, SpeciesId.MAMOSWINE, SpeciesId.WYRDEER, SpeciesId.URSALUNA ] },
|
||||
[BiomePoolTier.BOSS_RARE]: {
|
||||
[TimeOfDay.DAWN]: [ SpeciesId.SNEASLER, SpeciesId.GALAR_DARMANITAN ],
|
||||
[TimeOfDay.DAY]: [ SpeciesId.SNEASLER, SpeciesId.GALAR_DARMANITAN ],
|
||||
@ -1460,8 +1473,8 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.NIGHT]: [ SpeciesId.HISUI_ZOROARK ],
|
||||
[TimeOfDay.ALL]: [ SpeciesId.MR_RIME, SpeciesId.ARCTOZOLT, SpeciesId.ALOLA_SANDSLASH, SpeciesId.ALOLA_NINETALES ]
|
||||
},
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GLASTRIER, SpeciesId.CHIEN_PAO ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZACIAN, SpeciesId.GALAR_ARTICUNO ] }
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.GLASTRIER, SpeciesId.CHIEN_PAO, SpeciesId.GALAR_ARTICUNO ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZACIAN ] }
|
||||
},
|
||||
[BiomeId.ISLAND]: {
|
||||
[BiomePoolTier.COMMON]: {
|
||||
@ -1506,20 +1519,20 @@ export const biomePokemonPools: BiomePokemonPools = {
|
||||
[TimeOfDay.DUSK]: [],
|
||||
[TimeOfDay.NIGHT]: [],
|
||||
[TimeOfDay.ALL]: [
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.GRIMER,
|
||||
SpeciesId.VOLTORB,
|
||||
SpeciesId.BRONZOR,
|
||||
SpeciesId.MUNNA,
|
||||
SpeciesId.KLINK,
|
||||
]
|
||||
},
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.SOLOSIS ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.PORYGON ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.UNCOMMON]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MAGNEMITE, SpeciesId.SOLOSIS, SpeciesId.KLEFKI ] },
|
||||
[BiomePoolTier.RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.DITTO, SpeciesId.PORYGON, SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.TYPE_NULL ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.ELECTRODE, SpeciesId.BRONZONG, SpeciesId.MAGNEZONE, SpeciesId.PORYGON_Z, SpeciesId.REUNICLUS, SpeciesId.KLINKLANG ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ROTOM, SpeciesId.ZYGARDE, SpeciesId.TYPE_NULL ] },
|
||||
[BiomePoolTier.BOSS]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MUK, SpeciesId.ELECTRODE, SpeciesId.BRONZONG, SpeciesId.MAGNEZONE, SpeciesId.REUNICLUS, SpeciesId.KLINKLANG ] },
|
||||
[BiomePoolTier.BOSS_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.PORYGON_Z, SpeciesId.ROTOM ] },
|
||||
[BiomePoolTier.BOSS_SUPER_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.ZYGARDE, SpeciesId.TYPE_NULL ] },
|
||||
[BiomePoolTier.BOSS_ULTRA_RARE]: { [TimeOfDay.DAWN]: [], [TimeOfDay.DAY]: [], [TimeOfDay.DUSK]: [], [TimeOfDay.NIGHT]: [], [TimeOfDay.ALL]: [ SpeciesId.MEWTWO, SpeciesId.MIRAIDON ] }
|
||||
},
|
||||
[BiomeId.END]: {
|
||||
|
||||
@ -13,9 +13,9 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.SQUIRTLE]: [ MoveId.FREEZE_DRY, MoveId.ARMOR_CANNON, MoveId.SHORE_UP, MoveId.ORIGIN_PULSE ],
|
||||
[SpeciesId.CATERPIE]: [ MoveId.SANDSEAR_STORM, MoveId.SILK_TRAP, MoveId.TWIN_BEAM, MoveId.BLEAKWIND_STORM ],
|
||||
[SpeciesId.WEEDLE]: [ MoveId.THOUSAND_ARROWS, MoveId.NOXIOUS_TORQUE, MoveId.ATTACK_ORDER, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.PIDGEY]: [ MoveId.BLEAKWIND_STORM, MoveId.SANDSEAR_STORM, MoveId.CALM_MIND, MoveId.BOOMBURST ],
|
||||
[SpeciesId.PIDGEY]: [ MoveId.BLEAKWIND_STORM, MoveId.FOCUS_BLAST, MoveId.CALM_MIND, MoveId.BOOMBURST ],
|
||||
[SpeciesId.RATTATA]: [ MoveId.HYPER_FANG, MoveId.PSYCHIC_FANGS, MoveId.FIRE_FANG, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.SPEAROW]: [ MoveId.FLOATY_FALL, MoveId.EXTREME_SPEED, MoveId.KNOCK_OFF, MoveId.TRIPLE_ARROWS ],
|
||||
[SpeciesId.SPEAROW]: [ MoveId.FLOATY_FALL, MoveId.HYPER_DRILL, MoveId.SWORDS_DANCE, MoveId.TRIPLE_ARROWS ],
|
||||
[SpeciesId.EKANS]: [ MoveId.NOXIOUS_TORQUE, MoveId.DRAGON_DANCE, MoveId.SLACK_OFF, MoveId.SHED_TAIL ],
|
||||
[SpeciesId.SANDSHREW]: [ MoveId.HIGH_HORSEPOWER, MoveId.DIRE_CLAW, MoveId.SHORE_UP, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.NIDORAN_F]: [ MoveId.BANEFUL_BUNKER, MoveId.MOONLIGHT, MoveId.BARB_BARRAGE, MoveId.THOUSAND_WAVES ],
|
||||
@ -38,17 +38,17 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.GEODUDE]: [ MoveId.FLARE_BLITZ, MoveId.HEAD_SMASH, MoveId.SHORE_UP, MoveId.SHELL_SMASH ],
|
||||
[SpeciesId.PONYTA]: [ MoveId.HEADLONG_RUSH, MoveId.HIGH_JUMP_KICK, MoveId.SWORDS_DANCE, MoveId.VOLT_TACKLE ],
|
||||
[SpeciesId.SLOWPOKE]: [ MoveId.SPLISHY_SPLASH, MoveId.FROST_BREATH, MoveId.SHED_TAIL, MoveId.MYSTICAL_POWER ],
|
||||
[SpeciesId.MAGNEMITE]: [ MoveId.PARABOLIC_CHARGE, MoveId.FLAMETHROWER, MoveId.ICE_BEAM, MoveId.THUNDERCLAP ],
|
||||
[SpeciesId.MAGNEMITE]: [ MoveId.PARABOLIC_CHARGE, MoveId.FLAMETHROWER, MoveId.THUNDERCLAP, MoveId.ICE_BEAM ],
|
||||
[SpeciesId.FARFETCHD]: [ MoveId.IVY_CUDGEL, MoveId.TRIPLE_ARROWS, MoveId.DRILL_RUN, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.DODUO]: [ MoveId.TRIPLE_AXEL, MoveId.HYPER_DRILL, MoveId.FLOATY_FALL, MoveId.TRIPLE_ARROWS ],
|
||||
[SpeciesId.SEEL]: [ MoveId.FREEZE_DRY, MoveId.BOUNCY_BUBBLE, MoveId.SLACK_OFF, MoveId.STEAM_ERUPTION ],
|
||||
[SpeciesId.GRIMER]: [ MoveId.SUCKER_PUNCH, MoveId.CURSE, MoveId.NOXIOUS_TORQUE, MoveId.STRENGTH_SAP ],
|
||||
[SpeciesId.SHELLDER]: [ MoveId.ROCK_BLAST, MoveId.WATER_SHURIKEN, MoveId.BANEFUL_BUNKER, MoveId.BONE_RUSH ],
|
||||
[SpeciesId.SHELLDER]: [ MoveId.ROCK_BLAST, MoveId.WATER_SHURIKEN, MoveId.FREEZE_DRY, MoveId.BONE_RUSH ],
|
||||
[SpeciesId.GASTLY]: [ MoveId.MALIGNANT_CHAIN, MoveId.AURA_SPHERE, MoveId.PARTING_SHOT, MoveId.DARK_VOID ],
|
||||
[SpeciesId.ONIX]: [ MoveId.SHORE_UP, MoveId.THOUSAND_WAVES, MoveId.COIL, MoveId.DIAMOND_STORM ],
|
||||
[SpeciesId.DROWZEE]: [ MoveId.BADDY_BAD, MoveId.STRENGTH_SAP, MoveId.LUMINA_CRASH, MoveId.DARK_VOID ],
|
||||
[SpeciesId.KRABBY]: [ MoveId.DIRE_CLAW, MoveId.DRAGON_HAMMER, MoveId.IVY_CUDGEL, MoveId.JET_PUNCH ],
|
||||
[SpeciesId.VOLTORB]: [ MoveId.NASTY_PLOT, MoveId.FUSION_FLARE, MoveId.FROST_BREATH, MoveId.ELECTRO_DRIFT ],
|
||||
[SpeciesId.VOLTORB]: [ MoveId.NASTY_PLOT, MoveId.FUSION_FLARE, MoveId.ENERGY_BALL, MoveId.ELECTRO_DRIFT ],
|
||||
[SpeciesId.EXEGGCUTE]: [ MoveId.FICKLE_BEAM, MoveId.APPLE_ACID, MoveId.HEAT_WAVE, MoveId.LUMINA_CRASH ],
|
||||
[SpeciesId.CUBONE]: [ MoveId.HEAD_SMASH, MoveId.WOOD_HAMMER, MoveId.SHADOW_SNEAK, MoveId.BITTER_BLADE ],
|
||||
[SpeciesId.LICKITUNG]: [ MoveId.CRUSH_GRIP, MoveId.FIRE_LASH, MoveId.SLACK_OFF, MoveId.MAGICAL_TORQUE ],
|
||||
@ -69,7 +69,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.PORYGON]: [ MoveId.THUNDERCLAP, MoveId.DAZZLING_GLEAM, MoveId.FLAMETHROWER, MoveId.TECHNO_BLAST ],
|
||||
[SpeciesId.OMANYTE]: [ MoveId.FREEZE_DRY, MoveId.GIGA_DRAIN, MoveId.POWER_GEM, MoveId.STEAM_ERUPTION ],
|
||||
[SpeciesId.KABUTO]: [ MoveId.CEASELESS_EDGE, MoveId.HIGH_HORSEPOWER, MoveId.MIGHTY_CLEAVE, MoveId.CRABHAMMER ],
|
||||
[SpeciesId.AERODACTYL]: [ MoveId.FLOATY_FALL, MoveId.HIGH_HORSEPOWER, MoveId.STONE_AXE, MoveId.SWORDS_DANCE ],
|
||||
[SpeciesId.AERODACTYL]: [ MoveId.ACROBATICS, MoveId.HIGH_HORSEPOWER, MoveId.STONE_AXE, MoveId.SWORDS_DANCE ],
|
||||
[SpeciesId.ARTICUNO]: [ MoveId.EARTH_POWER, MoveId.CALM_MIND, MoveId.AURORA_VEIL, MoveId.AEROBLAST ],
|
||||
[SpeciesId.ZAPDOS]: [ MoveId.BLEAKWIND_STORM, MoveId.CALM_MIND, MoveId.SANDSEAR_STORM, MoveId.ELECTRO_SHOT ],
|
||||
[SpeciesId.MOLTRES]: [ MoveId.EARTH_POWER, MoveId.CALM_MIND, MoveId.AEROBLAST, MoveId.TORCH_SONG ],
|
||||
@ -86,23 +86,23 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.SPINARAK]: [ MoveId.PARTING_SHOT, MoveId.ATTACK_ORDER, MoveId.GASTRO_ACID, MoveId.STRENGTH_SAP ],
|
||||
[SpeciesId.CHINCHOU]: [ MoveId.THUNDERCLAP, MoveId.BOUNCY_BUBBLE, MoveId.THUNDER_CAGE, MoveId.TAIL_GLOW ],
|
||||
[SpeciesId.PICHU]: [ MoveId.MOONBLAST, MoveId.TRIPLE_AXEL, MoveId.FIERY_DANCE, MoveId.AURA_WHEEL ],
|
||||
[SpeciesId.CLEFFA]: [ MoveId.CALM_MIND, MoveId.EARTH_POWER, MoveId.WISH, MoveId.LIGHT_OF_RUIN ],
|
||||
[SpeciesId.CLEFFA]: [ MoveId.CALM_MIND, MoveId.EARTH_POWER, MoveId.LUNAR_BLESSING, MoveId.LIGHT_OF_RUIN ],
|
||||
[SpeciesId.IGGLYBUFF]: [ MoveId.DRAIN_PUNCH, MoveId.GRAV_APPLE, MoveId.SOFT_BOILED, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.TOGEPI]: [ MoveId.SCORCHING_SANDS, MoveId.SPLISHY_SPLASH, MoveId.RELIC_SONG, MoveId.FIERY_DANCE ],
|
||||
[SpeciesId.NATU]: [ MoveId.REVIVAL_BLESSING, MoveId.NASTY_PLOT, MoveId.MOONBLAST, MoveId.OBLIVION_WING ],
|
||||
[SpeciesId.MAREEP]: [ MoveId.ICE_BEAM, MoveId.PARABOLIC_CHARGE, MoveId.CORE_ENFORCER, MoveId.TAIL_GLOW ],
|
||||
[SpeciesId.MAREEP]: [ MoveId.FLAMETHROWER, MoveId.PARABOLIC_CHARGE, MoveId.CORE_ENFORCER, MoveId.TAIL_GLOW ],
|
||||
[SpeciesId.HOPPIP]: [ MoveId.FLOATY_FALL, MoveId.STRENGTH_SAP, MoveId.SAPPY_SEED, MoveId.SPORE ],
|
||||
[SpeciesId.AIPOM]: [ MoveId.ROCK_BLAST, MoveId.STORM_THROW, MoveId.FAKE_OUT, MoveId.SWORDS_DANCE ],
|
||||
[SpeciesId.SUNKERN]: [ MoveId.SPORE, MoveId.QUIVER_DANCE, MoveId.FIERY_DANCE, MoveId.HYDRO_STEAM ],
|
||||
[SpeciesId.YANMA]: [ MoveId.NASTY_PLOT, MoveId.EARTH_POWER, MoveId.HEAT_WAVE, MoveId.BLEAKWIND_STORM ],
|
||||
[SpeciesId.WOOPER]: [ MoveId.SIZZLY_SLIDE, MoveId.RECOVER, MoveId.SHED_TAIL, MoveId.SURGING_STRIKES ],
|
||||
[SpeciesId.MURKROW]: [ MoveId.TRIPLE_ARROWS, MoveId.FLOATY_FALL, MoveId.TIDY_UP, MoveId.WICKED_BLOW ],
|
||||
[SpeciesId.MURKROW]: [ MoveId.CROSS_CHOP, MoveId.FLOATY_FALL, MoveId.TIDY_UP, MoveId.WICKED_BLOW ],
|
||||
[SpeciesId.MISDREAVUS]: [ MoveId.TAKE_HEART, MoveId.MOONBLAST, MoveId.AURA_SPHERE, MoveId.MOONGEIST_BEAM ],
|
||||
[SpeciesId.UNOWN]: [ MoveId.NATURE_POWER, MoveId.COSMIC_POWER, MoveId.ANCIENT_POWER, MoveId.MYSTICAL_POWER ],
|
||||
[SpeciesId.GIRAFARIG]: [ MoveId.MYSTICAL_POWER, MoveId.NIGHT_DAZE, MoveId.RECOVER, MoveId.BOOMBURST ],
|
||||
[SpeciesId.PINECO]: [ MoveId.METAL_BURST, MoveId.RECOVER, MoveId.LEECH_LIFE, MoveId.SPIN_OUT ],
|
||||
[SpeciesId.DUNSPARCE]: [ MoveId.WICKED_TORQUE, MoveId.MAGICAL_TORQUE, MoveId.BLAZING_TORQUE, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.GLIGAR]: [ MoveId.FLOATY_FALL, MoveId.THOUSAND_WAVES, MoveId.SPIKY_SHIELD, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.GLIGAR]: [ MoveId.FLY, MoveId.THOUSAND_WAVES, MoveId.BANEFUL_BUNKER, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.SNUBBULL]: [ MoveId.FACADE, MoveId.HIGH_HORSEPOWER, MoveId.SWORDS_DANCE, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.QWILFISH]: [ MoveId.BARB_BARRAGE, MoveId.BANEFUL_BUNKER, MoveId.RECOVER, MoveId.FISHIOUS_REND ],
|
||||
[SpeciesId.SHUCKLE]: [ MoveId.STUFF_CHEEKS, MoveId.HEAL_ORDER, MoveId.BODY_PRESS, MoveId.SALT_CURE ],
|
||||
@ -132,7 +132,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.HO_OH]: [ MoveId.BRAVE_BIRD, MoveId.DRAGON_DANCE, MoveId.REVIVAL_BLESSING, MoveId.BOLT_BEAK ],
|
||||
[SpeciesId.CELEBI]: [ MoveId.PHOTON_GEYSER, MoveId.MATCHA_GOTCHA, MoveId.REVIVAL_BLESSING, MoveId.QUIVER_DANCE ],
|
||||
|
||||
[SpeciesId.TREECKO]: [ MoveId.NASTY_PLOT, MoveId.CORE_ENFORCER, MoveId.FLAMETHROWER, MoveId.SEED_FLARE ],
|
||||
[SpeciesId.TREECKO]: [ MoveId.NASTY_PLOT, MoveId.CLANGING_SCALES, MoveId.SECRET_SWORD, MoveId.SEED_FLARE ],
|
||||
[SpeciesId.TORCHIC]: [ MoveId.THUNDEROUS_KICK, MoveId.ZING_ZAP, MoveId.BURNING_BULWARK, MoveId.PYRO_BALL ],
|
||||
[SpeciesId.MUDKIP]: [ MoveId.SHORE_UP, MoveId.MOUNTAIN_GALE, MoveId.AQUA_STEP, MoveId.PRECIPICE_BLADES ],
|
||||
[SpeciesId.POOCHYENA]: [ MoveId.KNOCK_OFF, MoveId.CLOSE_COMBAT, MoveId.DIRE_CLAW, MoveId.VICTORY_DANCE ],
|
||||
@ -207,7 +207,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.DEOXYS]: [ MoveId.COLLISION_COURSE, MoveId.FUSION_FLARE, MoveId.PARTING_SHOT, MoveId.LUMINA_CRASH ],
|
||||
|
||||
[SpeciesId.TURTWIG]: [ MoveId.SHELL_SMASH, MoveId.STONE_AXE, MoveId.ICE_SPINNER, MoveId.SAPPY_SEED ],
|
||||
[SpeciesId.CHIMCHAR]: [ MoveId.THUNDERBOLT, MoveId.SECRET_SWORD, MoveId.TRIPLE_AXEL, MoveId.SACRED_FIRE ],
|
||||
[SpeciesId.CHIMCHAR]: [ MoveId.THUNDERBOLT, MoveId.SECRET_SWORD, MoveId.ICE_PUNCH, MoveId.SACRED_FIRE ],
|
||||
[SpeciesId.PIPLUP]: [ MoveId.KINGS_SHIELD, MoveId.TACHYON_CUTTER, MoveId.FREEZE_DRY, MoveId.STEAM_ERUPTION ],
|
||||
[SpeciesId.STARLY]: [ MoveId.SWORDS_DANCE, MoveId.HEAD_CHARGE, MoveId.FLARE_BLITZ, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.BIDOOF]: [ MoveId.EXTREME_SPEED, MoveId.COSMIC_POWER, MoveId.POWER_TRIP, MoveId.AQUA_STEP ],
|
||||
@ -234,7 +234,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.CHATOT]: [ MoveId.SPARKLING_ARIA, MoveId.BOOMBURST, MoveId.BATON_PASS, MoveId.TORCH_SONG ],
|
||||
[SpeciesId.SPIRITOMB]: [ MoveId.PARTING_SHOT, MoveId.BADDY_BAD, MoveId.BITTER_MALICE, MoveId.STRENGTH_SAP ],
|
||||
[SpeciesId.GIBLE]: [ MoveId.METEOR_MASH, MoveId.BITTER_BLADE, MoveId.LANDS_WRATH, MoveId.DRAGON_DANCE ],
|
||||
[SpeciesId.MUNCHLAX]: [ MoveId.STUFF_CHEEKS, MoveId.GRAV_APPLE, MoveId.SLACK_OFF, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.MUNCHLAX]: [ MoveId.OBSTRUCT, MoveId.GRAV_APPLE, MoveId.SUCKER_PUNCH, MoveId.SLACK_OFF ],
|
||||
[SpeciesId.RIOLU]: [ MoveId.THUNDEROUS_KICK, MoveId.TACHYON_CUTTER, MoveId.TRIPLE_AXEL, MoveId.SUNSTEEL_STRIKE ],
|
||||
[SpeciesId.HIPPOPOTAS]: [ MoveId.SHORE_UP, MoveId.STONE_AXE, MoveId.BULK_UP, MoveId.SALT_CURE ],
|
||||
[SpeciesId.SKORUPI]: [ MoveId.COIL, MoveId.DIRE_CLAW, MoveId.CRABHAMMER, MoveId.WICKED_BLOW ],
|
||||
@ -260,7 +260,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.ARCEUS]: [ MoveId.NO_RETREAT, MoveId.COLLISION_COURSE, MoveId.ASTRAL_BARRAGE, MoveId.MULTI_ATTACK ],
|
||||
|
||||
[SpeciesId.VICTINI]: [ MoveId.BLUE_FLARE, MoveId.BOLT_STRIKE, MoveId.LUSTER_PURGE, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.SNIVY]: [ MoveId.FLAMETHROWER, MoveId.CLANGING_SCALES, MoveId.MAKE_IT_RAIN, MoveId.FLEUR_CANNON ],
|
||||
[SpeciesId.SNIVY]: [ MoveId.BURNING_JEALOUSY, MoveId.LEECH_LIFE, MoveId.SUPERPOWER, MoveId.DRACO_METEOR ],
|
||||
[SpeciesId.TEPIG]: [ MoveId.WAVE_CRASH, MoveId.VOLT_TACKLE, MoveId.AXE_KICK, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.OSHAWOTT]: [ MoveId.FREEZE_DRY, MoveId.SHELL_SIDE_ARM, MoveId.SACRED_SWORD, MoveId.SHELL_SMASH ],
|
||||
[SpeciesId.PATRAT]: [ MoveId.FAKE_OUT, MoveId.INSTRUCT, MoveId.DYNAMIC_PUNCH, MoveId.EXTREME_SPEED ],
|
||||
@ -289,7 +289,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.DARUMAKA]: [ MoveId.DRAIN_PUNCH, MoveId.ZIPPY_ZAP, MoveId.HEADLONG_RUSH, MoveId.PYRO_BALL ],
|
||||
[SpeciesId.MARACTUS]: [ MoveId.EARTH_POWER, MoveId.SIZZLY_SLIDE, MoveId.FIERY_DANCE, MoveId.QUIVER_DANCE ],
|
||||
[SpeciesId.DWEBBLE]: [ MoveId.CRABHAMMER, MoveId.STONE_AXE, MoveId.LEECH_LIFE, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.SCRAGGY]: [ MoveId.SUCKER_PUNCH, MoveId.BULLET_PUNCH, MoveId.NOXIOUS_TORQUE, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.SCRAGGY]: [ MoveId.SUCKER_PUNCH, MoveId.SLACK_OFF, MoveId.GUNK_SHOT, MoveId.THUNDEROUS_KICK ],
|
||||
[SpeciesId.SIGILYPH]: [ MoveId.MOONBLAST, MoveId.PSYCHO_SHIFT, MoveId.ESPER_WING, MoveId.OBLIVION_WING ],
|
||||
[SpeciesId.YAMASK]: [ MoveId.STRENGTH_SAP, MoveId.GLARE, MoveId.AURA_SPHERE, MoveId.ASTRAL_BARRAGE ],
|
||||
[SpeciesId.TIRTOUGA]: [ MoveId.ICE_SPINNER, MoveId.AQUA_STEP, MoveId.SHORE_UP, MoveId.MIGHTY_CLEAVE ],
|
||||
@ -323,12 +323,12 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.GOLETT]: [ MoveId.SHIFT_GEAR, MoveId.DRAIN_PUNCH, MoveId.HEADLONG_RUSH, MoveId.RAGE_FIST ],
|
||||
[SpeciesId.PAWNIARD]: [ MoveId.SUCKER_PUNCH, MoveId.SPIRIT_BREAK, MoveId.LAST_RESPECTS, MoveId.BITTER_BLADE ],
|
||||
[SpeciesId.BOUFFALANT]: [ MoveId.HORN_LEECH, MoveId.HIGH_JUMP_KICK, MoveId.HEAD_SMASH, MoveId.FLARE_BLITZ ],
|
||||
[SpeciesId.RUFFLET]: [ MoveId.FLOATY_FALL, MoveId.AURA_SPHERE, MoveId.NO_RETREAT, MoveId.BOLT_BEAK ],
|
||||
[SpeciesId.RUFFLET]: [ MoveId.FLOATY_FALL, MoveId.AURA_SPHERE, MoveId.DRILL_RUN, MoveId.NO_RETREAT ],
|
||||
[SpeciesId.VULLABY]: [ MoveId.FOUL_PLAY, MoveId.BODY_PRESS, MoveId.ROOST, MoveId.RUINATION ],
|
||||
[SpeciesId.HEATMOR]: [ MoveId.EARTH_POWER, MoveId.OVERHEAT, MoveId.SUPERCELL_SLAM, MoveId.V_CREATE ],
|
||||
[SpeciesId.DURANT]: [ MoveId.HIGH_HORSEPOWER, MoveId.FIRST_IMPRESSION, MoveId.U_TURN, MoveId.BEHEMOTH_BASH ],
|
||||
[SpeciesId.DEINO]: [ MoveId.FIERY_WRATH, MoveId.ESPER_WING, MoveId.SLUDGE_BOMB, MoveId.FICKLE_BEAM ],
|
||||
[SpeciesId.LARVESTA]: [ MoveId.THUNDERBOLT, MoveId.DAZZLING_GLEAM, MoveId.EARTH_POWER, MoveId.HYDRO_STEAM ],
|
||||
[SpeciesId.LARVESTA]: [ MoveId.THUNDERBOLT, MoveId.DAZZLING_GLEAM, MoveId.SCALD, MoveId.SANDSEAR_STORM ],
|
||||
[SpeciesId.COBALION]: [ MoveId.BEHEMOTH_BLADE, MoveId.MIGHTY_CLEAVE, MoveId.CEASELESS_EDGE, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.TERRAKION]: [ MoveId.MIGHTY_CLEAVE, MoveId.HEADLONG_RUSH, MoveId.KNOCK_OFF, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.VIRIZION]: [ MoveId.SAPPY_SEED, MoveId.PSYBLADE, MoveId.STONE_AXE, MoveId.VICTORY_DANCE ],
|
||||
@ -348,7 +348,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.BUNNELBY]: [ MoveId.DRAIN_PUNCH, MoveId.TIDY_UP, MoveId.LANDS_WRATH, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.FLETCHLING]: [ MoveId.DRILL_RUN, MoveId.BURNING_BULWARK, MoveId.HEAD_SMASH, MoveId.VOLT_TACKLE ],
|
||||
[SpeciesId.SCATTERBUG]: [ MoveId.FOCUS_BLAST, MoveId.AFTER_YOU, MoveId.DECORATE, MoveId.BLIZZARD ],
|
||||
[SpeciesId.LITLEO]: [ MoveId.EARTH_POWER, MoveId.NASTY_PLOT, MoveId.BURNING_BULWARK, MoveId.BLUE_FLARE ],
|
||||
[SpeciesId.LITLEO]: [ MoveId.EARTH_POWER, MoveId.TAKE_HEART, MoveId.BURNING_BULWARK, MoveId.BOOMBURST ],
|
||||
[SpeciesId.FLABEBE]: [ MoveId.GLITZY_GLOW, MoveId.MYSTICAL_FIRE, MoveId.TAKE_HEART, MoveId.SEED_FLARE ],
|
||||
[SpeciesId.SKIDDO]: [ MoveId.HIGH_HORSEPOWER, MoveId.GRASSY_GLIDE, MoveId.STONE_AXE, MoveId.SAPPY_SEED ],
|
||||
[SpeciesId.PANCHAM]: [ MoveId.DRAIN_PUNCH, MoveId.SUCKER_PUNCH, MoveId.METEOR_MASH, MoveId.WICKED_BLOW ],
|
||||
@ -358,7 +358,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.SPRITZEE]: [ MoveId.SPEED_SWAP, MoveId.REVIVAL_BLESSING, MoveId.ROOST, MoveId.TORCH_SONG ],
|
||||
[SpeciesId.SWIRLIX]: [ MoveId.BELLY_DRUM, MoveId.HEADLONG_RUSH, MoveId.MAGICAL_TORQUE, MoveId.REVIVAL_BLESSING ],
|
||||
[SpeciesId.INKAY]: [ MoveId.POWER_TRIP, MoveId.SPIN_OUT, MoveId.RECOVER, MoveId.PSYCHO_BOOST ],
|
||||
[SpeciesId.BINACLE]: [ MoveId.TRIPLE_AXEL, MoveId.CRABHAMMER, MoveId.DIRE_CLAW, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.BINACLE]: [ MoveId.ICE_PUNCH, MoveId.CRABHAMMER, MoveId.METEOR_MASH, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.SKRELP]: [ MoveId.STRENGTH_SAP, MoveId.TRICK_ROOM, MoveId.CALM_MIND, MoveId.CORE_ENFORCER ],
|
||||
[SpeciesId.CLAUNCHER]: [ MoveId.SHELL_SMASH, MoveId.ARMOR_CANNON, MoveId.ENERGY_BALL, MoveId.ORIGIN_PULSE ],
|
||||
[SpeciesId.HELIOPTILE]: [ MoveId.WEATHER_BALL, MoveId.HYDRO_STEAM, MoveId.EARTH_POWER, MoveId.BOOMBURST ],
|
||||
@ -379,26 +379,26 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.DIANCIE]: [ MoveId.MAGICAL_TORQUE, MoveId.FIERY_DANCE, MoveId.SHORE_UP, MoveId.GEOMANCY ],
|
||||
[SpeciesId.HOOPA]: [ MoveId.PHOTON_GEYSER, MoveId.SECRET_SWORD, MoveId.FIERY_WRATH, MoveId.SHELL_SMASH ],
|
||||
[SpeciesId.VOLCANION]: [ MoveId.HYDRO_STEAM, MoveId.CALM_MIND, MoveId.SEARING_SHOT, MoveId.THUNDERCLAP ],
|
||||
[SpeciesId.ETERNAL_FLOETTE]: [ MoveId.MIND_BLOWN, MoveId.CHLOROBLAST, MoveId.LUSTER_PURGE, MoveId.QUIVER_DANCE ],
|
||||
[SpeciesId.ETERNAL_FLOETTE]: [ MoveId.MYSTICAL_FIRE, MoveId.CHLOROBLAST, MoveId.LUSTER_PURGE, MoveId.QUIVER_DANCE ],
|
||||
|
||||
[SpeciesId.ROWLET]: [ MoveId.THOUSAND_ARROWS, MoveId.SHADOW_BONE, MoveId.FIRST_IMPRESSION, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.LITTEN]: [ MoveId.SUCKER_PUNCH, MoveId.PARTING_SHOT, MoveId.SLACK_OFF, MoveId.SACRED_FIRE ],
|
||||
[SpeciesId.POPPLIO]: [ MoveId.PSYCHIC_NOISE, MoveId.MOONLIGHT, MoveId.OVERDRIVE, MoveId.TORCH_SONG ],
|
||||
[SpeciesId.PIKIPEK]: [ MoveId.TRAILBLAZE, MoveId.BONE_RUSH, MoveId.BURNING_BULWARK, MoveId.POPULATION_BOMB ],
|
||||
[SpeciesId.YUNGOOS]: [ MoveId.FAKE_OUT, MoveId.HIGH_HORSEPOWER, MoveId.TIDY_UP, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.GRUBBIN]: [ MoveId.ICE_BEAM, MoveId.EARTH_POWER, MoveId.CALM_MIND, MoveId.THUNDERCLAP ],
|
||||
[SpeciesId.GRUBBIN]: [ MoveId.THUNDERCLAP, MoveId.EARTH_POWER, MoveId.CALM_MIND, MoveId.ICE_BEAM ],
|
||||
[SpeciesId.CRABRAWLER]: [ MoveId.JET_PUNCH, MoveId.SHORE_UP, MoveId.MACH_PUNCH, MoveId.SURGING_STRIKES ],
|
||||
[SpeciesId.ORICORIO]: [ MoveId.QUIVER_DANCE, MoveId.FIERY_DANCE, MoveId.THUNDERCLAP, MoveId.OBLIVION_WING ],
|
||||
[SpeciesId.CUTIEFLY]: [ MoveId.STICKY_WEB, MoveId.SLEEP_POWDER, MoveId.HEAT_WAVE, MoveId.SPARKLY_SWIRL ],
|
||||
[SpeciesId.ROCKRUFF]: [ MoveId.HIGH_HORSEPOWER, MoveId.TIDY_UP, MoveId.ICE_SPINNER, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.WISHIWASHI]: [ MoveId.HEAL_ORDER, MoveId.FREEZE_DRY, MoveId.WATER_SHURIKEN, MoveId.TAIL_GLOW ],
|
||||
[SpeciesId.MAREANIE]: [ MoveId.CEASELESS_EDGE, MoveId.SIZZLY_SLIDE, MoveId.BODY_PRESS, MoveId.LEECH_SEED ],
|
||||
[SpeciesId.MAREANIE]: [ MoveId.CEASELESS_EDGE, MoveId.BARB_BARRAGE, MoveId.BODY_PRESS, MoveId.FLIP_TURN ],
|
||||
[SpeciesId.MUDBRAY]: [ MoveId.BODY_PRESS, MoveId.YAWN, MoveId.SHORE_UP, MoveId.THOUSAND_WAVES ],
|
||||
[SpeciesId.DEWPIDER]: [ MoveId.AQUA_STEP, MoveId.SILK_TRAP, MoveId.SWORDS_DANCE, MoveId.JET_PUNCH ],
|
||||
[SpeciesId.FOMANTIS]: [ MoveId.SUPERPOWER, MoveId.HEADLONG_RUSH, MoveId.ICE_HAMMER, MoveId.BITTER_BLADE ],
|
||||
[SpeciesId.MORELULL]: [ MoveId.CALM_MIND, MoveId.SAPPY_SEED, MoveId.DRAINING_KISS, MoveId.MATCHA_GOTCHA ],
|
||||
[SpeciesId.SALANDIT]: [ MoveId.SCALD, MoveId.MALIGNANT_CHAIN, MoveId.CORE_ENFORCER, MoveId.ERUPTION ],
|
||||
[SpeciesId.STUFFUL]: [ MoveId.DRAIN_PUNCH, MoveId.METEOR_MASH, MoveId.TRIPLE_AXEL, MoveId.RAGE_FIST ],
|
||||
[SpeciesId.STUFFUL]: [ MoveId.DRAIN_PUNCH, MoveId.METEOR_MASH, MoveId.ICE_HAMMER, MoveId.CRUSH_GRIP ],
|
||||
[SpeciesId.BOUNSWEET]: [ MoveId.TRIPLE_AXEL, MoveId.AQUA_STEP, MoveId.THUNDEROUS_KICK, MoveId.FLOWER_TRICK ],
|
||||
[SpeciesId.COMFEY]: [ MoveId.REVIVAL_BLESSING, MoveId.TAKE_HEART, MoveId.STRENGTH_SAP, MoveId.MATCHA_GOTCHA ],
|
||||
[SpeciesId.ORANGURU]: [ MoveId.JUNGLE_HEALING, MoveId.YAWN, MoveId.FOLLOW_ME, MoveId.LUMINA_CRASH ],
|
||||
@ -416,7 +416,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.DRAMPA]: [ MoveId.SLACK_OFF, MoveId.TRICK_ROOM, MoveId.CORE_ENFORCER, MoveId.BOOMBURST ],
|
||||
[SpeciesId.DHELMISE]: [ MoveId.SHADOW_BONE, MoveId.IVY_CUDGEL, MoveId.TRIPLE_DIVE, MoveId.STRENGTH_SAP ],
|
||||
[SpeciesId.JANGMO_O]: [ MoveId.BODY_PRESS, MoveId.SHELL_SIDE_ARM, MoveId.SECRET_SWORD, MoveId.GLAIVE_RUSH ],
|
||||
[SpeciesId.TAPU_KOKO]: [ MoveId.MAGICAL_TORQUE, MoveId.TRIPLE_AXEL, MoveId.SWORDS_DANCE, MoveId.BOLT_STRIKE ],
|
||||
[SpeciesId.TAPU_KOKO]: [ MoveId.PLAY_ROUGH, MoveId.ZING_ZAP, MoveId.SWORDS_DANCE, MoveId.TRIPLE_AXEL ],
|
||||
[SpeciesId.TAPU_LELE]: [ MoveId.MOONLIGHT, MoveId.NASTY_PLOT, MoveId.HEAT_WAVE, MoveId.EXPANDING_FORCE ],
|
||||
[SpeciesId.TAPU_BULU]: [ MoveId.SAPPY_SEED, MoveId.LANDS_WRATH, MoveId.MAGICAL_TORQUE, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.TAPU_FINI]: [ MoveId.SPRINGTIDE_STORM, MoveId.EARTH_POWER, MoveId.RECOVER, MoveId.QUIVER_DANCE ],
|
||||
@ -429,11 +429,11 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.KARTANA]: [ MoveId.MIGHTY_CLEAVE, MoveId.DUAL_CHOP, MoveId.BEHEMOTH_BLADE, MoveId.BITTER_BLADE ],
|
||||
[SpeciesId.GUZZLORD]: [ MoveId.SUCKER_PUNCH, MoveId.COMEUPPANCE, MoveId.SLACK_OFF, MoveId.SHED_TAIL ],
|
||||
[SpeciesId.NECROZMA]: [ MoveId.DYNAMAX_CANNON, MoveId.SACRED_FIRE, MoveId.ASTRAL_BARRAGE, MoveId.CLANGOROUS_SOUL ],
|
||||
[SpeciesId.MAGEARNA]: [ MoveId.STRENGTH_SAP, MoveId.EARTH_POWER, MoveId.MOONBLAST, MoveId.MAKE_IT_RAIN ],
|
||||
[SpeciesId.MAGEARNA]: [ MoveId.RECOVER, MoveId.EARTH_POWER, MoveId.MOONBLAST, MoveId.MAKE_IT_RAIN ],
|
||||
[SpeciesId.MARSHADOW]: [ MoveId.POWER_UP_PUNCH, MoveId.BONEMERANG, MoveId.METEOR_MASH, MoveId.TRIPLE_AXEL ],
|
||||
[SpeciesId.POIPOLE]: [ MoveId.MALIGNANT_CHAIN, MoveId.ICE_BEAM, MoveId.ARMOR_CANNON, MoveId.CLANGING_SCALES ],
|
||||
[SpeciesId.STAKATAKA]: [ MoveId.HEAVY_SLAM, MoveId.HEAL_ORDER, MoveId.CURSE, MoveId.SALT_CURE ],
|
||||
[SpeciesId.BLACEPHALON]: [ MoveId.STEEL_BEAM, MoveId.MOONBLAST, MoveId.CHLOROBLAST, MoveId.MOONGEIST_BEAM ],
|
||||
[SpeciesId.BLACEPHALON]: [ MoveId.CHILLY_RECEPTION, MoveId.MOONBLAST, MoveId.ENERGY_BALL, MoveId.MOONGEIST_BEAM ],
|
||||
[SpeciesId.ZERAORA]: [ MoveId.SWORDS_DANCE, MoveId.FIRE_LASH, MoveId.COLLISION_COURSE, MoveId.TRIPLE_AXEL ],
|
||||
[SpeciesId.MELTAN]: [ MoveId.BULLET_PUNCH, MoveId.DRAIN_PUNCH, MoveId.BULK_UP, MoveId.PLASMA_FISTS ],
|
||||
[SpeciesId.ALOLA_RATTATA]: [ MoveId.FALSE_SURRENDER, MoveId.PSYCHIC_FANGS, MoveId.COIL, MoveId.EXTREME_SPEED ],
|
||||
@ -455,7 +455,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.WOOLOO]: [ MoveId.NUZZLE, MoveId.MILK_DRINK, MoveId.BODY_PRESS, MoveId.MULTI_ATTACK ],
|
||||
[SpeciesId.CHEWTLE]: [ MoveId.ICE_FANG, MoveId.PSYCHIC_FANGS, MoveId.SHELL_SMASH, MoveId.MIGHTY_CLEAVE ],
|
||||
[SpeciesId.YAMPER]: [ MoveId.ICE_FANG, MoveId.SWORDS_DANCE, MoveId.THUNDER_FANG, MoveId.BOLT_STRIKE ],
|
||||
[SpeciesId.ROLYCOLY]: [ MoveId.BITTER_BLADE, MoveId.BODY_PRESS, MoveId.BULK_UP, MoveId.DIAMOND_STORM ],
|
||||
[SpeciesId.ROLYCOLY]: [ MoveId.BLAZING_TORQUE, MoveId.BURNING_BULWARK, MoveId.RECOVER, MoveId.DIAMOND_STORM ],
|
||||
[SpeciesId.APPLIN]: [ MoveId.CORE_ENFORCER, MoveId.COMBAT_TORQUE, MoveId.SAPPY_SEED, MoveId.MATCHA_GOTCHA ],
|
||||
[SpeciesId.SILICOBRA]: [ MoveId.SHORE_UP, MoveId.SHED_TAIL, MoveId.MOUNTAIN_GALE, MoveId.THOUSAND_ARROWS ],
|
||||
[SpeciesId.CRAMORANT]: [ MoveId.APPLE_ACID, MoveId.SURF, MoveId.BOLT_BEAK, MoveId.OBLIVION_WING ],
|
||||
@ -467,19 +467,19 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.HATENNA]: [ MoveId.RECOVER, MoveId.MOONBLAST, MoveId.BUZZY_BUZZ, MoveId.TORCH_SONG ],
|
||||
[SpeciesId.IMPIDIMP]: [ MoveId.SLACK_OFF, MoveId.PARTING_SHOT, MoveId.OCTOLOCK, MoveId.WICKED_BLOW ],
|
||||
[SpeciesId.MILCERY]: [ MoveId.MOONBLAST, MoveId.CHILLY_RECEPTION, MoveId.EARTH_POWER, MoveId.GEOMANCY ],
|
||||
[SpeciesId.FALINKS]: [ MoveId.BATON_PASS, MoveId.POWER_TRIP, MoveId.COMBAT_TORQUE, MoveId.HEAL_ORDER ],
|
||||
[SpeciesId.FALINKS]: [ MoveId.BATON_PASS, MoveId.POWER_TRIP, MoveId.SACRED_SWORD, MoveId.HEAL_ORDER ],
|
||||
[SpeciesId.PINCURCHIN]: [ MoveId.TRICK_ROOM, MoveId.VOLT_SWITCH, MoveId.STRENGTH_SAP, MoveId.THUNDERCLAP ],
|
||||
[SpeciesId.SNOM]: [ MoveId.FROST_BREATH, MoveId.HEAL_ORDER, MoveId.EARTH_POWER, MoveId.SPORE ],
|
||||
[SpeciesId.STONJOURNER]: [ MoveId.AXE_KICK, MoveId.HELPING_HAND, MoveId.ACCELEROCK, MoveId.DIAMOND_STORM ],
|
||||
[SpeciesId.EISCUE]: [ MoveId.TRIPLE_AXEL, MoveId.AQUA_STEP, MoveId.AXE_KICK, MoveId.SHELL_SMASH ],
|
||||
[SpeciesId.INDEEDEE]: [ MoveId.MATCHA_GOTCHA, MoveId.EXPANDING_FORCE, MoveId.MOONBLAST, MoveId.REVIVAL_BLESSING ],
|
||||
[SpeciesId.MORPEKO]: [ MoveId.TRIPLE_AXEL, MoveId.OBSTRUCT, MoveId.SWORDS_DANCE, MoveId.COLLISION_COURSE ],
|
||||
[SpeciesId.MORPEKO]: [ MoveId.ICE_SPINNER, MoveId.OBSTRUCT, MoveId.STUFF_CHEEKS, MoveId.COLLISION_COURSE ],
|
||||
[SpeciesId.CUFANT]: [ MoveId.LIQUIDATION, MoveId.CURSE, MoveId.COMBAT_TORQUE, MoveId.GIGATON_HAMMER ],
|
||||
[SpeciesId.DRACOZOLT]: [ MoveId.TRIPLE_AXEL, MoveId.GUNK_SHOT, MoveId.FIRE_LASH, MoveId.DRAGON_DANCE ],
|
||||
[SpeciesId.ARCTOZOLT]: [ MoveId.MOUNTAIN_GALE, MoveId.AQUA_STEP, MoveId.HIGH_HORSEPOWER, MoveId.SHIFT_GEAR ],
|
||||
[SpeciesId.DRACOVISH]: [ MoveId.TRIPLE_AXEL, MoveId.DRAGON_HAMMER, MoveId.THUNDER_FANG, MoveId.DRAGON_DANCE ],
|
||||
[SpeciesId.ARCTOVISH]: [ MoveId.ICE_FANG, MoveId.THUNDER_FANG, MoveId.HIGH_HORSEPOWER, MoveId.SHIFT_GEAR ],
|
||||
[SpeciesId.DURALUDON]: [ MoveId.CORE_ENFORCER, MoveId.BODY_PRESS, MoveId.RECOVER, MoveId.TACHYON_CUTTER ],
|
||||
[SpeciesId.DURALUDON]: [ MoveId.HEAT_WAVE, MoveId.BODY_PRESS, MoveId.THUNDERCLAP, MoveId.CORE_ENFORCER ],
|
||||
[SpeciesId.DREEPY]: [ MoveId.SHADOW_BONE, MoveId.POWER_UP_PUNCH, MoveId.FIRE_LASH, MoveId.DIRE_CLAW ],
|
||||
[SpeciesId.ZACIAN]: [ MoveId.MAGICAL_TORQUE, MoveId.MIGHTY_CLEAVE, MoveId.EARTHQUAKE, MoveId.BITTER_BLADE ],
|
||||
[SpeciesId.ZAMAZENTA]: [ MoveId.BULK_UP, MoveId.BODY_PRESS, MoveId.POWER_TRIP, MoveId.SLACK_OFF ],
|
||||
@ -505,7 +505,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.GALAR_YAMASK]: [ MoveId.STRENGTH_SAP, MoveId.DIRE_CLAW, MoveId.THOUSAND_WAVES, MoveId.SPECTRAL_THIEF ],
|
||||
[SpeciesId.GALAR_STUNFISK]: [ MoveId.SPIKY_SHIELD, MoveId.THOUSAND_ARROWS, MoveId.STRENGTH_SAP, MoveId.DOUBLE_IRON_BASH ],
|
||||
[SpeciesId.HISUI_GROWLITHE]: [ MoveId.WAVE_CRASH, MoveId.HEAD_SMASH, MoveId.VOLT_TACKLE, MoveId.DRAGON_DANCE ],
|
||||
[SpeciesId.HISUI_VOLTORB]: [ MoveId.FROST_BREATH, MoveId.NASTY_PLOT, MoveId.APPLE_ACID, MoveId.ELECTRO_DRIFT ],
|
||||
[SpeciesId.HISUI_VOLTORB]: [ MoveId.DAZZLING_GLEAM, MoveId.LEECH_SEED, MoveId.APPLE_ACID, MoveId.MIND_BLOWN ],
|
||||
[SpeciesId.HISUI_QWILFISH]: [ MoveId.CEASELESS_EDGE, MoveId.BANEFUL_BUNKER, MoveId.RECOVER, MoveId.FISHIOUS_REND ],
|
||||
[SpeciesId.HISUI_SNEASEL]: [ MoveId.DRAIN_PUNCH, MoveId.KNOCK_OFF, MoveId.PSYCHIC_FANGS, MoveId.TRIPLE_AXEL ],
|
||||
[SpeciesId.HISUI_ZORUA]: [ MoveId.MOONBLAST, MoveId.SECRET_SWORD, MoveId.PARTING_SHOT, MoveId.BLOOD_MOON ],
|
||||
@ -520,7 +520,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.TANDEMAUS]: [ MoveId.BATON_PASS, MoveId.FAKE_OUT, MoveId.POWER_UP_PUNCH, MoveId.REVIVAL_BLESSING ],
|
||||
[SpeciesId.FIDOUGH]: [ MoveId.SOFT_BOILED, MoveId.HIGH_HORSEPOWER, MoveId.SIZZLY_SLIDE, MoveId.TIDY_UP ],
|
||||
[SpeciesId.SMOLIV]: [ MoveId.STRENGTH_SAP, MoveId.EARTH_POWER, MoveId.CALM_MIND, MoveId.BOOMBURST ],
|
||||
[SpeciesId.SQUAWKABILLY]: [ MoveId.PARTING_SHOT, MoveId.EARTHQUAKE, MoveId.FLARE_BLITZ, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.SQUAWKABILLY]: [ MoveId.PARTING_SHOT, MoveId.BULK_UP, MoveId.CLOSE_COMBAT, MoveId.EXTREME_SPEED ],
|
||||
[SpeciesId.NACLI]: [ MoveId.KNOCK_OFF, MoveId.TOXIC, MoveId.SAND_TOMB, MoveId.DIAMOND_STORM ],
|
||||
[SpeciesId.CHARCADET]: [ MoveId.SACRED_SWORD, MoveId.PHOTON_GEYSER, MoveId.MOONBLAST, MoveId.SPECTRAL_THIEF ],
|
||||
[SpeciesId.TADBULB]: [ MoveId.PARABOLIC_CHARGE, MoveId.SCALD, MoveId.EARTH_POWER, MoveId.ELECTRO_SHOT ],
|
||||
@ -552,7 +552,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.BRUTE_BONNET]: [ MoveId.SAPPY_SEED, MoveId.STRENGTH_SAP, MoveId.EARTHQUAKE, MoveId.WICKED_BLOW ],
|
||||
[SpeciesId.FLUTTER_MANE]: [ MoveId.MOONLIGHT, MoveId.NASTY_PLOT, MoveId.EARTH_POWER, MoveId.MOONGEIST_BEAM ],
|
||||
[SpeciesId.SLITHER_WING]: [ MoveId.ROCK_SLIDE, MoveId.THUNDEROUS_KICK, MoveId.SUNSTEEL_STRIKE, MoveId.VICTORY_DANCE ],
|
||||
[SpeciesId.SANDY_SHOCKS]: [ MoveId.MORNING_SUN, MoveId.ICE_BEAM, MoveId.NASTY_PLOT, MoveId.THUNDERCLAP ],
|
||||
[SpeciesId.SANDY_SHOCKS]: [ MoveId.MORNING_SUN, MoveId.THUNDERCLAP, MoveId.NASTY_PLOT, MoveId.ICE_BEAM ],
|
||||
[SpeciesId.IRON_TREADS]: [ MoveId.FUSION_BOLT, MoveId.SHIFT_GEAR, MoveId.SHORE_UP, MoveId.SUNSTEEL_STRIKE ],
|
||||
[SpeciesId.IRON_BUNDLE]: [ MoveId.EARTH_POWER, MoveId.SPLISHY_SPLASH, MoveId.VOLT_SWITCH, MoveId.NASTY_PLOT ],
|
||||
[SpeciesId.IRON_HANDS]: [ MoveId.DRAIN_PUNCH, MoveId.BULK_UP, MoveId.PLASMA_FISTS, MoveId.ICE_HAMMER ],
|
||||
@ -582,7 +582,7 @@ export const speciesEggMoves = {
|
||||
[SpeciesId.IRON_CROWN]: [ MoveId.NASTY_PLOT, MoveId.SECRET_SWORD, MoveId.PSYSTRIKE, MoveId.ELECTRO_DRIFT ],
|
||||
[SpeciesId.TERAPAGOS]: [ MoveId.MOONBLAST, MoveId.NASTY_PLOT, MoveId.ASTRAL_BARRAGE, MoveId.RECOVER ],
|
||||
[SpeciesId.PECHARUNT]: [ MoveId.TAKE_HEART, MoveId.BODY_PRESS, MoveId.SAPPY_SEED, MoveId.ASTRAL_BARRAGE ],
|
||||
[SpeciesId.PALDEA_TAUROS]: [ MoveId.NO_RETREAT, MoveId.BLAZING_TORQUE, MoveId.AQUA_STEP, MoveId.THUNDEROUS_KICK ],
|
||||
[SpeciesId.PALDEA_TAUROS]: [ MoveId.U_TURN, MoveId.SUCKER_PUNCH, MoveId.HORN_LEECH, MoveId.THUNDEROUS_KICK ],
|
||||
[SpeciesId.PALDEA_WOOPER]: [ MoveId.STONE_AXE, MoveId.RECOVER, MoveId.BANEFUL_BUNKER, MoveId.BARB_BARRAGE ],
|
||||
[SpeciesId.BLOODMOON_URSALUNA]: [ MoveId.NASTY_PLOT, MoveId.ROCK_POLISH, MoveId.SANDSEAR_STORM, MoveId.BOOMBURST ]
|
||||
} satisfies Partial<Record<SpeciesId, [MoveId, MoveId, MoveId, MoveId]>>;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -16,9 +16,9 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.CHARMANDER]: { 0: AbilityId.SHEER_FORCE },
|
||||
[SpeciesId.CHARMELEON]: { 0: AbilityId.BEAST_BOOST },
|
||||
[SpeciesId.CHARIZARD]: { 0: AbilityId.BEAST_BOOST, 1: AbilityId.LEVITATE, 2: AbilityId.TURBOBLAZE, 3: AbilityId.UNNERVE },
|
||||
[SpeciesId.SQUIRTLE]: { 0: AbilityId.DAUNTLESS_SHIELD },
|
||||
[SpeciesId.WARTORTLE]: { 0: AbilityId.DAUNTLESS_SHIELD },
|
||||
[SpeciesId.BLASTOISE]: { 0: AbilityId.DAUNTLESS_SHIELD, 1: AbilityId.BULLETPROOF, 2: AbilityId.BULLETPROOF },
|
||||
[SpeciesId.SQUIRTLE]: { 0: AbilityId.BULLETPROOF },
|
||||
[SpeciesId.WARTORTLE]: { 0: AbilityId.BULLETPROOF },
|
||||
[SpeciesId.BLASTOISE]: { 0: AbilityId.BULLETPROOF, 1: AbilityId.BULLETPROOF, 2: AbilityId.BULLETPROOF },
|
||||
[SpeciesId.CATERPIE]: { 0: AbilityId.GLUTTONY },
|
||||
[SpeciesId.METAPOD]: { 0: AbilityId.STURDY },
|
||||
[SpeciesId.BUTTERFREE]: { 0: AbilityId.MAGICIAN, 1: AbilityId.MAGICIAN },
|
||||
@ -30,8 +30,8 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.PIDGEOT]: { 0: AbilityId.SHEER_FORCE, 1: AbilityId.SHEER_FORCE },
|
||||
[SpeciesId.RATTATA]: { 0: AbilityId.STRONG_JAW },
|
||||
[SpeciesId.RATICATE]: { 0: AbilityId.STRONG_JAW },
|
||||
[SpeciesId.SPEAROW]: { 0: AbilityId.MOXIE },
|
||||
[SpeciesId.FEAROW]: { 0: AbilityId.MOXIE },
|
||||
[SpeciesId.SPEAROW]: { 0: AbilityId.SPEED_BOOST },
|
||||
[SpeciesId.FEAROW]: { 0: AbilityId.SPEED_BOOST },
|
||||
[SpeciesId.EKANS]: { 0: AbilityId.REGENERATOR },
|
||||
[SpeciesId.ARBOK]: { 0: AbilityId.REGENERATOR },
|
||||
[SpeciesId.SANDSHREW]: { 0: AbilityId.TOUGH_CLAWS },
|
||||
@ -101,9 +101,9 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.MUK]: { 0: AbilityId.WATER_ABSORB },
|
||||
[SpeciesId.SHELLDER]: { 0: AbilityId.STURDY },
|
||||
[SpeciesId.CLOYSTER]: { 0: AbilityId.ICE_SCALES },
|
||||
[SpeciesId.GASTLY]: { 0: AbilityId.SHADOW_SHIELD },
|
||||
[SpeciesId.HAUNTER]: { 0: AbilityId.SHADOW_SHIELD },
|
||||
[SpeciesId.GENGAR]: { 0: AbilityId.SHADOW_SHIELD, 1: AbilityId.UNNERVE, 2: AbilityId.GLUTTONY },
|
||||
[SpeciesId.GASTLY]: { 0: AbilityId.PRANKSTER },
|
||||
[SpeciesId.HAUNTER]: { 0: AbilityId.PRANKSTER },
|
||||
[SpeciesId.GENGAR]: { 0: AbilityId.LEVITATE, 1: AbilityId.UNNERVE, 2: AbilityId.REGENERATOR },
|
||||
[SpeciesId.ONIX]: { 0: AbilityId.ROCKY_PAYLOAD },
|
||||
[SpeciesId.STEELIX]: { 0: AbilityId.ROCKY_PAYLOAD, 1: AbilityId.SAND_SPIT },
|
||||
[SpeciesId.DROWZEE]: { 0: AbilityId.MAGICIAN },
|
||||
@ -506,7 +506,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.SNOVER]: { 0: AbilityId.SLUSH_RUSH },
|
||||
[SpeciesId.ABOMASNOW]: { 0: AbilityId.SLUSH_RUSH, 1: AbilityId.SEED_SOWER },
|
||||
[SpeciesId.ROTOM]: { 0: AbilityId.HADRON_ENGINE, 1: AbilityId.HADRON_ENGINE, 2: AbilityId.HADRON_ENGINE, 3: AbilityId.HADRON_ENGINE, 4: AbilityId.HADRON_ENGINE, 5: AbilityId.HADRON_ENGINE },
|
||||
[SpeciesId.UXIE]: { 0: AbilityId.ILLUSION },
|
||||
[SpeciesId.UXIE]: { 0: AbilityId.MAGIC_BOUNCE },
|
||||
[SpeciesId.MESPRIT]: { 0: AbilityId.MOODY },
|
||||
[SpeciesId.AZELF]: { 0: AbilityId.NEUROFORCE },
|
||||
[SpeciesId.DIALGA]: { 0: AbilityId.BERSERK, 1: AbilityId.BERSERK },
|
||||
@ -589,8 +589,8 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.MARACTUS]: { 0: AbilityId.WELL_BAKED_BODY },
|
||||
[SpeciesId.DWEBBLE]: { 0: AbilityId.ROCKY_PAYLOAD },
|
||||
[SpeciesId.CRUSTLE]: { 0: AbilityId.ROCKY_PAYLOAD },
|
||||
[SpeciesId.SCRAGGY]: { 0: AbilityId.PROTEAN },
|
||||
[SpeciesId.SCRAFTY]: { 0: AbilityId.PROTEAN },
|
||||
[SpeciesId.SCRAGGY]: { 0: AbilityId.UNBURDEN },
|
||||
[SpeciesId.SCRAFTY]: { 0: AbilityId.UNBURDEN },
|
||||
[SpeciesId.SIGILYPH]: { 0: AbilityId.FLARE_BOOST },
|
||||
[SpeciesId.YAMASK]: { 0: AbilityId.PURIFYING_SALT },
|
||||
[SpeciesId.COFAGRIGUS]: { 0: AbilityId.PURIFYING_SALT },
|
||||
@ -669,7 +669,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.ZWEILOUS]: { 0: AbilityId.NO_GUARD },
|
||||
[SpeciesId.HYDREIGON]: { 0: AbilityId.PARENTAL_BOND },
|
||||
[SpeciesId.LARVESTA]: { 0: AbilityId.FLASH_FIRE },
|
||||
[SpeciesId.VOLCARONA]: { 0: AbilityId.DROUGHT },
|
||||
[SpeciesId.VOLCARONA]: { 0: AbilityId.FLASH_FIRE },
|
||||
[SpeciesId.COBALION]: { 0: AbilityId.INTREPID_SWORD },
|
||||
[SpeciesId.TERRAKION]: { 0: AbilityId.ROCKY_PAYLOAD },
|
||||
[SpeciesId.VIRIZION]: { 0: AbilityId.SHARPNESS },
|
||||
@ -689,9 +689,9 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.FENNEKIN]: { 0: AbilityId.FLUFFY },
|
||||
[SpeciesId.BRAIXEN]: { 0: AbilityId.PSYCHIC_SURGE },
|
||||
[SpeciesId.DELPHOX]: { 0: AbilityId.PSYCHIC_SURGE },
|
||||
[SpeciesId.FROAKIE]: { 0: AbilityId.TECHNICIAN, 1: AbilityId.STAKEOUT },
|
||||
[SpeciesId.FROGADIER]: { 0: AbilityId.TECHNICIAN, 1: AbilityId.STAKEOUT },
|
||||
[SpeciesId.GRENINJA]: { 0: AbilityId.TECHNICIAN, 1: AbilityId.STAKEOUT, 2: AbilityId.SUPER_LUCK },
|
||||
[SpeciesId.FROAKIE]: { 0: AbilityId.STAKEOUT, 1: AbilityId.STAKEOUT },
|
||||
[SpeciesId.FROGADIER]: { 0: AbilityId.STAKEOUT, 1: AbilityId.STAKEOUT },
|
||||
[SpeciesId.GRENINJA]: { 0: AbilityId.STAKEOUT, 1: AbilityId.STAKEOUT, 2: AbilityId.SUPER_LUCK },
|
||||
[SpeciesId.BUNNELBY]: { 0: AbilityId.INNER_FOCUS },
|
||||
[SpeciesId.DIGGERSBY]: { 0: AbilityId.THICK_FAT },
|
||||
[SpeciesId.FLETCHLING]: { 0: AbilityId.FLAME_BODY },
|
||||
@ -700,8 +700,8 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.SCATTERBUG]: { 0: AbilityId.RUN_AWAY, 1: AbilityId.RUN_AWAY, 2: AbilityId.RUN_AWAY, 3: AbilityId.RUN_AWAY, 4: AbilityId.RUN_AWAY, 5: AbilityId.RUN_AWAY, 6: AbilityId.RUN_AWAY, 7: AbilityId.RUN_AWAY, 8: AbilityId.RUN_AWAY, 9: AbilityId.RUN_AWAY, 10: AbilityId.RUN_AWAY, 11: AbilityId.RUN_AWAY, 12: AbilityId.RUN_AWAY, 13: AbilityId.RUN_AWAY, 14: AbilityId.RUN_AWAY, 15: AbilityId.RUN_AWAY, 16: AbilityId.RUN_AWAY, 17: AbilityId.RUN_AWAY, 18: AbilityId.RUN_AWAY, 19: AbilityId.RUN_AWAY },
|
||||
[SpeciesId.SPEWPA]: { 0: AbilityId.COMPOUND_EYES, 1: AbilityId.COMPOUND_EYES, 2: AbilityId.COMPOUND_EYES, 3: AbilityId.COMPOUND_EYES, 4: AbilityId.COMPOUND_EYES, 5: AbilityId.COMPOUND_EYES, 6: AbilityId.COMPOUND_EYES, 7: AbilityId.COMPOUND_EYES, 8: AbilityId.COMPOUND_EYES, 9: AbilityId.COMPOUND_EYES, 10: AbilityId.COMPOUND_EYES, 11: AbilityId.COMPOUND_EYES, 12: AbilityId.COMPOUND_EYES, 13: AbilityId.COMPOUND_EYES, 14: AbilityId.COMPOUND_EYES, 15: AbilityId.COMPOUND_EYES, 16: AbilityId.COMPOUND_EYES, 17: AbilityId.COMPOUND_EYES, 18: AbilityId.COMPOUND_EYES, 19: AbilityId.COMPOUND_EYES },
|
||||
[SpeciesId.VIVILLON]: { 0: AbilityId.PRANKSTER, 1: AbilityId.PRANKSTER, 2: AbilityId.PRANKSTER, 3: AbilityId.PRANKSTER, 4: AbilityId.PRANKSTER, 5: AbilityId.PRANKSTER, 6: AbilityId.PRANKSTER, 7: AbilityId.PRANKSTER, 8: AbilityId.PRANKSTER, 9: AbilityId.PRANKSTER, 10: AbilityId.PRANKSTER, 11: AbilityId.PRANKSTER, 12: AbilityId.PRANKSTER, 13: AbilityId.PRANKSTER, 14: AbilityId.PRANKSTER, 15: AbilityId.PRANKSTER, 16: AbilityId.PRANKSTER, 17: AbilityId.PRANKSTER, 18: AbilityId.PRANKSTER, 19: AbilityId.PRANKSTER },
|
||||
[SpeciesId.LITLEO]: { 0: AbilityId.BEAST_BOOST },
|
||||
[SpeciesId.PYROAR]: { 0: AbilityId.BEAST_BOOST },
|
||||
[SpeciesId.LITLEO]: { 0: AbilityId.DROUGHT },
|
||||
[SpeciesId.PYROAR]: { 0: AbilityId.DROUGHT },
|
||||
[SpeciesId.FLABEBE]: { 0: AbilityId.GRASSY_SURGE, 1: AbilityId.GRASSY_SURGE, 2: AbilityId.GRASSY_SURGE, 3: AbilityId.GRASSY_SURGE, 4: AbilityId.GRASSY_SURGE },
|
||||
[SpeciesId.FLOETTE]: { 0: AbilityId.GRASSY_SURGE, 1: AbilityId.GRASSY_SURGE, 2: AbilityId.GRASSY_SURGE, 3: AbilityId.GRASSY_SURGE, 4: AbilityId.GRASSY_SURGE },
|
||||
[SpeciesId.FLORGES]: { 0: AbilityId.GRASSY_SURGE, 1: AbilityId.GRASSY_SURGE, 2: AbilityId.GRASSY_SURGE, 3: AbilityId.GRASSY_SURGE, 4: AbilityId.GRASSY_SURGE },
|
||||
@ -934,7 +934,7 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.ARCTOZOLT]: { 0: AbilityId.WATER_ABSORB },
|
||||
[SpeciesId.DRACOVISH]: { 0: AbilityId.THERMAL_EXCHANGE },
|
||||
[SpeciesId.ARCTOVISH]: { 0: AbilityId.STRONG_JAW },
|
||||
[SpeciesId.DURALUDON]: { 0: AbilityId.FILTER, 1: AbilityId.UNAWARE },
|
||||
[SpeciesId.DURALUDON]: { 0: AbilityId.FILTER, 1: AbilityId.FILTER },
|
||||
[SpeciesId.ARCHALUDON]: { 0: AbilityId.TRANSISTOR },
|
||||
[SpeciesId.DREEPY]: { 0: AbilityId.TECHNICIAN },
|
||||
[SpeciesId.DRAKLOAK]: { 0: AbilityId.PARENTAL_BOND },
|
||||
@ -975,8 +975,8 @@ export const starterPassiveAbilities: StarterPassiveAbilities = {
|
||||
[SpeciesId.GALAR_STUNFISK]: { 0: AbilityId.ARENA_TRAP },
|
||||
[SpeciesId.HISUI_GROWLITHE]: { 0: AbilityId.RECKLESS },
|
||||
[SpeciesId.HISUI_ARCANINE]: { 0: AbilityId.RECKLESS },
|
||||
[SpeciesId.HISUI_VOLTORB]: { 0: AbilityId.TRANSISTOR },
|
||||
[SpeciesId.HISUI_ELECTRODE]: { 0: AbilityId.TRANSISTOR },
|
||||
[SpeciesId.HISUI_VOLTORB]: { 0: AbilityId.MAGIC_GUARD },
|
||||
[SpeciesId.HISUI_ELECTRODE]: { 0: AbilityId.MAGIC_GUARD },
|
||||
[SpeciesId.HISUI_QWILFISH]: { 0: AbilityId.MERCILESS },
|
||||
[SpeciesId.OVERQWIL]: { 0: AbilityId.MERCILESS },
|
||||
[SpeciesId.HISUI_SNEASEL]: { 0: AbilityId.SCRAPPY },
|
||||
|
||||
@ -655,10 +655,18 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
||||
new SpeciesEvolution(SpeciesId.GARDEVOIR, 30, null, null),
|
||||
new SpeciesEvolution(SpeciesId.GALLADE, 1, EvolutionItem.DAWN_STONE, {key: EvoCondKey.GENDER, gender: Gender.MALE}, [30, 30, 30]),
|
||||
],
|
||||
[SpeciesId.SURSKIT]: [new SpeciesEvolution(SpeciesId.MASQUERAIN, 22, null, null)],
|
||||
[SpeciesId.SHROOMISH]: [new SpeciesEvolution(SpeciesId.BRELOOM, 23, null, null)],
|
||||
[SpeciesId.SLAKOTH]: [new SpeciesEvolution(SpeciesId.VIGOROTH, 18, null, null)],
|
||||
[SpeciesId.VIGOROTH]: [new SpeciesEvolution(SpeciesId.SLAKING, 36, null, null)],
|
||||
[SpeciesId.SURSKIT]: [
|
||||
new SpeciesEvolution(SpeciesId.MASQUERAIN, 22, null, null)
|
||||
],
|
||||
[SpeciesId.SHROOMISH]: [
|
||||
new SpeciesEvolution(SpeciesId.BRELOOM, 23, null, null)
|
||||
],
|
||||
[SpeciesId.SLAKOTH]: [
|
||||
new SpeciesEvolution(SpeciesId.VIGOROTH, 18, null, null)
|
||||
],
|
||||
[SpeciesId.VIGOROTH]: [
|
||||
new SpeciesEvolution(SpeciesId.SLAKING, 36, null, null)
|
||||
],
|
||||
[SpeciesId.NINCADA]: [
|
||||
new SpeciesEvolution(SpeciesId.NINJASK, 20, null, null),
|
||||
new SpeciesEvolution(SpeciesId.SHEDINJA, 20, null, {key: EvoCondKey.SHEDINJA})
|
||||
@ -736,26 +744,66 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
||||
new SpeciesEvolution(SpeciesId.GLALIE, 42, null, null),
|
||||
new SpeciesEvolution(SpeciesId.FROSLASS, 1, EvolutionItem.DAWN_STONE, {key: EvoCondKey.GENDER, gender: Gender.FEMALE}, [42, 42, 42]),
|
||||
],
|
||||
[SpeciesId.SPHEAL]: [new SpeciesEvolution(SpeciesId.SEALEO, 32, null, null)],
|
||||
[SpeciesId.SEALEO]: [new SpeciesEvolution(SpeciesId.WALREIN, 44, null, null)],
|
||||
[SpeciesId.BAGON]: [new SpeciesEvolution(SpeciesId.SHELGON, 30, null, null)],
|
||||
[SpeciesId.SHELGON]: [new SpeciesEvolution(SpeciesId.SALAMENCE, 50, null, null)],
|
||||
[SpeciesId.BELDUM]: [new SpeciesEvolution(SpeciesId.METANG, 20, null, null)],
|
||||
[SpeciesId.METANG]: [new SpeciesEvolution(SpeciesId.METAGROSS, 45, null, null)],
|
||||
[SpeciesId.TURTWIG]: [new SpeciesEvolution(SpeciesId.GROTLE, 18, null, null)],
|
||||
[SpeciesId.GROTLE]: [new SpeciesEvolution(SpeciesId.TORTERRA, 32, null, null)],
|
||||
[SpeciesId.CHIMCHAR]: [new SpeciesEvolution(SpeciesId.MONFERNO, 14, null, null)],
|
||||
[SpeciesId.MONFERNO]: [new SpeciesEvolution(SpeciesId.INFERNAPE, 36, null, null)],
|
||||
[SpeciesId.PIPLUP]: [new SpeciesEvolution(SpeciesId.PRINPLUP, 16, null, null)],
|
||||
[SpeciesId.PRINPLUP]: [new SpeciesEvolution(SpeciesId.EMPOLEON, 36, null, null)],
|
||||
[SpeciesId.STARLY]: [new SpeciesEvolution(SpeciesId.STARAVIA, 14, null, null)],
|
||||
[SpeciesId.STARAVIA]: [new SpeciesEvolution(SpeciesId.STARAPTOR, 34, null, null)],
|
||||
[SpeciesId.BIDOOF]: [new SpeciesEvolution(SpeciesId.BIBAREL, 15, null, null)],
|
||||
[SpeciesId.KRICKETOT]: [new SpeciesEvolution(SpeciesId.KRICKETUNE, 10, null, null)],
|
||||
[SpeciesId.SHINX]: [new SpeciesEvolution(SpeciesId.LUXIO, 15, null, null)],
|
||||
[SpeciesId.LUXIO]: [new SpeciesEvolution(SpeciesId.LUXRAY, 30, null, null)],
|
||||
[SpeciesId.CRANIDOS]: [new SpeciesEvolution(SpeciesId.RAMPARDOS, 30, null, null)],
|
||||
[SpeciesId.SHIELDON]: [new SpeciesEvolution(SpeciesId.BASTIODON, 30, null, null)],
|
||||
[SpeciesId.SPHEAL]: [
|
||||
new SpeciesEvolution(SpeciesId.SEALEO, 32, null, null)
|
||||
],
|
||||
[SpeciesId.SEALEO]: [
|
||||
new SpeciesEvolution(SpeciesId.WALREIN, 44, null, null)
|
||||
],
|
||||
[SpeciesId.BAGON]: [
|
||||
new SpeciesEvolution(SpeciesId.SHELGON, 30, null, null)
|
||||
],
|
||||
[SpeciesId.SHELGON]: [
|
||||
new SpeciesEvolution(SpeciesId.SALAMENCE, 50, null, null)
|
||||
],
|
||||
[SpeciesId.BELDUM]: [
|
||||
new SpeciesEvolution(SpeciesId.METANG, 20, null, null)
|
||||
],
|
||||
[SpeciesId.METANG]: [
|
||||
new SpeciesEvolution(SpeciesId.METAGROSS, 45, null, null)
|
||||
],
|
||||
[SpeciesId.TURTWIG]: [
|
||||
new SpeciesEvolution(SpeciesId.GROTLE, 18, null, null)
|
||||
],
|
||||
[SpeciesId.GROTLE]: [
|
||||
new SpeciesEvolution(SpeciesId.TORTERRA, 32, null, null)
|
||||
],
|
||||
[SpeciesId.CHIMCHAR]: [
|
||||
new SpeciesEvolution(SpeciesId.MONFERNO, 14, null, null)
|
||||
],
|
||||
[SpeciesId.MONFERNO]: [
|
||||
new SpeciesEvolution(SpeciesId.INFERNAPE, 36, null, null)
|
||||
],
|
||||
[SpeciesId.PIPLUP]: [
|
||||
new SpeciesEvolution(SpeciesId.PRINPLUP, 16, null, null)
|
||||
],
|
||||
[SpeciesId.PRINPLUP]: [
|
||||
new SpeciesEvolution(SpeciesId.EMPOLEON, 36, null, null)
|
||||
],
|
||||
[SpeciesId.STARLY]: [
|
||||
new SpeciesEvolution(SpeciesId.STARAVIA, 14, null, null)
|
||||
],
|
||||
[SpeciesId.STARAVIA]: [
|
||||
new SpeciesEvolution(SpeciesId.STARAPTOR, 34, null, null)
|
||||
],
|
||||
[SpeciesId.BIDOOF]: [
|
||||
new SpeciesEvolution(SpeciesId.BIBAREL, 15, null, null)
|
||||
],
|
||||
[SpeciesId.KRICKETOT]: [
|
||||
new SpeciesEvolution(SpeciesId.KRICKETUNE, 10, null, null)
|
||||
],
|
||||
[SpeciesId.SHINX]: [
|
||||
new SpeciesEvolution(SpeciesId.LUXIO, 15, null, null)
|
||||
],
|
||||
[SpeciesId.LUXIO]: [
|
||||
new SpeciesEvolution(SpeciesId.LUXRAY, 30, null, null)
|
||||
],
|
||||
[SpeciesId.CRANIDOS]: [
|
||||
new SpeciesEvolution(SpeciesId.RAMPARDOS, 30, null, null)
|
||||
],
|
||||
[SpeciesId.SHIELDON]: [
|
||||
new SpeciesEvolution(SpeciesId.BASTIODON, 30, null, null)
|
||||
],
|
||||
[SpeciesId.BURMY]: [
|
||||
new SpeciesEvolution(SpeciesId.MOTHIM, 20, null, {key: EvoCondKey.GENDER, gender: Gender.MALE}),
|
||||
new SpeciesEvolution(SpeciesId.WORMADAM, 20, null, {key: EvoCondKey.GENDER, gender: Gender.FEMALE})
|
||||
|
||||
@ -450,7 +450,7 @@ export const speciesStarterCosts = {
|
||||
[SpeciesId.TAPU_KOKO]: 6,
|
||||
[SpeciesId.TAPU_LELE]: 7,
|
||||
[SpeciesId.TAPU_BULU]: 6,
|
||||
[SpeciesId.TAPU_FINI]: 5,
|
||||
[SpeciesId.TAPU_FINI]: 6,
|
||||
[SpeciesId.COSMOG]: 7,
|
||||
[SpeciesId.NIHILEGO]: 6,
|
||||
[SpeciesId.BUZZWOLE]: 6,
|
||||
|
||||
@ -144,7 +144,7 @@ export const tmPoolTiers: TmPoolTiers = {
|
||||
[MoveId.SPITE]: ModifierTier.COMMON,
|
||||
[MoveId.PROTECT]: ModifierTier.COMMON,
|
||||
[MoveId.SCARY_FACE]: ModifierTier.GREAT,
|
||||
[MoveId.SLUDGE_BOMB]: ModifierTier.GREAT,
|
||||
[MoveId.SLUDGE_BOMB]: ModifierTier.ULTRA,
|
||||
[MoveId.MUD_SLAP]: ModifierTier.COMMON,
|
||||
[MoveId.SPIKES]: ModifierTier.COMMON,
|
||||
[MoveId.ICY_WIND]: ModifierTier.GREAT,
|
||||
@ -195,7 +195,7 @@ export const tmPoolTiers: TmPoolTiers = {
|
||||
[MoveId.RECYCLE]: ModifierTier.COMMON,
|
||||
[MoveId.REVENGE]: ModifierTier.GREAT,
|
||||
[MoveId.BRICK_BREAK]: ModifierTier.GREAT,
|
||||
[MoveId.KNOCK_OFF]: ModifierTier.GREAT,
|
||||
[MoveId.KNOCK_OFF]: ModifierTier.ULTRA,
|
||||
[MoveId.ENDEAVOR]: ModifierTier.COMMON,
|
||||
[MoveId.SKILL_SWAP]: ModifierTier.COMMON,
|
||||
[MoveId.IMPRISON]: ModifierTier.COMMON,
|
||||
@ -299,7 +299,7 @@ export const tmPoolTiers: TmPoolTiers = {
|
||||
[MoveId.VENOSHOCK]: ModifierTier.GREAT,
|
||||
[MoveId.MAGIC_ROOM]: ModifierTier.COMMON,
|
||||
[MoveId.SMACK_DOWN]: ModifierTier.COMMON,
|
||||
[MoveId.SLUDGE_WAVE]: ModifierTier.GREAT,
|
||||
[MoveId.SLUDGE_WAVE]: ModifierTier.ULTRA,
|
||||
[MoveId.HEAVY_SLAM]: ModifierTier.GREAT,
|
||||
[MoveId.ELECTRO_BALL]: ModifierTier.GREAT,
|
||||
[MoveId.FLAME_CHARGE]: ModifierTier.GREAT,
|
||||
@ -351,9 +351,9 @@ export const tmPoolTiers: TmPoolTiers = {
|
||||
[MoveId.POWER_UP_PUNCH]: ModifierTier.GREAT,
|
||||
[MoveId.DARKEST_LARIAT]: ModifierTier.GREAT,
|
||||
[MoveId.HIGH_HORSEPOWER]: ModifierTier.ULTRA,
|
||||
[MoveId.SOLAR_BLADE]: ModifierTier.GREAT,
|
||||
[MoveId.SOLAR_BLADE]: ModifierTier.ULTRA,
|
||||
[MoveId.THROAT_CHOP]: ModifierTier.GREAT,
|
||||
[MoveId.POLLEN_PUFF]: ModifierTier.GREAT,
|
||||
[MoveId.POLLEN_PUFF]: ModifierTier.ULTRA,
|
||||
[MoveId.PSYCHIC_TERRAIN]: ModifierTier.COMMON,
|
||||
[MoveId.LUNGE]: ModifierTier.GREAT,
|
||||
[MoveId.SPEED_SWAP]: ModifierTier.COMMON,
|
||||
|
||||
@ -1109,7 +1109,16 @@ export class LowerStarterPointsChallenge extends Challenge {
|
||||
*/
|
||||
export class LimitedSupportChallenge extends Challenge {
|
||||
public override get ribbonAwarded(): RibbonFlag {
|
||||
return this.value ? ((RibbonData.NO_HEAL << (BigInt(this.value) - 1n)) as RibbonFlag) : 0n;
|
||||
switch (this.value) {
|
||||
case 1:
|
||||
return RibbonData.NO_HEAL as RibbonFlag;
|
||||
case 2:
|
||||
return RibbonData.NO_SHOP as RibbonFlag;
|
||||
case 3:
|
||||
return (RibbonData.NO_HEAL | RibbonData.NO_SHOP | RibbonData.NO_SUPPORT) as RibbonFlag;
|
||||
default:
|
||||
return 0n as RibbonFlag;
|
||||
}
|
||||
}
|
||||
constructor() {
|
||||
super(Challenges.LIMITED_SUPPORT, 3);
|
||||
|
||||
@ -1,42 +1,37 @@
|
||||
import { pokerogueApi } from "#api/pokerogue-api";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { speciesStarterCosts } from "#balance/starters";
|
||||
import type { PokemonSpeciesForm } from "#data/pokemon-species";
|
||||
import { PokemonSpecies } from "#data/pokemon-species";
|
||||
import { BiomeId } from "#enums/biome-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { PartyMemberStrength } from "#enums/party-member-strength";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import type { Starter } from "#types/save-data";
|
||||
import { randSeedGauss, randSeedInt, randSeedItem } from "#utils/common";
|
||||
import type { Variant } from "#sprites/variant";
|
||||
import type { Starter, StarterMoveset } from "#types/save-data";
|
||||
import { isBetween, randSeedGauss, randSeedInt, randSeedItem } from "#utils/common";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
import { chunkString } from "#utils/strings";
|
||||
|
||||
export interface DailyRunConfig {
|
||||
seed: number;
|
||||
starters: Starter;
|
||||
}
|
||||
type StarterTuple = [Starter, Starter, Starter];
|
||||
|
||||
export function fetchDailyRunSeed(): Promise<string | null> {
|
||||
return new Promise<string | null>((resolve, _reject) => {
|
||||
pokerogueApi.daily.getSeed().then(dailySeed => {
|
||||
resolve(dailySeed);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getDailyRunStarters(seed: string): Starter[] {
|
||||
export function getDailyRunStarters(seed: string): StarterTuple {
|
||||
const starters: Starter[] = [];
|
||||
|
||||
globalScene.executeWithSeedOffset(
|
||||
() => {
|
||||
const startingLevel = globalScene.gameMode.getStartingLevel();
|
||||
|
||||
const eventStarters = getDailyEventSeedStarters(seed);
|
||||
if (eventStarters != null) {
|
||||
starters.push(...eventStarters);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: explain this math
|
||||
const startingLevel = globalScene.gameMode.getStartingLevel();
|
||||
const starterCosts: number[] = [];
|
||||
starterCosts.push(Math.min(Math.round(3.5 + Math.abs(randSeedGauss(1))), 8));
|
||||
starterCosts.push(randSeedInt(9 - starterCosts[0], 1));
|
||||
@ -57,14 +52,25 @@ export function getDailyRunStarters(seed: string): Starter[] {
|
||||
seed,
|
||||
);
|
||||
|
||||
return starters;
|
||||
setDailyRunEventStarterMovesets(seed, starters as StarterTuple);
|
||||
|
||||
return starters as StarterTuple;
|
||||
}
|
||||
|
||||
function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLevel: number): Starter {
|
||||
// TODO: Refactor this unmaintainable mess
|
||||
function getDailyRunStarter(starterSpeciesForm: PokemonSpeciesForm, startingLevel: number, variant?: Variant): Starter {
|
||||
const starterSpecies =
|
||||
starterSpeciesForm instanceof PokemonSpecies ? starterSpeciesForm : getPokemonSpecies(starterSpeciesForm.speciesId);
|
||||
const formIndex = starterSpeciesForm instanceof PokemonSpecies ? undefined : starterSpeciesForm.formIndex;
|
||||
const pokemon = globalScene.addPlayerPokemon(starterSpecies, startingLevel, undefined, formIndex);
|
||||
const pokemon = globalScene.addPlayerPokemon(
|
||||
starterSpecies,
|
||||
startingLevel,
|
||||
undefined,
|
||||
formIndex,
|
||||
undefined,
|
||||
variant != null,
|
||||
variant,
|
||||
);
|
||||
const starter: Starter = {
|
||||
speciesId: starterSpecies.speciesId,
|
||||
shiny: pokemon.shiny,
|
||||
@ -169,30 +175,179 @@ export function isDailyEventSeed(seed: string): boolean {
|
||||
return globalScene.gameMode.isDaily && seed.length > 24;
|
||||
}
|
||||
|
||||
/**
|
||||
* The length of a single numeric Move ID string.
|
||||
* Must be updated whenever the `MoveId` enum gets a new digit!
|
||||
*/
|
||||
const MOVE_ID_STRING_LENGTH = 4;
|
||||
/**
|
||||
* The regex literal used to parse daily run custom movesets.
|
||||
* @privateRemarks
|
||||
* Intentionally does not use the `g` flag to avoid altering `lastIndex` after each match.
|
||||
*/
|
||||
const MOVE_ID_SEED_REGEX = /(?<=\/moves)((?:\d{4}){0,4})(?:,((?:\d{4}){0,4}))?(?:,((?:\d{4}){0,4}))?/;
|
||||
|
||||
/**
|
||||
* Perform moveset post-processing on Daily run starters. \
|
||||
* If the seed matches {@linkcode MOVE_ID_SEED_REGEX},
|
||||
* the extracted Move IDs will be used to populate the starters' moveset instead.
|
||||
* @param seed - The daily run seed
|
||||
* @param starters - The previously generated starters; will have movesets mutated in place
|
||||
*/
|
||||
function setDailyRunEventStarterMovesets(seed: string, starters: StarterTuple): void {
|
||||
const moveMatch: readonly string[] = MOVE_ID_SEED_REGEX.exec(seed)?.slice(1) ?? [];
|
||||
if (moveMatch.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isBetween(moveMatch.length, 1, 3)) {
|
||||
console.error(
|
||||
"Invalid custom seeded moveset used for daily run seed!\nSeed: %s\nMatch contents: %s",
|
||||
seed,
|
||||
moveMatch,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const moveIds = getEnumValues(MoveId);
|
||||
for (const [i, moveStr] of moveMatch.entries()) {
|
||||
if (!moveStr) {
|
||||
// Fallback for empty capture groups from omitted entries
|
||||
continue;
|
||||
}
|
||||
const starter = starters[i];
|
||||
const parsedMoveIds = chunkString(moveStr, MOVE_ID_STRING_LENGTH).map(m => Number.parseInt(m) as MoveId);
|
||||
|
||||
if (parsedMoveIds.some(f => !moveIds.includes(f))) {
|
||||
console.error("Invalid move IDs used for custom daily run seed moveset on starter %d:", i, parsedMoveIds);
|
||||
continue;
|
||||
}
|
||||
|
||||
starter.moveset = parsedMoveIds as StarterMoveset;
|
||||
}
|
||||
}
|
||||
|
||||
/** The regex literal string used to extract the content of the "starters" block of Daily Run custom seeds. */
|
||||
const STARTER_SEED_PREFIX_REGEX = /\/starters(.*?)(?:\/|$)/;
|
||||
/**
|
||||
* The regex literal used to parse daily run custom starter information for a single starter. \
|
||||
* Contains a 4-digit species ID, as well as an optional 2-digit form index and 1-digit variant.
|
||||
*
|
||||
* If either of form index or variant are omitted, the starter will default to its species' base form/
|
||||
* not be shiny, respectively.
|
||||
*/
|
||||
const STARTER_SEED_MATCH_REGEX = /(?:s(?<species>\d{4}))(?:f(?<form>\d{2}))?(?:v(?<variant>\d))?/g;
|
||||
|
||||
/**
|
||||
* Parse a custom daily run seed into a set of pre-defined starters.
|
||||
* @see {@linkcode STARTER_SEED_MATCH_REGEX}
|
||||
* @param seed - The daily run seed
|
||||
* @returns An array of {@linkcode Starter}s, or `null` if it did not match.
|
||||
*/
|
||||
// TODO: Rework this setup into JSON or similar - this is quite hard to maintain
|
||||
function getDailyEventSeedStarters(seed: string): StarterTuple | null {
|
||||
if (!isDailyEventSeed(seed)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const seedAfterPrefix = seed.split(STARTER_SEED_PREFIX_REGEX)[1] as string | undefined;
|
||||
if (!seedAfterPrefix) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const speciesConfigurations = [...seedAfterPrefix.matchAll(STARTER_SEED_MATCH_REGEX)];
|
||||
|
||||
if (speciesConfigurations.length !== 3) {
|
||||
// TODO: Remove legacy fallback code after next hotfix version - this is needed for Oct 31's daily to function
|
||||
const legacyStarters = getDailyEventSeedStartersLegacy(seed);
|
||||
if (legacyStarters == null) {
|
||||
return legacyStarters;
|
||||
}
|
||||
console.error("Invalid starters used for custom daily run seed!", seed);
|
||||
return null;
|
||||
}
|
||||
|
||||
const speciesIds = getEnumValues(SpeciesId);
|
||||
const starters: Starter[] = [];
|
||||
|
||||
for (const match of speciesConfigurations) {
|
||||
const { groups } = match;
|
||||
if (!groups) {
|
||||
console.error("Invalid seed used for custom daily run starter:", match);
|
||||
return null;
|
||||
}
|
||||
|
||||
const { species: speciesStr, form: formStr, variant: variantStr } = groups;
|
||||
|
||||
const speciesId = Number.parseInt(speciesStr) as SpeciesId;
|
||||
|
||||
// NB: We check the parsed integer here to exclude SpeciesID.NONE as well as invalid values;
|
||||
// other fields only check the string to permit 0 as valid inputs
|
||||
if (!speciesId || !speciesIds.includes(speciesId)) {
|
||||
console.error("Invalid species ID used for custom daily run starter:", speciesStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
const starterSpecies = getPokemonSpecies(speciesId);
|
||||
// Omitted form index = use base form
|
||||
const starterForm = formStr ? starterSpecies.forms[Number.parseInt(formStr)] : starterSpecies;
|
||||
|
||||
if (!starterForm) {
|
||||
console.log(starterSpecies.name);
|
||||
console.error("Invalid form index used for custom daily run starter:", formStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get and validate variant
|
||||
let variant = (variantStr ? Number.parseInt(variantStr) : undefined) as Variant | undefined;
|
||||
if (!isBetween(variant ?? 0, 0, 2)) {
|
||||
console.error("Variant used for custom daily run seed starter out of bounds:", variantStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fall back to default variant if none exists
|
||||
if (!starterSpecies.hasVariants() && !!variant) {
|
||||
console.warn("Variant for custom daily run seed starter does not exist, using base variant...", variant);
|
||||
variant = undefined;
|
||||
}
|
||||
|
||||
const startingLevel = globalScene.gameMode.getStartingLevel();
|
||||
const starter = getDailyRunStarter(starterForm, startingLevel, variant);
|
||||
starters.push(starter);
|
||||
}
|
||||
|
||||
return starters as StarterTuple;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the seed to contain `/starters\d{18}/`
|
||||
* where the digits alternate between 4 digits for the species ID and 2 digits for the form index
|
||||
* (left padded with `0`s as necessary).
|
||||
* @returns An array of {@linkcode Starter}s, or `null` if no valid match.
|
||||
*/
|
||||
export function getDailyEventSeedStarters(seed: string): Starter[] | null {
|
||||
// TODO: Can be removed after october 31st 2025
|
||||
function getDailyEventSeedStartersLegacy(seed: string): StarterTuple | null {
|
||||
if (!isDailyEventSeed(seed)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const starters: Starter[] = [];
|
||||
const match = /starters(\d{4})(\d{2})(\d{4})(\d{2})(\d{4})(\d{2})/g.exec(seed);
|
||||
const speciesMatch = /starters(\d{4})(\d{2})(\d{4})(\d{2})(\d{4})(\d{2})/g.exec(seed)?.slice(1);
|
||||
|
||||
if (!match || match.length !== 7) {
|
||||
if (!speciesMatch || speciesMatch.length !== 6) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let i = 1; i < match.length; i += 2) {
|
||||
const speciesId = Number.parseInt(match[i]) as SpeciesId;
|
||||
const formIndex = Number.parseInt(match[i + 1]);
|
||||
// TODO: Move these to server-side validation
|
||||
const speciesIds = getEnumValues(SpeciesId);
|
||||
|
||||
if (!getEnumValues(SpeciesId).includes(speciesId)) {
|
||||
console.warn("Invalid species ID used for custom daily run seed starter:", speciesId);
|
||||
// generate each starter in turn
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const speciesId = Number.parseInt(speciesMatch[2 * i]) as SpeciesId;
|
||||
const formIndex = Number.parseInt(speciesMatch[2 * i + 1]);
|
||||
|
||||
if (!speciesIds.includes(speciesId)) {
|
||||
console.error("Invalid species ID used for custom daily run seed starter:", speciesId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -202,7 +357,7 @@ export function getDailyEventSeedStarters(seed: string): Starter[] | null {
|
||||
starters.push(starter);
|
||||
}
|
||||
|
||||
return starters;
|
||||
return starters as StarterTuple;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,6 +388,31 @@ export function getDailyEventSeedBoss(seed: string): PokemonSpeciesForm | null {
|
||||
return starterForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the seed to contain `/boss\d{4}\d{2}\d{2}/`
|
||||
* where the first 4 digits are the species ID, the next 2 digits are the form index, and the last 2 digits are the variant.
|
||||
* Only the last 2 digits matter for the variant, and it is clamped to 0-2.
|
||||
* (left padded with `0`s as necessary).
|
||||
* @returns A {@linkcode Variant} to be used for the boss, or `null` if no valid match.
|
||||
*/
|
||||
export function getDailyEventSeedBossVariant(seed: string): Variant | null {
|
||||
if (!isDailyEventSeed(seed)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const match = /boss\d{6}(\d{2})/g.exec(seed);
|
||||
if (!match || match.length !== 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const variant = Number.parseInt(match[1]) as Variant;
|
||||
if (variant > 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expects the seed to contain `/biome\d{2}/` where the 2 digits are a biome ID (left padded with `0` if necessary).
|
||||
* @returns The biome to use or `null` if no valid match.
|
||||
|
||||
@ -98,8 +98,10 @@ import { areAllies } from "#utils/pokemon-utils";
|
||||
import { toCamelCase, toTitleCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
import { MovePhaseTimingModifier } from "#enums/move-phase-timing-modifier";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import { canSpeciesTera, willTerastallize } from "#utils/pokemon-utils";
|
||||
import type { ReadonlyGenericUint8Array } from "#types/typed-arrays";
|
||||
import { MovePriorityInBracket } from "#enums/move-priority-in-bracket";
|
||||
|
||||
/**
|
||||
* A function used to conditionally determine execution of a given {@linkcode MoveAttr}.
|
||||
@ -1031,8 +1033,9 @@ export abstract class Move implements Localizable {
|
||||
aura.apply({pokemon: source, simulated, opponent: target, move: this, power});
|
||||
}
|
||||
|
||||
const alliedField: Pokemon[] = source.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
alliedField.forEach(p => applyAbAttrs("UserFieldMoveTypePowerBoostAbAttr", {pokemon: p, opponent: target, move: this, simulated, power}));
|
||||
for (const p of source.getAlliesGenerator()) {
|
||||
applyAbAttrs("UserFieldMoveTypePowerBoostAbAttr", {pokemon: p, opponent: target, move: this, simulated, power});
|
||||
}
|
||||
|
||||
power.value *= typeChangeMovePowerMultiplier.value;
|
||||
|
||||
@ -1058,17 +1061,21 @@ export abstract class Move implements Localizable {
|
||||
|
||||
getPriority(user: Pokemon, simulated: boolean = true) {
|
||||
const priority = new NumberHolder(this.priority);
|
||||
|
||||
applyMoveAttrs("IncrementMovePriorityAttr", user, null, this, priority);
|
||||
applyAbAttrs("ChangeMovePriorityAbAttr", {pokemon: user, simulated, move: this, priority});
|
||||
|
||||
if (user.getTag(BattlerTagType.BYPASS_SPEED)) {
|
||||
priority.value += 0.2;
|
||||
}
|
||||
|
||||
return priority.value;
|
||||
}
|
||||
|
||||
public getPriorityModifier(user: Pokemon, simulated = true) {
|
||||
if (user.getTag(BattlerTagType.BYPASS_SPEED)) {
|
||||
return MovePriorityInBracket.FIRST;
|
||||
}
|
||||
const modifierHolder = new NumberHolder(MovePriorityInBracket.NORMAL);
|
||||
applyAbAttrs("ChangeMovePriorityInBracketAbAttr", { pokemon: user, simulated, move: this, priority: modifierHolder });
|
||||
return modifierHolder.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the [Expected Power](https://en.wikipedia.org/wiki/Expected_value) per turn
|
||||
* of this move, taking into account multi hit moves, accuracy, and the number of turns it
|
||||
@ -6218,8 +6225,10 @@ export class RemoveAllSubstitutesAttr extends MoveEffectAttr {
|
||||
return false;
|
||||
}
|
||||
|
||||
globalScene.getField(true).forEach(pokemon =>
|
||||
pokemon.findAndRemoveTags(tag => tag.tagType === BattlerTagType.SUBSTITUTE));
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
pokemon.findAndRemoveTags(tag => tag.tagType === BattlerTagType.SUBSTITUTE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -8156,7 +8165,9 @@ const failIfDampCondition: MoveConditionFunc = (user, target, move) => {
|
||||
// temporary workaround to prevent displaying the message during enemy command phase
|
||||
// TODO: either move this, or make the move condition func have a `simulated` param
|
||||
const simulated = globalScene.phaseManager.getCurrentPhase()?.is('EnemyCommandPhase');
|
||||
globalScene.getField(true).map(p=>applyAbAttrs("FieldPreventExplosiveMovesAbAttr", {pokemon: p, cancelled, simulated}));
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
applyAbAttrs("FieldPreventExplosiveMovesAbAttr", {pokemon: p, cancelled, simulated});
|
||||
}
|
||||
// Queue a message if an ability prevented usage of the move
|
||||
if (!simulated && cancelled.value) {
|
||||
globalScene.phaseManager.queueMessage(i18next.t("moveTriggers:cannotUseMove", { pokemonName: getPokemonNameWithAffix(user), moveName: move.name }));
|
||||
|
||||
@ -18,7 +18,7 @@ import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils
|
||||
import {
|
||||
generateModifierType,
|
||||
generateModifierTypeOption,
|
||||
getRandomEncounterSpecies,
|
||||
getRandomEncounterPokemon,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterExp,
|
||||
@ -66,7 +66,12 @@ export const BerriesAboundEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
|
||||
// Calculate boss mon
|
||||
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const bossPokemon = getRandomEncounterSpecies(level, true);
|
||||
const bossPokemon = getRandomEncounterPokemon({
|
||||
level,
|
||||
isBoss: true,
|
||||
eventShinyRerolls: 2,
|
||||
eventHiddenRerolls: 1,
|
||||
});
|
||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||
const config: EnemyPartyConfig = {
|
||||
pokemonConfigs: [
|
||||
|
||||
@ -175,6 +175,8 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(3, 6)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroDialogue([
|
||||
|
||||
@ -12,7 +12,7 @@ import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "
|
||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||
import {
|
||||
getRandomEncounterSpecies,
|
||||
getRandomEncounterPokemon,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterExp,
|
||||
@ -58,7 +58,12 @@ export const FightOrFlightEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
|
||||
// Calculate boss mon
|
||||
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||
const bossPokemon = getRandomEncounterSpecies(level, true);
|
||||
const bossPokemon = getRandomEncounterPokemon({
|
||||
level,
|
||||
isBoss: true,
|
||||
eventShinyRerolls: 2,
|
||||
eventHiddenRerolls: 1,
|
||||
});
|
||||
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
|
||||
const config: EnemyPartyConfig = {
|
||||
pokemonConfigs: [
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/constants";
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { allSpecies } from "#data/data-lists";
|
||||
import { Gender, getGenderSymbol } from "#data/gender";
|
||||
@ -20,17 +19,13 @@ import { doShinySparkleAnim } from "#field/anims";
|
||||
import type { PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||
import { EnemyPokemon } from "#field/pokemon";
|
||||
import type { PokemonHeldItemModifier } from "#modifiers/modifier";
|
||||
import {
|
||||
HiddenAbilityRateBoosterModifier,
|
||||
PokemonFormChangeItemModifier,
|
||||
ShinyRateBoosterModifier,
|
||||
SpeciesStatBoosterModifier,
|
||||
} from "#modifiers/modifier";
|
||||
import { PokemonFormChangeItemModifier, SpeciesStatBoosterModifier } from "#modifiers/modifier";
|
||||
import type { ModifierTypeOption } from "#modifiers/modifier-type";
|
||||
import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#modifiers/modifier-type";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { getEncounterText, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||
import {
|
||||
getRandomEncounterPokemon,
|
||||
leaveEncounterWithoutBattle,
|
||||
selectPokemonForOption,
|
||||
setEncounterRewards,
|
||||
@ -43,7 +38,7 @@ import { PartySizeRequirement } from "#mystery-encounters/mystery-encounter-requ
|
||||
import { PokemonData } from "#system/pokemon-data";
|
||||
import { MusicPreference } from "#system/settings";
|
||||
import type { OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import { NumberHolder, randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
|
||||
import { randInt, randSeedInt, randSeedItem, randSeedShuffle } from "#utils/common";
|
||||
import { getEnumKeys } from "#utils/enums";
|
||||
import { getRandomLocaleEntry } from "#utils/i18n";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
@ -58,6 +53,8 @@ const WONDER_TRADE_SHINY_CHANCE = 512;
|
||||
/** Max shiny chance of 4096/65536 -> 1/16 odds. */
|
||||
const MAX_WONDER_TRADE_SHINY_CHANCE = 4096;
|
||||
|
||||
const WONDER_TRADE_HIDDEN_ABILITY_CHANCE = 64;
|
||||
|
||||
const LEGENDARY_TRADE_POOLS = {
|
||||
1: [SpeciesId.RATTATA, SpeciesId.PIDGEY, SpeciesId.WEEDLE],
|
||||
2: [SpeciesId.SENTRET, SpeciesId.HOOTHOOT, SpeciesId.LEDYBA],
|
||||
@ -273,38 +270,23 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Randomly generate a Wonder Trade pokemon
|
||||
const randomTradeOption = generateTradeOption(globalScene.getPlayerParty().map(p => p.species));
|
||||
const tradePokemon = new EnemyPokemon(randomTradeOption, pokemon.level, TrainerSlot.NONE, false);
|
||||
// Extra shiny roll at 1/128 odds (boosted by events and charms)
|
||||
if (!tradePokemon.shiny) {
|
||||
const shinyThreshold = new NumberHolder(WONDER_TRADE_SHINY_CHANCE);
|
||||
if (timedEventManager.isEventActive()) {
|
||||
shinyThreshold.value *= timedEventManager.getShinyEncounterMultiplier();
|
||||
}
|
||||
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
||||
|
||||
// Base shiny chance of 512/65536 -> 1/128, affected by events and Shiny Charms
|
||||
// Maximum shiny chance of 4096/65536 -> 1/16, cannot improve further after that
|
||||
const shinyChance = Math.min(shinyThreshold.value, MAX_WONDER_TRADE_SHINY_CHANCE);
|
||||
|
||||
tradePokemon.trySetShinySeed(shinyChance, false);
|
||||
}
|
||||
|
||||
// Extra HA roll at base 1/64 odds (boosted by events and charms)
|
||||
const hiddenIndex = tradePokemon.species.ability2 ? 2 : 1;
|
||||
if (tradePokemon.species.abilityHidden && tradePokemon.abilityIndex < hiddenIndex) {
|
||||
const hiddenAbilityChance = new NumberHolder(64);
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||
|
||||
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
|
||||
|
||||
if (hasHiddenAbility) {
|
||||
tradePokemon.abilityIndex = hiddenIndex;
|
||||
}
|
||||
}
|
||||
const tradePokemon = getRandomEncounterPokemon({
|
||||
level: pokemon.level,
|
||||
speciesFunction: () => generateTradeOption(globalScene.getPlayerParty().map(p => p.species)),
|
||||
isBoss: false,
|
||||
eventChance: 100,
|
||||
shinyRerolls: 1,
|
||||
hiddenRerolls: 1,
|
||||
eventShinyRerolls: 1,
|
||||
eventHiddenRerolls: 1,
|
||||
hiddenAbilityChance: WONDER_TRADE_HIDDEN_ABILITY_CHANCE,
|
||||
shinyChance: WONDER_TRADE_SHINY_CHANCE,
|
||||
maxShinyChance: MAX_WONDER_TRADE_SHINY_CHANCE,
|
||||
speciesFilter: s => !globalScene.getPlayerParty().some(p => p.species === s),
|
||||
});
|
||||
|
||||
// If Pokemon is still not shiny or with HA, give the Pokemon a random Common egg move in its moveset
|
||||
if (!tradePokemon.shiny && (!tradePokemon.species.abilityHidden || tradePokemon.abilityIndex < hiddenIndex)) {
|
||||
if (!tradePokemon.shiny && (!tradePokemon.species.abilityHidden || tradePokemon.abilityIndex < 2)) {
|
||||
const eggMoves = tradePokemon.getEggMoves();
|
||||
if (eggMoves) {
|
||||
// Cannot gen the rare egg move, only 1 of the first 3 common moves
|
||||
|
||||
@ -9,11 +9,11 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { PlayerGender } from "#enums/player-gender";
|
||||
import { PokeballType } from "#enums/pokeball";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import type { EnemyPokemon } from "#field/pokemon";
|
||||
import { HiddenAbilityRateBoosterModifier, IvScannerModifier } from "#modifiers/modifier";
|
||||
import { IvScannerModifier } from "#modifiers/modifier";
|
||||
import { getEncounterText, showEncounterText } from "#mystery-encounters/encounter-dialogue-utils";
|
||||
import {
|
||||
getRandomEncounterPokemon,
|
||||
initSubsequentOptionSelect,
|
||||
leaveEncounterWithoutBattle,
|
||||
transitionMysteryEncounterIntroVisuals,
|
||||
@ -30,7 +30,7 @@ import { MysteryEncounterBuilder } from "#mystery-encounters/mystery-encounter";
|
||||
import type { MysteryEncounterOption } from "#mystery-encounters/mystery-encounter-option";
|
||||
import { MysteryEncounterOptionBuilder } from "#mystery-encounters/mystery-encounter-option";
|
||||
import { MoneyRequirement } from "#mystery-encounters/mystery-encounter-requirements";
|
||||
import { NumberHolder, randSeedInt } from "#utils/common";
|
||||
import { BooleanHolder, NumberHolder, randSeedInt } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
@ -42,6 +42,9 @@ const SAFARI_MONEY_MULTIPLIER = 2;
|
||||
|
||||
const NUM_SAFARI_ENCOUNTERS = 3;
|
||||
|
||||
const eventEncs = new NumberHolder(0);
|
||||
const eventChance = new NumberHolder(50);
|
||||
|
||||
/**
|
||||
* Safari Zone encounter.
|
||||
* @see {@link https://github.com/pagefaultgames/pokerogue/issues/3800 | GitHub Issue #3800}
|
||||
@ -74,6 +77,8 @@ export const SafariZoneEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
.withQuery(`${namespace}:query`)
|
||||
.withOnInit(() => {
|
||||
globalScene.currentBattle.mysteryEncounter?.setDialogueToken("numEncounters", NUM_SAFARI_ENCOUNTERS.toString());
|
||||
eventEncs.value = 0;
|
||||
eventChance.value = 50;
|
||||
return true;
|
||||
})
|
||||
.withOption(
|
||||
@ -279,37 +284,37 @@ async function summonSafariPokemon() {
|
||||
|
||||
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
||||
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
||||
let enemySpecies: PokemonSpecies;
|
||||
let pokemon: any;
|
||||
globalScene.executeWithSeedOffset(
|
||||
() => {
|
||||
enemySpecies = getSafariSpeciesSpawn();
|
||||
const level = globalScene.currentBattle.getLevelForWave();
|
||||
enemySpecies = getPokemonSpecies(enemySpecies.getWildSpeciesForLevel(level, true, false, globalScene.gameMode));
|
||||
pokemon = globalScene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, false);
|
||||
console.log("Event chance %d", eventChance.value);
|
||||
const fromEvent = new BooleanHolder(false);
|
||||
pokemon = getRandomEncounterPokemon({
|
||||
level: globalScene.currentBattle.getLevelForWave(),
|
||||
includeLegendary: false,
|
||||
includeSubLegendary: false,
|
||||
includeMythical: false,
|
||||
speciesFunction: getSafariSpeciesSpawn,
|
||||
shinyRerolls: 1,
|
||||
eventShinyRerolls: 1,
|
||||
hiddenRerolls: 1,
|
||||
eventHiddenRerolls: 1,
|
||||
eventChance: eventChance.value,
|
||||
isEventEncounter: fromEvent,
|
||||
});
|
||||
|
||||
// Roll shiny twice
|
||||
if (!pokemon.shiny) {
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.init();
|
||||
|
||||
// Increase chance of event encounter by 25% until one spawns
|
||||
if (fromEvent.value) {
|
||||
console.log("Safari zone encounter is from event");
|
||||
eventEncs.value++;
|
||||
eventChance.value = 50;
|
||||
} else if (eventEncs.value === 0) {
|
||||
console.log("Safari zone encounter is not from event");
|
||||
eventChance.value += 25;
|
||||
}
|
||||
|
||||
// Roll HA twice
|
||||
if (pokemon.species.abilityHidden) {
|
||||
const hiddenIndex = pokemon.species.ability2 ? 2 : 1;
|
||||
if (pokemon.abilityIndex < hiddenIndex) {
|
||||
const hiddenAbilityChance = new NumberHolder(256);
|
||||
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, hiddenAbilityChance);
|
||||
|
||||
const hasHiddenAbility = !randSeedInt(hiddenAbilityChance.value);
|
||||
|
||||
if (hasHiddenAbility) {
|
||||
pokemon.abilityIndex = hiddenIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pokemon.calculateStats();
|
||||
|
||||
globalScene.currentBattle.enemyParty.unshift(pokemon);
|
||||
},
|
||||
globalScene.currentBattle.waveIndex * 1000 * encounter.misc.safariPokemonRemaining,
|
||||
@ -569,7 +574,7 @@ async function doEndTurn(cursorIndex: number) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns A random species that has at most 5 starter cost and is not Mythical, Paradox, etc.
|
||||
* @returns A function to get a random species that has at most 5 starter cost and is not Mythical, Paradox, etc.
|
||||
*/
|
||||
export function getSafariSpeciesSpawn(): PokemonSpecies {
|
||||
return getPokemonSpecies(
|
||||
|
||||
@ -77,6 +77,8 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
.withOnInit(() => {
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
||||
let isEventEncounter = false;
|
||||
|
||||
let species = getSalesmanSpeciesOffer();
|
||||
let tries = 0;
|
||||
|
||||
@ -88,16 +90,12 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
|
||||
const r = randSeedInt(SHINY_MAGIKARP_WEIGHT);
|
||||
|
||||
const validEventEncounters = timedEventManager
|
||||
.getEventEncounters()
|
||||
.filter(
|
||||
s =>
|
||||
!getPokemonSpecies(s.species).legendary
|
||||
&& !getPokemonSpecies(s.species).subLegendary
|
||||
&& !getPokemonSpecies(s.species).mythical
|
||||
&& !NON_LEGEND_PARADOX_POKEMON.includes(s.species)
|
||||
&& !NON_LEGEND_ULTRA_BEASTS.includes(s.species),
|
||||
);
|
||||
const validEventEncounters = timedEventManager.getAllValidEventEncounters(
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
s => !NON_LEGEND_PARADOX_POKEMON.includes(s.speciesId) && !NON_LEGEND_ULTRA_BEASTS.includes(s.speciesId),
|
||||
);
|
||||
|
||||
let pokemon: PlayerPokemon;
|
||||
/**
|
||||
@ -122,7 +120,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
) {
|
||||
tries = 0;
|
||||
do {
|
||||
// If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one
|
||||
// If you roll 50%, give event encounter with 3 extra shiny rolls and its HA, if it has one
|
||||
const enc = randSeedItem(validEventEncounters);
|
||||
species = getPokemonSpecies(enc.species);
|
||||
pokemon = new PlayerPokemon(
|
||||
@ -135,6 +133,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.trySetShinySeed();
|
||||
if (pokemon.shiny || pokemon.abilityIndex === 2) {
|
||||
isEventEncounter = true;
|
||||
break;
|
||||
}
|
||||
tries++;
|
||||
@ -149,6 +148,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.trySetShinySeed();
|
||||
pokemon.trySetShinySeed();
|
||||
isEventEncounter = true;
|
||||
} else {
|
||||
// If there's, and this would never happen, no eligible event encounters with a hidden ability, just do Magikarp
|
||||
species = getPokemonSpecies(SpeciesId.MAGIKARP);
|
||||
@ -177,7 +177,9 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
||||
if (pokemon.shiny) {
|
||||
// Always max price for shiny (flip HA back to normal), and add special messaging
|
||||
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
||||
pokemon.abilityIndex = 0;
|
||||
if (!isEventEncounter) {
|
||||
pokemon.abilityIndex = 0;
|
||||
}
|
||||
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}:descriptionShiny`;
|
||||
encounter.options[0].dialogue!.buttonTooltip = `${namespace}:option.1.tooltipShiny`;
|
||||
}
|
||||
|
||||
@ -45,6 +45,8 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
||||
)
|
||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withScenePartySizeRequirement(3, 6)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "vito",
|
||||
|
||||
@ -47,7 +47,8 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
MysteryEncounterType.TRASH_TO_TREASURE,
|
||||
)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withScenePartySizeRequirement(3, 6)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withFleeAllowed(false)
|
||||
.withIntroSpriteConfigs([
|
||||
@ -148,6 +149,48 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
},
|
||||
],
|
||||
})
|
||||
.withOptionPhase(async () => {
|
||||
// Investigate garbage, battle Gmax Garbodor
|
||||
globalScene.setFieldScale(0.75);
|
||||
await showEncounterText(`${namespace}:option.1.selected2`);
|
||||
await transitionMysteryEncounterIntroVisuals();
|
||||
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
||||
setEncounterRewards({
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
|
||||
guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT],
|
||||
fillRemaining: true,
|
||||
});
|
||||
encounter.startOfBattleEffects.push(
|
||||
{
|
||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||
targets: [BattlerIndex.PLAYER],
|
||||
move: new PokemonMove(MoveId.TOXIC),
|
||||
useMode: MoveUseMode.IGNORE_PP,
|
||||
},
|
||||
{
|
||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||
targets: [BattlerIndex.ENEMY],
|
||||
move: new PokemonMove(MoveId.STOCKPILE),
|
||||
useMode: MoveUseMode.IGNORE_PP,
|
||||
},
|
||||
);
|
||||
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
|
||||
})
|
||||
.build(),
|
||||
)
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.withPreOptionPhase(async () => {
|
||||
// Play Dig2 and then Venom Drench sfx
|
||||
doGarbageDig();
|
||||
@ -180,48 +223,6 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
||||
})
|
||||
.build(),
|
||||
)
|
||||
.withOption(
|
||||
MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||
.withDialogue({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
},
|
||||
],
|
||||
})
|
||||
.withOptionPhase(async () => {
|
||||
// Investigate garbage, battle Gmax Garbodor
|
||||
globalScene.setFieldScale(0.75);
|
||||
await showEncounterText(`${namespace}:option.2.selected2`);
|
||||
await transitionMysteryEncounterIntroVisuals();
|
||||
|
||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||
|
||||
setEncounterRewards({
|
||||
guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS],
|
||||
guaranteedModifierTiers: [ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.GREAT],
|
||||
fillRemaining: true,
|
||||
});
|
||||
encounter.startOfBattleEffects.push(
|
||||
{
|
||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||
targets: [BattlerIndex.PLAYER],
|
||||
move: new PokemonMove(MoveId.TOXIC),
|
||||
useMode: MoveUseMode.IGNORE_PP,
|
||||
},
|
||||
{
|
||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||
targets: [BattlerIndex.ENEMY],
|
||||
move: new PokemonMove(MoveId.STOCKPILE),
|
||||
useMode: MoveUseMode.IGNORE_PP,
|
||||
},
|
||||
);
|
||||
await initBattleWithEnemyConfig(encounter.enemyPartyConfigs[0]);
|
||||
})
|
||||
.build(),
|
||||
)
|
||||
.build();
|
||||
|
||||
async function tryApplyDigRewardItems() {
|
||||
|
||||
@ -15,7 +15,7 @@ import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { queueEncounterMessage } from "#mystery-encounters/encounter-dialogue-utils";
|
||||
import type { EnemyPartyConfig } from "#mystery-encounters/encounter-phase-utils";
|
||||
import {
|
||||
getRandomEncounterSpecies,
|
||||
getRandomEncounterPokemon,
|
||||
initBattleWithEnemyConfig,
|
||||
leaveEncounterWithoutBattle,
|
||||
setEncounterExp,
|
||||
@ -62,7 +62,12 @@ export const UncommonBreedEncounter: MysteryEncounter = MysteryEncounterBuilder.
|
||||
// Calculate boss mon
|
||||
// Level equal to 2 below highest party member
|
||||
const level = getHighestLevelPlayerPokemon(false, true).level - 2;
|
||||
const pokemon = getRandomEncounterSpecies(level, true, true);
|
||||
const pokemon = getRandomEncounterPokemon({
|
||||
level,
|
||||
isBoss: true,
|
||||
eventShinyRerolls: 2,
|
||||
eventHiddenRerolls: 1,
|
||||
});
|
||||
|
||||
// Pokemon will always have one of its egg moves in its moveset
|
||||
const eggMoves = pokemon.getEggMoves();
|
||||
|
||||
@ -127,8 +127,9 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
||||
)
|
||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||
.withDisallowedChallenges(Challenges.SINGLE_TYPE, Challenges.SINGLE_GENERATION)
|
||||
// TODO: should reset minimum wave to 10 when there are more Rogue tiers in pool. Matching Dark Deal minimum for now.
|
||||
.withSceneWaveRangeRequirement(30, 140)
|
||||
.withScenePartySizeRequirement(3, 6)
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "weird_dream_woman",
|
||||
|
||||
@ -4,6 +4,7 @@ import { timedEventManager } from "#app/global-event-manager";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { biomeLinks } from "#balance/biomes";
|
||||
import { BASE_HIDDEN_ABILITY_CHANCE, BASE_SHINY_CHANCE } from "#balance/rates";
|
||||
import { initMoveAnim, loadMoveAnimAssets } from "#data/battle-anims";
|
||||
import { modifierTypes } from "#data/data-lists";
|
||||
import type { IEggOptions } from "#data/egg";
|
||||
@ -47,11 +48,12 @@ import type { PokemonData } from "#system/pokemon-data";
|
||||
import type { TrainerConfig } from "#trainers/trainer-config";
|
||||
import { trainerConfigs } from "#trainers/trainer-config";
|
||||
import type { HeldModifierConfig } from "#types/held-modifier-config";
|
||||
import type { RandomEncounterParams } from "#types/pokemon-common";
|
||||
import type { OptionSelectConfig, OptionSelectItem } from "#ui/abstract-option-select-ui-handler";
|
||||
import type { PartyOption, PokemonSelectFilter } from "#ui/party-ui-handler";
|
||||
import { PartyUiMode } from "#ui/party-ui-handler";
|
||||
import { coerceArray } from "#utils/array";
|
||||
import { randomString, randSeedInt, randSeedItem } from "#utils/common";
|
||||
import { BooleanHolder, randomString, randSeedInt, randSeedItem } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
||||
@ -990,19 +992,39 @@ export function handleMysteryEncounterTurnStartEffects(): boolean {
|
||||
|
||||
/**
|
||||
* Helper function for encounters such as {@linkcode UncommonBreedEncounter} which call for a random species including event encounters.
|
||||
* If the mon is from the event encounter list, it will do an extra shiny roll.
|
||||
* @param level the level of the mon, which differs between MEs
|
||||
* @param isBoss whether the mon should be a Boss
|
||||
* @param rerollHidden whether the mon should get an extra roll for Hidden Ability
|
||||
* @returns for the requested encounter
|
||||
* If the mon is from the event encounter list, it may do an extra shiny or HA roll.
|
||||
* @param params - The {@linkcode RandomEncounterParams} used to configure the encounter
|
||||
* @returns The generated {@linkcode EnemyPokemon} for the requested encounter
|
||||
*/
|
||||
export function getRandomEncounterSpecies(level: number, isBoss = false, rerollHidden = false): EnemyPokemon {
|
||||
export function getRandomEncounterPokemon(params: RandomEncounterParams): EnemyPokemon {
|
||||
let {
|
||||
level,
|
||||
speciesFunction,
|
||||
isBoss = false,
|
||||
includeSubLegendary = true,
|
||||
includeLegendary = true,
|
||||
includeMythical = true,
|
||||
eventChance = 50,
|
||||
hiddenRerolls = 0,
|
||||
shinyRerolls = 0,
|
||||
eventHiddenRerolls = 0,
|
||||
eventShinyRerolls = 0,
|
||||
hiddenAbilityChance = BASE_HIDDEN_ABILITY_CHANCE,
|
||||
shinyChance = BASE_SHINY_CHANCE,
|
||||
maxShinyChance = 0,
|
||||
speciesFilter = () => true,
|
||||
isEventEncounter = new BooleanHolder(false),
|
||||
} = params;
|
||||
let bossSpecies: PokemonSpecies;
|
||||
let isEventEncounter = false;
|
||||
const eventEncounters = timedEventManager.getEventEncounters();
|
||||
const eventEncounters = timedEventManager.getAllValidEventEncounters(
|
||||
includeSubLegendary,
|
||||
includeLegendary,
|
||||
includeMythical,
|
||||
speciesFilter,
|
||||
);
|
||||
let formIndex: number | undefined;
|
||||
|
||||
if (eventEncounters.length > 0 && randSeedInt(2) === 1) {
|
||||
if (eventChance && eventEncounters.length > 0 && (eventChance === 100 || randSeedInt(100) < eventChance)) {
|
||||
const eventEncounter = randSeedItem(eventEncounters);
|
||||
const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(
|
||||
level,
|
||||
@ -1010,9 +1032,13 @@ export function getRandomEncounterSpecies(level: number, isBoss = false, rerollH
|
||||
isBoss,
|
||||
globalScene.gameMode,
|
||||
);
|
||||
isEventEncounter = true;
|
||||
if (params.isEventEncounter) {
|
||||
params.isEventEncounter.value = true;
|
||||
}
|
||||
bossSpecies = getPokemonSpecies(levelSpecies);
|
||||
formIndex = eventEncounter.formIndex;
|
||||
} else if (speciesFunction) {
|
||||
bossSpecies = speciesFunction();
|
||||
} else {
|
||||
bossSpecies = globalScene.arena.randomSpecies(
|
||||
globalScene.currentBattle.waveIndex,
|
||||
@ -1027,13 +1053,19 @@ export function getRandomEncounterSpecies(level: number, isBoss = false, rerollH
|
||||
ret.formIndex = formIndex;
|
||||
}
|
||||
|
||||
//Reroll shiny or variant for event encounters
|
||||
if (isEventEncounter) {
|
||||
ret.trySetShinySeed();
|
||||
if (isEventEncounter.value) {
|
||||
hiddenRerolls += eventHiddenRerolls;
|
||||
shinyRerolls += eventShinyRerolls;
|
||||
}
|
||||
//Reroll hidden ability
|
||||
if (rerollHidden && ret.abilityIndex !== 2 && ret.species.abilityHidden) {
|
||||
ret.tryRerollHiddenAbilitySeed();
|
||||
|
||||
while (shinyRerolls > 0) {
|
||||
ret.trySetShinySeed(shinyChance, true, maxShinyChance);
|
||||
shinyRerolls--;
|
||||
}
|
||||
|
||||
while (hiddenRerolls > 0) {
|
||||
ret.tryRerollHiddenAbilitySeed(hiddenAbilityChance, true);
|
||||
hiddenRerolls--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@ -13,18 +13,11 @@ import type { SpeciesId } from "#enums/species-id";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import type { AttackMoveResult } from "#types/attack-move-result";
|
||||
import type { IllusionData } from "#types/illusion-data";
|
||||
import type { SerializedSpeciesForm } from "#types/pokemon-common";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import type { CoerceNullPropertiesToUndefined } from "#types/type-helpers";
|
||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
|
||||
/**
|
||||
* The type that {@linkcode PokemonSpeciesForm} is converted to when an object containing it serializes it.
|
||||
*/
|
||||
type SerializedSpeciesForm = {
|
||||
id: SpeciesId;
|
||||
formIdx: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Permanent data that can customize a Pokemon in non-standard ways from its Species.
|
||||
* Includes abilities, nature, changed types, etc.
|
||||
|
||||
@ -67,7 +67,7 @@ export class Terrain {
|
||||
return (
|
||||
!isFieldTargeted(move)
|
||||
&& !isSpreadMove(move)
|
||||
&& move.getPriority(user) > 0.2 // fractional priority is used by quick claw etc and is not blocked by terrain
|
||||
&& move.getPriority(user) > 0
|
||||
&& user.getOpponents(true).some(o => targets.includes(o.getBattlerIndex()) && o.isGrounded())
|
||||
);
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ const SLOT_3_FIGHT_2 = [
|
||||
SpeciesId.MACHOP,
|
||||
SpeciesId.GASTLY,
|
||||
SpeciesId.MAGNEMITE,
|
||||
SpeciesId.RHYDON,
|
||||
SpeciesId.RHYHORN,
|
||||
SpeciesId.TANGELA,
|
||||
SpeciesId.PORYGON,
|
||||
SpeciesId.ELEKID,
|
||||
@ -298,7 +298,7 @@ const SLOT_3_FIGHT_3 = [
|
||||
SpeciesId.RHYDON,
|
||||
SpeciesId.TANGROWTH,
|
||||
SpeciesId.PORYGON2,
|
||||
SpeciesId.ELECTIVIRE,
|
||||
SpeciesId.ELECTABUZZ,
|
||||
SpeciesId.MAGMAR,
|
||||
SpeciesId.AZUMARILL,
|
||||
SpeciesId.URSARING,
|
||||
@ -520,7 +520,6 @@ const SLOT_5_FINAL = [
|
||||
SpeciesId.DRAGAPULT,
|
||||
SpeciesId.KINGAMBIT,
|
||||
SpeciesId.BAXCALIBUR,
|
||||
SpeciesId.GHOLDENGO,
|
||||
SpeciesId.ARCHALUDON,
|
||||
SpeciesId.HYDRAPPLE,
|
||||
SpeciesId.HISUI_GOODRA,
|
||||
|
||||
@ -251,25 +251,31 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
const hasSun = arena.getTimeOfDay() < 2;
|
||||
switch (arena.biomeType) {
|
||||
case BiomeId.GRASS:
|
||||
weatherPool = [{ weatherType: WeatherType.NONE, weight: 7 }];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 3 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.TALL_GRASS:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 8 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 5 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 4 },
|
||||
];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 8 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.TALL_GRASS:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 8 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 4 },
|
||||
];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 4 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.FOREST:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 8 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 5 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 4 },
|
||||
];
|
||||
if (!hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.FOG, weight: 1 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.SEA:
|
||||
weatherPool = [
|
||||
@ -296,7 +302,7 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
case BiomeId.LAKE:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 10 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 5 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 4 },
|
||||
{ weatherType: WeatherType.FOG, weight: 1 },
|
||||
];
|
||||
break;
|
||||
@ -313,9 +319,12 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
}
|
||||
break;
|
||||
case BiomeId.DESERT:
|
||||
weatherPool = [{ weatherType: WeatherType.SANDSTORM, weight: 2 }];
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 2 },
|
||||
{ weatherType: WeatherType.SANDSTORM, weight: 8 },
|
||||
];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.ICE_CAVE:
|
||||
@ -326,9 +335,9 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
];
|
||||
break;
|
||||
case BiomeId.MEADOW:
|
||||
weatherPool = [{ weatherType: WeatherType.NONE, weight: 2 }];
|
||||
weatherPool = [{ weatherType: WeatherType.NONE, weight: 3 }];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
|
||||
}
|
||||
break;
|
||||
case BiomeId.VOLCANO:
|
||||
@ -348,7 +357,8 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
case BiomeId.JUNGLE:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 8 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 2 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 6 },
|
||||
{ weatherType: WeatherType.FOG, weight: 1 },
|
||||
];
|
||||
break;
|
||||
case BiomeId.SNOWY_FOREST:
|
||||
@ -359,11 +369,11 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
||||
break;
|
||||
case BiomeId.ISLAND:
|
||||
weatherPool = [
|
||||
{ weatherType: WeatherType.NONE, weight: 5 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 1 },
|
||||
{ weatherType: WeatherType.NONE, weight: 7 },
|
||||
{ weatherType: WeatherType.RAIN, weight: 3 },
|
||||
];
|
||||
if (hasSun) {
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 });
|
||||
weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 5 });
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
13
src/enums/move-priority-in-bracket.ts
Normal file
13
src/enums/move-priority-in-bracket.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import type { ObjectValues } from "#types/type-helpers";
|
||||
|
||||
/**
|
||||
* Enum representing modifiers for Move priorities.
|
||||
*/
|
||||
export const MovePriorityInBracket = Object.freeze({
|
||||
/** Used when moves go last in their priority bracket, but before moves of lower priority. */
|
||||
LAST: 0,
|
||||
NORMAL: 1,
|
||||
/** Used when moves go first in their priority bracket, but before moves of lower priority. */
|
||||
FIRST: 2,
|
||||
});
|
||||
export type MovePriorityInBracket = ObjectValues<typeof MovePriorityInBracket>;
|
||||
@ -40,6 +40,7 @@ import type { Constructor } from "#types/common";
|
||||
import type { AbstractConstructor } from "#types/type-helpers";
|
||||
import { NumberHolder, randSeedInt } from "#utils/common";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
|
||||
export class Arena {
|
||||
public biomeType: BiomeId;
|
||||
@ -248,20 +249,6 @@ export class Arena {
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
case SpeciesId.ROTOM:
|
||||
switch (this.biomeType) {
|
||||
case BiomeId.VOLCANO:
|
||||
return 1;
|
||||
case BiomeId.SEA:
|
||||
return 2;
|
||||
case BiomeId.ICE_CAVE:
|
||||
return 3;
|
||||
case BiomeId.MOUNTAIN:
|
||||
return 4;
|
||||
case BiomeId.TALL_GRASS:
|
||||
return 5;
|
||||
}
|
||||
break;
|
||||
case SpeciesId.LYCANROC: {
|
||||
const timeOfDay = this.getTimeOfDay();
|
||||
switch (timeOfDay) {
|
||||
@ -358,15 +345,12 @@ export class Arena {
|
||||
globalScene.phaseManager.queueMessage(getWeatherClearMessage(oldWeatherType)!); // TODO: is this bang correct?
|
||||
}
|
||||
|
||||
globalScene
|
||||
.getField(true)
|
||||
.filter(p => p.isOnField())
|
||||
.map(pokemon => {
|
||||
pokemon.findAndRemoveTags(
|
||||
t => "weatherTypes" in t && !(t.weatherTypes as WeatherType[]).find(t => t === weather),
|
||||
);
|
||||
applyAbAttrs("PostWeatherChangeAbAttr", { pokemon, weather });
|
||||
});
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
pokemon.findAndRemoveTags(
|
||||
tag => "weatherTypes" in tag && !(tag.weatherTypes as WeatherType[]).find(t => t === weather),
|
||||
);
|
||||
applyAbAttrs("PostWeatherChangeAbAttr", { pokemon, weather });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -376,11 +360,11 @@ export class Arena {
|
||||
* @param source - The Pokemon causing the changes by removing itself from the field
|
||||
*/
|
||||
triggerWeatherBasedFormChanges(source?: Pokemon): void {
|
||||
globalScene.getField(true).forEach(p => {
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
// TODO - This is a bandaid. Abilities leaving the field needs a better approach than
|
||||
// calling this method for every switch out that happens
|
||||
if (p === source) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const isCastformWithForecast = p.hasAbility(AbilityId.FORECAST) && p.species.speciesId === SpeciesId.CASTFORM;
|
||||
const isCherrimWithFlowerGift = p.hasAbility(AbilityId.FLOWER_GIFT) && p.species.speciesId === SpeciesId.CHERRIM;
|
||||
@ -388,23 +372,23 @@ export class Arena {
|
||||
if (isCastformWithForecast || isCherrimWithFlowerGift) {
|
||||
globalScene.triggerPokemonFormChange(p, SpeciesFormChangeWeatherTrigger);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to trigger all weather based form changes back into their normal forms
|
||||
*/
|
||||
triggerWeatherBasedFormChangesToNormal(): void {
|
||||
globalScene.getField(true).forEach(p => {
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
const isCastformWithForecast =
|
||||
p.hasAbility(AbilityId.FORECAST, false, true) && p.species.speciesId === SpeciesId.CASTFORM;
|
||||
const isCherrimWithFlowerGift =
|
||||
p.hasAbility(AbilityId.FLOWER_GIFT, false, true) && p.species.speciesId === SpeciesId.CHERRIM;
|
||||
|
||||
if (isCastformWithForecast || isCherrimWithFlowerGift) {
|
||||
return globalScene.triggerPokemonFormChange(p, SpeciesFormChangeRevertWeatherFormTrigger);
|
||||
globalScene.triggerPokemonFormChange(p, SpeciesFormChangeRevertWeatherFormTrigger);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns whether or not the terrain can be set to {@linkcode terrain} */
|
||||
@ -453,16 +437,13 @@ export class Arena {
|
||||
globalScene.phaseManager.queueMessage(getTerrainClearMessage(oldTerrainType));
|
||||
}
|
||||
|
||||
globalScene
|
||||
.getField(true)
|
||||
.filter(p => p.isOnField())
|
||||
.map(pokemon => {
|
||||
pokemon.findAndRemoveTags(
|
||||
t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain),
|
||||
);
|
||||
applyAbAttrs("PostTerrainChangeAbAttr", { pokemon, terrain });
|
||||
applyAbAttrs("TerrainEventTypeChangeAbAttr", { pokemon });
|
||||
});
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
pokemon.findAndRemoveTags(
|
||||
t => "terrainTypes" in t && !(t.terrainTypes as TerrainType[]).find(t => t === terrain),
|
||||
);
|
||||
applyAbAttrs("PostTerrainChangeAbAttr", { pokemon, terrain });
|
||||
applyAbAttrs("TerrainEventTypeChangeAbAttr", { pokemon });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ import {
|
||||
TrappedTag,
|
||||
TypeImmuneTag,
|
||||
} from "#data/battler-tags";
|
||||
import { getDailyEventSeedBoss } from "#data/daily-run";
|
||||
import { getDailyEventSeedBoss, getDailyEventSeedBossVariant } from "#data/daily-run";
|
||||
import { allAbilities, allMoves } from "#data/data-lists";
|
||||
import { getLevelTotalExp } from "#data/exp";
|
||||
import {
|
||||
@ -143,7 +143,6 @@ import type { AbAttrMap, AbAttrString, TypeMultiplierAbAttrParams } from "#types
|
||||
import type { Constructor } from "#types/common";
|
||||
import type { getAttackDamageParams, getBaseDamageParams } from "#types/damage-params";
|
||||
import type { DamageCalculationResult, DamageResult } from "#types/damage-result";
|
||||
import type { IllusionData } from "#types/illusion-data";
|
||||
import type { LevelMoves } from "#types/pokemon-level-moves";
|
||||
import type { StarterDataEntry, StarterMoveset } from "#types/save-data";
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
@ -173,6 +172,7 @@ import {
|
||||
import { calculateBossSegmentDamage } from "#utils/damage";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import { getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#utils/pokemon-utils";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import { argbFromRgba, QuantizerCelebi, rgbaFromArgb } from "@material/material-color-utilities";
|
||||
import i18next from "i18next";
|
||||
import Phaser from "phaser";
|
||||
@ -2347,15 +2347,14 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
/** Holds whether the pokemon is trapped due to an ability */
|
||||
const trapped = new BooleanHolder(false);
|
||||
/**
|
||||
* Contains opposing Pokemon (Enemy/Player Pokemon) depending on perspective
|
||||
* Afterwards, it filters out Pokemon that have been switched out of the field so trapped abilities/moves do not trigger
|
||||
*/
|
||||
const opposingFieldUnfiltered = this.isPlayer() ? globalScene.getEnemyField() : globalScene.getPlayerField();
|
||||
const opposingField = opposingFieldUnfiltered.filter(enemyPkm => enemyPkm.switchOutStatus === false);
|
||||
|
||||
for (const opponent of opposingField) {
|
||||
applyAbAttrs("CheckTrappedAbAttr", { pokemon: opponent, trapped, opponent: this, simulated }, trappedAbMessages);
|
||||
for (const opponent of inSpeedOrder(this.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER)) {
|
||||
if (opponent.switchOutStatus === false) {
|
||||
applyAbAttrs(
|
||||
"CheckTrappedAbAttr",
|
||||
{ pokemon: opponent, trapped, opponent: this, simulated },
|
||||
trappedAbMessages,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const side = this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY;
|
||||
@ -2468,8 +2467,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
// Do not check queenly majesty unless this is being simulated
|
||||
// This is because the move effect phase should not check queenly majesty, as that is handled by the move phase
|
||||
if (simulated && !cancelledHolder.value) {
|
||||
const defendingSidePlayField = this.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
defendingSidePlayField.forEach((p: (typeof defendingSidePlayField)[0]) => {
|
||||
for (const p of this.getAlliesGenerator()) {
|
||||
applyAbAttrs("FieldPriorityMoveImmunityAbAttr", {
|
||||
pokemon: p,
|
||||
opponent: source,
|
||||
@ -2477,7 +2475,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
cancelled: cancelledHolder,
|
||||
simulated,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2904,12 +2902,15 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (thresholdOverride === undefined) {
|
||||
if (timedEventManager.isEventActive()) {
|
||||
const tchance = timedEventManager.getClassicTrainerShinyChance();
|
||||
shinyThreshold.value *= timedEventManager.getShinyEncounterMultiplier();
|
||||
if (this.hasTrainer() && tchance > 0) {
|
||||
if (this.isEnemy() && this.hasTrainer() && tchance > 0) {
|
||||
shinyThreshold.value = Math.max(tchance, shinyThreshold.value); // Choose the higher boost
|
||||
} else {
|
||||
// Wild shiny event multiplier
|
||||
shinyThreshold.value *= timedEventManager.getShinyEncounterMultiplier();
|
||||
}
|
||||
}
|
||||
if (!this.hasTrainer()) {
|
||||
if (this.isPlayer() || !this.hasTrainer()) {
|
||||
// Apply shiny modifiers only to Player or wild mons
|
||||
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
||||
}
|
||||
} else {
|
||||
@ -2933,11 +2934,16 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* If it rolls shiny, or if it's already shiny, also sets a random variant and give the Pokemon the associated luck.
|
||||
*
|
||||
* The base shiny odds are {@linkcode BASE_SHINY_CHANCE} / `65536`
|
||||
* @param thresholdOverride - number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
||||
* @param applyModifiersToOverride - If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
||||
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the shiny chance, overrides {@linkcode shinyThreshold} if set (bypassing shiny rate modifiers such as Shiny Charm)
|
||||
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Shiny Charm and event modifiers to {@linkcode thresholdOverride}
|
||||
* @param maxThreshold The maximum threshold allowed after applying modifiers
|
||||
* @returns Whether this Pokémon was set to shiny
|
||||
*/
|
||||
public trySetShinySeed(thresholdOverride?: number, applyModifiersToOverride?: boolean): boolean {
|
||||
public trySetShinySeed(
|
||||
thresholdOverride?: number,
|
||||
applyModifiersToOverride?: boolean,
|
||||
maxThreshold?: number,
|
||||
): boolean {
|
||||
if (!this.shiny) {
|
||||
const shinyThreshold = new NumberHolder(thresholdOverride ?? BASE_SHINY_CHANCE);
|
||||
if (applyModifiersToOverride) {
|
||||
@ -2947,6 +2953,10 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
globalScene.applyModifiers(ShinyRateBoosterModifier, true, shinyThreshold);
|
||||
}
|
||||
|
||||
if (maxThreshold && maxThreshold > 0) {
|
||||
shinyThreshold.value = Math.min(maxThreshold, shinyThreshold.value);
|
||||
}
|
||||
|
||||
this.shiny = randSeedInt(65536) < shinyThreshold.value;
|
||||
}
|
||||
|
||||
@ -3243,7 +3253,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pokemon that oppose this one and are active
|
||||
* Returns the pokemon that oppose this one and are active in non-speed order
|
||||
*
|
||||
* @param onField - whether to also check if the pokemon is currently on the field (defaults to true)
|
||||
*/
|
||||
@ -3253,6 +3263,13 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns A generator of pokemon that oppose this one in speed order
|
||||
*/
|
||||
public getOpponentsGenerator(): Generator<Pokemon, number> {
|
||||
return inSpeedOrder(this.isPlayer() ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER);
|
||||
}
|
||||
|
||||
getOpponentDescriptor(): string {
|
||||
return this.isPlayer() ? i18next.t("arenaTag:opposingTeam") : i18next.t("arenaTag:yourTeam");
|
||||
}
|
||||
@ -3262,12 +3279,10 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Pokémon on the allied field.
|
||||
*
|
||||
* @returns An array of Pokémon on the allied field.
|
||||
* @returns A generator of Pokémon on the allied field in speed order.
|
||||
*/
|
||||
getAlliedField(): Pokemon[] {
|
||||
return this.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
getAlliesGenerator(): Generator<Pokemon, number> {
|
||||
return inSpeedOrder(this.isPlayer() ? ArenaTagSide.PLAYER : ArenaTagSide.ENEMY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4020,16 +4035,15 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const cancelled = new BooleanHolder(false);
|
||||
applyAbAttrs("BattlerTagImmunityAbAttr", { pokemon: this, tag: stubTag, cancelled, simulated: true });
|
||||
|
||||
const userField = this.getAlliedField();
|
||||
userField.forEach(pokemon =>
|
||||
for (const pokemon of this.getAlliesGenerator()) {
|
||||
applyAbAttrs("UserFieldBattlerTagImmunityAbAttr", {
|
||||
pokemon,
|
||||
tag: stubTag,
|
||||
cancelled,
|
||||
simulated: true,
|
||||
target: this,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return !cancelled.value;
|
||||
}
|
||||
@ -4063,7 +4077,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const pokemon of this.getAlliedField()) {
|
||||
for (const pokemon of this.getAlliesGenerator()) {
|
||||
applyAbAttrs("UserFieldBattlerTagImmunityAbAttr", { pokemon, tag: newTag, cancelled, target: this });
|
||||
if (cancelled.value) {
|
||||
return false;
|
||||
@ -4811,7 +4825,7 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const pokemon of this.getAlliedField()) {
|
||||
for (const pokemon of this.getAlliesGenerator()) {
|
||||
applyAbAttrs("UserFieldStatusEffectImmunityAbAttr", {
|
||||
pokemon,
|
||||
effect,
|
||||
@ -5104,14 +5118,12 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
* in preparation for switching pokemon, as well as removing any relevant on-switch tags.
|
||||
*/
|
||||
public resetSummonData(): void {
|
||||
const illusion: IllusionData | null = this.summonData.illusion;
|
||||
if (this.summonData.speciesForm) {
|
||||
this.summonData.speciesForm = null;
|
||||
this.updateFusionPalette();
|
||||
}
|
||||
this.summonData = new PokemonSummonData();
|
||||
this.tempSummonData = new PokemonTempSummonData();
|
||||
this.summonData.illusion = illusion;
|
||||
this.updateInfo();
|
||||
}
|
||||
|
||||
@ -5619,10 +5631,11 @@ export abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
leaveField(clearEffects = true, hideInfo = true, destroy = false) {
|
||||
this.resetSprite();
|
||||
this.resetTurnData();
|
||||
globalScene
|
||||
.getField(true)
|
||||
.filter(p => p !== this)
|
||||
.forEach(p => p.removeTagsBySourceId(this.id));
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (p !== this) {
|
||||
p.removeTagsBySourceId(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (clearEffects) {
|
||||
this.destroySubstitute();
|
||||
@ -5845,19 +5858,27 @@ export class PlayerPokemon extends Pokemon {
|
||||
}
|
||||
}
|
||||
|
||||
tryPopulateMoveset(moveset: StarterMoveset): boolean {
|
||||
/**
|
||||
* Attempt to populate this Pokemon's moveset based on those from a Starter
|
||||
* @param moveset - The {@linkcode StarterMoveset} to use; will override corresponding slots
|
||||
* of this Pokemon's moveset
|
||||
* @param ignoreValidate - Whether to ignore validating the passed-in moveset; default `false`
|
||||
*/
|
||||
tryPopulateMoveset(moveset: StarterMoveset, ignoreValidate = false): void {
|
||||
// TODO: Why do we need to re-validate starter movesets after picking them?
|
||||
if (
|
||||
!this.getSpeciesForm().validateStarterMoveset(
|
||||
!ignoreValidate
|
||||
&& !this.getSpeciesForm().validateStarterMoveset(
|
||||
moveset,
|
||||
globalScene.gameData.starterData[this.species.getRootSpeciesId()].eggMoves,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.moveset = moveset.map(m => new PokemonMove(m));
|
||||
|
||||
return true;
|
||||
moveset.forEach((m, i) => {
|
||||
this.moveset[i] = new PokemonMove(m);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6363,8 +6384,15 @@ export class EnemyPokemon extends Pokemon {
|
||||
this.initShinySparkle();
|
||||
}
|
||||
|
||||
const eventBossVariant = getDailyEventSeedBossVariant(globalScene.seed);
|
||||
const eventBossVariantEnabled =
|
||||
eventBossVariant != null && globalScene.gameMode.isWaveFinal(globalScene.currentBattle.waveIndex);
|
||||
if (eventBossVariantEnabled) {
|
||||
this.shiny = true;
|
||||
}
|
||||
|
||||
if (this.shiny) {
|
||||
this.variant = this.generateShinyVariant();
|
||||
this.variant = eventBossVariantEnabled ? eventBossVariant : this.generateShinyVariant();
|
||||
if (Overrides.ENEMY_VARIANT_OVERRIDE !== null) {
|
||||
this.variant = Overrides.ENEMY_VARIANT_OVERRIDE;
|
||||
}
|
||||
|
||||
@ -1915,9 +1915,7 @@ export class PokemonInstantReviveModifier extends PokemonHeldItemModifier {
|
||||
// Remove the Pokemon's FAINT status
|
||||
pokemon.resetStatus(true, false, true, false);
|
||||
|
||||
// Reapply Commander on the Pokemon's side of the field, if applicable
|
||||
const field = pokemon.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
for (const p of field) {
|
||||
for (const p of pokemon.getAlliesGenerator()) {
|
||||
applyAbAttrs("CommanderAbAttr", { pokemon: p });
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { applyAbAttrs } from "#abilities/apply-ab-attrs";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import Overrides from "#app/overrides";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import { FieldPhase } from "#phases/field-phase";
|
||||
import { NumberHolder } from "#utils/common";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class AttemptRunPhase extends FieldPhase {
|
||||
@ -15,16 +17,14 @@ export class AttemptRunPhase extends FieldPhase {
|
||||
|
||||
// Increment escape attempts count on entry
|
||||
const currentAttempts = globalScene.currentBattle.escapeAttempts++;
|
||||
|
||||
const activePlayerField = globalScene.getPlayerField(true);
|
||||
const enemyField = globalScene.getEnemyField();
|
||||
|
||||
const escapeRoll = globalScene.randBattleSeedInt(100);
|
||||
const escapeChance = new NumberHolder(this.calculateEscapeChance(currentAttempts));
|
||||
|
||||
activePlayerField.forEach(pokemon => {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.PLAYER)) {
|
||||
applyAbAttrs("RunSuccessAbAttr", { pokemon, chance: escapeChance });
|
||||
});
|
||||
}
|
||||
|
||||
if (escapeRoll < escapeChance.value) {
|
||||
enemyField.forEach(pokemon => applyAbAttrs("PreLeaveFieldAbAttr", { pokemon }));
|
||||
@ -56,7 +56,7 @@ export class AttemptRunPhase extends FieldPhase {
|
||||
|
||||
globalScene.phaseManager.pushNew("NewBattlePhase");
|
||||
} else {
|
||||
activePlayerField.forEach(p => {
|
||||
globalScene.getPlayerField(true).forEach(p => {
|
||||
p.turnData.failedRunAway = true;
|
||||
});
|
||||
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Phase } from "#app/phase";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
|
||||
export class CheckStatusEffectPhase extends Phase {
|
||||
public readonly phaseName = "CheckStatusEffectPhase";
|
||||
|
||||
start() {
|
||||
const field = globalScene.getField();
|
||||
for (const p of field) {
|
||||
if (p?.status?.isPostTurn()) {
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (p.status?.isPostTurn()) {
|
||||
globalScene.phaseManager.unshiftNew("PostTurnStatusEffectPhase", p.getBattlerIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import { FRIENDSHIP_LOSS_FROM_FAINT } from "#balance/starters";
|
||||
import { allMoves } from "#data/data-lists";
|
||||
import { battleSpecDialogue } from "#data/dialogue";
|
||||
import { SpeciesFormChangeActiveTrigger } from "#data/form-change-triggers";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
import { BattleType } from "#enums/battle-type";
|
||||
import type { BattlerIndex } from "#enums/battler-index";
|
||||
@ -17,6 +18,7 @@ import type { EnemyPokemon, PlayerPokemon, Pokemon } from "#field/pokemon";
|
||||
import { PokemonInstantReviveModifier } from "#modifiers/modifier";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import { PokemonPhase } from "#phases/pokemon-phase";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class FaintPhase extends PokemonPhase {
|
||||
@ -126,8 +128,7 @@ export class FaintPhase extends PokemonPhase {
|
||||
applyAbAttrs("PostFaintAbAttr", { pokemon });
|
||||
}
|
||||
|
||||
const alivePlayField = globalScene.getField(true);
|
||||
for (const p of alivePlayField) {
|
||||
for (const p of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
applyAbAttrs("PostKnockOutAbAttr", { pokemon: p, victim: pokemon });
|
||||
}
|
||||
if (pokemon.turnData.attacksReceived?.length > 0) {
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { BattlePhase } from "#phases/battle-phase";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
|
||||
type PokemonFunc = (pokemon: Pokemon) => void;
|
||||
|
||||
export abstract class FieldPhase extends BattlePhase {
|
||||
executeForAll(func: PokemonFunc): void {
|
||||
for (const pokemon of globalScene.getField(true)) {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
func(pokemon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import { getStatusEffectActivationText } from "#data/status-effect";
|
||||
import { getTerrainBlockMessage } from "#data/terrain";
|
||||
import { getWeatherBlockMessage } from "#data/weather";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import { BattlerIndex } from "#enums/battler-index";
|
||||
import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type";
|
||||
@ -35,6 +36,7 @@ import type { TurnMove } from "#types/turn-move";
|
||||
import { applyChallenges } from "#utils/challenge-utils";
|
||||
import { BooleanHolder, NumberHolder } from "#utils/common";
|
||||
import { enumValueToKey } from "#utils/enums";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class MovePhase extends PokemonPhase {
|
||||
@ -284,7 +286,7 @@ export class MovePhase extends PokemonPhase {
|
||||
|
||||
// Apply queenly majesty / dazzling
|
||||
if (!failed) {
|
||||
const defendingSidePlayField = user.isPlayer() ? globalScene.getPlayerField() : globalScene.getEnemyField();
|
||||
const defendingSidePlayField = user.isPlayer() ? globalScene.getEnemyField() : globalScene.getPlayerField();
|
||||
const cancelled = new BooleanHolder(false);
|
||||
defendingSidePlayField.forEach((pokemon: Pokemon) => {
|
||||
applyAbAttrs("FieldPriorityMoveImmunityAbAttr", {
|
||||
@ -321,17 +323,16 @@ export class MovePhase extends PokemonPhase {
|
||||
|
||||
// check move redirection abilities of every pokemon *except* the user.
|
||||
// TODO: Make storm drain, lightning rod, etc, redirect at this point for type changing moves
|
||||
globalScene
|
||||
.getField(true)
|
||||
.filter(p => p !== this.pokemon)
|
||||
.forEach(pokemon => {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (pokemon !== this.pokemon) {
|
||||
applyAbAttrs("RedirectMoveAbAttr", {
|
||||
pokemon,
|
||||
moveId: this.move.moveId,
|
||||
targetIndex: redirectTarget,
|
||||
sourcePokemon: this.pokemon,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** `true` if an Ability is responsible for redirecting the move to another target; `false` otherwise */
|
||||
let redirectedByAbility = currentTarget !== redirectTarget.value;
|
||||
@ -848,9 +849,9 @@ export class MovePhase extends PokemonPhase {
|
||||
// TODO: This needs to go at the end of `MoveEffectPhase` to check move results
|
||||
const dancerModes: MoveUseMode[] = [MoveUseMode.INDIRECT, MoveUseMode.REFLECTED] as const;
|
||||
if (this.move.getMove().hasFlag(MoveFlags.DANCE_MOVE) && !dancerModes.includes(this.useMode)) {
|
||||
globalScene.getField(true).forEach(pokemon => {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
applyAbAttrs("PostMoveUsedAbAttr", { pokemon, move: this.move, source: user, targets });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Phase } from "#app/phase";
|
||||
import { getCharVariantFromDialogue } from "#data/dialogue";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { BattleSpec } from "#enums/battle-spec";
|
||||
import { BattlerTagLapseType } from "#enums/battler-tag-lapse-type";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
@ -15,6 +16,7 @@ import { transitionMysteryEncounterIntroVisuals } from "#mystery-encounters/enco
|
||||
import type { MysteryEncounterOption, OptionPhaseCallback } from "#mystery-encounters/mystery-encounter-option";
|
||||
import { SeenEncounterData } from "#mystery-encounters/mystery-encounter-save-data";
|
||||
import { randSeedItem } from "#utils/common";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
/**
|
||||
@ -216,7 +218,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
|
||||
// Lapse any residual flinches/endures but ignore all other turn-end battle tags
|
||||
const includedLapseTags = [BattlerTagType.FLINCHED, BattlerTagType.ENDURING];
|
||||
globalScene.getField(true).forEach(pokemon => {
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
const tags = pokemon.summonData.tags;
|
||||
tags
|
||||
.filter(
|
||||
@ -229,7 +231,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
t.onRemove(pokemon);
|
||||
tags.splice(tags.indexOf(t), 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Remove any status tick phases
|
||||
globalScene.phaseManager.removeAllPhasesOfType("PostTurnStatusEffectPhase");
|
||||
@ -427,7 +429,9 @@ export class MysteryEncounterBattlePhase extends Phase {
|
||||
}
|
||||
} else {
|
||||
if (availablePartyMembers.length > 1 && availablePartyMembers[1].isOnField()) {
|
||||
globalScene.getPlayerField().forEach(pokemon => pokemon.lapseTag(BattlerTagType.COMMANDED));
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.PLAYER)) {
|
||||
pokemon.lapseTag(BattlerTagType.COMMANDED);
|
||||
}
|
||||
globalScene.phaseManager.pushNew("ReturnPhase", 1);
|
||||
}
|
||||
globalScene.phaseManager.pushNew("ToggleDoublePositionPhase", false);
|
||||
|
||||
@ -30,8 +30,7 @@ export class PostSummonPhase extends PokemonPhase {
|
||||
) {
|
||||
pokemon.lapseTag(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON);
|
||||
}
|
||||
const field = pokemon.isPlayer() ? globalScene.getPlayerField(true) : globalScene.getEnemyField(true);
|
||||
for (const p of field) {
|
||||
for (const p of pokemon.getAlliesGenerator()) {
|
||||
applyAbAttrs("CommanderAbAttr", { pokemon: p });
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +71,9 @@ export class SelectStarterPhase extends Phase {
|
||||
starter.ivs,
|
||||
starter.nature,
|
||||
);
|
||||
starter.moveset && starterPokemon.tryPopulateMoveset(starter.moveset);
|
||||
if (starter.moveset) {
|
||||
starterPokemon.tryPopulateMoveset(starter.moveset);
|
||||
}
|
||||
if (starter.passive) {
|
||||
starterPokemon.passive = true;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
}
|
||||
|
||||
if (stages.value > 0 && this.canBeCopied) {
|
||||
for (const opponent of pokemon.getOpponents()) {
|
||||
for (const opponent of pokemon.getOpponentsGenerator()) {
|
||||
applyAbAttrs("StatStageChangeCopyAbAttr", { pokemon: opponent, stats: this.stats, numStages: stages.value });
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,12 +5,14 @@ import { SubstituteTag } from "#data/battler-tags";
|
||||
import { allMoves } from "#data/data-lists";
|
||||
import { SpeciesFormChangeActiveTrigger } from "#data/form-change-triggers";
|
||||
import { getPokeballTintColor } from "#data/pokeball";
|
||||
import { ArenaTagSide } from "#enums/arena-tag-side";
|
||||
import { Command } from "#enums/command";
|
||||
import { SwitchType } from "#enums/switch-type";
|
||||
import { TrainerSlot } from "#enums/trainer-slot";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import { SwitchEffectTransferModifier } from "#modifiers/modifier";
|
||||
import { SummonPhase } from "#phases/summon-phase";
|
||||
import { inSpeedOrder } from "#utils/speed-order-generator";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class SwitchSummonPhase extends SummonPhase {
|
||||
@ -69,9 +71,9 @@ export class SwitchSummonPhase extends SummonPhase {
|
||||
}
|
||||
|
||||
const pokemon = this.getPokemon();
|
||||
(this.player ? globalScene.getEnemyField() : globalScene.getPlayerField()).forEach(enemyPokemon =>
|
||||
enemyPokemon.removeTagsBySourceId(pokemon.id),
|
||||
);
|
||||
for (const enemyPokemon of inSpeedOrder(this.player ? ArenaTagSide.ENEMY : ArenaTagSide.PLAYER)) {
|
||||
enemyPokemon.removeTagsBySourceId(pokemon.id);
|
||||
}
|
||||
|
||||
if (this.switchType === SwitchType.SWITCH || this.switchType === SwitchType.INITIAL_SWITCH) {
|
||||
const substitute = pokemon.getTag(SubstituteTag);
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { pokerogueApi } from "#api/pokerogue-api";
|
||||
import { loggedInUser } from "#app/account";
|
||||
import { GameMode, getGameMode } from "#app/game-mode";
|
||||
import { timedEventManager } from "#app/global-event-manager";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import Overrides from "#app/overrides";
|
||||
import { Phase } from "#app/phase";
|
||||
import { bypassLogin } from "#constants/app-constants";
|
||||
import { fetchDailyRunSeed, getDailyRunStarters } from "#data/daily-run";
|
||||
import { getDailyRunStarters } from "#data/daily-run";
|
||||
import { modifierTypes } from "#data/data-lists";
|
||||
import { Gender } from "#data/gender";
|
||||
import { BattleType } from "#enums/battle-type";
|
||||
@ -217,6 +219,7 @@ export class TitlePhase extends Phase {
|
||||
const starters = getDailyRunStarters(seed);
|
||||
const startingLevel = globalScene.gameMode.getStartingLevel();
|
||||
|
||||
// TODO: Dedupe this
|
||||
const party = globalScene.getPlayerParty();
|
||||
const loadPokemonAssets: Promise<void>[] = [];
|
||||
for (const starter of starters) {
|
||||
@ -236,6 +239,11 @@ export class TitlePhase extends Phase {
|
||||
starter.nature,
|
||||
);
|
||||
starterPokemon.setVisible(false);
|
||||
if (starter.moveset) {
|
||||
// avoid validating daily run starter movesets which are pre-populated already
|
||||
starterPokemon.tryPopulateMoveset(starter.moveset, true);
|
||||
}
|
||||
|
||||
party.push(starterPokemon);
|
||||
loadPokemonAssets.push(starterPokemon.loadAssets());
|
||||
}
|
||||
@ -259,6 +267,9 @@ export class TitlePhase extends Phase {
|
||||
for (const m of modifiers) {
|
||||
globalScene.addModifier(m, true, false, false, true);
|
||||
}
|
||||
for (const m of timedEventManager.getEventDailyStartingItems()) {
|
||||
globalScene.addModifier(modifierTypes[m]().newModifier(), true, false, false, true);
|
||||
}
|
||||
globalScene.updateModifiers(true, true);
|
||||
|
||||
Promise.all(loadPokemonAssets).then(() => {
|
||||
@ -275,7 +286,8 @@ export class TitlePhase extends Phase {
|
||||
|
||||
// If Online, calls seed fetch from db to generate daily run. If Offline, generates a daily run based on current date.
|
||||
if (!bypassLogin || isLocalServerConnected) {
|
||||
fetchDailyRunSeed()
|
||||
pokerogueApi.daily
|
||||
.getSeed()
|
||||
.then(seed => {
|
||||
if (seed) {
|
||||
generateDaily(seed);
|
||||
|
||||
@ -69,6 +69,10 @@ export class TurnStartPhase extends FieldPhase {
|
||||
|
||||
const phaseManager = globalScene.phaseManager;
|
||||
for (const pokemon of inSpeedOrder(ArenaTagSide.BOTH)) {
|
||||
if (globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()]?.command !== Command.FIGHT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
applyAbAttrs("BypassSpeedChanceAbAttr", { pokemon });
|
||||
globalScene.applyModifiers(BypassSpeedChanceModifier, pokemon.isPlayer(), pokemon);
|
||||
}
|
||||
|
||||
@ -92,11 +92,18 @@ export class MovePhasePriorityQueue extends PokemonPhasePriorityQueue<MovePhase>
|
||||
});
|
||||
|
||||
const timingModifiers = [a, b].map(movePhase => movePhase.timingModifier);
|
||||
const priorityModifiers = [a, b].map(movePhase =>
|
||||
movePhase.move.getMove().getPriorityModifier(movePhase.pokemon),
|
||||
);
|
||||
|
||||
if (timingModifiers[0] !== timingModifiers[1]) {
|
||||
return timingModifiers[1] - timingModifiers[0];
|
||||
}
|
||||
|
||||
if (priority[0] === priority[1] && priorityModifiers[0] !== priorityModifiers[1]) {
|
||||
return priorityModifiers[1] - priorityModifiers[0];
|
||||
}
|
||||
|
||||
return priority[1] - priority[0];
|
||||
});
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import { sortInSpeedOrder } from "#app/utils/speed-order";
|
||||
*/
|
||||
export class PostSummonPhasePriorityQueue extends PokemonPhasePriorityQueue<PostSummonPhase> {
|
||||
protected override reorder(): void {
|
||||
this.queue = sortInSpeedOrder(this.queue, false);
|
||||
this.queue = sortInSpeedOrder(this.queue);
|
||||
this.queue.sort((phaseA, phaseB) => phaseB.getPriority() - phaseA.getPriority());
|
||||
}
|
||||
|
||||
|
||||
@ -458,7 +458,7 @@ export const achvs = {
|
||||
CLASSIC_VICTORY: new Achv(
|
||||
"classicVictory",
|
||||
"classicVictory.description",
|
||||
"relic_crown",
|
||||
"classic_ribbon_default",
|
||||
250,
|
||||
_ => globalScene.gameData.gameStats.sessionsWon === 0,
|
||||
),
|
||||
@ -483,7 +483,7 @@ export const achvs = {
|
||||
LV_250: new LevelAchv("lv250", 250, "rarer_candy", 25).setSecret(true),
|
||||
LV_1000: new LevelAchv("lv1000", 1000, "candy_jar", 50).setSecret(true),
|
||||
TRANSFER_MAX_STAT_STAGE: new Achv("transferMaxStatStage", "transferMaxStatStage.description", "baton", 25),
|
||||
MAX_FRIENDSHIP: new Achv("maxFriendship", "maxFriendship.description", "soothe_bell", 25),
|
||||
MAX_FRIENDSHIP: new Achv("maxFriendship", "maxFriendship.description", "ribbon_friendship", 25),
|
||||
MEGA_EVOLVE: new Achv("megaEvolve", "megaEvolve.description", "mega_bracelet", 50),
|
||||
GIGANTAMAX: new Achv("gigantamax", "gigantamax.description", "dynamax_band", 50),
|
||||
TERASTALLIZE: new Achv("terastallize", "terastallize.description", "tera_orb", 25),
|
||||
@ -651,7 +651,7 @@ export const achvs = {
|
||||
MONO_NORMAL: new ChallengeAchv(
|
||||
"monoNormal",
|
||||
"monoNormal.description",
|
||||
"silk_scarf",
|
||||
"ribbon_normal",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -663,7 +663,7 @@ export const achvs = {
|
||||
MONO_FIGHTING: new ChallengeAchv(
|
||||
"monoFighting",
|
||||
"monoFighting.description",
|
||||
"black_belt",
|
||||
"ribbon_fighting",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -675,7 +675,7 @@ export const achvs = {
|
||||
MONO_FLYING: new ChallengeAchv(
|
||||
"monoFlying",
|
||||
"monoFlying.description",
|
||||
"sharp_beak",
|
||||
"ribbon_flying",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -687,7 +687,7 @@ export const achvs = {
|
||||
MONO_POISON: new ChallengeAchv(
|
||||
"monoPoison",
|
||||
"monoPoison.description",
|
||||
"poison_barb",
|
||||
"ribbon_poison",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -699,7 +699,7 @@ export const achvs = {
|
||||
MONO_GROUND: new ChallengeAchv(
|
||||
"monoGround",
|
||||
"monoGround.description",
|
||||
"soft_sand",
|
||||
"ribbon_ground",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -711,7 +711,7 @@ export const achvs = {
|
||||
MONO_ROCK: new ChallengeAchv(
|
||||
"monoRock",
|
||||
"monoRock.description",
|
||||
"hard_stone",
|
||||
"ribbon_rock",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -723,7 +723,7 @@ export const achvs = {
|
||||
MONO_BUG: new ChallengeAchv(
|
||||
"monoBug",
|
||||
"monoBug.description",
|
||||
"silver_powder",
|
||||
"ribbon_bug",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -735,7 +735,7 @@ export const achvs = {
|
||||
MONO_GHOST: new ChallengeAchv(
|
||||
"monoGhost",
|
||||
"monoGhost.description",
|
||||
"spell_tag",
|
||||
"ribbon_ghost",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -747,7 +747,7 @@ export const achvs = {
|
||||
MONO_STEEL: new ChallengeAchv(
|
||||
"monoSteel",
|
||||
"monoSteel.description",
|
||||
"metal_coat",
|
||||
"ribbon_steel",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -759,7 +759,7 @@ export const achvs = {
|
||||
MONO_FIRE: new ChallengeAchv(
|
||||
"monoFire",
|
||||
"monoFire.description",
|
||||
"charcoal",
|
||||
"ribbon_fire",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -771,7 +771,7 @@ export const achvs = {
|
||||
MONO_WATER: new ChallengeAchv(
|
||||
"monoWater",
|
||||
"monoWater.description",
|
||||
"mystic_water",
|
||||
"ribbon_water",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -783,7 +783,7 @@ export const achvs = {
|
||||
MONO_GRASS: new ChallengeAchv(
|
||||
"monoGrass",
|
||||
"monoGrass.description",
|
||||
"miracle_seed",
|
||||
"ribbon_grass",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -795,7 +795,7 @@ export const achvs = {
|
||||
MONO_ELECTRIC: new ChallengeAchv(
|
||||
"monoElectric",
|
||||
"monoElectric.description",
|
||||
"magnet",
|
||||
"ribbon_electric",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -807,7 +807,7 @@ export const achvs = {
|
||||
MONO_PSYCHIC: new ChallengeAchv(
|
||||
"monoPsychic",
|
||||
"monoPsychic.description",
|
||||
"twisted_spoon",
|
||||
"ribbon_psychic",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -819,7 +819,7 @@ export const achvs = {
|
||||
MONO_ICE: new ChallengeAchv(
|
||||
"monoIce",
|
||||
"monoIce.description",
|
||||
"never_melt_ice",
|
||||
"ribbon_ice",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -831,7 +831,7 @@ export const achvs = {
|
||||
MONO_DRAGON: new ChallengeAchv(
|
||||
"monoDragon",
|
||||
"monoDragon.description",
|
||||
"dragon_fang",
|
||||
"ribbon_dragon",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -843,7 +843,7 @@ export const achvs = {
|
||||
MONO_DARK: new ChallengeAchv(
|
||||
"monoDark",
|
||||
"monoDark.description",
|
||||
"black_glasses",
|
||||
"ribbon_dark",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
@ -855,7 +855,7 @@ export const achvs = {
|
||||
MONO_FAIRY: new ChallengeAchv(
|
||||
"monoFairy",
|
||||
"monoFairy.description",
|
||||
"fairy_feather",
|
||||
"ribbon_fairy",
|
||||
100,
|
||||
c =>
|
||||
c instanceof SingleTypeChallenge
|
||||
|
||||
@ -22,8 +22,12 @@ export function ribbonFlagToAssetKey(flag: RibbonFlag): Phaser.GameObjects.Sprit
|
||||
let imageKey: string;
|
||||
switch (flag) {
|
||||
// biome-ignore-start lint/suspicious/noFallthroughSwitchClause: intentional
|
||||
case RibbonData.CLASSIC:
|
||||
imageKey ??= "classic_ribbon_default";
|
||||
case RibbonData.FRIENDSHIP:
|
||||
imageKey ??= "ribbon_friendship";
|
||||
case RibbonData.MONO_GEN_1:
|
||||
imageKey = "ribbon_gen1";
|
||||
imageKey ??= "ribbon_gen1";
|
||||
case RibbonData.MONO_GEN_2:
|
||||
imageKey ??= "ribbon_gen2";
|
||||
case RibbonData.MONO_GEN_3:
|
||||
@ -40,20 +44,45 @@ export function ribbonFlagToAssetKey(flag: RibbonFlag): Phaser.GameObjects.Sprit
|
||||
imageKey ??= "ribbon_gen8";
|
||||
case RibbonData.MONO_GEN_9:
|
||||
imageKey ??= "ribbon_gen9";
|
||||
case RibbonData.MONO_NORMAL:
|
||||
imageKey ??= "ribbon_normal";
|
||||
case RibbonData.MONO_FIGHTING:
|
||||
imageKey ??= "ribbon_fighting";
|
||||
case RibbonData.MONO_FLYING:
|
||||
imageKey ??= "ribbon_flying";
|
||||
case RibbonData.MONO_POISON:
|
||||
imageKey ??= "ribbon_poison";
|
||||
case RibbonData.MONO_GROUND:
|
||||
imageKey ??= "ribbon_ground";
|
||||
case RibbonData.MONO_ROCK:
|
||||
imageKey ??= "ribbon_rock";
|
||||
case RibbonData.MONO_BUG:
|
||||
imageKey ??= "ribbon_bug";
|
||||
case RibbonData.MONO_GHOST:
|
||||
imageKey ??= "ribbon_ghost";
|
||||
case RibbonData.MONO_STEEL:
|
||||
imageKey ??= "ribbon_steel";
|
||||
case RibbonData.MONO_FIRE:
|
||||
imageKey ??= "ribbon_fire";
|
||||
case RibbonData.MONO_WATER:
|
||||
imageKey ??= "ribbon_water";
|
||||
case RibbonData.MONO_GRASS:
|
||||
imageKey ??= "ribbon_grass";
|
||||
case RibbonData.MONO_ELECTRIC:
|
||||
imageKey ??= "ribbon_electric";
|
||||
case RibbonData.MONO_PSYCHIC:
|
||||
imageKey ??= "ribbon_psychic";
|
||||
case RibbonData.MONO_ICE:
|
||||
imageKey ??= "ribbon_ice";
|
||||
case RibbonData.MONO_DRAGON:
|
||||
imageKey ??= "ribbon_dragon";
|
||||
case RibbonData.MONO_DARK:
|
||||
imageKey ??= "ribbon_dark";
|
||||
case RibbonData.MONO_FAIRY:
|
||||
imageKey ??= "ribbon_fairy";
|
||||
default:
|
||||
imageKey ??= "ribbon_typeless";
|
||||
return globalScene.add.image(0, 0, "items", imageKey).setDisplaySize(16, 16);
|
||||
// biome-ignore-end lint/suspicious/noFallthroughSwitchClause: done with fallthrough
|
||||
// Ribbons that don't use the items atlas
|
||||
// biome-ignore-start lint/suspicious/noFallthroughSwitchClause: Another fallthrough block
|
||||
case RibbonData.NUZLOCKE:
|
||||
imageKey = "champion_ribbon_emerald";
|
||||
default:
|
||||
imageKey ??= "champion_ribbon";
|
||||
{
|
||||
const img = globalScene.add.image(0, 0, imageKey);
|
||||
const target = 12;
|
||||
const scale = Math.min(target / img.width, target / img.height);
|
||||
return img.setScale(scale);
|
||||
}
|
||||
// biome-ignore-end lint/suspicious/noFallthroughSwitchClause: End fallthrough block
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { SHINY_CATCH_RATE_MULTIPLIER } from "#balance/rates";
|
||||
import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER } from "#balance/starters";
|
||||
import type { PokemonSpeciesFilter } from "#data/pokemon-species";
|
||||
import type { WeatherPoolEntry } from "#data/weather";
|
||||
import { Challenges } from "#enums/challenges";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
@ -11,6 +12,7 @@ import { WeatherType } from "#enums/weather-type";
|
||||
import type { ModifierTypeKeys } from "#modifiers/modifier-type";
|
||||
import type { nil } from "#types/common";
|
||||
import { addTextObject } from "#ui/text";
|
||||
import { getPokemonSpecies } from "#utils/pokemon-utils";
|
||||
import i18next from "i18next";
|
||||
|
||||
export enum EventType {
|
||||
@ -27,7 +29,7 @@ interface EventBanner {
|
||||
readonly availableLangs?: readonly string[];
|
||||
}
|
||||
|
||||
interface EventEncounter {
|
||||
export interface EventEncounter {
|
||||
readonly species: SpeciesId;
|
||||
readonly blockEvolution?: boolean;
|
||||
readonly formIndex?: number;
|
||||
@ -75,6 +77,7 @@ interface TimedEvent extends EventBanner {
|
||||
readonly trainerShinyChance?: number; // Odds over 65536 of trainer mon generating as shiny
|
||||
readonly music?: readonly EventMusicReplacement[];
|
||||
readonly dailyRunChallenges?: readonly EventChallenge[];
|
||||
readonly dailyRunStartingItems?: readonly ModifierTypeKeys[];
|
||||
}
|
||||
|
||||
const timedEvents: readonly TimedEvent[] = [
|
||||
@ -387,6 +390,50 @@ const timedEvents: readonly TimedEvent[] = [
|
||||
{ wave: 8, type: "CATCHING_CHARM" },
|
||||
{ wave: 25, type: "SHINY_CHARM" },
|
||||
],
|
||||
dailyRunStartingItems: ["SHINY_CHARM", "ABILITY_CHARM"],
|
||||
},
|
||||
{
|
||||
name: "Halloween 25",
|
||||
eventType: EventType.SHINY,
|
||||
startDate: new Date(Date.UTC(2025, 9, 30)),
|
||||
endDate: new Date(Date.UTC(2025, 10, 10)),
|
||||
bannerKey: "halloween2025",
|
||||
scale: 0.19,
|
||||
availableLangs: ["en", "de", "it", "fr", "ja", "ko", "es-ES", "es-419", "pt-BR", "zh-Hans", "zh-Hant", "da", "ru"],
|
||||
shinyEncounterMultiplier: 2,
|
||||
shinyCatchMultiplier: 3,
|
||||
eventEncounters: [
|
||||
{ species: SpeciesId.CATERPIE },
|
||||
{ species: SpeciesId.SPEAROW },
|
||||
{ species: SpeciesId.PARAS },
|
||||
{ species: SpeciesId.LICKITUNG },
|
||||
{ species: SpeciesId.AERODACTYL },
|
||||
{ species: SpeciesId.SMOOCHUM },
|
||||
{ species: SpeciesId.RALTS },
|
||||
{ species: SpeciesId.GULPIN },
|
||||
{ species: SpeciesId.FEEBAS },
|
||||
{ species: SpeciesId.WYNAUT },
|
||||
{ species: SpeciesId.CLAMPERL },
|
||||
{ species: SpeciesId.BUDEW },
|
||||
{ species: SpeciesId.DEOXYS },
|
||||
{ species: SpeciesId.CHINGLING },
|
||||
{ species: SpeciesId.DWEBBLE },
|
||||
{ species: SpeciesId.TIRTOUGA },
|
||||
{ species: SpeciesId.LARVESTA },
|
||||
{ species: SpeciesId.SPRITZEE },
|
||||
{ species: SpeciesId.SWIRLIX },
|
||||
{ species: SpeciesId.BINACLE },
|
||||
{ species: SpeciesId.PUMPKABOO },
|
||||
{ species: SpeciesId.SANDYGAST },
|
||||
],
|
||||
classicWaveRewards: [
|
||||
{ wave: 8, type: "SHINY_CHARM" },
|
||||
{ wave: 8, type: "ABILITY_CHARM" },
|
||||
{ wave: 8, type: "CATCHING_CHARM" },
|
||||
{ wave: 25, type: "SHINY_CHARM" },
|
||||
{ wave: 25, type: "CANDY_JAR" },
|
||||
],
|
||||
dailyRunStartingItems: ["ABILITY_CHARM", "SHINY_CHARM", "CANDY_JAR"],
|
||||
},
|
||||
];
|
||||
|
||||
@ -448,6 +495,23 @@ export class TimedEventManager {
|
||||
return [...(this.activeEvent()?.eventEncounters ?? [])];
|
||||
}
|
||||
|
||||
getAllValidEventEncounters(
|
||||
allowSubLegendary = true,
|
||||
allowLegendary = true,
|
||||
allowMythical = true,
|
||||
speciesFilter: PokemonSpeciesFilter,
|
||||
): EventEncounter[] {
|
||||
return this.getEventEncounters().filter(enc => {
|
||||
const species = getPokemonSpecies(enc.species);
|
||||
return (
|
||||
(allowSubLegendary || !species.subLegendary)
|
||||
&& (allowLegendary || !species.legendary)
|
||||
&& (allowMythical || !species.mythical)
|
||||
&& speciesFilter(species)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* For events that change the classic candy friendship multiplier
|
||||
* @returns The classic friendship multiplier of the active {@linkcode TimedEvent}, or the default {@linkcode CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER}
|
||||
@ -566,6 +630,10 @@ export class TimedEventManager {
|
||||
globalScene.gameMode.setChallengeValue(eventChal.challenge, eventChal.value);
|
||||
}
|
||||
}
|
||||
|
||||
getEventDailyStartingItems(): readonly ModifierTypeKeys[] {
|
||||
return this.activeEvent()?.dailyRunStartingItems ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import type { PokemonSpecies } from "#data/pokemon-species";
|
||||
import { Button } from "#enums/buttons";
|
||||
import type { RibbonData, RibbonFlag } from "#system/ribbons/ribbon-data";
|
||||
import { RibbonData, type RibbonFlag } from "#system/ribbons/ribbon-data";
|
||||
import { ribbonFlagToAssetKey } from "#system/ribbons/ribbon-methods";
|
||||
import type { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
import { addWindow } from "#ui/ui-theme";
|
||||
import { getAvailableRibbons, getRibbonKey } from "#utils/ribbon-utils";
|
||||
import { getAvailableRibbons, getRibbonKey, orderedRibbons } from "#utils/ribbon-utils";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class RibbonTray extends Phaser.GameObjects.Container {
|
||||
@ -111,8 +111,22 @@ export class RibbonTray extends Phaser.GameObjects.Container {
|
||||
|
||||
this.trayIcons = [];
|
||||
let index = 0;
|
||||
for (const ribbon of getAvailableRibbons(species)) {
|
||||
const hasRibbon = this.ribbonData.has(ribbon);
|
||||
|
||||
const availableRibbons = getAvailableRibbons(species);
|
||||
const availableOrderedRibbons = orderedRibbons.filter(r => availableRibbons.includes(r));
|
||||
|
||||
// Classic win count (always 0 for evolutions)
|
||||
const classicWinCount = globalScene.gameData.starterData[species.speciesId]?.classicWinCount ?? 0;
|
||||
|
||||
for (const ribbon of availableOrderedRibbons) {
|
||||
// TODO: eventually, write a save migrator to fix the ribbon save data and get rid of these two conditions
|
||||
// Display classic ribbons for starters with at least one classic win
|
||||
const overrideClassicRibbon = ribbon === RibbonData.CLASSIC && classicWinCount > 0;
|
||||
// Display no heal and no shop ribbons for mons that have the no support ribbon
|
||||
const overrideNoSupportRibbons =
|
||||
(ribbon === RibbonData.NO_HEAL || ribbon === RibbonData.NO_SHOP) && this.ribbonData.has(RibbonData.NO_SUPPORT);
|
||||
const hasRibbon = this.ribbonData.has(ribbon) || overrideClassicRibbon || overrideNoSupportRibbons;
|
||||
|
||||
if (!hasRibbon && !globalScene.dexForDevs && !globalScene.showMissingRibbons) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ export class EggGachaUiHandler extends MessageUiHandler {
|
||||
let pokemonIconX = -20;
|
||||
let pokemonIconY = 6;
|
||||
|
||||
if (["de", "es-ES", "es-419", "fr", "ko", "pt-BR", "ja", "ru"].includes(currentLanguage)) {
|
||||
if (["de", "es-ES", "es-419", "fr", "ko", "pt-BR", "ja", "ru", "tr"].includes(currentLanguage)) {
|
||||
gachaTextStyle = TextStyle.SMALLER_WINDOW_ALT;
|
||||
gachaX = 2;
|
||||
gachaY = 2;
|
||||
@ -89,7 +89,7 @@ export class EggGachaUiHandler extends MessageUiHandler {
|
||||
|
||||
let legendaryLabelX = gachaX;
|
||||
let legendaryLabelY = gachaY;
|
||||
if (["de", "es-ES", "es-419"].includes(currentLanguage)) {
|
||||
if (["de", "es-ES", "es-419", "tr"].includes(currentLanguage)) {
|
||||
pokemonIconX = -25;
|
||||
pokemonIconY = 10;
|
||||
legendaryLabelX = -6;
|
||||
@ -108,8 +108,7 @@ export class EggGachaUiHandler extends MessageUiHandler {
|
||||
let xOffset = 0;
|
||||
const pokemonIcon = globalScene.add.sprite(pokemonIconX, pokemonIconY, "pokemon_icons_0");
|
||||
|
||||
// Intentionally left as "array includes" instead of an equality check to allow for future languages to reuse
|
||||
if (["pt-BR"].includes(currentLanguage)) {
|
||||
if (["pt-BR", "tr"].includes(currentLanguage)) {
|
||||
xOffset = 2;
|
||||
pokemonIcon.setX(pokemonIconX - 2);
|
||||
}
|
||||
@ -120,14 +119,14 @@ export class EggGachaUiHandler extends MessageUiHandler {
|
||||
}
|
||||
break;
|
||||
case GachaType.MOVE:
|
||||
if (["de", "es-ES", "fr", "pt-BR", "ru"].includes(currentLanguage)) {
|
||||
if (["de", "es-ES", "fr", "pt-BR", "ru", "tr"].includes(currentLanguage)) {
|
||||
gachaUpLabel.setAlign("center").setY(0);
|
||||
}
|
||||
|
||||
gachaUpLabel.setText(i18next.t("egg:moveUpGacha")).setX(0).setOrigin(0.5, 0);
|
||||
break;
|
||||
case GachaType.SHINY:
|
||||
if (["de", "fr", "ko", "ru"].includes(currentLanguage)) {
|
||||
if (["de", "fr", "ko", "ru", "tr"].includes(currentLanguage)) {
|
||||
gachaUpLabel.setAlign("center").setY(0);
|
||||
}
|
||||
|
||||
|
||||
@ -251,7 +251,7 @@ export class GameStatsUiHandler extends UiHandler {
|
||||
const resolvedLang = i18next.resolvedLanguage ?? "en";
|
||||
// NOTE TO TRANSLATION TEAM: Add more languages that want to display
|
||||
// in a single-column inside of the `[]` (e.g. `["ru", "fr"]`)
|
||||
return ["fr", "es-ES", "es-419", "it", "ja", "pt-BR", "ru"].includes(resolvedLang);
|
||||
return ["fr", "es-ES", "es-419", "it", "ja", "pt-BR", "ru", "tr"].includes(resolvedLang);
|
||||
}
|
||||
/** The number of columns used by this menu in the resolved language */
|
||||
private get columnCount(): 1 | 2 {
|
||||
|
||||
@ -1586,9 +1586,8 @@ export class PartyUiHandler extends MessageUiHandler {
|
||||
this.updateOptionsWithModifierTransferMode(pokemon);
|
||||
break;
|
||||
case PartyUiMode.SWITCH:
|
||||
this.options.push(PartyOption.RELEASE);
|
||||
break;
|
||||
case PartyUiMode.RELEASE:
|
||||
case PartyUiMode.CHECK:
|
||||
this.options.push(PartyOption.RELEASE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -776,7 +776,8 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|| (this.tmMoves.length === 0 && o === MenuOptions.TM_MOVES)
|
||||
|| (!globalScene.gameData.dexData[this.species.speciesId].ribbons.getRibbons()
|
||||
&& o === MenuOptions.RIBBONS
|
||||
&& !globalScene.showMissingRibbons);
|
||||
&& !globalScene.showMissingRibbons
|
||||
&& !globalScene.gameData.starterData[this.species.speciesId]?.classicWinCount);
|
||||
const color = getTextColor(isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, false);
|
||||
const shadow = getTextColor(isDark ? TextStyle.SHADOW_TEXT : TextStyle.SETTINGS_VALUE, true);
|
||||
return `[shadow=${shadow}][color=${color}]${label}[/color][/shadow]`;
|
||||
@ -1778,6 +1779,7 @@ export class PokedexPageUiHandler extends MessageUiHandler {
|
||||
} else if (
|
||||
!globalScene.gameData.dexData[this.species.speciesId].ribbons.getRibbons()
|
||||
&& !globalScene.showMissingRibbons
|
||||
&& !globalScene.gameData.starterData[this.species.speciesId]?.classicWinCount
|
||||
) {
|
||||
ui.showText(i18next.t("pokedexUiHandler:noRibbons"));
|
||||
error = true;
|
||||
|
||||
@ -155,6 +155,7 @@ const languageSettings: { [key: string]: LanguageSetting } = {
|
||||
tr: {
|
||||
starterInfoTextSize: "56px",
|
||||
instructionTextSize: "38px",
|
||||
starterInfoXPos: 34,
|
||||
},
|
||||
ro: {
|
||||
starterInfoTextSize: "56px",
|
||||
|
||||
@ -47,6 +47,10 @@ export class TitleUiHandler extends OptionSelectUiHandler {
|
||||
return i18next.t("menu:loggedInAs", { username: displayName });
|
||||
}
|
||||
|
||||
updateUsername() {
|
||||
this.usernameLabel.setText(this.getUsername());
|
||||
}
|
||||
|
||||
constructor(mode: UiMode = UiMode.TITLE) {
|
||||
super(mode);
|
||||
}
|
||||
@ -167,6 +171,8 @@ export class TitleUiHandler extends OptionSelectUiHandler {
|
||||
const scaledHeight = globalScene.scaledCanvas.height;
|
||||
const windowHeight = this.getWindowHeight();
|
||||
|
||||
this.updateUsername();
|
||||
|
||||
// Moving username and player count to top of the menu
|
||||
// and sorting it, to display the shorter one on top
|
||||
const UPPER_LABEL = scaledHeight - 23 - windowHeight;
|
||||
|
||||
@ -10,6 +10,7 @@ import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
import { NavigationManager, NavigationMenu } from "#ui/navigation-menu";
|
||||
import { ScrollBar } from "#ui/scroll-bar";
|
||||
import { addTextObject, getTextColor } from "#ui/text";
|
||||
import type { TitleUiHandler } from "#ui/title-ui-handler";
|
||||
import { addWindow } from "#ui/ui-theme";
|
||||
import i18next from "i18next";
|
||||
|
||||
@ -497,6 +498,7 @@ export class AbstractSettingsUiHandler extends MessageUiHandler {
|
||||
this.setScrollCursor(0);
|
||||
this.eraseCursor();
|
||||
this.getUi().bgmBar.toggleBgmBar(globalScene.showBgmBar);
|
||||
(this.getUi().handlers[UiMode.TITLE] as TitleUiHandler)?.updateUsername();
|
||||
if (this.reloadRequired) {
|
||||
this.reloadRequired = false;
|
||||
globalScene.reset(true, false, true);
|
||||
|
||||
@ -473,7 +473,7 @@ export function getLocalizedSpriteKey(baseKey: string) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a number is **inclusively** between two numbers
|
||||
* Check if a number is **inclusively** between two numbers.
|
||||
* @param num - the number to check
|
||||
* @param min - the minimum value (inclusive)
|
||||
* @param max - the maximum value (inclusive)
|
||||
|
||||
@ -118,11 +118,9 @@ export function getFusedSpeciesName(speciesAName: string, speciesBName: string):
|
||||
}
|
||||
|
||||
export function getPokemonSpeciesForm(species: SpeciesId, formIndex: number): PokemonSpeciesForm {
|
||||
const retSpecies: PokemonSpecies =
|
||||
species >= 2000
|
||||
? allSpecies.find(s => s.speciesId === species)! // TODO: is the bang correct?
|
||||
: allSpecies[species - 1];
|
||||
if (formIndex < retSpecies.forms?.length) {
|
||||
const retSpecies: PokemonSpecies = getPokemonSpecies(species);
|
||||
|
||||
if (formIndex < retSpecies.forms.length) {
|
||||
return retSpecies.forms[formIndex];
|
||||
}
|
||||
return retSpecies;
|
||||
|
||||
@ -65,7 +65,7 @@ export function getAvailableRibbons(species: PokemonSpecies): RibbonFlag[] {
|
||||
data |= getRibbonForType(checkingSpecies.type2);
|
||||
}
|
||||
|
||||
for (const form of species.forms) {
|
||||
for (const form of checkingSpecies.forms) {
|
||||
data |= getRibbonForType(form.type1);
|
||||
if (form.type2 != null) {
|
||||
data |= getRibbonForType(form.type2);
|
||||
@ -170,3 +170,47 @@ export function getRibbonKey(flag: RibbonFlag): string {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This list is used to determined the display order of ribbons in the Pokédex.
|
||||
*/
|
||||
export const orderedRibbons: RibbonFlag[] = [
|
||||
RibbonData.CLASSIC,
|
||||
RibbonData.FRIENDSHIP,
|
||||
RibbonData.FRESH_START,
|
||||
RibbonData.HARDCORE,
|
||||
RibbonData.LIMITED_CATCH,
|
||||
RibbonData.NUZLOCKE,
|
||||
RibbonData.NO_HEAL,
|
||||
RibbonData.NO_SHOP,
|
||||
RibbonData.NO_SUPPORT,
|
||||
RibbonData.MONO_GEN_1,
|
||||
RibbonData.MONO_GEN_2,
|
||||
RibbonData.MONO_GEN_3,
|
||||
RibbonData.MONO_GEN_4,
|
||||
RibbonData.MONO_GEN_5,
|
||||
RibbonData.MONO_GEN_6,
|
||||
RibbonData.MONO_GEN_7,
|
||||
RibbonData.MONO_GEN_8,
|
||||
RibbonData.MONO_GEN_9,
|
||||
RibbonData.MONO_NORMAL,
|
||||
RibbonData.MONO_FIGHTING,
|
||||
RibbonData.MONO_FLYING,
|
||||
RibbonData.MONO_POISON,
|
||||
RibbonData.MONO_GROUND,
|
||||
RibbonData.MONO_ROCK,
|
||||
RibbonData.MONO_BUG,
|
||||
RibbonData.MONO_GHOST,
|
||||
RibbonData.MONO_STEEL,
|
||||
RibbonData.MONO_FIRE,
|
||||
RibbonData.MONO_WATER,
|
||||
RibbonData.MONO_GRASS,
|
||||
RibbonData.MONO_ELECTRIC,
|
||||
RibbonData.MONO_PSYCHIC,
|
||||
RibbonData.MONO_ICE,
|
||||
RibbonData.MONO_DRAGON,
|
||||
RibbonData.MONO_DARK,
|
||||
RibbonData.MONO_FAIRY,
|
||||
RibbonData.INVERSE,
|
||||
RibbonData.FLIP_STATS,
|
||||
];
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Pokemon } from "#app/field/pokemon";
|
||||
import type { Pokemon } from "#app/field/pokemon";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { BooleanHolder, randSeedShuffle } from "#app/utils/common";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
@ -12,15 +12,13 @@ interface hasPokemon {
|
||||
/**
|
||||
* Sorts an array of {@linkcode Pokemon} by speed, taking Trick Room into account.
|
||||
* @param pokemonList - The list of Pokemon or objects containing Pokemon
|
||||
* @param shuffleFirst - Whether to shuffle the list before sorting (to handle speed ties). Default `true`.
|
||||
* @returns The sorted array of {@linkcode Pokemon}
|
||||
*/
|
||||
export function sortInSpeedOrder<T extends Pokemon | hasPokemon>(pokemonList: T[], shuffleFirst = true): T[] {
|
||||
if (shuffleFirst) {
|
||||
shufflePokemonList(pokemonList);
|
||||
}
|
||||
sortBySpeed(pokemonList);
|
||||
return pokemonList;
|
||||
export function sortInSpeedOrder<T extends Pokemon | hasPokemon>(pokemonList: T[]): T[] {
|
||||
const grouped = groupPokemon(pokemonList);
|
||||
shufflePokemonList(grouped);
|
||||
sortBySpeed(grouped);
|
||||
return grouped.flat();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,7 +26,7 @@ export function sortInSpeedOrder<T extends Pokemon | hasPokemon>(pokemonList: T[
|
||||
* @param pokemonList - The array of Pokemon or objects containing Pokemon
|
||||
* @returns The same array instance that was passed in, shuffled.
|
||||
*/
|
||||
function shufflePokemonList<T extends Pokemon | hasPokemon>(pokemonList: T[]): T[] {
|
||||
function shufflePokemonList<T extends Pokemon | hasPokemon>(pokemonList: T[][]): void {
|
||||
// This is seeded with the current turn to prevent an inconsistency where it
|
||||
// was varying based on how long since you last reloaded
|
||||
globalScene.executeWithSeedOffset(
|
||||
@ -36,14 +34,22 @@ function shufflePokemonList<T extends Pokemon | hasPokemon>(pokemonList: T[]): T
|
||||
globalScene.currentBattle.turn * 1000 + pokemonList.length,
|
||||
globalScene.waveSeed,
|
||||
);
|
||||
return pokemonList;
|
||||
}
|
||||
|
||||
/** Type guard for {@linkcode sortBySpeed} to avoid importing {@linkcode Pokemon} */
|
||||
function isPokemon(p: Pokemon | hasPokemon): p is Pokemon {
|
||||
return typeof (p as hasPokemon).getPokemon !== "function";
|
||||
}
|
||||
|
||||
function getPokemon(p: Pokemon | hasPokemon): Pokemon {
|
||||
return isPokemon(p) ? p : p.getPokemon();
|
||||
}
|
||||
|
||||
/** Sorts an array of {@linkcode Pokemon} by speed (without shuffling) */
|
||||
function sortBySpeed<T extends Pokemon | hasPokemon>(pokemonList: T[]): void {
|
||||
pokemonList.sort((a, b) => {
|
||||
const aSpeed = (a instanceof Pokemon ? a : a.getPokemon()).getEffectiveStat(Stat.SPD);
|
||||
const bSpeed = (b instanceof Pokemon ? b : b.getPokemon()).getEffectiveStat(Stat.SPD);
|
||||
function sortBySpeed<T extends Pokemon | hasPokemon>(groupedPokemonList: T[][]): void {
|
||||
groupedPokemonList.sort((a, b) => {
|
||||
const aSpeed = getPokemon(a[0]).getEffectiveStat(Stat.SPD);
|
||||
const bSpeed = getPokemon(b[0]).getEffectiveStat(Stat.SPD);
|
||||
|
||||
return bSpeed - aSpeed;
|
||||
});
|
||||
@ -52,6 +58,21 @@ function sortBySpeed<T extends Pokemon | hasPokemon>(pokemonList: T[]): void {
|
||||
const speedReversed = new BooleanHolder(false);
|
||||
globalScene.arena.applyTags(ArenaTagType.TRICK_ROOM, speedReversed);
|
||||
if (speedReversed.value) {
|
||||
pokemonList.reverse();
|
||||
groupedPokemonList.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
function groupPokemon<T extends Pokemon | hasPokemon>(pokemonList: T[]): T[][] {
|
||||
const runs: T[][] = [];
|
||||
for (const pkmn of pokemonList) {
|
||||
const pokemon = getPokemon(pkmn);
|
||||
const lastGroup = runs.at(-1);
|
||||
if (lastGroup != null && lastGroup.length > 0 && getPokemon(lastGroup[0]) === pokemon) {
|
||||
lastGroup.push(pkmn);
|
||||
} else {
|
||||
runs.push([pkmn]);
|
||||
}
|
||||
}
|
||||
|
||||
return runs;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
|
||||
const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
|
||||
/** Regexp involved with stripping non-word delimiters from the result. */
|
||||
const DELIM_STRIP_REGEXP = /[-_ ]+/giu;
|
||||
// The replacement value for splits.
|
||||
/** The replacement value for splits. */
|
||||
const SPLIT_REPLACE_VALUE = "$1\0$2";
|
||||
|
||||
/**
|
||||
@ -57,8 +57,6 @@ function trimFromStartAndEnd(str: string, charToTrim: string): string {
|
||||
return str.slice(start, end);
|
||||
}
|
||||
|
||||
// #endregion Split String code
|
||||
|
||||
/**
|
||||
* Capitalize the first letter of a string.
|
||||
* @param str - The string whose first letter is to be capitalized
|
||||
@ -179,3 +177,26 @@ export function toPascalSnakeCase(str: string) {
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join("_");
|
||||
}
|
||||
// #endregion Split String code
|
||||
|
||||
/**
|
||||
* Chunk a string into an array, creating a new element every `length` characters.
|
||||
* @param str - The string to chunk
|
||||
* @param length - The length of each chunk; should be a non-negative integer
|
||||
* @returns The result of splitting `str` after every instance of `length` characters.
|
||||
* @example
|
||||
* ```ts
|
||||
* console.log(chunkString("123456789abc", 4)); // Output: ["1234", "5678", "9abc"]
|
||||
* console.log(chunkString("1234567890", 4)); // Output: ["1234", "5678", "90"]
|
||||
* ```
|
||||
*/
|
||||
export function chunkString(str: string, length: number): string[] {
|
||||
const numChunks = Math.ceil(str.length / length);
|
||||
const chunks = new Array(numChunks);
|
||||
|
||||
for (let i = 0; i < numChunks; i++) {
|
||||
chunks[i] = str.substring(i * length, (i + 1) * length);
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import { GameManager } from "#test/test-utils/game-manager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Abilities - Illusion", () => {
|
||||
describe.todo("Abilities - Illusion", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ describe("Arena - Psychic Terrain", () => {
|
||||
await game.phaseInterceptor.to("MovePhase", false);
|
||||
|
||||
const feebas = game.field.getPlayerPokemon();
|
||||
expect(allMoves[MoveId.POUND].getPriority(feebas)).toBe(0.2);
|
||||
expect(allMoves[MoveId.POUND].getPriority(feebas)).toBe(0);
|
||||
|
||||
await game.toEndOfTurn();
|
||||
|
||||
@ -93,7 +93,7 @@ describe("Arena - Psychic Terrain", () => {
|
||||
await game.phaseInterceptor.to("MovePhase", false);
|
||||
|
||||
const feebas = game.field.getPlayerPokemon();
|
||||
expect(allMoves[MoveId.QUICK_ATTACK].getPriority(feebas)).toBe(1.2);
|
||||
expect(allMoves[MoveId.QUICK_ATTACK].getPriority(feebas)).toBe(1);
|
||||
|
||||
await game.toEndOfTurn();
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import { SpeciesId } from "#enums/species-id";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
import { MapModifier } from "#modifiers/modifier";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import { stringifyEnumArray } from "#test/test-utils/string-utils";
|
||||
import { ModifierSelectUiHandler } from "#ui/modifier-select-ui-handler";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
@ -20,7 +21,8 @@ describe("Daily Mode", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed");
|
||||
|
||||
game.override.disableShinies = false;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@ -28,6 +30,7 @@ describe("Daily Mode", () => {
|
||||
});
|
||||
|
||||
it("should initialize properly", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("test-seed");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const party = game.scene.getPlayerParty();
|
||||
@ -36,7 +39,90 @@ describe("Daily Mode", () => {
|
||||
expect(pkm.level).toBe(20);
|
||||
expect(pkm.moveset.length).toBeGreaterThan(0);
|
||||
});
|
||||
expect(game.scene.getModifiers(MapModifier).length).toBeGreaterThan(0);
|
||||
expect(game.scene.getModifiers(MapModifier).length).toBe(1);
|
||||
});
|
||||
|
||||
describe("Custom Seeds", () => {
|
||||
describe("Moves", () => {
|
||||
it("should support custom moves", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004,03320006,01300919");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId));
|
||||
expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([
|
||||
MoveId.POUND,
|
||||
MoveId.KARATE_CHOP,
|
||||
MoveId.DOUBLE_SLAP,
|
||||
MoveId.COMET_PUNCH,
|
||||
]);
|
||||
expect(moves2, stringifyEnumArray(MoveId, moves2)).toEqual([
|
||||
MoveId.AERIAL_ACE,
|
||||
MoveId.PAY_DAY,
|
||||
expect.anything(), // make sure it doesn't replace normal moveset gen
|
||||
expect.anything(),
|
||||
]);
|
||||
expect(moves3, stringifyEnumArray(MoveId, moves3)).toEqual([
|
||||
MoveId.SKULL_BASH,
|
||||
MoveId.MALIGNANT_CHAIN,
|
||||
expect.anything(),
|
||||
expect.anything(),
|
||||
]);
|
||||
});
|
||||
|
||||
it("should allow omitting movesets for some starters", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves0001000200030004");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const [moves1, moves2, moves3] = game.scene.getPlayerParty().map(p => p.moveset.map(pm => pm.moveId));
|
||||
expect(moves1, stringifyEnumArray(MoveId, moves1)).toEqual([
|
||||
MoveId.POUND,
|
||||
MoveId.KARATE_CHOP,
|
||||
MoveId.DOUBLE_SLAP,
|
||||
MoveId.COMET_PUNCH,
|
||||
]);
|
||||
expect(moves2, "was not a random moveset").toHaveLength(4);
|
||||
expect(moves3, "was not a random moveset").toHaveLength(4);
|
||||
});
|
||||
|
||||
it("should skip invalid move IDs", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/moves9999,,0919");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const moves = game.field.getPlayerPokemon().moveset.map(pm => pm.moveId);
|
||||
expect(moves, "invalid move was in moveset").not.toContain(MoveId[9999]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Starters", () => {
|
||||
it("should support custom species IDs", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("foo/starterss0001s0113s1024");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const party = game.scene.getPlayerParty().map(p => p.species.speciesId);
|
||||
expect(party, stringifyEnumArray(SpeciesId, party)).toEqual([
|
||||
SpeciesId.BULBASAUR,
|
||||
SpeciesId.CHANSEY,
|
||||
SpeciesId.TERAPAGOS,
|
||||
]);
|
||||
});
|
||||
|
||||
it("should support custom forms and variants", async () => {
|
||||
vi.spyOn(pokerogueApi.daily, "getSeed").mockResolvedValue("/starterss0006f01v2s0113v0s1024f02");
|
||||
await game.dailyMode.startBattle();
|
||||
|
||||
const party = game.scene.getPlayerParty().map(p => ({
|
||||
speciesId: p.species.speciesId,
|
||||
variant: p.getVariant(),
|
||||
form: p.formIndex,
|
||||
shiny: p.isShiny(),
|
||||
}));
|
||||
expect(party).toEqual<typeof party>([
|
||||
{ speciesId: SpeciesId.CHARIZARD, variant: 2, form: 1, shiny: true },
|
||||
{ speciesId: SpeciesId.CHANSEY, variant: 0, form: 0, shiny: true },
|
||||
{ speciesId: SpeciesId.TERAPAGOS, variant: expect.anything(), form: 2, shiny: false },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -151,7 +151,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
||||
expect(onInitResult).toBe(true);
|
||||
});
|
||||
|
||||
describe("Option 1 - Dig for Valuables", () => {
|
||||
describe("Option 1 - Battle Garbodor", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option1 = TrashToTreasureEncounter.options[0];
|
||||
expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||
@ -167,56 +167,11 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should give 1 Leftovers, 1 Shell Bell, and Black Sludge", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1);
|
||||
expect(game).toBeAtPhase("SelectModifierPhase");
|
||||
await game.phaseInterceptor.to("SelectModifierPhase");
|
||||
|
||||
const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
expect(leftovers).toBeDefined();
|
||||
expect(leftovers?.stackCount).toBe(1);
|
||||
|
||||
const shellBell = scene.findModifier(m => m instanceof HitHealModifier) as HitHealModifier;
|
||||
expect(shellBell).toBeDefined();
|
||||
expect(shellBell?.stackCount).toBe(1);
|
||||
|
||||
const blackSludge = scene.findModifier(m => m instanceof HealShopCostModifier) as HealShopCostModifier;
|
||||
expect(blackSludge).toBeDefined();
|
||||
expect(blackSludge?.stackCount).toBe(1);
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 1);
|
||||
|
||||
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Option 2 - Battle Garbodor", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option1 = TrashToTreasureEncounter.options[1];
|
||||
expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||
expect(option1.dialogue).toBeDefined();
|
||||
expect(option1.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should start battle against Garbodor", async () => {
|
||||
const phaseSpy = vi.spyOn(scene.phaseManager, "pushPhase");
|
||||
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
|
||||
const enemyField = scene.getEnemyField();
|
||||
expect(game).toBeAtPhase("CommandPhase");
|
||||
@ -238,7 +193,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
||||
|
||||
it("should have 2 Rogue, 1 Ultra, 1 Great in rewards", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||
await game.phaseInterceptor.to("SelectModifierPhase", false);
|
||||
expect(game).toBeAtPhase("SelectModifierPhase");
|
||||
@ -267,4 +222,49 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
||||
).toEqual(ModifierTier.GREAT);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Option 2 - Dig for Valuables", () => {
|
||||
it("should have the correct properties", () => {
|
||||
const option1 = TrashToTreasureEncounter.options[1];
|
||||
expect(option1.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||
expect(option1.dialogue).toBeDefined();
|
||||
expect(option1.dialogue).toStrictEqual({
|
||||
buttonLabel: `${namespace}:option.2.label`,
|
||||
buttonTooltip: `${namespace}:option.2.tooltip`,
|
||||
selected: [
|
||||
{
|
||||
text: `${namespace}:option.2.selected`,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("should give 1 Leftovers, 1 Shell Bell, and Black Sludge", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
expect(game).toBeAtPhase("SelectModifierPhase");
|
||||
await game.phaseInterceptor.to("SelectModifierPhase");
|
||||
|
||||
const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||
expect(leftovers).toBeDefined();
|
||||
expect(leftovers?.stackCount).toBe(1);
|
||||
|
||||
const shellBell = scene.findModifier(m => m instanceof HitHealModifier) as HitHealModifier;
|
||||
expect(shellBell).toBeDefined();
|
||||
expect(shellBell?.stackCount).toBe(1);
|
||||
|
||||
const blackSludge = scene.findModifier(m => m instanceof HealShopCostModifier) as HealShopCostModifier;
|
||||
expect(blackSludge).toBeDefined();
|
||||
expect(blackSludge?.stackCount).toBe(1);
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -190,7 +190,7 @@ describe("check if every variant's sprite are correctly set", () => {
|
||||
if (errors.length > 0) {
|
||||
console.log("errors", errors);
|
||||
}
|
||||
expect(errors.length).toBe(0);
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
|
||||
it("check exp back male variant files", () => {
|
||||
@ -270,7 +270,7 @@ describe("check if every variant's sprite are correctly set", () => {
|
||||
if (errors.length > 0) {
|
||||
console.log("errors for ", dirPath, errors);
|
||||
}
|
||||
expect(errors.length).toBe(0);
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
|
||||
it("look over every file in variant exp female and check if present in masterlist", () => {
|
||||
|
||||
@ -66,8 +66,8 @@ function getResultStr(result: RunnerTaskResult | undefined): string {
|
||||
|
||||
const resultStr =
|
||||
result.state === "pass"
|
||||
? chalk.green.bold("✔ Passed")
|
||||
: (result?.duration ?? 0) > 2
|
||||
? chalk.green.bold("✓ Passed")
|
||||
: (result?.duration ?? 0) > 20_000
|
||||
? chalk.cyan.bold("◴ Timed out")
|
||||
: chalk.red.bold("✗ Failed");
|
||||
|
||||
|
||||
58
test/utils/speed-order.test.ts
Normal file
58
test/utils/speed-order.test.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import { sortInSpeedOrder } from "#utils/speed-order";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Utils - Speed Order", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.battleStyle("single")
|
||||
.startingLevel(100)
|
||||
.enemyLevel(100)
|
||||
.enemyMoveset(MoveId.SPLASH)
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.ability(AbilityId.BALL_FETCH)
|
||||
.enemySpecies(SpeciesId.REGIELEKI);
|
||||
});
|
||||
|
||||
it("Sorts correctly in the basic case", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.SLOWPOKE, SpeciesId.MEW]);
|
||||
const [slowpoke, mew] = game.field.getPlayerParty();
|
||||
const regieleki = game.field.getEnemyPokemon();
|
||||
const pkmnList = [slowpoke, regieleki, mew];
|
||||
|
||||
expect(sortInSpeedOrder(pkmnList)).toEqual([regieleki, mew, slowpoke]);
|
||||
});
|
||||
|
||||
it("Correctly sorts grouped pokemon", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.SLOWPOKE, SpeciesId.MEW, SpeciesId.DITTO]);
|
||||
const [slowpoke, mew, ditto] = game.field.getPlayerParty();
|
||||
const regieleki = game.field.getEnemyPokemon();
|
||||
ditto.stats[Stat.SPD] = slowpoke.getStat(Stat.SPD);
|
||||
|
||||
const pkmnList = [slowpoke, slowpoke, ditto, ditto, mew, regieleki, regieleki];
|
||||
const sorted = sortInSpeedOrder(pkmnList);
|
||||
|
||||
expect([
|
||||
[regieleki, regieleki, mew, slowpoke, slowpoke, ditto, ditto],
|
||||
[regieleki, regieleki, mew, ditto, ditto, slowpoke, slowpoke],
|
||||
]).toContainEqual(sorted);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user