Merge branch 'beta' into hebrew-pr
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"version": "1.4.3",
|
"version": "1.5.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"version": "1.4.3",
|
"version": "1.5.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material/material-color-utilities": "^0.2.7",
|
"@material/material-color-utilities": "^0.2.7",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "pokemon-rogue-battle",
|
"name": "pokemon-rogue-battle",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.4.3",
|
"version": "1.5.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
"start": "vite",
|
||||||
|
BIN
public/images/events/yearofthesnakeevent-de.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
public/images/events/yearofthesnakeevent-en.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-es-ES.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-fr.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-it.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-ja.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-ko.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-pt-BR.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/images/events/yearofthesnakeevent-zh-CN.png
Normal file
After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 37 KiB |
@ -1 +1 @@
|
|||||||
Subproject commit e07ab625f2080afe36b61fad291b0ec5eff4000c
|
Subproject commit 5ef993b95fa8248adc0fb7d9489baccf546bf8e3
|
@ -869,6 +869,12 @@ export default class BattleScene extends SceneBase {
|
|||||||
return party.slice(0, Math.min(party.length, this.currentBattle?.double ? 2 : 1));
|
return party.slice(0, Math.min(party.length, this.currentBattle?.double ? 2 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of Pokemon on both sides of the battle - player first, then enemy.
|
||||||
|
* Does not actually check if the pokemon are on the field or not, and always has length 4 regardless of battle type.
|
||||||
|
* @param activeOnly Whether to consider only active pokemon
|
||||||
|
* @returns array of {@linkcode Pokemon}
|
||||||
|
*/
|
||||||
public getField(activeOnly: boolean = false): Pokemon[] {
|
public getField(activeOnly: boolean = false): Pokemon[] {
|
||||||
const ret = new Array(4).fill(null);
|
const ret = new Array(4).fill(null);
|
||||||
const playerField = this.getPlayerField();
|
const playerField = this.getPlayerField();
|
||||||
@ -1843,8 +1849,10 @@ export default class BattleScene extends SceneBase {
|
|||||||
this.currentBattle.battleScore += Math.ceil(scoreIncrease);
|
this.currentBattle.battleScore += Math.ceil(scoreIncrease);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxExpLevel(ignoreLevelCap?: boolean): integer {
|
getMaxExpLevel(ignoreLevelCap: boolean = false): integer {
|
||||||
if (ignoreLevelCap) {
|
if (Overrides.LEVEL_CAP_OVERRIDE > 0) {
|
||||||
|
return Overrides.LEVEL_CAP_OVERRIDE;
|
||||||
|
} else if (ignoreLevelCap || Overrides.LEVEL_CAP_OVERRIDE < 0) {
|
||||||
return Number.MAX_SAFE_INTEGER;
|
return Number.MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
const waveIndex = Math.ceil((this.currentBattle?.waveIndex || 1) / 10) * 10;
|
const waveIndex = Math.ceil((this.currentBattle?.waveIndex || 1) / 10) * 10;
|
||||||
@ -2082,8 +2090,11 @@ export default class BattleScene extends SceneBase {
|
|||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The loop point of any given battle, mystery encounter, or title track, read as seconds and milliseconds. */
|
||||||
getBgmLoopPoint(bgmName: string): number {
|
getBgmLoopPoint(bgmName: string): number {
|
||||||
switch (bgmName) {
|
switch (bgmName) {
|
||||||
|
case "title": //Firel PokéRogue Title
|
||||||
|
return 46.500;
|
||||||
case "battle_kanto_champion": //B2W2 Kanto Champion Battle
|
case "battle_kanto_champion": //B2W2 Kanto Champion Battle
|
||||||
return 13.950;
|
return 13.950;
|
||||||
case "battle_johto_champion": //B2W2 Johto Champion Battle
|
case "battle_johto_champion": //B2W2 Johto Champion Battle
|
||||||
@ -3388,7 +3399,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
const previousEncounter = this.mysteryEncounterSaveData.encounteredEvents.length > 0 ?
|
const previousEncounter = this.mysteryEncounterSaveData.encounteredEvents.length > 0 ?
|
||||||
this.mysteryEncounterSaveData.encounteredEvents[this.mysteryEncounterSaveData.encounteredEvents.length - 1].type
|
this.mysteryEncounterSaveData.encounteredEvents[this.mysteryEncounterSaveData.encounteredEvents.length - 1].type
|
||||||
: null;
|
: null;
|
||||||
const biomeMysteryEncounters = mysteryEncountersByBiome.get(this.arena.biomeType) ?? [];
|
const disabledEncounters = this.eventManager.getEventMysteryEncountersDisabled();
|
||||||
|
const biomeMysteryEncounters = mysteryEncountersByBiome.get(this.arena.biomeType)?.filter(enc => !disabledEncounters.includes(enc)) ?? [];
|
||||||
// If no valid encounters exist at tier, checks next tier down, continuing until there are some encounters available
|
// If no valid encounters exist at tier, checks next tier down, continuing until there are some encounters available
|
||||||
while (availableEncounters.length === 0 && tier !== null) {
|
while (availableEncounters.length === 0 && tier !== null) {
|
||||||
availableEncounters = biomeMysteryEncounters
|
availableEncounters = biomeMysteryEncounters
|
||||||
@ -3397,7 +3409,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
if (!encounterCandidate) {
|
if (!encounterCandidate) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (encounterCandidate.encounterTier !== tier) {
|
if (this.eventManager.getMysteryEncounterTierForEvent(encounterType, encounterCandidate.encounterTier) !== tier) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const disallowedGameModes = encounterCandidate.disallowedGameModes;
|
const disallowedGameModes = encounterCandidate.disallowedGameModes;
|
||||||
|
@ -24,9 +24,26 @@ import { ModifierTier } from "#app/modifier/modifier-tier";
|
|||||||
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import type { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
|
||||||
export enum ClassicFixedBossWaves {
|
export enum ClassicFixedBossWaves {
|
||||||
// TODO: other fixed wave battles should be added here
|
TOWN_YOUNGSTER = 5,
|
||||||
|
RIVAL_1 = 8,
|
||||||
|
RIVAL_2 = 25,
|
||||||
|
EVIL_GRUNT_1 = 35,
|
||||||
|
RIVAL_3 = 55,
|
||||||
|
EVIL_GRUNT_2 = 62,
|
||||||
|
EVIL_GRUNT_3 = 64,
|
||||||
|
EVIL_ADMIN_1 = 66,
|
||||||
|
RIVAL_4 = 95,
|
||||||
|
EVIL_GRUNT_4 = 112,
|
||||||
|
EVIL_ADMIN_2 = 114,
|
||||||
EVIL_BOSS_1 = 115,
|
EVIL_BOSS_1 = 115,
|
||||||
|
RIVAL_5 = 145,
|
||||||
EVIL_BOSS_2 = 165,
|
EVIL_BOSS_2 = 165,
|
||||||
|
ELITE_FOUR_1 = 182,
|
||||||
|
ELITE_FOUR_2 = 184,
|
||||||
|
ELITE_FOUR_3 = 186,
|
||||||
|
ELITE_FOUR_4 = 188,
|
||||||
|
CHAMPION = 190,
|
||||||
|
RIVAL_6 = 195,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BattleType {
|
export enum BattleType {
|
||||||
@ -500,7 +517,7 @@ export class FixedBattleConfig {
|
|||||||
* @param seedOffset the seed offset to use for the random generation of the trainer
|
* @param seedOffset the seed offset to use for the random generation of the trainer
|
||||||
* @returns the generated trainer
|
* @returns the generated trainer
|
||||||
*/
|
*/
|
||||||
function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], randomGender: boolean = false, seedOffset: number = 0): GetTrainerFunc {
|
export function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], randomGender: boolean = false, seedOffset: number = 0): GetTrainerFunc {
|
||||||
return () => {
|
return () => {
|
||||||
const rand = Utils.randSeedInt(trainerPool.length);
|
const rand = Utils.randSeedInt(trainerPool.length);
|
||||||
const trainerTypes: TrainerType[] = [];
|
const trainerTypes: TrainerType[] = [];
|
||||||
@ -544,51 +561,51 @@ export interface FixedBattleConfigs {
|
|||||||
* Champion on 190
|
* Champion on 190
|
||||||
*/
|
*/
|
||||||
export const classicFixedBattles: FixedBattleConfigs = {
|
export const classicFixedBattles: FixedBattleConfigs = {
|
||||||
[5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.TOWN_YOUNGSTER]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.setGetTrainerFunc(() => new Trainer(TrainerType.YOUNGSTER, Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
||||||
[8]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT)),
|
||||||
[25]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_2, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_2, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
||||||
[35]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.EVIL_GRUNT_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[55]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_3, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_3, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false }),
|
||||||
[62]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_GRUNT_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[64]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_GRUNT_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[66]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_ADMIN_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true)),
|
||||||
[95]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_4, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_4, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[112]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_GRUNT_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_GRUNT, TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT, TrainerType.GALACTIC_GRUNT, TrainerType.PLASMA_GRUNT, TrainerType.FLARE_GRUNT, TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT, TrainerType.MACRO_GRUNT, TrainerType.STAR_GRUNT ], true)),
|
||||||
[114]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_ADMIN_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)),
|
.setGetTrainerFunc(getRandomTrainerFunc([[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], TrainerType.FABA, TrainerType.PLUMERIA, TrainerType.OLEANA, [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]], true, 1)),
|
||||||
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_BOSS_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_1, TrainerType.MAXIE, TrainerType.ARCHIE, TrainerType.CYRUS, TrainerType.GHETSIS, TrainerType.LYSANDRE, TrainerType.LUSAMINE, TrainerType.GUZMA, TrainerType.ROSE, TrainerType.PENNY ]))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[145]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_5]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_5, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_5, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(35)
|
[ClassicFixedBossWaves.EVIL_BOSS_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.ROCKET_BOSS_GIOVANNI_2, TrainerType.MAXIE_2, TrainerType.ARCHIE_2, TrainerType.CYRUS_2, TrainerType.GHETSIS_2, TrainerType.LYSANDRE_2, TrainerType.LUSAMINE_2, TrainerType.GUZMA_2, TrainerType.ROSE_2, TrainerType.PENNY_2 ]))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false }),
|
||||||
[182]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.ELITE_FOUR_1]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, [ TrainerType.HALA, TrainerType.MOLAYNE ], TrainerType.MARNIE_ELITE, TrainerType.RIKA, TrainerType.CRISPIN ])),
|
||||||
[184]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
[ClassicFixedBossWaves.ELITE_FOUR_2]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY, TrainerType.AMARYS ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY, TrainerType.AMARYS ])),
|
||||||
[186]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
[ClassicFixedBossWaves.ELITE_FOUR_3]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, [ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ], TrainerType.LARRY_ELITE, TrainerType.LACEY ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, [ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ], TrainerType.LARRY_ELITE, TrainerType.LACEY ])),
|
||||||
[188]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
[ClassicFixedBossWaves.ELITE_FOUR_4]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL, TrainerType.DRAYTON ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL, TrainerType.DRAYTON ])),
|
||||||
[190]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(182)
|
[ClassicFixedBossWaves.CHAMPION]: new FixedBattleConfig().setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.ELITE_FOUR_1)
|
||||||
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
|
.setGetTrainerFunc(getRandomTrainerFunc([ TrainerType.BLUE, [ TrainerType.RED, TrainerType.LANCE_CHAMPION ], [ TrainerType.STEVEN, TrainerType.WALLACE ], TrainerType.CYNTHIA, [ TrainerType.ALDER, TrainerType.IRIS ], TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, [ TrainerType.GEETA, TrainerType.NEMONA ], TrainerType.KIERAN ])),
|
||||||
[195]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
[ClassicFixedBossWaves.RIVAL_6]: new FixedBattleConfig().setBattleType(BattleType.TRAINER)
|
||||||
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_6, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
.setGetTrainerFunc(() => new Trainer(TrainerType.RIVAL_6, globalScene.gameData.gender === PlayerGender.MALE ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT))
|
||||||
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false })
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.GREAT, ModifierTier.GREAT ], allowLuckUpgrades: false })
|
||||||
};
|
};
|
||||||
|
@ -16,7 +16,7 @@ import type { ArenaTrapTag } from "./arena-tag";
|
|||||||
import { ArenaTagSide } from "./arena-tag";
|
import { ArenaTagSide } from "./arena-tag";
|
||||||
import { BerryModifier, HitHealModifier, PokemonHeldItemModifier } from "../modifier/modifier";
|
import { BerryModifier, HitHealModifier, PokemonHeldItemModifier } from "../modifier/modifier";
|
||||||
import { TerrainType } from "./terrain";
|
import { TerrainType } from "./terrain";
|
||||||
import { SpeciesFormChangeManualTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms";
|
import { SpeciesFormChangeAbilityTrigger, SpeciesFormChangeRevertWeatherFormTrigger, SpeciesFormChangeWeatherTrigger } from "./pokemon-forms";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import type { Localizable } from "#app/interfaces/locales";
|
import type { Localizable } from "#app/interfaces/locales";
|
||||||
import { Command } from "../ui/command-ui-handler";
|
import { Command } from "../ui/command-ui-handler";
|
||||||
@ -232,7 +232,7 @@ export class PostBattleInitFormChangeAbAttr extends PostBattleInitAbAttr {
|
|||||||
applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
applyPostBattleInit(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||||
const formIndex = this.formFunc(pokemon);
|
const formIndex = this.formFunc(pokemon);
|
||||||
if (formIndex !== pokemon.formIndex && !simulated) {
|
if (formIndex !== pokemon.formIndex && !simulated) {
|
||||||
return globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
return globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1875,7 +1875,7 @@ export class PostVictoryFormChangeAbAttr extends PostVictoryAbAttr {
|
|||||||
const formIndex = this.formFunc(pokemon);
|
const formIndex = this.formFunc(pokemon);
|
||||||
if (formIndex !== pokemon.formIndex) {
|
if (formIndex !== pokemon.formIndex) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2306,7 +2306,7 @@ export class PostSummonFormChangeAbAttr extends PostSummonAbAttr {
|
|||||||
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
applyPostSummon(pokemon: Pokemon, passive: boolean, simulated: boolean, args: any[]): boolean {
|
||||||
const formIndex = this.formFunc(pokemon);
|
const formIndex = this.formFunc(pokemon);
|
||||||
if (formIndex !== pokemon.formIndex) {
|
if (formIndex !== pokemon.formIndex) {
|
||||||
return simulated || globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
return simulated || globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -2734,7 +2734,7 @@ export class PreSwitchOutFormChangeAbAttr extends PreSwitchOutAbAttr {
|
|||||||
const formIndex = this.formFunc(pokemon);
|
const formIndex = this.formFunc(pokemon);
|
||||||
if (formIndex !== pokemon.formIndex) {
|
if (formIndex !== pokemon.formIndex) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3704,7 +3704,7 @@ export class PostTurnFormChangeAbAttr extends PostTurnAbAttr {
|
|||||||
const formIndex = this.formFunc(pokemon);
|
const formIndex = this.formFunc(pokemon);
|
||||||
if (formIndex !== pokemon.formIndex) {
|
if (formIndex !== pokemon.formIndex) {
|
||||||
if (!simulated) {
|
if (!simulated) {
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -12,6 +12,8 @@ import { Species } from "#enums/species";
|
|||||||
import { TimeOfDay } from "#enums/time-of-day";
|
import { TimeOfDay } from "#enums/time-of-day";
|
||||||
import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, TempExtraModifierModifier } from "#app/modifier/modifier";
|
import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifier, TempExtraModifierModifier } from "#app/modifier/modifier";
|
||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
import { speciesStarterCosts } from "./starters";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
|
||||||
export enum SpeciesWildEvolutionDelay {
|
export enum SpeciesWildEvolutionDelay {
|
||||||
@ -120,17 +122,214 @@ export class FusionSpeciesFormEvolution extends SpeciesFormEvolution {
|
|||||||
|
|
||||||
export class SpeciesEvolutionCondition {
|
export class SpeciesEvolutionCondition {
|
||||||
public predicate: EvolutionConditionPredicate;
|
public predicate: EvolutionConditionPredicate;
|
||||||
public enforceFunc: EvolutionConditionEnforceFunc | undefined;
|
public enforceFunc?: EvolutionConditionEnforceFunc;
|
||||||
|
public description: string;
|
||||||
|
|
||||||
constructor(predicate: EvolutionConditionPredicate, enforceFunc?: EvolutionConditionEnforceFunc) {
|
constructor(predicate: EvolutionConditionPredicate, enforceFunc?: EvolutionConditionEnforceFunc) {
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.enforceFunc = enforceFunc;
|
this.enforceFunc = enforceFunc;
|
||||||
|
this.description = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SpeciesFriendshipEvolutionCondition extends SpeciesEvolutionCondition {
|
class GenderEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
constructor(friendshipAmount: integer, predicate?: EvolutionConditionPredicate, enforceFunc?: EvolutionConditionEnforceFunc) {
|
public gender: Gender;
|
||||||
super(p => p.friendship >= friendshipAmount && (!predicate || predicate(p)), enforceFunc);
|
constructor(gender: Gender) {
|
||||||
|
super(p => p.gender === gender, p => p.gender = gender);
|
||||||
|
this.gender = gender;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:gender", { gender: i18next.t(`pokemonEvolutions:${Gender[gender]}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public timesOfDay: TimeOfDay[];
|
||||||
|
constructor(tod: "day" | "night") {
|
||||||
|
if (tod === "day") {
|
||||||
|
super(() => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY);
|
||||||
|
this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ];
|
||||||
|
} else if (tod === "night") {
|
||||||
|
super(() => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT);
|
||||||
|
this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ];
|
||||||
|
} else {
|
||||||
|
super(() => false);
|
||||||
|
this.timesOfDay = [];
|
||||||
|
}
|
||||||
|
this.description = i18next.t("pokemonEvolutions:timeOfDay", { tod: i18next.t(`pokemonEvolutions:${tod}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public move: Moves;
|
||||||
|
constructor(move: Moves) {
|
||||||
|
super(p => p.moveset.filter(m => m?.moveId === move).length > 0);
|
||||||
|
this.move = move;
|
||||||
|
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
|
||||||
|
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FriendshipEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public amount: integer;
|
||||||
|
constructor(amount: number) {
|
||||||
|
super(p => p.friendship >= amount);
|
||||||
|
this.amount = amount;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:friendship");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FriendshipTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public amount: integer;
|
||||||
|
public timesOfDay: TimeOfDay[];
|
||||||
|
constructor(amount: number, tod: "day" | "night") {
|
||||||
|
if (tod === "day") {
|
||||||
|
super(p => p.friendship >= amount && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY));
|
||||||
|
this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ];
|
||||||
|
} else if (tod === "night") {
|
||||||
|
super(p => p.friendship >= amount && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT));
|
||||||
|
this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ];
|
||||||
|
} else {
|
||||||
|
super(p => false);
|
||||||
|
this.timesOfDay = [];
|
||||||
|
}
|
||||||
|
this.amount = amount;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:friendshipTimeOfDay", { tod: i18next.t(`pokemonEvolutions:${tod}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FriendshipMoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public amount: integer;
|
||||||
|
public type: Type;
|
||||||
|
constructor(amount: number, type: Type) {
|
||||||
|
super(p => p.friendship >= amount && !!p.getMoveset().find(m => m?.getMove().type === type));
|
||||||
|
this.amount = amount;
|
||||||
|
this.type = type;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:friendshipMoveType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShedinjaEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
constructor() {
|
||||||
|
super(() => globalScene.getPlayerParty().length < 6 && globalScene.pokeballCounts[PokeballType.POKEBALL] > 0);
|
||||||
|
this.description = i18next.t("pokemonEvolutions:shedinja");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PartyTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public type: Type;
|
||||||
|
constructor(type: Type) {
|
||||||
|
super(() => !!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(type) > -1));
|
||||||
|
this.type = type;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:partyType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CaughtEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public species: Species;
|
||||||
|
constructor(species: Species) {
|
||||||
|
super(() => !!globalScene.gameData.dexData[species].caughtAttr);
|
||||||
|
this.species = species;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:caught", { species: i18next.t(`pokemon:${Species[this.species].toLowerCase()}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeatherEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public weatherTypes: WeatherType[];
|
||||||
|
constructor(weatherTypes: WeatherType[]) {
|
||||||
|
super(() => weatherTypes.indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1);
|
||||||
|
this.weatherTypes = weatherTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public type: Type;
|
||||||
|
constructor(type: Type) {
|
||||||
|
super(p => p.moveset.filter(m => m?.getMove().type === type).length > 0);
|
||||||
|
this.type = type;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:moveType", { type: i18next.t(`pokemonInfo:Type.${Type[this.type]}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TreasureEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
constructor() {
|
||||||
|
super(p => p.evoCounter
|
||||||
|
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
|
||||||
|
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|
||||||
|
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9);
|
||||||
|
this.description = i18next.t("pokemonEvolutions:treasure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TyrogueEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public move: Moves;
|
||||||
|
constructor(move: Moves) {
|
||||||
|
super(p =>
|
||||||
|
p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m?.moveId))?.moveId === move);
|
||||||
|
this.move = move;
|
||||||
|
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
|
||||||
|
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NatureEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public natures: Nature[];
|
||||||
|
constructor(natures: Nature[]) {
|
||||||
|
super(p => natures.indexOf(p.getNature()) > -1);
|
||||||
|
this.natures = natures;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:nature");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public move: Moves;
|
||||||
|
public timesOfDay: TimeOfDay[];
|
||||||
|
constructor(move: Moves, tod: "day" | "night") {
|
||||||
|
if (tod === "day") {
|
||||||
|
super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY));
|
||||||
|
this.move = move;
|
||||||
|
this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ];
|
||||||
|
} else if (tod === "night") {
|
||||||
|
super(p => p.moveset.filter(m => m?.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT));
|
||||||
|
this.move = move;
|
||||||
|
this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ];
|
||||||
|
} else {
|
||||||
|
super(() => false);
|
||||||
|
this.timesOfDay = [];
|
||||||
|
}
|
||||||
|
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
|
||||||
|
this.description = i18next.t("pokemonEvolutions:moveTimeOfDay", { move: i18next.t(`move:${moveKey}.name`), tod: i18next.t(`pokemonEvolutions:${tod}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BiomeEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
public biomes: Biome[];
|
||||||
|
constructor(biomes: Biome[]) {
|
||||||
|
super(() => biomes.filter(b => b === globalScene.arena.biomeType).length > 0);
|
||||||
|
this.biomes = biomes;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:biome");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
constructor() {
|
||||||
|
super(p => {
|
||||||
|
let ret = false;
|
||||||
|
if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) {
|
||||||
|
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
const moveKey = Moves[Moves.HYPER_DRILL].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
|
||||||
|
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TandemausEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
|
constructor() {
|
||||||
|
super(p => {
|
||||||
|
let ret = false;
|
||||||
|
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,8 +466,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ELECTRODE, 30, null, null)
|
new SpeciesEvolution(Species.ELECTRODE, 30, null, null)
|
||||||
],
|
],
|
||||||
[Species.CUBONE]: [
|
[Species.CUBONE]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.ALOLA_MAROWAK, 28, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.MAROWAK, 28, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.MAROWAK, 28, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.TYROGUE]: [
|
[Species.TYROGUE]: [
|
||||||
/**
|
/**
|
||||||
@ -277,19 +476,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
* If Tyrogue knows multiple of these moves, its evolution is based on
|
* If Tyrogue knows multiple of these moves, its evolution is based on
|
||||||
* the first qualifying move in its moveset.
|
* the first qualifying move in its moveset.
|
||||||
*/
|
*/
|
||||||
new SpeciesEvolution(Species.HITMONLEE, 20, null, new SpeciesEvolutionCondition(p =>
|
new SpeciesEvolution(Species.HITMONLEE, 20, null, new TyrogueEvolutionCondition(Moves.LOW_SWEEP)),
|
||||||
p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.LOW_SWEEP
|
new SpeciesEvolution(Species.HITMONCHAN, 20, null, new TyrogueEvolutionCondition(Moves.MACH_PUNCH)),
|
||||||
)),
|
new SpeciesEvolution(Species.HITMONTOP, 20, null, new TyrogueEvolutionCondition(Moves.RAPID_SPIN)),
|
||||||
new SpeciesEvolution(Species.HITMONCHAN, 20, null, new SpeciesEvolutionCondition(p =>
|
|
||||||
p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.MACH_PUNCH
|
|
||||||
)),
|
|
||||||
new SpeciesEvolution(Species.HITMONTOP, 20, null, new SpeciesEvolutionCondition(p =>
|
|
||||||
p.getMoveset(true).find(move => move && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(move?.moveId))?.moveId === Moves.RAPID_SPIN
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
[Species.KOFFING]: [
|
[Species.KOFFING]: [
|
||||||
new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.GALAR_WEEZING, 35, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.WEEZING, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.WEEZING, 35, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.RHYHORN]: [
|
[Species.RHYHORN]: [
|
||||||
new SpeciesEvolution(Species.RHYDON, 42, null, null)
|
new SpeciesEvolution(Species.RHYDON, 42, null, null)
|
||||||
@ -334,8 +527,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.QUILAVA, 14, null, null)
|
new SpeciesEvolution(Species.QUILAVA, 14, null, null)
|
||||||
],
|
],
|
||||||
[Species.QUILAVA]: [
|
[Species.QUILAVA]: [
|
||||||
new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_TYPHLOSION, 36, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.TYPHLOSION, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.TYPHLOSION, 36, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.TOTODILE]: [
|
[Species.TOTODILE]: [
|
||||||
new SpeciesEvolution(Species.CROCONAW, 18, null, null)
|
new SpeciesEvolution(Species.CROCONAW, 18, null, null)
|
||||||
@ -437,8 +630,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.LINOONE, 20, null, null)
|
new SpeciesEvolution(Species.LINOONE, 20, null, null)
|
||||||
],
|
],
|
||||||
[Species.WURMPLE]: [
|
[Species.WURMPLE]: [
|
||||||
new SpeciesEvolution(Species.SILCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)),
|
new SpeciesEvolution(Species.SILCOON, 7, null, new TimeOfDayEvolutionCondition("day")),
|
||||||
new SpeciesEvolution(Species.CASCOON, 7, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
|
new SpeciesEvolution(Species.CASCOON, 7, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.SILCOON]: [
|
[Species.SILCOON]: [
|
||||||
new SpeciesEvolution(Species.BEAUTIFLY, 10, null, null)
|
new SpeciesEvolution(Species.BEAUTIFLY, 10, null, null)
|
||||||
@ -462,8 +655,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.KIRLIA, 20, null, null)
|
new SpeciesEvolution(Species.KIRLIA, 20, null, null)
|
||||||
],
|
],
|
||||||
[Species.KIRLIA]: [
|
[Species.KIRLIA]: [
|
||||||
new SpeciesEvolution(Species.GARDEVOIR, 30, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
|
new SpeciesEvolution(Species.GARDEVOIR, 30, null, new GenderEvolutionCondition(Gender.FEMALE)),
|
||||||
new SpeciesEvolution(Species.GALLADE, 30, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
|
new SpeciesEvolution(Species.GALLADE, 30, null, new GenderEvolutionCondition(Gender.MALE))
|
||||||
],
|
],
|
||||||
[Species.SURSKIT]: [
|
[Species.SURSKIT]: [
|
||||||
new SpeciesEvolution(Species.MASQUERAIN, 22, null, null)
|
new SpeciesEvolution(Species.MASQUERAIN, 22, null, null)
|
||||||
@ -479,7 +672,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
],
|
],
|
||||||
[Species.NINCADA]: [
|
[Species.NINCADA]: [
|
||||||
new SpeciesEvolution(Species.NINJASK, 20, null, null),
|
new SpeciesEvolution(Species.NINJASK, 20, null, null),
|
||||||
new SpeciesEvolution(Species.SHEDINJA, 20, null, new SpeciesEvolutionCondition(p => globalScene.getPlayerParty().length < 6 && globalScene.pokeballCounts[PokeballType.POKEBALL] > 0))
|
new SpeciesEvolution(Species.SHEDINJA, 20, null, new ShedinjaEvolutionCondition())
|
||||||
],
|
],
|
||||||
[Species.WHISMUR]: [
|
[Species.WHISMUR]: [
|
||||||
new SpeciesEvolution(Species.LOUDRED, 20, null, null)
|
new SpeciesEvolution(Species.LOUDRED, 20, null, null)
|
||||||
@ -551,8 +744,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.DUSCLOPS, 37, null, null)
|
new SpeciesEvolution(Species.DUSCLOPS, 37, null, null)
|
||||||
],
|
],
|
||||||
[Species.SNORUNT]: [
|
[Species.SNORUNT]: [
|
||||||
new SpeciesEvolution(Species.GLALIE, 42, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)),
|
new SpeciesEvolution(Species.GLALIE, 42, null, new GenderEvolutionCondition(Gender.MALE)),
|
||||||
new SpeciesEvolution(Species.FROSLASS, 42, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE))
|
new SpeciesEvolution(Species.FROSLASS, 42, null, new GenderEvolutionCondition(Gender.FEMALE))
|
||||||
],
|
],
|
||||||
[Species.SPHEAL]: [
|
[Species.SPHEAL]: [
|
||||||
new SpeciesEvolution(Species.SEALEO, 32, null, null)
|
new SpeciesEvolution(Species.SEALEO, 32, null, null)
|
||||||
@ -615,11 +808,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.BASTIODON, 30, null, null)
|
new SpeciesEvolution(Species.BASTIODON, 30, null, null)
|
||||||
],
|
],
|
||||||
[Species.BURMY]: [
|
[Species.BURMY]: [
|
||||||
new SpeciesEvolution(Species.MOTHIM, 20, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE)),
|
new SpeciesEvolution(Species.MOTHIM, 20, null, new GenderEvolutionCondition(Gender.MALE)),
|
||||||
new SpeciesEvolution(Species.WORMADAM, 20, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE))
|
new SpeciesEvolution(Species.WORMADAM, 20, null, new GenderEvolutionCondition(Gender.FEMALE))
|
||||||
],
|
],
|
||||||
[Species.COMBEE]: [
|
[Species.COMBEE]: [
|
||||||
new SpeciesEvolution(Species.VESPIQUEN, 21, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE))
|
new SpeciesEvolution(Species.VESPIQUEN, 21, null, new GenderEvolutionCondition(Gender.FEMALE))
|
||||||
],
|
],
|
||||||
[Species.BUIZEL]: [
|
[Species.BUIZEL]: [
|
||||||
new SpeciesEvolution(Species.FLOATZEL, 26, null, null)
|
new SpeciesEvolution(Species.FLOATZEL, 26, null, null)
|
||||||
@ -661,7 +854,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.LUMINEON, 31, null, null)
|
new SpeciesEvolution(Species.LUMINEON, 31, null, null)
|
||||||
],
|
],
|
||||||
[Species.MANTYKE]: [
|
[Species.MANTYKE]: [
|
||||||
new SpeciesEvolution(Species.MANTINE, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.REMORAID].caughtAttr), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.MANTINE, 32, null, new CaughtEvolutionCondition(Species.REMORAID), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.SNOVER]: [
|
[Species.SNOVER]: [
|
||||||
new SpeciesEvolution(Species.ABOMASNOW, 40, null, null)
|
new SpeciesEvolution(Species.ABOMASNOW, 40, null, null)
|
||||||
@ -682,8 +875,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.DEWOTT, 17, null, null)
|
new SpeciesEvolution(Species.DEWOTT, 17, null, null)
|
||||||
],
|
],
|
||||||
[Species.DEWOTT]: [
|
[Species.DEWOTT]: [
|
||||||
new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_SAMUROTT, 36, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.SAMUROTT, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.SAMUROTT, 36, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.PATRAT]: [
|
[Species.PATRAT]: [
|
||||||
new SpeciesEvolution(Species.WATCHOG, 20, null, null)
|
new SpeciesEvolution(Species.WATCHOG, 20, null, null)
|
||||||
@ -833,8 +1026,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.KINGAMBIT, 1, EvolutionItem.LEADERS_CREST, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.KINGAMBIT, 1, EvolutionItem.LEADERS_CREST, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.RUFFLET]: [
|
[Species.RUFFLET]: [
|
||||||
new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_BRAVIARY, 54, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.BRAVIARY, 54, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.BRAVIARY, 54, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.VULLABY]: [
|
[Species.VULLABY]: [
|
||||||
new SpeciesEvolution(Species.MANDIBUZZ, 54, null, null)
|
new SpeciesEvolution(Species.MANDIBUZZ, 54, null, null)
|
||||||
@ -891,11 +1084,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.GOGOAT, 32, null, null)
|
new SpeciesEvolution(Species.GOGOAT, 32, null, null)
|
||||||
],
|
],
|
||||||
[Species.PANCHAM]: [
|
[Species.PANCHAM]: [
|
||||||
new SpeciesEvolution(Species.PANGORO, 32, null, new SpeciesEvolutionCondition(p => !!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(Type.DARK) > -1)), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.PANGORO, 32, null, new PartyTypeEvolutionCondition(Type.DARK), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.ESPURR]: [
|
[Species.ESPURR]: [
|
||||||
new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
|
new SpeciesFormEvolution(Species.MEOWSTIC, "", "female", 25, null, new GenderEvolutionCondition(Gender.FEMALE)),
|
||||||
new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
|
new SpeciesFormEvolution(Species.MEOWSTIC, "", "", 25, null, new GenderEvolutionCondition(Gender.MALE))
|
||||||
],
|
],
|
||||||
[Species.HONEDGE]: [
|
[Species.HONEDGE]: [
|
||||||
new SpeciesEvolution(Species.DOUBLADE, 35, null, null)
|
new SpeciesEvolution(Species.DOUBLADE, 35, null, null)
|
||||||
@ -913,21 +1106,21 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.CLAWITZER, 37, null, null)
|
new SpeciesEvolution(Species.CLAWITZER, 37, null, null)
|
||||||
],
|
],
|
||||||
[Species.TYRUNT]: [
|
[Species.TYRUNT]: [
|
||||||
new SpeciesEvolution(Species.TYRANTRUM, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.TYRANTRUM, 39, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.AMAURA]: [
|
[Species.AMAURA]: [
|
||||||
new SpeciesEvolution(Species.AURORUS, 39, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
|
new SpeciesEvolution(Species.AURORUS, 39, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.GOOMY]: [
|
[Species.GOOMY]: [
|
||||||
new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_SLIGGOO, 40, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.SLIGGOO, 40, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.SLIGGOO, 40, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.SLIGGOO]: [
|
[Species.SLIGGOO]: [
|
||||||
new SpeciesEvolution(Species.GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.GOODRA, 50, null, new WeatherEvolutionCondition([ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ]), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.BERGMITE]: [
|
[Species.BERGMITE]: [
|
||||||
new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_AVALUGG, 37, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.AVALUGG, 37, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.AVALUGG, 37, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.NOIBAT]: [
|
[Species.NOIBAT]: [
|
||||||
new SpeciesEvolution(Species.NOIVERN, 48, null, null)
|
new SpeciesEvolution(Species.NOIVERN, 48, null, null)
|
||||||
@ -936,8 +1129,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.DARTRIX, 17, null, null)
|
new SpeciesEvolution(Species.DARTRIX, 17, null, null)
|
||||||
],
|
],
|
||||||
[Species.DARTRIX]: [
|
[Species.DARTRIX]: [
|
||||||
new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)),
|
new SpeciesEvolution(Species.HISUI_DECIDUEYE, 36, null, new TimeOfDayEvolutionCondition("night")),
|
||||||
new SpeciesEvolution(Species.DECIDUEYE, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.DECIDUEYE, 34, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.LITTEN]: [
|
[Species.LITTEN]: [
|
||||||
new SpeciesEvolution(Species.TORRACAT, 17, null, null)
|
new SpeciesEvolution(Species.TORRACAT, 17, null, null)
|
||||||
@ -958,7 +1151,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.TOUCANNON, 28, null, null)
|
new SpeciesEvolution(Species.TOUCANNON, 28, null, null)
|
||||||
],
|
],
|
||||||
[Species.YUNGOOS]: [
|
[Species.YUNGOOS]: [
|
||||||
new SpeciesEvolution(Species.GUMSHOOS, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.GUMSHOOS, 20, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.GRUBBIN]: [
|
[Species.GRUBBIN]: [
|
||||||
new SpeciesEvolution(Species.CHARJABUG, 20, null, null)
|
new SpeciesEvolution(Species.CHARJABUG, 20, null, null)
|
||||||
@ -976,13 +1169,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ARAQUANID, 22, null, null)
|
new SpeciesEvolution(Species.ARAQUANID, 22, null, null)
|
||||||
],
|
],
|
||||||
[Species.FOMANTIS]: [
|
[Species.FOMANTIS]: [
|
||||||
new SpeciesEvolution(Species.LURANTIS, 34, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY))
|
new SpeciesEvolution(Species.LURANTIS, 34, null, new TimeOfDayEvolutionCondition("day"))
|
||||||
],
|
],
|
||||||
[Species.MORELULL]: [
|
[Species.MORELULL]: [
|
||||||
new SpeciesEvolution(Species.SHIINOTIC, 24, null, null)
|
new SpeciesEvolution(Species.SHIINOTIC, 24, null, null)
|
||||||
],
|
],
|
||||||
[Species.SALANDIT]: [
|
[Species.SALANDIT]: [
|
||||||
new SpeciesEvolution(Species.SALAZZLE, 33, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE))
|
new SpeciesEvolution(Species.SALAZZLE, 33, null, new GenderEvolutionCondition(Gender.FEMALE))
|
||||||
],
|
],
|
||||||
[Species.STUFFUL]: [
|
[Species.STUFFUL]: [
|
||||||
new SpeciesEvolution(Species.BEWEAR, 27, null, null)
|
new SpeciesEvolution(Species.BEWEAR, 27, null, null)
|
||||||
@ -1013,7 +1206,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.MELMETAL, 48, null, null)
|
new SpeciesEvolution(Species.MELMETAL, 48, null, null)
|
||||||
],
|
],
|
||||||
[Species.ALOLA_RATTATA]: [
|
[Species.ALOLA_RATTATA]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
|
new SpeciesEvolution(Species.ALOLA_RATICATE, 20, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.ALOLA_DIGLETT]: [
|
[Species.ALOLA_DIGLETT]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_DUGTRIO, 26, null, null)
|
new SpeciesEvolution(Species.ALOLA_DUGTRIO, 26, null, null)
|
||||||
@ -1086,7 +1279,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
],
|
],
|
||||||
[Species.TOXEL]: [
|
[Species.TOXEL]: [
|
||||||
new SpeciesFormEvolution(Species.TOXTRICITY, "", "lowkey", 30, null,
|
new SpeciesFormEvolution(Species.TOXTRICITY, "", "lowkey", 30, null,
|
||||||
new SpeciesEvolutionCondition(p => [ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ].indexOf(p.getNature()) > -1)),
|
new NatureEvolutionCondition([ Nature.LONELY, Nature.BOLD, Nature.RELAXED, Nature.TIMID, Nature.SERIOUS, Nature.MODEST, Nature.MILD, Nature.QUIET, Nature.BASHFUL, Nature.CALM, Nature.GENTLE, Nature.CAREFUL ])
|
||||||
|
),
|
||||||
new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null)
|
new SpeciesFormEvolution(Species.TOXTRICITY, "", "amped", 30, null, null)
|
||||||
],
|
],
|
||||||
[Species.SIZZLIPEDE]: [
|
[Species.SIZZLIPEDE]: [
|
||||||
@ -1136,7 +1330,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.GALAR_LINOONE, 20, null, null)
|
new SpeciesEvolution(Species.GALAR_LINOONE, 20, null, null)
|
||||||
],
|
],
|
||||||
[Species.GALAR_LINOONE]: [
|
[Species.GALAR_LINOONE]: [
|
||||||
new SpeciesEvolution(Species.OBSTAGOON, 35, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
|
new SpeciesEvolution(Species.OBSTAGOON, 35, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.GALAR_YAMASK]: [
|
[Species.GALAR_YAMASK]: [
|
||||||
new SpeciesEvolution(Species.RUNERIGUS, 34, null, null)
|
new SpeciesEvolution(Species.RUNERIGUS, 34, null, null)
|
||||||
@ -1145,7 +1339,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null)
|
new SpeciesEvolution(Species.HISUI_ZOROARK, 30, null, null)
|
||||||
],
|
],
|
||||||
[Species.HISUI_SLIGGOO]: [
|
[Species.HISUI_SLIGGOO]: [
|
||||||
new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new SpeciesEvolutionCondition(p => [ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ].indexOf(globalScene.arena.weather?.weatherType || WeatherType.NONE) > -1), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.HISUI_GOODRA, 50, null, new WeatherEvolutionCondition([ WeatherType.RAIN, WeatherType.FOG, WeatherType.HEAVY_RAIN ]), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.SPRIGATITO]: [
|
[Species.SPRIGATITO]: [
|
||||||
new SpeciesEvolution(Species.FLORAGATO, 16, null, null)
|
new SpeciesEvolution(Species.FLORAGATO, 16, null, null)
|
||||||
@ -1166,8 +1360,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null)
|
new SpeciesEvolution(Species.QUAQUAVAL, 36, null, null)
|
||||||
],
|
],
|
||||||
[Species.LECHONK]: [
|
[Species.LECHONK]: [
|
||||||
new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE)),
|
new SpeciesFormEvolution(Species.OINKOLOGNE, "", "female", 18, null, new GenderEvolutionCondition(Gender.FEMALE)),
|
||||||
new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE))
|
new SpeciesFormEvolution(Species.OINKOLOGNE, "", "", 18, null, new GenderEvolutionCondition(Gender.MALE))
|
||||||
],
|
],
|
||||||
[Species.TAROUNTULA]: [
|
[Species.TAROUNTULA]: [
|
||||||
new SpeciesEvolution(Species.SPIDOPS, 15, null, null)
|
new SpeciesEvolution(Species.SPIDOPS, 15, null, null)
|
||||||
@ -1182,11 +1376,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.PAWMOT, 32, null, null)
|
new SpeciesEvolution(Species.PAWMOT, 32, null, null)
|
||||||
],
|
],
|
||||||
[Species.TANDEMAUS]: [
|
[Species.TANDEMAUS]: [
|
||||||
new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new SpeciesEvolutionCondition(p => {
|
new SpeciesFormEvolution(Species.MAUSHOLD, "", "three", 25, null, new TandemausEvolutionCondition()),
|
||||||
let ret = false;
|
|
||||||
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
|
||||||
return ret;
|
|
||||||
})),
|
|
||||||
new SpeciesEvolution(Species.MAUSHOLD, 25, null, null)
|
new SpeciesEvolution(Species.MAUSHOLD, 25, null, null)
|
||||||
],
|
],
|
||||||
[Species.FIDOUGH]: [
|
[Species.FIDOUGH]: [
|
||||||
@ -1244,7 +1434,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.GLIMMORA, 35, null, null)
|
new SpeciesEvolution(Species.GLIMMORA, 35, null, null)
|
||||||
],
|
],
|
||||||
[Species.GREAVARD]: [
|
[Species.GREAVARD]: [
|
||||||
new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT))
|
new SpeciesEvolution(Species.HOUNDSTONE, 30, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.FRIGIBAX]: [
|
[Species.FRIGIBAX]: [
|
||||||
new SpeciesEvolution(Species.ARCTIBAX, 35, null, null)
|
new SpeciesEvolution(Species.ARCTIBAX, 35, null, null)
|
||||||
@ -1301,21 +1491,21 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.TANGELA]: [
|
[Species.TANGELA]: [
|
||||||
new SpeciesEvolution(Species.TANGROWTH, 34, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.TANGROWTH, 34, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.LICKITUNG]: [
|
[Species.LICKITUNG]: [
|
||||||
new SpeciesEvolution(Species.LICKILICKY, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ROLLOUT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LICKILICKY, 32, null, new MoveEvolutionCondition(Moves.ROLLOUT), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.STARYU]: [
|
[Species.STARYU]: [
|
||||||
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.EEVEE]: [
|
[Species.EEVEE]: [
|
||||||
new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new FriendshipMoveTypeEvolutionCondition(120, Type.FAIRY), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new FriendshipMoveTypeEvolutionCondition(120, Type.FAIRY), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "night"), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.UMBREON, "partner", "", 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "night"), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.VAPOREON, "", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.VAPOREON, "partner", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.VAPOREON, "partner", "", 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.JOLTEON, "", "", 1, EvolutionItem.THUNDER_STONE, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
@ -1331,13 +1521,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.AIPOM]: [
|
[Species.AIPOM]: [
|
||||||
new SpeciesEvolution(Species.AMBIPOM, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DOUBLE_HIT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.AMBIPOM, 32, null, new MoveEvolutionCondition(Moves.DOUBLE_HIT), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.SUNKERN]: [
|
[Species.SUNKERN]: [
|
||||||
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.YANMA]: [
|
[Species.YANMA]: [
|
||||||
new SpeciesEvolution(Species.YANMEGA, 33, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.YANMEGA, 33, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.MURKROW]: [
|
[Species.MURKROW]: [
|
||||||
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1346,32 +1536,26 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.GIRAFARIG]: [
|
[Species.GIRAFARIG]: [
|
||||||
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new MoveEvolutionCondition(Moves.TWIN_BEAM), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.DUNSPARCE]: [
|
[Species.DUNSPARCE]: [
|
||||||
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
|
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new DunsparceEvolutionCondition(), SpeciesWildEvolutionDelay.LONG),
|
||||||
let ret = false;
|
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new MoveEvolutionCondition(Moves.HYPER_DRILL), SpeciesWildEvolutionDelay.LONG)
|
||||||
if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) {
|
|
||||||
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}), SpeciesWildEvolutionDelay.LONG),
|
|
||||||
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
|
|
||||||
],
|
],
|
||||||
[Species.GLIGAR]: [
|
[Species.GLIGAR]: [
|
||||||
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new TimeOfDayEvolutionCondition("night") /* Razor fang at night*/, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.SNEASEL]: [
|
[Species.SNEASEL]: [
|
||||||
new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor claw at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.WEAVILE, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("night") /* Razor claw at night*/, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.URSARING]: [
|
[Species.URSARING]: [
|
||||||
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
|
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
|
||||||
],
|
],
|
||||||
[Species.PILOSWINE]: [
|
[Species.PILOSWINE]: [
|
||||||
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new MoveEvolutionCondition(Moves.ANCIENT_POWER), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.STANTLER]: [
|
[Species.STANTLER]: [
|
||||||
new SpeciesEvolution(Species.WYRDEER, 25, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.PSYSHIELD_BASH).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.WYRDEER, 25, null, new MoveEvolutionCondition(Moves.PSYSHIELD_BASH), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.LOMBRE]: [
|
[Species.LOMBRE]: [
|
||||||
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1389,11 +1573,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.BONSLY]: [
|
[Species.BONSLY]: [
|
||||||
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new MoveEvolutionCondition(Moves.MIMIC), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.MIME_JR]: [
|
[Species.MIME_JR]: [
|
||||||
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM),
|
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "night"), SpeciesWildEvolutionDelay.MEDIUM),
|
||||||
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.MR_MIME, 1, null, new MoveTimeOfDayEvolutionCondition(Moves.MIMIC, "day"), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.PANSAGE]: [
|
[Species.PANSAGE]: [
|
||||||
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1415,8 +1599,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LILLIGANT, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.BASCULIN]: [
|
[Species.BASCULIN]: [
|
||||||
new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG),
|
new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "female", 40, null, new GenderEvolutionCondition(Gender.FEMALE), SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesFormEvolution(Species.BASCULEGION, "white-striped", "male", 40, null, new GenderEvolutionCondition(Gender.MALE), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.MINCCINO]: [
|
[Species.MINCCINO]: [
|
||||||
new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.CINCCINO, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1443,15 +1627,15 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.CRABOMINABLE, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.ROCKRUFF]: [
|
[Species.ROCKRUFF]: [
|
||||||
new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY) && (p.formIndex === 0))),
|
new SpeciesFormEvolution(Species.LYCANROC, "own-tempo", "dusk", 25, null, null),
|
||||||
new SpeciesFormEvolution(Species.LYCANROC, "own-tempo", "dusk", 25, null, new SpeciesEvolutionCondition(p => p.formIndex === 1)),
|
new SpeciesFormEvolution(Species.LYCANROC, "", "midday", 25, null, new TimeOfDayEvolutionCondition("day")),
|
||||||
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)))
|
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new TimeOfDayEvolutionCondition("night"))
|
||||||
],
|
],
|
||||||
[Species.STEENEE]: [
|
[Species.STEENEE]: [
|
||||||
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.TSAREENA, 28, null, new MoveEvolutionCondition(Moves.STOMP), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.POIPOLE]: [
|
[Species.POIPOLE]: [
|
||||||
new SpeciesEvolution(Species.NAGANADEL, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_PULSE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.NAGANADEL, 1, null, new MoveEvolutionCondition(Moves.DRAGON_PULSE), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.ALOLA_SANDSHREW]: [
|
[Species.ALOLA_SANDSHREW]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1465,22 +1649,40 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.CLOBBOPUS]: [
|
[Species.CLOBBOPUS]: [
|
||||||
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TAUNT).length > 0)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/)
|
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new MoveEvolutionCondition(Moves.TAUNT)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/)
|
||||||
],
|
],
|
||||||
[Species.SINISTEA]: [
|
[Species.SINISTEA]: [
|
||||||
new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesFormEvolution(Species.POLTEAGEIST, "antique", "antique", 1, EvolutionItem.CHIPPED_POT, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.MILCERY]: [
|
[Species.MILCERY]: [
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TOWN || globalScene.arena.biomeType === Biome.PLAINS || globalScene.arena.biomeType === Biome.GRASS || globalScene.arena.biomeType === Biome.TALL_GRASS || globalScene.arena.biomeType === Biome.METROPOLIS), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "vanilla-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.BADLANDS || globalScene.arena.biomeType === Biome.VOLCANO || globalScene.arena.biomeType === Biome.GRAVEYARD || globalScene.arena.biomeType === Biome.FACTORY || globalScene.arena.biomeType === Biome.SLUM), SpeciesWildEvolutionDelay.LONG),
|
new BiomeEvolutionCondition([ Biome.TOWN, Biome.PLAINS, Biome.GRASS, Biome.TALL_GRASS, Biome.METROPOLIS ]),
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.FOREST || globalScene.arena.biomeType === Biome.SWAMP || globalScene.arena.biomeType === Biome.MEADOW || globalScene.arena.biomeType === Biome.JUNGLE), SpeciesWildEvolutionDelay.LONG),
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.SEA || globalScene.arena.biomeType === Biome.BEACH || globalScene.arena.biomeType === Biome.LAKE || globalScene.arena.biomeType === Biome.SEABED), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.DESERT || globalScene.arena.biomeType === Biome.POWER_PLANT || globalScene.arena.biomeType === Biome.DOJO || globalScene.arena.biomeType === Biome.RUINS || globalScene.arena.biomeType === Biome.CONSTRUCTION_SITE), SpeciesWildEvolutionDelay.LONG),
|
new BiomeEvolutionCondition([ Biome.BADLANDS, Biome.VOLCANO, Biome.GRAVEYARD, Biome.FACTORY, Biome.SLUM ]),
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.MOUNTAIN || globalScene.arena.biomeType === Biome.CAVE || globalScene.arena.biomeType === Biome.ICE_CAVE || globalScene.arena.biomeType === Biome.FAIRY_CAVE || globalScene.arena.biomeType === Biome.SNOWY_FOREST), SpeciesWildEvolutionDelay.LONG),
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.WASTELAND || globalScene.arena.biomeType === Biome.LABORATORY), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "matcha-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.TEMPLE || globalScene.arena.biomeType === Biome.ISLAND), SpeciesWildEvolutionDelay.LONG),
|
new BiomeEvolutionCondition([ Biome.FOREST, Biome.SWAMP, Biome.MEADOW, Biome.JUNGLE ]),
|
||||||
new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET, new SpeciesEvolutionCondition(p => globalScene.arena.biomeType === Biome.ABYSS || globalScene.arena.biomeType === Biome.SPACE || globalScene.arena.biomeType === Biome.END), SpeciesWildEvolutionDelay.LONG)
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "mint-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.SEA, Biome.BEACH, Biome.LAKE, Biome.SEABED ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "lemon-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.DESERT, Biome.POWER_PLANT, Biome.DOJO, Biome.RUINS, Biome.CONSTRUCTION_SITE ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "salted-cream", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.MOUNTAIN, Biome.CAVE, Biome.ICE_CAVE, Biome.FAIRY_CAVE, Biome.SNOWY_FOREST ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "ruby-swirl", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.WASTELAND, Biome.LABORATORY ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "caramel-swirl", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.TEMPLE, Biome.ISLAND ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG),
|
||||||
|
new SpeciesFormEvolution(Species.ALCREMIE, "", "rainbow-swirl", 1, EvolutionItem.STRAWBERRY_SWEET,
|
||||||
|
new BiomeEvolutionCondition([ Biome.ABYSS, Biome.SPACE, Biome.END ]),
|
||||||
|
SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.DURALUDON]: [
|
[Species.DURALUDON]: [
|
||||||
new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesFormEvolution(Species.ARCHALUDON, "", "", 1, EvolutionItem.METAL_ALLOY, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1499,10 +1701,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.HISUI_QWILFISH]: [
|
[Species.HISUI_QWILFISH]: [
|
||||||
new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.OVERQWIL, 28, null, new MoveEvolutionCondition(Moves.BARB_BARRAGE), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.HISUI_SNEASEL]: [
|
[Species.HISUI_SNEASEL]: [
|
||||||
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new TimeOfDayEvolutionCondition("day") /* Razor claw at day*/, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.CHARCADET]: [
|
[Species.CHARCADET]: [
|
||||||
new SpeciesEvolution(Species.ARMAROUGE, 1, EvolutionItem.AUSPICIOUS_ARMOR, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesEvolution(Species.ARMAROUGE, 1, EvolutionItem.AUSPICIOUS_ARMOR, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
@ -1522,7 +1724,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.DIPPLIN]: [
|
[Species.DIPPLIN]: [
|
||||||
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new MoveEvolutionCondition(Moves.DRAGON_CHEER), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.KADABRA]: [
|
[Species.KADABRA]: [
|
||||||
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1537,9 +1739,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.GENGAR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.GENGAR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.ONIX]: [
|
[Species.ONIX]: [
|
||||||
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new MoveTypeEvolutionCondition(Type.STEEL), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0),
|
|
||||||
SpeciesWildEvolutionDelay.VERY_LONG)
|
|
||||||
],
|
],
|
||||||
[Species.RHYDON]: [
|
[Species.RHYDON]: [
|
||||||
new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.PROTECTOR, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.RHYPERIOR, 1, EvolutionItem.PROTECTOR, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1548,9 +1748,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.DRAGON_SCALE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.KINGDRA, 1, EvolutionItem.DRAGON_SCALE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.SCYTHER]: [
|
[Species.SCYTHER]: [
|
||||||
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new MoveTypeEvolutionCondition(Type.STEEL), SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0),
|
|
||||||
SpeciesWildEvolutionDelay.VERY_LONG),
|
|
||||||
new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.ELECTABUZZ]: [
|
[Species.ELECTABUZZ]: [
|
||||||
@ -1572,8 +1770,8 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.REAPER_CLOTH, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.DUSKNOIR, 1, EvolutionItem.REAPER_CLOTH, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.CLAMPERL]: [
|
[Species.CLAMPERL]: [
|
||||||
new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.gender === Gender.MALE, p => p.gender = Gender.MALE /* Deep Sea Tooth */), SpeciesWildEvolutionDelay.VERY_LONG),
|
new SpeciesEvolution(Species.HUNTAIL, 1, EvolutionItem.LINKING_CORD, new GenderEvolutionCondition(Gender.MALE /* Deep Sea Tooth */), SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
new SpeciesEvolution(Species.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => p.gender === Gender.FEMALE, p => p.gender = Gender.FEMALE /* Deep Sea Scale */), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.GOREBYSS, 1, EvolutionItem.LINKING_CORD, new GenderEvolutionCondition(Gender.FEMALE /* Deep Sea Scale */), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.BOLDORE]: [
|
[Species.BOLDORE]: [
|
||||||
new SpeciesEvolution(Species.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.GIGALITH, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1582,10 +1780,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.CONKELDURR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.CONKELDURR, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.KARRABLAST]: [
|
[Species.KARRABLAST]: [
|
||||||
new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.SHELMET].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ESCAVALIER, 1, EvolutionItem.LINKING_CORD, new CaughtEvolutionCondition(Species.SHELMET), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.SHELMET]: [
|
[Species.SHELMET]: [
|
||||||
new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(p => !!globalScene.gameData.dexData[Species.KARRABLAST].caughtAttr), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ACCELGOR, 1, EvolutionItem.LINKING_CORD, new CaughtEvolutionCondition(Species.KARRABLAST), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.SPRITZEE]: [
|
[Species.SPRITZEE]: [
|
||||||
new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.SACHET, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.AROMATISSE, 1, EvolutionItem.SACHET, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1603,72 +1801,66 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.PRIMEAPE]: [
|
[Species.PRIMEAPE]: [
|
||||||
new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.RAGE_FIST).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new MoveEvolutionCondition(Moves.RAGE_FIST), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.GOLBAT]: [
|
[Species.GOLBAT]: [
|
||||||
new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.CROBAT, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.CHANSEY]: [
|
[Species.CHANSEY]: [
|
||||||
new SpeciesEvolution(Species.BLISSEY, 1, null, new SpeciesFriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.BLISSEY, 1, null, new FriendshipEvolutionCondition(200), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.PICHU]: [
|
[Species.PICHU]: [
|
||||||
new SpeciesFormEvolution(Species.PIKACHU, "spiky", "partner", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
new SpeciesFormEvolution(Species.PIKACHU, "spiky", "partner", 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
||||||
new SpeciesFormEvolution(Species.PIKACHU, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
new SpeciesFormEvolution(Species.PIKACHU, "", "", 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.SHORT),
|
||||||
],
|
],
|
||||||
[Species.CLEFFA]: [
|
[Species.CLEFFA]: [
|
||||||
new SpeciesEvolution(Species.CLEFAIRY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.CLEFAIRY, 1, null, new FriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.IGGLYBUFF]: [
|
[Species.IGGLYBUFF]: [
|
||||||
new SpeciesEvolution(Species.JIGGLYPUFF, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.JIGGLYPUFF, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.TOGEPI]: [
|
[Species.TOGEPI]: [
|
||||||
new SpeciesEvolution(Species.TOGETIC, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.TOGETIC, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.AZURILL]: [
|
[Species.AZURILL]: [
|
||||||
new SpeciesEvolution(Species.MARILL, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.MARILL, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.BUDEW]: [
|
[Species.BUDEW]: [
|
||||||
new SpeciesEvolution(Species.ROSELIA, 1, null, new SpeciesFriendshipEvolutionCondition(70, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.ROSELIA, 1, null, new FriendshipTimeOfDayEvolutionCondition(70, "day"), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.BUNEARY]: [
|
[Species.BUNEARY]: [
|
||||||
new SpeciesEvolution(Species.LOPUNNY, 1, null, new SpeciesFriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.LOPUNNY, 1, null, new FriendshipEvolutionCondition(70), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.CHINGLING]: [
|
[Species.CHINGLING]: [
|
||||||
new SpeciesEvolution(Species.CHIMECHO, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.CHIMECHO, 1, null, new FriendshipTimeOfDayEvolutionCondition(90, "night"), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.HAPPINY]: [
|
[Species.HAPPINY]: [
|
||||||
new SpeciesEvolution(Species.CHANSEY, 1, null, new SpeciesFriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
new SpeciesEvolution(Species.CHANSEY, 1, null, new FriendshipEvolutionCondition(160), SpeciesWildEvolutionDelay.SHORT)
|
||||||
],
|
],
|
||||||
[Species.MUNCHLAX]: [
|
[Species.MUNCHLAX]: [
|
||||||
new SpeciesEvolution(Species.SNORLAX, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SNORLAX, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.RIOLU]: [
|
[Species.RIOLU]: [
|
||||||
new SpeciesEvolution(Species.LUCARIO, 1, null, new SpeciesFriendshipEvolutionCondition(120, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LUCARIO, 1, null, new FriendshipTimeOfDayEvolutionCondition(120, "day"), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.WOOBAT]: [
|
[Species.WOOBAT]: [
|
||||||
new SpeciesEvolution(Species.SWOOBAT, 1, null, new SpeciesFriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.SWOOBAT, 1, null, new FriendshipEvolutionCondition(90), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.SWADLOON]: [
|
[Species.SWADLOON]: [
|
||||||
new SpeciesEvolution(Species.LEAVANNY, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LEAVANNY, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.TYPE_NULL]: [
|
[Species.TYPE_NULL]: [
|
||||||
new SpeciesEvolution(Species.SILVALLY, 1, null, new SpeciesFriendshipEvolutionCondition(100), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SILVALLY, 1, null, new FriendshipEvolutionCondition(100), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.ALOLA_MEOWTH]: [
|
[Species.ALOLA_MEOWTH]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.ALOLA_PERSIAN, 1, null, new FriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.SNOM]: [
|
[Species.SNOM]: [
|
||||||
new SpeciesEvolution(Species.FROSMOTH, 1, null, new SpeciesFriendshipEvolutionCondition(90, p => globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.FROSMOTH, 1, null, new FriendshipTimeOfDayEvolutionCondition(90, "night"), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.GIMMIGHOUL]: [
|
[Species.GIMMIGHOUL]: [
|
||||||
new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
|
new SpeciesFormEvolution(Species.GHOLDENGO, "chest", "", 1, null, new TreasureEvolutionCondition(), SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
|
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new TreasureEvolutionCondition(), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|
|
||||||
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG),
|
|
||||||
new SpeciesFormEvolution(Species.GHOLDENGO, "roaming", "", 1, null, new SpeciesEvolutionCondition(p => p.evoCounter
|
|
||||||
+ p.getHeldItems().filter(m => m instanceof DamageMoneyRewardModifier).length
|
|
||||||
+ globalScene.findModifiers(m => m instanceof MoneyMultiplierModifier
|
|
||||||
|| m instanceof ExtraModifierModifier || m instanceof TempExtraModifierModifier).length > 9), SpeciesWildEvolutionDelay.VERY_LONG)
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1691,3 +1883,19 @@ export function initPokemonPrevolutions(): void {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: This may cause funny business for double starters such as Pichu/Pikachu
|
||||||
|
export const pokemonStarters: PokemonPrevolutions = {};
|
||||||
|
|
||||||
|
export function initPokemonStarters(): void {
|
||||||
|
const starterKeys = Object.keys(pokemonPrevolutions);
|
||||||
|
starterKeys.forEach(pk => {
|
||||||
|
const prevolution = pokemonPrevolutions[pk];
|
||||||
|
if (speciesStarterCosts.hasOwnProperty(prevolution)) {
|
||||||
|
pokemonStarters[pk] = prevolution;
|
||||||
|
} else {
|
||||||
|
pokemonStarters[pk] = pokemonPrevolutions[prevolution];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -19718,6 +19718,44 @@ export const pokemonFormLevelMoves: PokemonSpeciesFormLevelMoves = {
|
|||||||
[ 48, Moves.CLOSE_COMBAT ],
|
[ 48, Moves.CLOSE_COMBAT ],
|
||||||
[ 52, Moves.FOCUS_PUNCH ],
|
[ 52, Moves.FOCUS_PUNCH ],
|
||||||
],
|
],
|
||||||
|
2: [
|
||||||
|
[ EVOLVE_MOVE, Moves.WICKED_BLOW ],
|
||||||
|
[ 1, Moves.LEER ],
|
||||||
|
[ 1, Moves.FOCUS_ENERGY ],
|
||||||
|
[ 1, Moves.ENDURE ],
|
||||||
|
[ 1, Moves.ROCK_SMASH ],
|
||||||
|
[ 1, Moves.SUCKER_PUNCH ],
|
||||||
|
[ 12, Moves.AERIAL_ACE ],
|
||||||
|
[ 16, Moves.SCARY_FACE ],
|
||||||
|
[ 20, Moves.HEADBUTT ],
|
||||||
|
[ 24, Moves.BRICK_BREAK ],
|
||||||
|
[ 28, Moves.DETECT ],
|
||||||
|
[ 32, Moves.BULK_UP ],
|
||||||
|
[ 36, Moves.IRON_HEAD ],
|
||||||
|
[ 40, Moves.DYNAMIC_PUNCH ],
|
||||||
|
[ 44, Moves.COUNTER ],
|
||||||
|
[ 48, Moves.CLOSE_COMBAT ],
|
||||||
|
[ 52, Moves.FOCUS_PUNCH ],
|
||||||
|
],
|
||||||
|
3: [
|
||||||
|
[ EVOLVE_MOVE, Moves.SURGING_STRIKES ],
|
||||||
|
[ 1, Moves.LEER ],
|
||||||
|
[ 1, Moves.FOCUS_ENERGY ],
|
||||||
|
[ 1, Moves.ENDURE ],
|
||||||
|
[ 1, Moves.ROCK_SMASH ],
|
||||||
|
[ 1, Moves.AQUA_JET ],
|
||||||
|
[ 12, Moves.AERIAL_ACE ],
|
||||||
|
[ 16, Moves.SCARY_FACE ],
|
||||||
|
[ 20, Moves.HEADBUTT ],
|
||||||
|
[ 24, Moves.BRICK_BREAK ],
|
||||||
|
[ 28, Moves.DETECT ],
|
||||||
|
[ 32, Moves.BULK_UP ],
|
||||||
|
[ 36, Moves.IRON_HEAD ],
|
||||||
|
[ 40, Moves.DYNAMIC_PUNCH ],
|
||||||
|
[ 44, Moves.COUNTER ],
|
||||||
|
[ 48, Moves.CLOSE_COMBAT ],
|
||||||
|
[ 52, Moves.FOCUS_PUNCH ],
|
||||||
|
],
|
||||||
},
|
},
|
||||||
[Species.CALYREX]: {
|
[Species.CALYREX]: {
|
||||||
1: [
|
1: [
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
MoveFlags,
|
MoveFlags,
|
||||||
StatusCategoryOnAllyAttr
|
StatusCategoryOnAllyAttr
|
||||||
} from "#app/data/move";
|
} from "#app/data/move";
|
||||||
import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeAbilityTrigger } from "#app/data/pokemon-forms";
|
||||||
import { getStatusEffectHealText } from "#app/data/status-effect";
|
import { getStatusEffectHealText } from "#app/data/status-effect";
|
||||||
import { TerrainType } from "#app/data/terrain";
|
import { TerrainType } from "#app/data/terrain";
|
||||||
import { Type } from "#enums/type";
|
import { Type } from "#enums/type";
|
||||||
@ -2149,7 +2149,7 @@ export class FormBlockDamageTag extends BattlerTag {
|
|||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
if (pokemon.formIndex !== 0) {
|
if (pokemon.formIndex !== 0) {
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2161,7 +2161,7 @@ export class FormBlockDamageTag extends BattlerTag {
|
|||||||
onRemove(pokemon: Pokemon): void {
|
onRemove(pokemon: Pokemon): void {
|
||||||
super.onRemove(pokemon);
|
super.onRemove(pokemon);
|
||||||
|
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Provides the additional weather-based effects of the Ice Face ability */
|
/** Provides the additional weather-based effects of the Ice Face ability */
|
||||||
@ -2361,12 +2361,12 @@ export class GulpMissileTag extends BattlerTag {
|
|||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove(pokemon: Pokemon): void {
|
onRemove(pokemon: Pokemon): void {
|
||||||
super.onRemove(pokemon);
|
super.onRemove(pokemon);
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import { speciesStarterCosts } from "#app/data/balance/starters";
|
|||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import type { FixedBattleConfig } from "#app/battle";
|
import type { FixedBattleConfig } from "#app/battle";
|
||||||
import { BattleType } from "#app/battle";
|
import { ClassicFixedBossWaves, BattleType, getRandomTrainerFunc } from "#app/battle";
|
||||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||||
import type { GameMode } from "#app/game-mode";
|
import type { GameMode } from "#app/game-mode";
|
||||||
import { Type } from "#enums/type";
|
import { Type } from "#enums/type";
|
||||||
@ -20,6 +20,7 @@ import type { Moves } from "#enums/moves";
|
|||||||
import { TypeColor, TypeShadow } from "#enums/color";
|
import { TypeColor, TypeShadow } from "#enums/color";
|
||||||
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||||
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
||||||
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
|
||||||
/** A constant for the default max cost of the starting party before a run */
|
/** A constant for the default max cost of the starting party before a run */
|
||||||
const DEFAULT_PARTY_MAX_COST = 10;
|
const DEFAULT_PARTY_MAX_COST = 10;
|
||||||
@ -464,30 +465,64 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyFixedBattle(waveIndex: Number, battleConfig: FixedBattleConfig): boolean {
|
applyFixedBattle(waveIndex: number, battleConfig: FixedBattleConfig): boolean {
|
||||||
let trainerTypes: TrainerType[] = [];
|
let trainerTypes: (TrainerType | TrainerType[])[] = [];
|
||||||
|
const evilTeamWaves: number[] = [ ClassicFixedBossWaves.EVIL_GRUNT_1, ClassicFixedBossWaves.EVIL_GRUNT_2, ClassicFixedBossWaves.EVIL_GRUNT_3, ClassicFixedBossWaves.EVIL_ADMIN_1, ClassicFixedBossWaves.EVIL_GRUNT_4, ClassicFixedBossWaves.EVIL_ADMIN_2, ClassicFixedBossWaves.EVIL_BOSS_1, ClassicFixedBossWaves.EVIL_BOSS_2 ];
|
||||||
|
const evilTeamGrunts = [[ TrainerType.ROCKET_GRUNT ], [ TrainerType.ROCKET_GRUNT ], [ TrainerType.MAGMA_GRUNT, TrainerType.AQUA_GRUNT ], [ TrainerType.GALACTIC_GRUNT ], [ TrainerType.PLASMA_GRUNT ], [ TrainerType.FLARE_GRUNT ], [ TrainerType.AETHER_GRUNT, TrainerType.SKULL_GRUNT ], [ TrainerType.MACRO_GRUNT ], [ TrainerType.STAR_GRUNT ]];
|
||||||
|
const evilTeamAdmins = [[ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [ TrainerType.ARCHER, TrainerType.ARIANA, TrainerType.PROTON, TrainerType.PETREL ], [[ TrainerType.TABITHA, TrainerType.COURTNEY ], [ TrainerType.MATT, TrainerType.SHELLY ]], [ TrainerType.JUPITER, TrainerType.MARS, TrainerType.SATURN ], [ TrainerType.ZINZOLIN, TrainerType.ROOD ], [ TrainerType.XEROSIC, TrainerType.BRYONY ], [ TrainerType.FABA, TrainerType.PLUMERIA ], [ TrainerType.OLEANA ], [ TrainerType.GIACOMO, TrainerType.MELA, TrainerType.ATTICUS, TrainerType.ORTEGA, TrainerType.ERI ]];
|
||||||
|
const evilTeamBosses = [[ TrainerType.ROCKET_BOSS_GIOVANNI_1 ], [ TrainerType.ROCKET_BOSS_GIOVANNI_1 ], [ TrainerType.MAXIE, TrainerType.ARCHIE ], [ TrainerType.CYRUS ], [ TrainerType.GHETSIS ], [ TrainerType.LYSANDRE ], [ TrainerType.LUSAMINE, TrainerType.GUZMA ], [ TrainerType.ROSE ], [ TrainerType.PENNY ]];
|
||||||
|
const evilTeamBossRematches = [[ TrainerType.ROCKET_BOSS_GIOVANNI_2 ], [ TrainerType.ROCKET_BOSS_GIOVANNI_2 ], [ TrainerType.MAXIE_2, TrainerType.ARCHIE_2 ], [ TrainerType.CYRUS_2 ], [ TrainerType.GHETSIS_2 ], [ TrainerType.LYSANDRE_2 ], [ TrainerType.LUSAMINE_2, TrainerType.GUZMA_2 ], [ TrainerType.ROSE_2 ], [ TrainerType.PENNY_2 ]];
|
||||||
switch (waveIndex) {
|
switch (waveIndex) {
|
||||||
case 182:
|
case ClassicFixedBossWaves.EVIL_GRUNT_1:
|
||||||
|
trainerTypes = evilTeamGrunts[this.value - 1];
|
||||||
|
battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true));
|
||||||
|
return true;
|
||||||
|
case ClassicFixedBossWaves.EVIL_GRUNT_2:
|
||||||
|
case ClassicFixedBossWaves.EVIL_GRUNT_3:
|
||||||
|
case ClassicFixedBossWaves.EVIL_GRUNT_4:
|
||||||
|
trainerTypes = evilTeamGrunts[this.value - 1];
|
||||||
|
break;
|
||||||
|
case ClassicFixedBossWaves.EVIL_ADMIN_1:
|
||||||
|
case ClassicFixedBossWaves.EVIL_ADMIN_2:
|
||||||
|
trainerTypes = evilTeamAdmins[this.value - 1];
|
||||||
|
break;
|
||||||
|
case ClassicFixedBossWaves.EVIL_BOSS_1:
|
||||||
|
trainerTypes = evilTeamBosses[this.value - 1];
|
||||||
|
battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
||||||
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false });
|
||||||
|
return true;
|
||||||
|
case ClassicFixedBossWaves.EVIL_BOSS_2:
|
||||||
|
trainerTypes = evilTeamBossRematches[this.value - 1];
|
||||||
|
battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true))
|
||||||
|
.setCustomModifierRewards({ guaranteedModifierTiers: [ ModifierTier.ROGUE, ModifierTier.ROGUE, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA, ModifierTier.ULTRA ], allowLuckUpgrades: false });
|
||||||
|
return true;
|
||||||
|
case ClassicFixedBossWaves.ELITE_FOUR_1:
|
||||||
trainerTypes = [ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, Utils.randSeedItem([ TrainerType.HALA, TrainerType.MOLAYNE ]), TrainerType.MARNIE_ELITE, TrainerType.RIKA ];
|
trainerTypes = [ TrainerType.LORELEI, TrainerType.WILL, TrainerType.SIDNEY, TrainerType.AARON, TrainerType.SHAUNTAL, TrainerType.MALVA, Utils.randSeedItem([ TrainerType.HALA, TrainerType.MOLAYNE ]), TrainerType.MARNIE_ELITE, TrainerType.RIKA ];
|
||||||
break;
|
break;
|
||||||
case 184:
|
case ClassicFixedBossWaves.ELITE_FOUR_2:
|
||||||
trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ];
|
trainerTypes = [ TrainerType.BRUNO, TrainerType.KOGA, TrainerType.PHOEBE, TrainerType.BERTHA, TrainerType.MARSHAL, TrainerType.SIEBOLD, TrainerType.OLIVIA, TrainerType.NESSA_ELITE, TrainerType.POPPY ];
|
||||||
break;
|
break;
|
||||||
case 186:
|
case ClassicFixedBossWaves.ELITE_FOUR_3:
|
||||||
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ];
|
trainerTypes = [ TrainerType.AGATHA, TrainerType.BRUNO, TrainerType.GLACIA, TrainerType.FLINT, TrainerType.GRIMSLEY, TrainerType.WIKSTROM, TrainerType.ACEROLA, Utils.randSeedItem([ TrainerType.BEA_ELITE, TrainerType.ALLISTER_ELITE ]), TrainerType.LARRY_ELITE ];
|
||||||
break;
|
break;
|
||||||
case 188:
|
case ClassicFixedBossWaves.ELITE_FOUR_4:
|
||||||
trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ];
|
trainerTypes = [ TrainerType.LANCE, TrainerType.KAREN, TrainerType.DRAKE, TrainerType.LUCIAN, TrainerType.CAITLIN, TrainerType.DRASNA, TrainerType.KAHILI, TrainerType.RAIHAN_ELITE, TrainerType.HASSEL ];
|
||||||
break;
|
break;
|
||||||
case 190:
|
case ClassicFixedBossWaves.CHAMPION:
|
||||||
trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ];
|
trainerTypes = [ TrainerType.BLUE, Utils.randSeedItem([ TrainerType.RED, TrainerType.LANCE_CHAMPION ]), Utils.randSeedItem([ TrainerType.STEVEN, TrainerType.WALLACE ]), TrainerType.CYNTHIA, Utils.randSeedItem([ TrainerType.ALDER, TrainerType.IRIS ]), TrainerType.DIANTHA, TrainerType.HAU, TrainerType.LEON, Utils.randSeedItem([ TrainerType.GEETA, TrainerType.NEMONA ]) ];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (trainerTypes.length === 0) {
|
if (trainerTypes.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else if (evilTeamWaves.includes(waveIndex)) {
|
||||||
battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(() => new Trainer(trainerTypes[this.value - 1], TrainerVariant.DEFAULT));
|
battleConfig.setBattleType(BattleType.TRAINER).setSeedOffsetWave(ClassicFixedBossWaves.EVIL_GRUNT_1).setGetTrainerFunc(getRandomTrainerFunc(trainerTypes, true));
|
||||||
return true;
|
return true;
|
||||||
|
} else if (waveIndex >= ClassicFixedBossWaves.ELITE_FOUR_1 && waveIndex <= ClassicFixedBossWaves.CHAMPION) {
|
||||||
|
const ttypes = trainerTypes as TrainerType[];
|
||||||
|
battleConfig.setBattleType(BattleType.TRAINER).setGetTrainerFunc(() => new Trainer(ttypes[this.value - 1], TrainerVariant.DEFAULT));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,8 +1380,10 @@ export class UserHpDamageAttr extends FixedDamageAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TargetHalfHpDamageAttr extends FixedDamageAttr {
|
export class TargetHalfHpDamageAttr extends FixedDamageAttr {
|
||||||
// the initial amount of hp the target had before the first hit
|
/**
|
||||||
// used for multi lens
|
* The initial amount of hp the target had before the first hit.
|
||||||
|
* Used for calculating multi lens damage.
|
||||||
|
*/
|
||||||
private initialHp: number;
|
private initialHp: number;
|
||||||
constructor() {
|
constructor() {
|
||||||
super(0);
|
super(0);
|
||||||
@ -1405,12 +1407,10 @@ export class TargetHalfHpDamageAttr extends FixedDamageAttr {
|
|||||||
// multi lens added hit; use initialHp tracker to ensure correct damage
|
// multi lens added hit; use initialHp tracker to ensure correct damage
|
||||||
(args[0] as Utils.NumberHolder).value = Utils.toDmgValue(this.initialHp / 2);
|
(args[0] as Utils.NumberHolder).value = Utils.toDmgValue(this.initialHp / 2);
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
case lensCount + 1:
|
case lensCount + 1:
|
||||||
// parental bond added hit; calc damage as normal
|
// parental bond added hit; calc damage as normal
|
||||||
(args[0] as Utils.NumberHolder).value = Utils.toDmgValue(target.hp / 2);
|
(args[0] as Utils.NumberHolder).value = Utils.toDmgValue(target.hp / 2);
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6129,7 +6129,7 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't allow wild mons to flee with U-turn et al
|
// Don't allow wild mons to flee with U-turn et al.
|
||||||
if (this.selfSwitch && !user.isPlayer() && move.category !== MoveCategory.STATUS) {
|
if (this.selfSwitch && !user.isPlayer() && move.category !== MoveCategory.STATUS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -7084,7 +7084,25 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
// get the last move used (excluding status based failures) as well as the corresponding moveset slot
|
// get the last move used (excluding status based failures) as well as the corresponding moveset slot
|
||||||
const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE)!;
|
const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE)!;
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move)!;
|
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move)!;
|
||||||
const moveTargets = lastMove.targets ?? [];
|
// If the last move used can hit more than one target or has variable targets,
|
||||||
|
// re-compute the targets for the attack
|
||||||
|
// (mainly for alternating double/single battle shenanigans)
|
||||||
|
// Rampaging moves (e.g. Outrage) are not included due to being incompatible with Instruct
|
||||||
|
// TODO: Fix this once dragon darts gets smart targeting
|
||||||
|
let moveTargets = movesetMove.getMove().isMultiTarget() ? getMoveTargets(target, lastMove.move).targets : lastMove.targets;
|
||||||
|
|
||||||
|
/** In the event the instructed move's only target is a fainted opponent, redirect it to an alive ally if possible
|
||||||
|
Normally, all yet-unexecuted move phases would swap over when the enemy in question faints
|
||||||
|
(see `redirectPokemonMoves` in `battle-scene.ts`),
|
||||||
|
but since instruct adds a new move phase pre-emptively, we need to handle this interaction manually.
|
||||||
|
*/
|
||||||
|
const firstTarget = globalScene.getField()[moveTargets[0]];
|
||||||
|
if (globalScene.currentBattle.double && moveTargets.length === 1 && firstTarget.isFainted() && firstTarget !== target.getAlly()) {
|
||||||
|
const ally = firstTarget.getAlly();
|
||||||
|
if (ally.isActive()) { // ally exists, is not dead and can sponge the blast
|
||||||
|
moveTargets = [ ally.getBattlerIndex() ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
globalScene.queueMessage(i18next.t("moveTriggers:instructingMove", {
|
globalScene.queueMessage(i18next.t("moveTriggers:instructingMove", {
|
||||||
userPokemonName: getPokemonNameWithAffix(user),
|
userPokemonName: getPokemonNameWithAffix(user),
|
||||||
@ -7098,12 +7116,9 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user, target, move) => {
|
return (user, target, move) => {
|
||||||
// TODO: Confirm behavior of instructing move known by target but called by another move
|
|
||||||
const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE);
|
const lastMove = target.getLastXMoves(-1).find(m => m.move !== Moves.NONE);
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove?.move);
|
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove?.move);
|
||||||
const moveTargets = lastMove?.targets ?? [];
|
const uninstructableMoves = [
|
||||||
// TODO: Add a way of adding moves to list procedurally rather than a pre-defined blacklist
|
|
||||||
const unrepeatablemoves = [
|
|
||||||
// Locking/Continually Executed moves
|
// Locking/Continually Executed moves
|
||||||
Moves.OUTRAGE,
|
Moves.OUTRAGE,
|
||||||
Moves.RAGING_FURY,
|
Moves.RAGING_FURY,
|
||||||
@ -7158,11 +7173,11 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
// TODO: Add Max/G-Move blockage if or when they are implemented
|
// TODO: Add Max/G-Move blockage if or when they are implemented
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!movesetMove // called move not in target's moveset (dancer, forgetting the move, etc.)
|
if (!lastMove?.move // no move to instruct
|
||||||
|
|| !movesetMove // called move not in target's moveset (forgetting the move, etc.)
|
||||||
|| movesetMove.ppUsed === movesetMove.getMovePp() // move out of pp
|
|| movesetMove.ppUsed === movesetMove.getMovePp() // move out of pp
|
||||||
|| allMoves[lastMove?.move ?? Moves.NONE].isChargingMove() // called move is a charging/recharging move
|
|| allMoves[lastMove.move].isChargingMove() // called move is a charging/recharging move
|
||||||
|| !moveTargets.length // called move has no targets
|
|| uninstructableMoves.includes(lastMove.move)) { // called move is in the banlist
|
||||||
|| unrepeatablemoves.includes(lastMove?.move ?? Moves.NONE)) { // called move is explicitly in the banlist
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -7170,7 +7185,7 @@ export class RepeatMoveAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
|
||||||
// TODO: Make the AI acutally use instruct
|
// TODO: Make the AI actually use instruct
|
||||||
/* Ideally, the AI would score instruct based on the scorings of the on-field pokemons'
|
/* Ideally, the AI would score instruct based on the scorings of the on-field pokemons'
|
||||||
* last used moves at the time of using Instruct (by the time the instructor gets to act)
|
* last used moves at the time of using Instruct (by the time the instructor gets to act)
|
||||||
* with respect to the user's side.
|
* with respect to the user's side.
|
||||||
@ -10279,7 +10294,10 @@ export function initMoves() {
|
|||||||
new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7)
|
new StatusMove(Moves.INSTRUCT, Type.PSYCHIC, -1, 15, -1, 0, 7)
|
||||||
.ignoresSubstitute()
|
.ignoresSubstitute()
|
||||||
.attr(RepeatMoveAttr)
|
.attr(RepeatMoveAttr)
|
||||||
.edgeCase(), // incorrect interactions with Gigaton Hammer, Blood Moon & Torment
|
// incorrect interactions with Gigaton Hammer, Blood Moon & Torment
|
||||||
|
// Also has incorrect interactions with Dancer due to the latter
|
||||||
|
// erroneously adding copied moves to move history.
|
||||||
|
.edgeCase(),
|
||||||
new AttackMove(Moves.BEAK_BLAST, Type.FLYING, MoveCategory.PHYSICAL, 100, 100, 15, -1, -3, 7)
|
new AttackMove(Moves.BEAK_BLAST, Type.FLYING, MoveCategory.PHYSICAL, 100, 100, 15, -1, -3, 7)
|
||||||
.attr(BeakBlastHeaderAttr)
|
.attr(BeakBlastHeaderAttr)
|
||||||
.ballBombMove()
|
.ballBombMove()
|
||||||
|
@ -4,6 +4,7 @@ import type {
|
|||||||
import {
|
import {
|
||||||
generateModifierType,
|
generateModifierType,
|
||||||
generateModifierTypeOption,
|
generateModifierTypeOption,
|
||||||
|
getRandomEncounterSpecies,
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
setEncounterExp,
|
setEncounterExp,
|
||||||
@ -11,17 +12,15 @@ import {
|
|||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { EnemyPokemon } from "#app/field/pokemon";
|
|
||||||
import type {
|
import type {
|
||||||
BerryModifierType,
|
BerryModifierType,
|
||||||
ModifierTypeOption } from "#app/modifier/modifier-type";
|
ModifierTypeOption } from "#app/modifier/modifier-type";
|
||||||
import {
|
import {
|
||||||
getPartyLuckValue,
|
|
||||||
ModifierPoolType,
|
ModifierPoolType,
|
||||||
modifierTypes,
|
modifierTypes,
|
||||||
regenerateModifierPoolThresholds,
|
regenerateModifierPoolThresholds,
|
||||||
} from "#app/modifier/modifier-type";
|
} from "#app/modifier/modifier-type";
|
||||||
import { randSeedInt, randSeedItem } from "#app/utils";
|
import { randSeedInt } from "#app/utils";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
@ -31,7 +30,6 @@ import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-enco
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
|
||||||
import { applyModifierTypeToPlayerPokemon, getEncounterPokemonLevelForWave, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { applyModifierTypeToPlayerPokemon, getEncounterPokemonLevelForWave, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { BerryModifier } from "#app/modifier/modifier";
|
import { BerryModifier } from "#app/modifier/modifier";
|
||||||
@ -40,8 +38,6 @@ import { BerryType } from "#enums/berry-type";
|
|||||||
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/berriesAbound";
|
const namespace = "mysteryEncounters/berriesAbound";
|
||||||
@ -69,20 +65,12 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||||
let bossSpecies: PokemonSpecies;
|
const bossPokemon = getRandomEncounterSpecies(level, true);
|
||||||
if (globalScene.eventManager.isEventActive() && globalScene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
|
|
||||||
const eventEncounter = randSeedItem(globalScene.eventManager.activeEvent()!.uncommonBreedEncounters!);
|
|
||||||
const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, globalScene.gameMode);
|
|
||||||
bossSpecies = getPokemonSpecies( levelSpecies );
|
|
||||||
} else {
|
|
||||||
bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getPlayerParty()), true);
|
|
||||||
}
|
|
||||||
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
|
|
||||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
level: level,
|
level: level,
|
||||||
species: bossSpecies,
|
species: bossPokemon.species,
|
||||||
dataSource: new PokemonData(bossPokemon),
|
dataSource: new PokemonData(bossPokemon),
|
||||||
isBoss: true
|
isBoss: true
|
||||||
}],
|
}],
|
||||||
|
@ -41,7 +41,7 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
|||||||
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 2;
|
||||||
|
|
||||||
const doEventReward = () => {
|
const doEventReward = () => {
|
||||||
const event_buff = globalScene.eventManager.activeEvent()?.delibirdyBuff ?? [];
|
const event_buff = globalScene.eventManager.getDelibirdyBuff();
|
||||||
if (event_buff.length > 0) {
|
if (event_buff.length > 0) {
|
||||||
const candidates = event_buff.filter((c => {
|
const candidates = event_buff.filter((c => {
|
||||||
const mtype = generateModifierType(modifierTypes[c]);
|
const mtype = generateModifierType(modifierTypes[c]);
|
||||||
|
@ -2,6 +2,7 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/myst
|
|||||||
import type {
|
import type {
|
||||||
EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import {
|
import {
|
||||||
|
getRandomEncounterSpecies,
|
||||||
initBattleWithEnemyConfig,
|
initBattleWithEnemyConfig,
|
||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
setEncounterExp,
|
setEncounterExp,
|
||||||
@ -9,12 +10,10 @@ import {
|
|||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { EnemyPokemon } from "#app/field/pokemon";
|
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import type {
|
import type {
|
||||||
ModifierTypeOption } from "#app/modifier/modifier-type";
|
ModifierTypeOption } from "#app/modifier/modifier-type";
|
||||||
import {
|
import {
|
||||||
getPartyLuckValue,
|
|
||||||
getPlayerModifierTypeOptions,
|
getPlayerModifierTypeOptions,
|
||||||
ModifierPoolType,
|
ModifierPoolType,
|
||||||
regenerateModifierPoolThresholds,
|
regenerateModifierPoolThresholds,
|
||||||
@ -26,16 +25,13 @@ import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-en
|
|||||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
|
||||||
import { getEncounterPokemonLevelForWave, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getEncounterPokemonLevelForWave, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { randSeedInt, randSeedItem } from "#app/utils";
|
import { randSeedInt } from "#app/utils";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/fightOrFlight";
|
const namespace = "mysteryEncounters/fightOrFlight";
|
||||||
@ -63,20 +59,12 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
const level = getEncounterPokemonLevelForWave(STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
|
||||||
let bossSpecies: PokemonSpecies;
|
const bossPokemon = getRandomEncounterSpecies(level, true);
|
||||||
if (globalScene.eventManager.isEventActive() && globalScene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
|
|
||||||
const eventEncounter = randSeedItem(globalScene.eventManager.activeEvent()!.uncommonBreedEncounters!);
|
|
||||||
const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, globalScene.gameMode);
|
|
||||||
bossSpecies = getPokemonSpecies( levelSpecies );
|
|
||||||
} else {
|
|
||||||
bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getPlayerParty()), true);
|
|
||||||
}
|
|
||||||
const bossPokemon = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, true);
|
|
||||||
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
|
encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender());
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
level: level,
|
level: level,
|
||||||
species: bossSpecies,
|
species: bossPokemon.species,
|
||||||
dataSource: new PokemonData(bossPokemon),
|
dataSource: new PokemonData(bossPokemon),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
|
@ -449,7 +449,7 @@ function getPokemonTradeOptions(): Map<number, EnemyPokemon[]> {
|
|||||||
});
|
});
|
||||||
tradeOptionsMap.set(pokemon.id, tradeOptions);
|
tradeOptionsMap.set(pokemon.id, tradeOptions);
|
||||||
} else {
|
} else {
|
||||||
const originalBst = pokemon.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const originalBst = pokemon.getSpeciesForm().getBaseStatTotal();
|
||||||
|
|
||||||
const tradeOptions: PokemonSpecies[] = [];
|
const tradeOptions: PokemonSpecies[] = [];
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
|
@ -452,7 +452,7 @@ function getSpeciesFromPool(speciesPool: (Species | BreederSpeciesEvolution)[][]
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number] {
|
function calculateEggRewardsForPokemon(pokemon: PlayerPokemon): [number, number] {
|
||||||
const bst = pokemon.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const bst = pokemon.getSpeciesForm().getBaseStatTotal();
|
||||||
// 1 point for every 20 points below 680 BST the pokemon is, (max 18, min 1)
|
// 1 point for every 20 points below 680 BST the pokemon is, (max 18, min 1)
|
||||||
const pointsFromBst = Math.min(Math.max(Math.floor((680 - bst) / 20), 1), 18);
|
const pointsFromBst = Math.min(Math.max(Math.floor((680 - bst) / 20), 1), 18);
|
||||||
|
|
||||||
|
@ -147,8 +147,8 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
// Sort party by bst
|
// Sort party by bst
|
||||||
const sortedParty = globalScene.getPlayerParty().slice(0)
|
const sortedParty = globalScene.getPlayerParty().slice(0)
|
||||||
.sort((pokemon1, pokemon2) => {
|
.sort((pokemon1, pokemon2) => {
|
||||||
const pokemon1Bst = pokemon1.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const pokemon1Bst = pokemon1.getSpeciesForm().getBaseStatTotal();
|
||||||
const pokemon2Bst = pokemon2.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const pokemon2Bst = pokemon2.getSpeciesForm().getBaseStatTotal();
|
||||||
return pokemon2Bst - pokemon1Bst;
|
return pokemon2Bst - pokemon1Bst;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import { Nature } from "#enums/nature";
|
|||||||
import { Type } from "#enums/type";
|
import { Type } from "#enums/type";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { SpeciesFormChangeManualTrigger } from "#app/data/pokemon-forms";
|
import { SpeciesFormChangeAbilityTrigger } from "#app/data/pokemon-forms";
|
||||||
import { applyPostBattleInitAbAttrs, PostBattleInitAbAttr } from "#app/data/ability";
|
import { applyPostBattleInitAbAttrs, PostBattleInitAbAttr } from "#app/data/ability";
|
||||||
import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
@ -198,7 +198,7 @@ function endTrainerBattleAndShowDialogue(): Promise<void> {
|
|||||||
// Only trigger form change when Eiscue is in Noice form
|
// Only trigger form change when Eiscue is in Noice form
|
||||||
// Hardcoded Eiscue for now in case it is fused with another pokemon
|
// Hardcoded Eiscue for now in case it is fused with another pokemon
|
||||||
if (pokemon.species.speciesId === Species.EISCUE && pokemon.hasAbility(Abilities.ICE_FACE) && pokemon.formIndex === 1) {
|
if (pokemon.species.speciesId === Species.EISCUE && pokemon.hasAbility(Abilities.ICE_FACE) && pokemon.formIndex === 1) {
|
||||||
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger);
|
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeAbilityTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon.resetBattleData();
|
pokemon.resetBattleData();
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import type { EnemyPartyConfig } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { getRandomEncounterSpecies, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { CHARMING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
import { CHARMING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
import type { EnemyPokemon } from "#app/field/pokemon";
|
||||||
import { getPartyLuckValue } from "#app/modifier/modifier-type";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
@ -12,10 +12,9 @@ import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-en
|
|||||||
import { MoveRequirement, PersistentModifierRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
import { MoveRequirement, PersistentModifierRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
|
||||||
import { catchPokemon, getHighestLevelPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { catchPokemon, getHighestLevelPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { isNullOrUndefined, randSeedInt, randSeedItem } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import type { Moves } from "#enums/moves";
|
import type { Moves } from "#enums/moves";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { SelfStatusMove } from "#app/data/move";
|
import { SelfStatusMove } from "#app/data/move";
|
||||||
@ -26,8 +25,6 @@ import { BerryModifier } from "#app/modifier/modifier";
|
|||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/uncommonBreed";
|
const namespace = "mysteryEncounters/uncommonBreed";
|
||||||
@ -56,15 +53,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
// Level equal to 2 below highest party member
|
// Level equal to 2 below highest party member
|
||||||
const level = getHighestLevelPlayerPokemon(false, true).level - 2;
|
const level = getHighestLevelPlayerPokemon(false, true).level - 2;
|
||||||
let species: PokemonSpecies;
|
const pokemon = getRandomEncounterSpecies(level, true, true);
|
||||||
if (globalScene.eventManager.isEventActive() && globalScene.eventManager.activeEvent()?.uncommonBreedEncounters && randSeedInt(2) === 1) {
|
|
||||||
const eventEncounter = randSeedItem(globalScene.eventManager.activeEvent()!.uncommonBreedEncounters!);
|
|
||||||
const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, eventEncounter.allowEvolution ?? false, true, globalScene.gameMode);
|
|
||||||
species = getPokemonSpecies( levelSpecies );
|
|
||||||
} else {
|
|
||||||
species = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getPlayerParty()), true);
|
|
||||||
}
|
|
||||||
const pokemon = new EnemyPokemon(species, level, TrainerSlot.NONE, true);
|
|
||||||
|
|
||||||
// Pokemon will always have one of its egg moves in its moveset
|
// Pokemon will always have one of its egg moves in its moveset
|
||||||
const eggMoves = pokemon.getEggMoves();
|
const eggMoves = pokemon.getEggMoves();
|
||||||
@ -92,7 +81,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
|
|||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
level: level,
|
level: level,
|
||||||
species: species,
|
species: pokemon.species,
|
||||||
dataSource: new PokemonData(pokemon),
|
dataSource: new PokemonData(pokemon),
|
||||||
isBoss: false,
|
isBoss: false,
|
||||||
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
tags: [ BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON ],
|
||||||
|
@ -360,7 +360,7 @@ function getTeamTransformations(): PokemonTransformation[] {
|
|||||||
const index = pokemonTransformations.findIndex(p => p.previousPokemon.id === removed.id);
|
const index = pokemonTransformations.findIndex(p => p.previousPokemon.id === removed.id);
|
||||||
pokemonTransformations[index].heldItems = removed.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier));
|
pokemonTransformations[index].heldItems = removed.getHeldItems().filter(m => !(m instanceof PokemonFormChangeItemModifier));
|
||||||
|
|
||||||
const bst = removed.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const bst = removed.getSpeciesForm().getBaseStatTotal();
|
||||||
let newBstRange: [number, number];
|
let newBstRange: [number, number];
|
||||||
if (i < 2) {
|
if (i < 2) {
|
||||||
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
||||||
|
@ -6,9 +6,9 @@ import { AVERAGE_ENCOUNTERS_PER_RUN_TARGET, WEIGHT_INCREMENT_ON_SPAWN_MISS } fro
|
|||||||
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import type { AiType, PlayerPokemon } from "#app/field/pokemon";
|
import type { AiType, PlayerPokemon } from "#app/field/pokemon";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { FieldPosition, PokemonMove, PokemonSummonData } from "#app/field/pokemon";
|
import { EnemyPokemon, FieldPosition, PokemonMove, PokemonSummonData } from "#app/field/pokemon";
|
||||||
import type { CustomModifierSettings, ModifierType } from "#app/modifier/modifier-type";
|
import type { CustomModifierSettings, ModifierType } from "#app/modifier/modifier-type";
|
||||||
import { ModifierPoolType, ModifierTypeGenerator, ModifierTypeOption, modifierTypes, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type";
|
import { getPartyLuckValue, ModifierPoolType, ModifierTypeGenerator, ModifierTypeOption, modifierTypes, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type";
|
||||||
import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
||||||
import type PokemonData from "#app/system/pokemon-data";
|
import type PokemonData from "#app/system/pokemon-data";
|
||||||
import type { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
import type { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
@ -16,7 +16,7 @@ import type { PartyOption, PokemonSelectFilter } from "#app/ui/party-ui-handler"
|
|||||||
import { PartyUiMode } from "#app/ui/party-ui-handler";
|
import { PartyUiMode } from "#app/ui/party-ui-handler";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt, randSeedItem } from "#app/utils";
|
||||||
import type { BattlerTagType } from "#enums/battler-tag-type";
|
import type { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { Biome } from "#enums/biome";
|
import { Biome } from "#enums/biome";
|
||||||
import type { TrainerType } from "#enums/trainer-type";
|
import type { TrainerType } from "#enums/trainer-type";
|
||||||
@ -45,6 +45,7 @@ import { PartyExpPhase } from "#app/phases/party-exp-phase";
|
|||||||
import type { Variant } from "#app/data/variant";
|
import type { Variant } from "#app/data/variant";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animates exclamation sprite over trainer's head at start of encounter
|
* Animates exclamation sprite over trainer's head at start of encounter
|
||||||
@ -874,6 +875,41 @@ export function handleMysteryEncounterTurnStartEffects(): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 {@linkcode EnemyPokemon} for the requested encounter
|
||||||
|
*/
|
||||||
|
export function getRandomEncounterSpecies(level: number, isBoss: boolean = false, rerollHidden: boolean = false): EnemyPokemon {
|
||||||
|
let bossSpecies: PokemonSpecies;
|
||||||
|
let isEventEncounter = false;
|
||||||
|
const eventEncounters = globalScene.eventManager.getEventEncounters();
|
||||||
|
|
||||||
|
if (eventEncounters.length > 0 && randSeedInt(2) === 1) {
|
||||||
|
const eventEncounter = randSeedItem(eventEncounters);
|
||||||
|
const levelSpecies = getPokemonSpecies(eventEncounter.species).getWildSpeciesForLevel(level, !eventEncounter.blockEvolution, isBoss, globalScene.gameMode);
|
||||||
|
isEventEncounter = true;
|
||||||
|
bossSpecies = getPokemonSpecies(levelSpecies);
|
||||||
|
} else {
|
||||||
|
bossSpecies = globalScene.arena.randomSpecies(globalScene.currentBattle.waveIndex, level, 0, getPartyLuckValue(globalScene.getPlayerParty()), isBoss);
|
||||||
|
}
|
||||||
|
const ret = new EnemyPokemon(bossSpecies, level, TrainerSlot.NONE, isBoss);
|
||||||
|
|
||||||
|
//Reroll shiny for event encounters
|
||||||
|
if (isEventEncounter && !ret.shiny) {
|
||||||
|
ret.trySetShinySeed();
|
||||||
|
}
|
||||||
|
//Reroll hidden ability
|
||||||
|
if (rerollHidden && ret.abilityIndex !== 2 && ret.species.abilityHidden) {
|
||||||
|
ret.tryRerollHiddenAbilitySeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: remove once encounter spawn rate is finalized
|
* TODO: remove once encounter spawn rate is finalized
|
||||||
* Just a helper function to calculate aggregate stats for MEs in a Classic run
|
* Just a helper function to calculate aggregate stats for MEs in a Classic run
|
||||||
|
@ -212,6 +212,8 @@ export class SpeciesFormChangeCondition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export abstract class SpeciesFormChangeTrigger {
|
export abstract class SpeciesFormChangeTrigger {
|
||||||
|
public description: string = "";
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -222,16 +224,19 @@ export abstract class SpeciesFormChangeTrigger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SpeciesFormChangeManualTrigger extends SpeciesFormChangeTrigger {
|
export class SpeciesFormChangeManualTrigger extends SpeciesFormChangeTrigger {
|
||||||
canChange(pokemon: Pokemon): boolean {
|
}
|
||||||
return true;
|
|
||||||
}
|
export class SpeciesFormChangeAbilityTrigger extends SpeciesFormChangeTrigger {
|
||||||
|
public description: string = i18next.t("pokemonEvolutions:Forms.ability");
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SpeciesFormChangeCompoundTrigger {
|
export class SpeciesFormChangeCompoundTrigger {
|
||||||
|
public description: string = "";
|
||||||
public triggers: SpeciesFormChangeTrigger[];
|
public triggers: SpeciesFormChangeTrigger[];
|
||||||
|
|
||||||
constructor(...triggers: SpeciesFormChangeTrigger[]) {
|
constructor(...triggers: SpeciesFormChangeTrigger[]) {
|
||||||
this.triggers = triggers;
|
this.triggers = triggers;
|
||||||
|
this.description = this.triggers.filter(trigger => trigger?.description?.length > 0).map(trigger => trigger.description).join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -257,6 +262,9 @@ export class SpeciesFormChangeItemTrigger extends SpeciesFormChangeTrigger {
|
|||||||
super();
|
super();
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.active = active;
|
this.active = active;
|
||||||
|
this.description = this.active ?
|
||||||
|
i18next.t("pokemonEvolutions:Forms.item", { item: i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.item]}`) }) :
|
||||||
|
i18next.t("pokemonEvolutions:Forms.deactivateItem", { item: i18next.t(`modifierType:FormChangeItem.${FormChangeItem[this.item]}`) });
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -270,6 +278,7 @@ export class SpeciesFormChangeTimeOfDayTrigger extends SpeciesFormChangeTrigger
|
|||||||
constructor(...timesOfDay: TimeOfDay[]) {
|
constructor(...timesOfDay: TimeOfDay[]) {
|
||||||
super();
|
super();
|
||||||
this.timesOfDay = timesOfDay;
|
this.timesOfDay = timesOfDay;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.timeOfDay");
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -283,6 +292,7 @@ export class SpeciesFormChangeActiveTrigger extends SpeciesFormChangeTrigger {
|
|||||||
constructor(active: boolean = false) {
|
constructor(active: boolean = false) {
|
||||||
super();
|
super();
|
||||||
this.active = active;
|
this.active = active;
|
||||||
|
this.description = this.active ? i18next.t("pokemonEvolutions:Forms.enter") : i18next.t("pokemonEvolutions:Forms.leave");
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -301,6 +311,7 @@ export class SpeciesFormChangeStatusEffectTrigger extends SpeciesFormChangeTrigg
|
|||||||
}
|
}
|
||||||
this.statusEffects = statusEffects;
|
this.statusEffects = statusEffects;
|
||||||
this.invert = invert;
|
this.invert = invert;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.statusEffect");
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -316,6 +327,8 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
|
|||||||
super();
|
super();
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.known = known;
|
this.known = known;
|
||||||
|
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.moveLearned", { move: i18next.t(`move:${moveKey}.name`) });
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -335,6 +348,8 @@ export abstract class SpeciesFormChangeMoveTrigger extends SpeciesFormChangeTrig
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigger {
|
export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigger {
|
||||||
|
description = i18next.t("pokemonEvolutions:Forms.preMove");
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
const command = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
|
const command = globalScene.currentBattle.turnCommands[pokemon.getBattlerIndex()];
|
||||||
return !!command?.move && this.movePredicate(command.move.move) === this.used;
|
return !!command?.move && this.movePredicate(command.move.move) === this.used;
|
||||||
@ -342,6 +357,8 @@ export class SpeciesFormChangePreMoveTrigger extends SpeciesFormChangeMoveTrigge
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigger {
|
export class SpeciesFormChangePostMoveTrigger extends SpeciesFormChangeMoveTrigger {
|
||||||
|
description = i18next.t("pokemonEvolutions:Forms.postMove");
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
return pokemon.summonData && !!pokemon.getLastXMoves(1).filter(m => this.movePredicate(m.move)).length === this.used;
|
return pokemon.summonData && !!pokemon.getLastXMoves(1).filter(m => this.movePredicate(m.move)).length === this.used;
|
||||||
}
|
}
|
||||||
@ -367,6 +384,7 @@ export class SpeciesDefaultFormMatchTrigger extends SpeciesFormChangeTrigger {
|
|||||||
constructor(formKey: string) {
|
constructor(formKey: string) {
|
||||||
super();
|
super();
|
||||||
this.formKey = formKey;
|
this.formKey = formKey;
|
||||||
|
this.description = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
@ -386,6 +404,7 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
|
|||||||
constructor(teraType: Type) {
|
constructor(teraType: Type) {
|
||||||
super();
|
super();
|
||||||
this.teraType = teraType;
|
this.teraType = teraType;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.tera", { teraType: i18next.t(`pokemonInfo:Type.${Type[this.teraType]}`) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -404,6 +423,8 @@ export class SpeciesFormChangeTeraTrigger extends SpeciesFormChangeTrigger {
|
|||||||
* @extends SpeciesFormChangeTrigger
|
* @extends SpeciesFormChangeTrigger
|
||||||
*/
|
*/
|
||||||
export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger {
|
export class SpeciesFormChangeLapseTeraTrigger extends SpeciesFormChangeTrigger {
|
||||||
|
description = i18next.t("pokemonEvolutions:Forms.teraLapse");
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id);
|
return !!globalScene.findModifier(m => m instanceof TerastallizeModifier && m.pokemonId === pokemon.id);
|
||||||
}
|
}
|
||||||
@ -424,6 +445,7 @@ export class SpeciesFormChangeWeatherTrigger extends SpeciesFormChangeTrigger {
|
|||||||
super();
|
super();
|
||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
this.weathers = weathers;
|
this.weathers = weathers;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.weather");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -457,6 +479,7 @@ export class SpeciesFormChangeRevertWeatherFormTrigger extends SpeciesFormChange
|
|||||||
super();
|
super();
|
||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
this.weathers = weathers;
|
this.weathers = weathers;
|
||||||
|
this.description = i18next.t("pokemonEvolutions:Forms.weatherRevert");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -751,8 +774,8 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE))
|
new SpeciesFormChange(Species.ARCEUS, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.PIXIE_PLATE))
|
||||||
],
|
],
|
||||||
[Species.DARMANITAN]: [
|
[Species.DARMANITAN]: [
|
||||||
new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.DARMANITAN, "zen", "", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.GARBODOR]: [
|
[Species.GARBODOR]: [
|
||||||
new SpeciesFormChange(Species.GARBODOR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
new SpeciesFormChange(Species.GARBODOR, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
||||||
@ -785,12 +808,12 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.GENESECT, "", "douse", new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE))
|
new SpeciesFormChange(Species.GENESECT, "", "douse", new SpeciesFormChangeItemTrigger(FormChangeItem.DOUSE_DRIVE))
|
||||||
],
|
],
|
||||||
[Species.GRENINJA]: [
|
[Species.GRENINJA]: [
|
||||||
new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.GRENINJA, "battle-bond", "ash", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.GRENINJA, "ash", "battle-bond", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.PALAFIN] : [
|
[Species.PALAFIN] : [
|
||||||
new SpeciesFormChange(Species.PALAFIN, "zero", "hero", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.PALAFIN, "zero", "hero", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.PALAFIN, "hero", "zero", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.AEGISLASH]: [
|
[Species.AEGISLASH]: [
|
||||||
new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))),
|
new SpeciesFormChange(Species.AEGISLASH, "blade", "shield", new SpeciesFormChangePreMoveTrigger(Moves.KINGS_SHIELD), true, new SpeciesFormChangeCondition(p => p.hasAbility(Abilities.STANCE_CHANGE))),
|
||||||
@ -802,10 +825,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.XERNEAS, "active", "neutral", new SpeciesFormChangeActiveTrigger(false), true)
|
new SpeciesFormChange(Species.XERNEAS, "active", "neutral", new SpeciesFormChangeActiveTrigger(false), true)
|
||||||
],
|
],
|
||||||
[Species.ZYGARDE]: [
|
[Species.ZYGARDE]: [
|
||||||
new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.ZYGARDE, "50-pc", "complete", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.ZYGARDE, "complete", "50-pc", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.ZYGARDE, "10-pc", "10-complete", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.ZYGARDE, "10-pc", "10-complete", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.ZYGARDE, "10-complete", "10-pc", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.ZYGARDE, "10-complete", "10-pc", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.DIANCIE]: [
|
[Species.DIANCIE]: [
|
||||||
new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
|
new SpeciesFormChange(Species.DIANCIE, "", SpeciesFormKey.MEGA, new SpeciesFormChangeItemTrigger(FormChangeItem.DIANCITE))
|
||||||
@ -814,8 +837,8 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.HOOPA, "", "unbound", new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE))
|
new SpeciesFormChange(Species.HOOPA, "", "unbound", new SpeciesFormChangeItemTrigger(FormChangeItem.PRISON_BOTTLE))
|
||||||
],
|
],
|
||||||
[Species.WISHIWASHI]: [
|
[Species.WISHIWASHI]: [
|
||||||
new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.WISHIWASHI, "", "school", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.WISHIWASHI, "school", "", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.SILVALLY]: [
|
[Species.SILVALLY]: [
|
||||||
new SpeciesFormChange(Species.SILVALLY, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)),
|
new SpeciesFormChange(Species.SILVALLY, "normal", "fighting", new SpeciesFormChangeItemTrigger(FormChangeItem.FIGHTING_MEMORY)),
|
||||||
@ -837,24 +860,24 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY))
|
new SpeciesFormChange(Species.SILVALLY, "normal", "fairy", new SpeciesFormChangeItemTrigger(FormChangeItem.FAIRY_MEMORY))
|
||||||
],
|
],
|
||||||
[Species.MINIOR]: [
|
[Species.MINIOR]: [
|
||||||
new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "red-meteor", "red", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "red", "red-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "orange-meteor", "orange", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "orange-meteor", "orange", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "orange", "orange-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "orange", "orange-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "yellow-meteor", "yellow", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "yellow-meteor", "yellow", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "yellow", "yellow-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "yellow", "yellow-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "green-meteor", "green", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "green-meteor", "green", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "green", "green-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "green", "green-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "blue-meteor", "blue", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "blue-meteor", "blue", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "blue", "blue-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "blue", "blue-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "indigo-meteor", "indigo", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "indigo-meteor", "indigo", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "indigo", "indigo-meteor", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "indigo", "indigo-meteor", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MINIOR, "violet-meteor", "violet", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.MINIOR, "violet", "violet-meteor", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.MIMIKYU]: [
|
[Species.MIMIKYU]: [
|
||||||
new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MIMIKYU, "disguised", "busted", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.MIMIKYU, "busted", "disguised", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.NECROZMA]: [
|
[Species.NECROZMA]: [
|
||||||
new SpeciesFormChange(Species.NECROZMA, "", "dawn-wings", new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER), false, getSpeciesDependentFormChangeCondition(Species.LUNALA)),
|
new SpeciesFormChange(Species.NECROZMA, "", "dawn-wings", new SpeciesFormChangeItemTrigger(FormChangeItem.N_LUNARIZER), false, getSpeciesDependentFormChangeCondition(Species.LUNALA)),
|
||||||
@ -896,10 +919,10 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.SANDACONDA, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
new SpeciesFormChange(Species.SANDACONDA, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
||||||
],
|
],
|
||||||
[Species.CRAMORANT]: [
|
[Species.CRAMORANT]: [
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "", "gulping", new SpeciesFormChangeManualTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() >= .5)),
|
new SpeciesFormChange(Species.CRAMORANT, "", "gulping", new SpeciesFormChangeAbilityTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() >= .5)),
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "", "gorging", new SpeciesFormChangeManualTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() < .5)),
|
new SpeciesFormChange(Species.CRAMORANT, "", "gorging", new SpeciesFormChangeAbilityTrigger, true, new SpeciesFormChangeCondition(p => p.getHpRatio() < .5)),
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeManualTrigger, true),
|
new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeAbilityTrigger, true),
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeManualTrigger, true),
|
new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeAbilityTrigger, true),
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeActiveTrigger(false), true),
|
new SpeciesFormChange(Species.CRAMORANT, "gulping", "", new SpeciesFormChangeActiveTrigger(false), true),
|
||||||
new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeActiveTrigger(false), true)
|
new SpeciesFormChange(Species.CRAMORANT, "gorging", "", new SpeciesFormChangeActiveTrigger(false), true)
|
||||||
],
|
],
|
||||||
@ -930,12 +953,12 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.ALCREMIE, "rainbow-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
new SpeciesFormChange(Species.ALCREMIE, "rainbow-swirl", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
||||||
],
|
],
|
||||||
[Species.EISCUE]: [
|
[Species.EISCUE]: [
|
||||||
new SpeciesFormChange(Species.EISCUE, "", "no-ice", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.EISCUE, "", "no-ice", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.EISCUE, "no-ice", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.EISCUE, "no-ice", "", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.MORPEKO]: [
|
[Species.MORPEKO]: [
|
||||||
new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.MORPEKO, "full-belly", "hangry", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.MORPEKO, "hangry", "full-belly", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
[Species.COPPERAJAH]: [
|
[Species.COPPERAJAH]: [
|
||||||
new SpeciesFormChange(Species.COPPERAJAH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
new SpeciesFormChange(Species.COPPERAJAH, "", SpeciesFormKey.GIGANTAMAX, new SpeciesFormChangeItemTrigger(FormChangeItem.MAX_MUSHROOMS))
|
||||||
@ -978,13 +1001,13 @@ export const pokemonFormChanges: PokemonFormChanges = {
|
|||||||
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.ROCK))
|
new SpeciesFormChange(Species.OGERPON, "cornerstone-mask-tera", "cornerstone-mask", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.ROCK))
|
||||||
],
|
],
|
||||||
[Species.TERAPAGOS]: [
|
[Species.TERAPAGOS]: [
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.TERAPAGOS, "", "terastal", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(Type.STELLAR)),
|
new SpeciesFormChange(Species.TERAPAGOS, "terastal", "stellar", new SpeciesFormChangeTeraTrigger(Type.STELLAR)),
|
||||||
new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.STELLAR))
|
new SpeciesFormChange(Species.TERAPAGOS, "stellar", "terastal", new SpeciesFormChangeLapseTeraTrigger(), true, new SpeciesFormChangeCondition(p => p.getTeraType() !== Type.STELLAR))
|
||||||
],
|
],
|
||||||
[Species.GALAR_DARMANITAN]: [
|
[Species.GALAR_DARMANITAN]: [
|
||||||
new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeManualTrigger(), true),
|
new SpeciesFormChange(Species.GALAR_DARMANITAN, "", "zen", new SpeciesFormChangeAbilityTrigger(), true),
|
||||||
new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeManualTrigger(), true)
|
new SpeciesFormChange(Species.GALAR_DARMANITAN, "zen", "", new SpeciesFormChangeAbilityTrigger(), true)
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1002,3 +1025,4 @@ export function initPokemonForms() {
|
|||||||
formChanges.push(...newFormChanges);
|
formChanges.push(...newFormChanges);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import type { Variant, VariantSet } from "#app/data/variant";
|
|||||||
import { variantData } from "#app/data/variant";
|
import { variantData } from "#app/data/variant";
|
||||||
import { speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
import { speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
|
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
||||||
|
|
||||||
export enum Region {
|
export enum Region {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
@ -230,6 +231,31 @@ export abstract class PokemonSpeciesForm {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the passive ability of a Pokemon species
|
||||||
|
* @param formIndex The form index to use, defaults to form for this species instance
|
||||||
|
* @returns The id of the ability
|
||||||
|
*/
|
||||||
|
getPassiveAbility(formIndex?: number): Abilities {
|
||||||
|
if (Utils.isNullOrUndefined(formIndex)) {
|
||||||
|
formIndex = this.formIndex;
|
||||||
|
}
|
||||||
|
let starterSpeciesId = this.speciesId;
|
||||||
|
while (!(starterSpeciesId in starterPassiveAbilities) || !(formIndex in starterPassiveAbilities[starterSpeciesId])) {
|
||||||
|
if (pokemonPrevolutions.hasOwnProperty(starterSpeciesId)) {
|
||||||
|
starterSpeciesId = pokemonPrevolutions[starterSpeciesId];
|
||||||
|
} else { // If we've reached the base species and still haven't found a matching ability, use form 0 if possible
|
||||||
|
if (0 in starterPassiveAbilities[starterSpeciesId]) {
|
||||||
|
return starterPassiveAbilities[starterSpeciesId][0];
|
||||||
|
} else {
|
||||||
|
console.log("No passive ability found for %s, using run away", this.speciesId);
|
||||||
|
return Abilities.RUN_AWAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return starterPassiveAbilities[starterSpeciesId][formIndex];
|
||||||
|
}
|
||||||
|
|
||||||
getLevelMoves(): LevelMoves {
|
getLevelMoves(): LevelMoves {
|
||||||
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
|
if (pokemonSpeciesFormLevelMoves.hasOwnProperty(this.speciesId) && pokemonSpeciesFormLevelMoves[this.speciesId].hasOwnProperty(this.formIndex)) {
|
||||||
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0);
|
return pokemonSpeciesFormLevelMoves[this.speciesId][this.formIndex].slice(0);
|
||||||
|
@ -162,7 +162,7 @@ export function getNonVolatileStatusEffects():Array<StatusEffect> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a statuss effect is non volatile.
|
* Returns whether a status effect is non volatile.
|
||||||
* Non-volatile status condition is a status that remains after being switched out.
|
* Non-volatile status condition is a status that remains after being switched out.
|
||||||
* @param status The status to check
|
* @param status The status to check
|
||||||
*/
|
*/
|
||||||
|
@ -375,8 +375,8 @@ export function getRandomWeatherType(arena: Arena): WeatherType {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arena.biomeType === Biome.TOWN && globalScene.eventManager.isEventActive() && (globalScene.eventManager.activeEvent()?.weather?.length ?? 0) > 0) {
|
if (arena.biomeType === Biome.TOWN && globalScene.eventManager.isEventActive()) {
|
||||||
globalScene.eventManager.activeEvent()?.weather?.map(w => weatherPool.push(w));
|
globalScene.eventManager.getWeather()?.map(w => weatherPool.push(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (weatherPool.length > 1) {
|
if (weatherPool.length > 1) {
|
||||||
|
@ -695,6 +695,7 @@ export class Arena {
|
|||||||
globalScene.loadBgm(this.bgm);
|
globalScene.loadBgm(this.bgm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The loop point of any given biome track, read as seconds and milliseconds. */
|
||||||
getBgmLoopPoint(): number {
|
getBgmLoopPoint(): number {
|
||||||
switch (this.biomeType) {
|
switch (this.biomeType) {
|
||||||
case Biome.TOWN:
|
case Biome.TOWN:
|
||||||
|
@ -10,8 +10,7 @@ import type Move from "#app/data/move";
|
|||||||
import { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr, VariableMoveTypeChartAttr } from "#app/data/move";
|
import { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr, MoveTarget, CombinedPledgeStabBoostAttr, VariableMoveTypeChartAttr } from "#app/data/move";
|
||||||
import type { PokemonSpeciesForm } from "#app/data/pokemon-species";
|
import type { PokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
import { default as PokemonSpecies, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
import { default as PokemonSpecies, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER, getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
import { getStarterValueFriendshipCap, speciesStarterCosts } from "#app/data/balance/starters";
|
||||||
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
|
||||||
import type { Constructor } from "#app/utils";
|
import type { Constructor } from "#app/utils";
|
||||||
import { isNullOrUndefined, randSeedInt, type nil } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt, type nil } from "#app/utils";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
@ -1108,6 +1107,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return this.getStat(Stat.HP);
|
return this.getStat(Stat.HP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the amount of hp currently missing from this {@linkcode Pokemon} (max - current) */
|
||||||
getInverseHp(): integer {
|
getInverseHp(): integer {
|
||||||
return this.getMaxHp() - this.hp;
|
return this.getMaxHp() - this.hp;
|
||||||
}
|
}
|
||||||
@ -1400,11 +1400,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
return allAbilities[this.customPokemonData.passive];
|
return allAbilities[this.customPokemonData.passive];
|
||||||
}
|
}
|
||||||
|
|
||||||
let starterSpeciesId = this.species.speciesId;
|
return allAbilities[this.species.getPassiveAbility(this.formIndex)];
|
||||||
while (pokemonPrevolutions.hasOwnProperty(starterSpeciesId)) {
|
|
||||||
starterSpeciesId = pokemonPrevolutions[starterSpeciesId];
|
|
||||||
}
|
|
||||||
return allAbilities[starterPassiveAbilities[starterSpeciesId]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1955,7 +1951,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
* @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 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)
|
||||||
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
* @returns true if the Pokemon has been set as a shiny, false otherwise
|
||||||
*/
|
*/
|
||||||
trySetShiny(thresholdOverride?: integer): boolean {
|
trySetShiny(thresholdOverride?: number): boolean {
|
||||||
// Shiny Pokemon should not spawn in the end biome in endless
|
// Shiny Pokemon should not spawn in the end biome in endless
|
||||||
if (globalScene.gameMode.isEndless && globalScene.arena.biomeType === Biome.END) {
|
if (globalScene.gameMode.isEndless && globalScene.arena.biomeType === Biome.END) {
|
||||||
return false;
|
return false;
|
||||||
@ -1967,7 +1963,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
const E = globalScene.gameData.trainerId ^ globalScene.gameData.secretId;
|
const E = globalScene.gameData.trainerId ^ globalScene.gameData.secretId;
|
||||||
const F = rand1 ^ rand2;
|
const F = rand1 ^ rand2;
|
||||||
|
|
||||||
const shinyThreshold = new Utils.IntegerHolder(BASE_SHINY_CHANCE);
|
const shinyThreshold = new Utils.NumberHolder(BASE_SHINY_CHANCE);
|
||||||
if (thresholdOverride === undefined) {
|
if (thresholdOverride === undefined) {
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
if (globalScene.eventManager.isEventActive()) {
|
||||||
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
|
shinyThreshold.value *= globalScene.eventManager.getShinyMultiplier();
|
||||||
@ -2058,6 +2054,38 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that tries to set a Pokemon to have its hidden ability based on seed, if it exists.
|
||||||
|
* For manual use only, usually to roll a Pokemon's hidden ability chance a second time.
|
||||||
|
*
|
||||||
|
* The base hidden ability odds are {@linkcode BASE_HIDDEN_ABILITY_CHANCE} / `65536`
|
||||||
|
* @param thresholdOverride number that is divided by `2^16` (`65536`) to get the HA chance, overrides {@linkcode haThreshold} if set (bypassing HA rate modifiers such as Ability Charm)
|
||||||
|
* @param applyModifiersToOverride If {@linkcode thresholdOverride} is set and this is true, will apply Ability Charm to {@linkcode thresholdOverride}
|
||||||
|
* @returns `true` if the Pokemon has been set to have its hidden ability, `false` otherwise
|
||||||
|
*/
|
||||||
|
public tryRerollHiddenAbilitySeed(thresholdOverride?: number, applyModifiersToOverride?: boolean): boolean {
|
||||||
|
if (!this.species.abilityHidden) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const haThreshold = new Utils.NumberHolder(BASE_HIDDEN_ABILITY_CHANCE);
|
||||||
|
if (thresholdOverride === undefined || applyModifiersToOverride) {
|
||||||
|
if (thresholdOverride !== undefined && applyModifiersToOverride) {
|
||||||
|
haThreshold.value = thresholdOverride;
|
||||||
|
}
|
||||||
|
if (!this.hasTrainer()) {
|
||||||
|
globalScene.applyModifiers(HiddenAbilityRateBoosterModifier, true, haThreshold);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
haThreshold.value = thresholdOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (randSeedInt(65536) < haThreshold.value) {
|
||||||
|
this.abilityIndex = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.abilityIndex === 2;
|
||||||
|
}
|
||||||
|
|
||||||
public generateFusionSpecies(forStarter?: boolean): void {
|
public generateFusionSpecies(forStarter?: boolean): void {
|
||||||
const hiddenAbilityChance = new Utils.NumberHolder(BASE_HIDDEN_ABILITY_CHANCE);
|
const hiddenAbilityChance = new Utils.NumberHolder(BASE_HIDDEN_ABILITY_CHANCE);
|
||||||
if (!this.hasTrainer()) {
|
if (!this.hasTrainer()) {
|
||||||
@ -2391,8 +2419,13 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
this.battleInfo.toggleFlyout(visible);
|
this.battleInfo.toggleFlyout(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
addExp(exp: integer) {
|
/**
|
||||||
const maxExpLevel = globalScene.getMaxExpLevel();
|
* Adds experience to this PlayerPokemon, subject to wave based level caps.
|
||||||
|
* @param exp The amount of experience to add
|
||||||
|
* @param ignoreLevelCap Whether to ignore level caps when adding experience (defaults to false)
|
||||||
|
*/
|
||||||
|
addExp(exp: integer, ignoreLevelCap: boolean = false) {
|
||||||
|
const maxExpLevel = globalScene.getMaxExpLevel(ignoreLevelCap);
|
||||||
const initialExp = this.exp;
|
const initialExp = this.exp;
|
||||||
this.exp += exp;
|
this.exp += exp;
|
||||||
while (this.level < maxExpLevel && this.exp >= getLevelTotalExp(this.level + 1, this.species.growthRate)) {
|
while (this.level < maxExpLevel && this.exp >= getLevelTotalExp(this.level + 1, this.species.growthRate)) {
|
||||||
@ -4323,10 +4356,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
].filter(d => !!d);
|
].filter(d => !!d);
|
||||||
const amount = new Utils.NumberHolder(friendship);
|
const amount = new Utils.NumberHolder(friendship);
|
||||||
globalScene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
|
globalScene.applyModifier(PokemonFriendshipBoosterModifier, true, this, amount);
|
||||||
let candyFriendshipMultiplier = CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER;
|
const candyFriendshipMultiplier = globalScene.eventManager.getClassicFriendshipMultiplier();
|
||||||
if (globalScene.eventManager.isEventActive()) {
|
|
||||||
candyFriendshipMultiplier *= globalScene.eventManager.getFriendshipMultiplier();
|
|
||||||
}
|
|
||||||
const starterAmount = new Utils.NumberHolder(Math.floor(amount.value * (globalScene.gameMode.isClassic ? candyFriendshipMultiplier : 1) / (fusionStarterSpeciesId ? 2 : 1)));
|
const starterAmount = new Utils.NumberHolder(Math.floor(amount.value * (globalScene.gameMode.isClassic ? candyFriendshipMultiplier : 1) / (fusionStarterSpeciesId ? 2 : 1)));
|
||||||
|
|
||||||
// Add friendship to this PlayerPokemon
|
// Add friendship to this PlayerPokemon
|
||||||
|
@ -246,9 +246,9 @@ export class LoadingScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ];
|
const availableLangs = [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ];
|
||||||
if (lang && availableLangs.includes(lang)) {
|
if (lang && availableLangs.includes(lang)) {
|
||||||
this.loadImage("winter_holidays2024-event-" + lang, "events");
|
this.loadImage("yearofthesnakeevent-" + lang, "events");
|
||||||
} else {
|
} else {
|
||||||
this.loadImage("winter_holidays2024-event-en", "events");
|
this.loadImage("yearofthesnakeevent-en", "events");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadAtlas("statuses", "");
|
this.loadAtlas("statuses", "");
|
||||||
|
@ -2537,9 +2537,10 @@ export function getPartyLuckValue(party: Pokemon[]): integer {
|
|||||||
}, 0, globalScene.seed);
|
}, 0, globalScene.seed);
|
||||||
return DailyLuck.value;
|
return DailyLuck.value;
|
||||||
}
|
}
|
||||||
const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() : 0)
|
const eventSpecies = globalScene.eventManager.getEventLuckBoostedSpecies();
|
||||||
|
const luck = Phaser.Math.Clamp(party.map(p => p.isAllowedInBattle() ? p.getLuck() + (eventSpecies.includes(p.species.speciesId) ? 1 : 0) : 0)
|
||||||
.reduce((total: integer, value: integer) => total += value, 0), 0, 14);
|
.reduce((total: integer, value: integer) => total += value, 0), 0, 14);
|
||||||
return luck ?? 0;
|
return Math.min(globalScene.eventManager.getEventLuckBoost() + (luck ?? 0), 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLuckString(luckValue: integer): string {
|
export function getLuckString(luckValue: integer): string {
|
||||||
|
@ -22,7 +22,7 @@ import { WeatherType } from "#enums/weather-type";
|
|||||||
*
|
*
|
||||||
* Any override added here will be used instead of the value in {@linkcode DefaultOverrides}
|
* Any override added here will be used instead of the value in {@linkcode DefaultOverrides}
|
||||||
*
|
*
|
||||||
* If an override name starts with "STARTING", it will apply when a new run begins
|
* If an override name starts with "STARTING", it will only apply when a new run begins.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```
|
* ```
|
||||||
@ -39,7 +39,7 @@ const overrides = {} satisfies Partial<InstanceType<typeof DefaultOverrides>>;
|
|||||||
* ---
|
* ---
|
||||||
* Defaults for Overrides that are used when testing different in game situations
|
* Defaults for Overrides that are used when testing different in game situations
|
||||||
*
|
*
|
||||||
* If an override name starts with "STARTING", it will apply when a new run begins
|
* If an override name starts with "STARTING", it will only apply when a new run begins.
|
||||||
*/
|
*/
|
||||||
class DefaultOverrides {
|
class DefaultOverrides {
|
||||||
// -----------------
|
// -----------------
|
||||||
@ -63,8 +63,11 @@ class DefaultOverrides {
|
|||||||
readonly STARTING_WAVE_OVERRIDE: number = 0;
|
readonly STARTING_WAVE_OVERRIDE: number = 0;
|
||||||
readonly STARTING_BIOME_OVERRIDE: Biome = Biome.TOWN;
|
readonly STARTING_BIOME_OVERRIDE: Biome = Biome.TOWN;
|
||||||
readonly ARENA_TINT_OVERRIDE: TimeOfDay | null = null;
|
readonly ARENA_TINT_OVERRIDE: TimeOfDay | null = null;
|
||||||
/** Multiplies XP gained by this value including 0. Set to null to ignore the override */
|
/** Multiplies XP gained by this value including 0. Set to null to ignore the override. */
|
||||||
readonly XP_MULTIPLIER_OVERRIDE: number | null = null;
|
readonly XP_MULTIPLIER_OVERRIDE: number | null = null;
|
||||||
|
/** Sets the level cap to this number during experience gain calculations. Set to `0` to disable override & use normal wave-based level caps,
|
||||||
|
or any negative number to set it to 9 quadrillion (effectively disabling it). */
|
||||||
|
readonly LEVEL_CAP_OVERRIDE: number = 0;
|
||||||
readonly NEVER_CRIT_OVERRIDE: boolean = false;
|
readonly NEVER_CRIT_OVERRIDE: boolean = false;
|
||||||
/** default 1000 */
|
/** default 1000 */
|
||||||
readonly STARTING_MONEY_OVERRIDE: number = 0;
|
readonly STARTING_MONEY_OVERRIDE: number = 0;
|
||||||
|
@ -26,7 +26,7 @@ export enum LearnMoveType {
|
|||||||
export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
||||||
private moveId: Moves;
|
private moveId: Moves;
|
||||||
private messageMode: Mode;
|
private messageMode: Mode;
|
||||||
private learnMoveType;
|
private learnMoveType: LearnMoveType;
|
||||||
private cost: number;
|
private cost: number;
|
||||||
|
|
||||||
constructor(partyMemberIndex: integer, moveId: Moves, learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE, cost: number = -1) {
|
constructor(partyMemberIndex: integer, moveId: Moves, learnMoveType: LearnMoveType = LearnMoveType.LEARN_MOVE, cost: number = -1) {
|
||||||
|
@ -39,9 +39,13 @@ export class TrainerVictoryPhase extends BattlePhase {
|
|||||||
// Validate Voucher for boss trainers
|
// Validate Voucher for boss trainers
|
||||||
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
|
if (vouchers.hasOwnProperty(TrainerType[trainerType])) {
|
||||||
if (!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) && globalScene.currentBattle.trainer?.config.isBoss) {
|
if (!globalScene.validateVoucher(vouchers[TrainerType[trainerType]]) && globalScene.currentBattle.trainer?.config.isBoss) {
|
||||||
|
if (globalScene.eventManager.getUpgradeUnlockedVouchers()) {
|
||||||
|
globalScene.unshiftPhase(new ModifierRewardPhase([ modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType]));
|
||||||
|
} else {
|
||||||
globalScene.unshiftPhase(new ModifierRewardPhase([ modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType]));
|
globalScene.unshiftPhase(new ModifierRewardPhase([ modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Breeders in Space achievement
|
// Breeders in Space achievement
|
||||||
if (
|
if (
|
||||||
globalScene.arena.biomeType === Biome.SPACE
|
globalScene.arena.biomeType === Biome.SPACE
|
||||||
|
@ -204,6 +204,7 @@ export async function initI18n(): Promise<void> {
|
|||||||
"nature",
|
"nature",
|
||||||
"pokeball",
|
"pokeball",
|
||||||
"pokemon",
|
"pokemon",
|
||||||
|
"pokemonEvolutions",
|
||||||
"pokemonForm",
|
"pokemonForm",
|
||||||
"pokemonInfo",
|
"pokemonInfo",
|
||||||
"pokemonInfoContainer",
|
"pokemonInfoContainer",
|
||||||
|
@ -166,7 +166,7 @@ export const SettingKeys = {
|
|||||||
Field_Volume: "FIELD_VOLUME",
|
Field_Volume: "FIELD_VOLUME",
|
||||||
SE_Volume: "SE_VOLUME",
|
SE_Volume: "SE_VOLUME",
|
||||||
UI_Volume: "UI_SOUND_EFFECTS",
|
UI_Volume: "UI_SOUND_EFFECTS",
|
||||||
Music_Preference: "MUSIC_PREFERENCE",
|
Battle_Music: "BATTLE_MUSIC",
|
||||||
Show_BGM_Bar: "SHOW_BGM_BAR",
|
Show_BGM_Bar: "SHOW_BGM_BAR",
|
||||||
Move_Touch_Controls: "MOVE_TOUCH_CONTROLS",
|
Move_Touch_Controls: "MOVE_TOUCH_CONTROLS",
|
||||||
Shop_Overlay_Opacity: "SHOP_OVERLAY_OPACITY"
|
Shop_Overlay_Opacity: "SHOP_OVERLAY_OPACITY"
|
||||||
@ -577,8 +577,8 @@ export const Setting: Array<Setting> = [
|
|||||||
label: i18next.t("settings:consistent")
|
label: i18next.t("settings:consistent")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "Mixed Animated",
|
value: "Experimental",
|
||||||
label: i18next.t("settings:mixedAnimated")
|
label: i18next.t("settings:experimental")
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
default: 0,
|
default: 0,
|
||||||
@ -658,11 +658,11 @@ export const Setting: Array<Setting> = [
|
|||||||
type: SettingType.AUDIO
|
type: SettingType.AUDIO
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: SettingKeys.Music_Preference,
|
key: SettingKeys.Battle_Music,
|
||||||
label: i18next.t("settings:musicPreference"),
|
label: i18next.t("settings:battleMusic"),
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: "Gen V + PMD",
|
value: "Gen V",
|
||||||
label: i18next.t("settings:musicGenFive")
|
label: i18next.t("settings:musicGenFive")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -741,7 +741,7 @@ export function setSetting(setting: string, value: integer): boolean {
|
|||||||
case SettingKeys.UI_Volume:
|
case SettingKeys.UI_Volume:
|
||||||
globalScene.uiVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0;
|
globalScene.uiVolume = value ? parseInt(Setting[index].options[value].value) * 0.01 : 0;
|
||||||
break;
|
break;
|
||||||
case SettingKeys.Music_Preference:
|
case SettingKeys.Battle_Music:
|
||||||
globalScene.musicPreference = value;
|
globalScene.musicPreference = value;
|
||||||
break;
|
break;
|
||||||
case SettingKeys.Damage_Numbers:
|
case SettingKeys.Damage_Numbers:
|
||||||
|
@ -7,7 +7,6 @@ import GameManager from "#test/utils/gameManager";
|
|||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
|
||||||
describe("Abilities - Dancer", () => {
|
describe("Abilities - Dancer", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
@ -24,20 +23,21 @@ describe("Abilities - Dancer", () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
game.override
|
game.override.battleType("double");
|
||||||
.battleType("double")
|
|
||||||
.moveset([ Moves.SWORDS_DANCE, Moves.SPLASH ])
|
|
||||||
.enemySpecies(Species.MAGIKARP)
|
|
||||||
.enemyAbility(Abilities.DANCER)
|
|
||||||
.enemyMoveset([ Moves.VICTORY_DANCE ]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)
|
// Reference Link: https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)
|
||||||
|
|
||||||
it("triggers when dance moves are used, doesn't consume extra PP", async () => {
|
it("triggers when dance moves are used, doesn't consume extra PP", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyAbility(Abilities.DANCER)
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyMoveset(Moves.VICTORY_DANCE);
|
||||||
await game.classicMode.startBattle([ Species.ORICORIO, Species.FEEBAS ]);
|
await game.classicMode.startBattle([ Species.ORICORIO, Species.FEEBAS ]);
|
||||||
|
|
||||||
const [ oricorio ] = game.scene.getPlayerField();
|
const [ oricorio, feebas ] = game.scene.getPlayerField();
|
||||||
|
game.move.changeMoveset(oricorio, [ Moves.SWORDS_DANCE, Moves.VICTORY_DANCE, Moves.SPLASH ]);
|
||||||
|
game.move.changeMoveset(feebas, [ Moves.SWORDS_DANCE, Moves.SPLASH ]);
|
||||||
|
|
||||||
game.move.select(Moves.SPLASH);
|
game.move.select(Moves.SPLASH);
|
||||||
game.move.select(Moves.SWORDS_DANCE, 1);
|
game.move.select(Moves.SWORDS_DANCE, 1);
|
||||||
@ -59,5 +59,44 @@ describe("Abilities - Dancer", () => {
|
|||||||
|
|
||||||
// doesn't use PP if copied move is also in moveset
|
// doesn't use PP if copied move is also in moveset
|
||||||
expect(oricorio.moveset[0]?.ppUsed).toBe(0);
|
expect(oricorio.moveset[0]?.ppUsed).toBe(0);
|
||||||
|
expect(oricorio.moveset[1]?.ppUsed).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: Enable after Dancer rework to not push to move history
|
||||||
|
it.todo("should not count as the last move used for mirror move/instruct", async () => {
|
||||||
|
game.override
|
||||||
|
.moveset([ Moves.FIERY_DANCE, Moves.REVELATION_DANCE ])
|
||||||
|
.enemyMoveset([ Moves.INSTRUCT, Moves.MIRROR_MOVE, Moves.SPLASH ])
|
||||||
|
.enemySpecies(Species.SHUCKLE)
|
||||||
|
.enemyLevel(10);
|
||||||
|
await game.classicMode.startBattle([ Species.ORICORIO, Species.FEEBAS ]);
|
||||||
|
|
||||||
|
const [ oricorio ] = game.scene.getPlayerField();
|
||||||
|
const [ , shuckle2 ] = game.scene.getEnemyField();
|
||||||
|
|
||||||
|
game.move.select(Moves.REVELATION_DANCE, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2);
|
||||||
|
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2);
|
||||||
|
await game.forceEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER);
|
||||||
|
await game.forceEnemyMove(Moves.MIRROR_MOVE, BattlerIndex.PLAYER);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY_2, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // Oricorio rev dance
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // Feebas fiery dance
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // Oricorio fiery dance (from dancer)
|
||||||
|
await game.phaseInterceptor.to("MoveEndPhase", false);
|
||||||
|
// dancer copied move doesn't appear in move history
|
||||||
|
expect(oricorio.getLastXMoves(-1)[0].move).toBe(Moves.REVELATION_DANCE);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // shuckle 2 mirror moves oricorio
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // calls instructed rev dance
|
||||||
|
let currentPhase = game.scene.getCurrentPhase() as MovePhase;
|
||||||
|
expect(currentPhase.pokemon).toBe(shuckle2);
|
||||||
|
expect(currentPhase.move.moveId).toBe(Moves.REVELATION_DANCE);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // shuckle 1 instructs oricorio
|
||||||
|
await game.phaseInterceptor.to("MovePhase");
|
||||||
|
currentPhase = game.scene.getCurrentPhase() as MovePhase;
|
||||||
|
expect(currentPhase.pokemon).toBe(oricorio);
|
||||||
|
expect(currentPhase.move.moveId).toBe(Moves.REVELATION_DANCE);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { MoveResult } from "#app/field/pokemon";
|
import { MoveResult } from "#app/field/pokemon";
|
||||||
|
import type { MovePhase } from "#app/phases/move-phase";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
@ -12,10 +13,10 @@ describe("Moves - Instruct", () => {
|
|||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
let game: GameManager;
|
let game: GameManager;
|
||||||
|
|
||||||
function instructSuccess(pokemon: Pokemon, move: Moves): void {
|
function instructSuccess(target: Pokemon, move: Moves): void {
|
||||||
expect(pokemon.getLastXMoves(-1)[0].move).toBe(move);
|
expect(target.getLastXMoves(-1)[0].move).toBe(move);
|
||||||
expect(pokemon.getLastXMoves(-1)[1].move).toBe(pokemon.getLastXMoves()[0].move);
|
expect(target.getLastXMoves(-1)[1].move).toBe(target.getLastXMoves()[0].move);
|
||||||
expect(pokemon.getMoveset().find(m => m?.moveId === move)?.ppUsed).toBe(2);
|
expect(target.getMoveset().find(m => m?.moveId === move)?.ppUsed).toBe(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -36,27 +37,40 @@ describe("Moves - Instruct", () => {
|
|||||||
.enemyAbility(Abilities.NO_GUARD)
|
.enemyAbility(Abilities.NO_GUARD)
|
||||||
.enemyLevel(100)
|
.enemyLevel(100)
|
||||||
.startingLevel(100)
|
.startingLevel(100)
|
||||||
.ability(Abilities.BALL_FETCH)
|
|
||||||
.moveset([ Moves.INSTRUCT, Moves.SONIC_BOOM, Moves.SPLASH, Moves.TORMENT ])
|
|
||||||
.disableCrits();
|
.disableCrits();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should repeat enemy's attack move when moving last", async () => {
|
it("should repeat target's last used move", async () => {
|
||||||
|
game.override
|
||||||
|
.moveset(Moves.INSTRUCT)
|
||||||
|
.enemyLevel(1000); // ensures shuckle no die
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
game.move.changeMoveset(enemy, Moves.SONIC_BOOM);
|
game.move.changeMoveset(enemy, Moves.SONIC_BOOM);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.forceEnemyMove(Moves.SONIC_BOOM, BattlerIndex.PLAYER);
|
await game.forceEnemyMove(Moves.SONIC_BOOM);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MovePhase"); // enemy attacks us
|
||||||
|
await game.phaseInterceptor.to("MovePhase", false); // instruct
|
||||||
|
let currentPhase = game.scene.getCurrentPhase() as MovePhase;
|
||||||
|
expect(currentPhase.pokemon).toBe(game.scene.getPlayerPokemon());
|
||||||
|
await game.phaseInterceptor.to("MoveEndPhase");
|
||||||
|
|
||||||
|
await game.phaseInterceptor.to("MovePhase", false); // enemy repeats move
|
||||||
|
currentPhase = game.scene.getCurrentPhase() as MovePhase;
|
||||||
|
expect(currentPhase.pokemon).toBe(enemy);
|
||||||
|
expect(currentPhase.move.moveId).toBe(Moves.SONIC_BOOM);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getPlayerPokemon()?.getInverseHp()).toBe(40);
|
|
||||||
instructSuccess(enemy, Moves.SONIC_BOOM);
|
instructSuccess(enemy, Moves.SONIC_BOOM);
|
||||||
|
expect(game.scene.getPlayerPokemon()?.getInverseHp()).toBe(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should repeat enemy's move through substitute", async () => {
|
it("should repeat enemy's move through substitute", async () => {
|
||||||
|
game.override.moveset([ Moves.INSTRUCT, Moves.SPLASH ]);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
@ -72,75 +86,94 @@ describe("Moves - Instruct", () => {
|
|||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getPlayerPokemon()?.getInverseHp()).toBe(40);
|
|
||||||
instructSuccess(game.scene.getEnemyPokemon()!, Moves.SONIC_BOOM);
|
instructSuccess(game.scene.getEnemyPokemon()!, Moves.SONIC_BOOM);
|
||||||
|
expect(game.scene.getPlayerPokemon()?.getInverseHp()).toBe(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should repeat ally's attack on enemy", async () => {
|
it("should repeat ally's attack on enemy", async () => {
|
||||||
game.override
|
game.override
|
||||||
.battleType("double")
|
.battleType("double")
|
||||||
.moveset([]);
|
.enemyMoveset(Moves.SPLASH);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS, Species.SHUCKLE ]);
|
||||||
|
|
||||||
const [ amoonguss, shuckle ] = game.scene.getPlayerField();
|
const [ amoonguss, shuckle ] = game.scene.getPlayerField();
|
||||||
game.move.changeMoveset(amoonguss, Moves.INSTRUCT);
|
game.move.changeMoveset(amoonguss, [ Moves.INSTRUCT, Moves.SONIC_BOOM ]);
|
||||||
game.move.changeMoveset(shuckle, Moves.SONIC_BOOM);
|
game.move.changeMoveset(shuckle, [ Moves.INSTRUCT, Moves.SONIC_BOOM ]);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2);
|
||||||
game.move.select(Moves.SONIC_BOOM, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
game.move.select(Moves.SONIC_BOOM, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
|
||||||
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getEnemyField()[0].getInverseHp()).toBe(40);
|
|
||||||
instructSuccess(shuckle, Moves.SONIC_BOOM);
|
instructSuccess(shuckle, Moves.SONIC_BOOM);
|
||||||
|
expect(game.scene.getEnemyField()[0].getInverseHp()).toBe(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Enable test case once gigaton hammer (and blood moon) is fixed
|
// TODO: Enable test case once gigaton hammer (and blood moon) are reworked
|
||||||
it.todo("should repeat enemy's Gigaton Hammer", async () => {
|
it.todo("should repeat enemy's Gigaton Hammer", async () => {
|
||||||
game.override
|
game.override
|
||||||
|
.moveset(Moves.INSTRUCT)
|
||||||
.enemyLevel(5);
|
.enemyLevel(5);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
const enemy = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
game.move.changeMoveset(enemy, Moves.GIGATON_HAMMER);
|
game.move.changeMoveset(enemy, [ Moves.GIGATON_HAMMER, Moves.BLOOD_MOON ]);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
instructSuccess(enemy, Moves.GIGATON_HAMMER);
|
instructSuccess(enemy, Moves.GIGATON_HAMMER);
|
||||||
|
expect(game.scene.getPlayerPokemon()!.turnData.attacksReceived.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should add moves to move queue for copycat", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("double")
|
||||||
|
.moveset(Moves.INSTRUCT)
|
||||||
|
.enemyLevel(5);
|
||||||
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
|
const [ enemy1, enemy2 ] = game.scene.getEnemyField()!;
|
||||||
|
game.move.changeMoveset(enemy1, Moves.WATER_GUN);
|
||||||
|
game.move.changeMoveset(enemy2, Moves.COPYCAT);
|
||||||
|
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
instructSuccess(enemy1, Moves.WATER_GUN);
|
||||||
|
// amoonguss gets hit by water gun thrice; once by original attack, once by instructed use and once by copycat
|
||||||
|
expect(game.scene.getPlayerPokemon()!.turnData.attacksReceived.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should respect enemy's status condition", async () => {
|
it("should respect enemy's status condition", async () => {
|
||||||
game.override
|
game.override
|
||||||
.moveset([ Moves.THUNDER_WAVE, Moves.INSTRUCT ])
|
.moveset([ Moves.INSTRUCT, Moves.THUNDER_WAVE ])
|
||||||
.enemyMoveset([ Moves.SPLASH, Moves.SONIC_BOOM ]);
|
.enemyMoveset(Moves.SONIC_BOOM);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
game.move.select(Moves.THUNDER_WAVE);
|
game.move.select(Moves.THUNDER_WAVE);
|
||||||
await game.forceEnemyMove(Moves.SONIC_BOOM);
|
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
|
||||||
await game.move.forceStatusActivation(true);
|
|
||||||
await game.phaseInterceptor.to("MovePhase");
|
await game.phaseInterceptor.to("MovePhase");
|
||||||
|
// force enemy's instructed move to bork and then immediately thaw out
|
||||||
|
await game.move.forceStatusActivation(true);
|
||||||
await game.move.forceStatusActivation(false);
|
await game.move.forceStatusActivation(false);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
const moveHistory = game.scene.getEnemyPokemon()!.getMoveHistory();
|
const moveHistory = game.scene.getEnemyPokemon()?.getLastXMoves(-1)!;
|
||||||
expect(moveHistory.length).toBe(3);
|
expect(moveHistory.map(m => m.move)).toEqual([ Moves.SONIC_BOOM, Moves.NONE, Moves.SONIC_BOOM ]);
|
||||||
expect(moveHistory[0].move).toBe(Moves.SONIC_BOOM);
|
expect(game.scene.getPlayerPokemon()?.getInverseHp()).toBe(40);
|
||||||
expect(moveHistory[1].move).toBe(Moves.NONE);
|
|
||||||
expect(moveHistory[2].move).toBe(Moves.SONIC_BOOM);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not repeat enemy's out of pp move", async () => {
|
it("should not repeat enemy's out of pp move", async () => {
|
||||||
game.override.enemySpecies(Species.UNOWN);
|
game.override
|
||||||
|
.moveset(Moves.INSTRUCT)
|
||||||
|
.enemySpecies(Species.UNOWN);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||||
@ -153,13 +186,85 @@ describe("Moves - Instruct", () => {
|
|||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
const playerMove = game.scene.getPlayerPokemon()!.getLastXMoves()!;
|
const playerMoves = game.scene.getPlayerPokemon()!.getLastXMoves(-1)!;
|
||||||
expect(playerMove[0].result).toBe(MoveResult.FAIL);
|
expect(playerMoves[0].result).toBe(MoveResult.FAIL);
|
||||||
expect(enemyPokemon.getMoveHistory().length).toBe(1);
|
expect(enemyPokemon.getMoveHistory().length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should redirect attacking moves if enemy faints", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("double")
|
||||||
|
.enemyMoveset(Moves.SPLASH)
|
||||||
|
.enemySpecies(Species.MAGIKARP)
|
||||||
|
.enemyLevel(1);
|
||||||
|
await game.classicMode.startBattle([ Species.HISUI_ELECTRODE, Species.KOMMO_O ]);
|
||||||
|
|
||||||
|
const [ electrode, kommo_o ] = game.scene.getPlayerField()!;
|
||||||
|
game.move.changeMoveset(electrode, Moves.CHLOROBLAST);
|
||||||
|
game.move.changeMoveset(kommo_o, Moves.INSTRUCT);
|
||||||
|
|
||||||
|
game.move.select(Moves.CHLOROBLAST, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
// Chloroblast always deals 50% max HP% recoil UNLESS you whiff
|
||||||
|
// due to lack of targets or similar,
|
||||||
|
// so all we have to do is check whether electrode fainted or not.
|
||||||
|
// Naturally, both karps should also be dead as well.
|
||||||
|
expect(electrode.isFainted()).toBe(true);
|
||||||
|
const [ karp1, karp2 ] = game.scene.getEnemyField()!;
|
||||||
|
expect(karp1.isFainted()).toBe(true);
|
||||||
|
expect(karp2.isFainted()).toBe(true);
|
||||||
|
}),
|
||||||
|
|
||||||
|
it("should allow for dancer copying of instructed dance move", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("double")
|
||||||
|
.enemyMoveset([ Moves.INSTRUCT, Moves.SPLASH ]);
|
||||||
|
await game.classicMode.startBattle([ Species.ORICORIO, Species.VOLCARONA ]);
|
||||||
|
|
||||||
|
const [ oricorio, volcarona ] = game.scene.getPlayerField();
|
||||||
|
game.move.changeMoveset(oricorio, Moves.SPLASH);
|
||||||
|
game.move.changeMoveset(volcarona, Moves.FIERY_DANCE);
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
|
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||||
|
await game.forceEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER_2);
|
||||||
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
// fiery dance triggered dancer successfully for a total of 4 hits
|
||||||
|
// Volcarona fiery dance has a _small_ chance to 3HKO a shuckle in worst case, so we add the hit count of both
|
||||||
|
// foes to account for spillover
|
||||||
|
instructSuccess(volcarona, Moves.FIERY_DANCE);
|
||||||
|
expect(game.scene.getEnemyField()[0].turnData.attacksReceived.length +
|
||||||
|
game.scene.getEnemyField()[1].turnData.attacksReceived.length).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not repeat move when switching out", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyMoveset(Moves.INSTRUCT)
|
||||||
|
.enemySpecies(Species.UNOWN);
|
||||||
|
await game.classicMode.startBattle([ Species.AMOONGUSS, Species.TOXICROAK ]);
|
||||||
|
|
||||||
|
const amoonguss = game.scene.getPlayerPokemon()!;
|
||||||
|
game.move.changeMoveset(amoonguss, Moves.SEED_BOMB);
|
||||||
|
|
||||||
|
amoonguss.battleSummonData.moveHistory = [{ move: Moves.SEED_BOMB, targets: [ BattlerIndex.ENEMY ], result: MoveResult.SUCCESS }];
|
||||||
|
|
||||||
|
game.doSwitchPokemon(1);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
|
const enemyMoves = game.scene.getEnemyPokemon()!.getLastXMoves(-1)!;
|
||||||
|
expect(enemyMoves[0].result).toBe(MoveResult.FAIL);
|
||||||
|
});
|
||||||
|
|
||||||
it("should fail if no move has yet been used by target", async () => {
|
it("should fail if no move has yet been used by target", async () => {
|
||||||
game.override.enemyMoveset(Moves.SPLASH);
|
game.override
|
||||||
|
.moveset(Moves.INSTRUCT)
|
||||||
|
.enemyMoveset(Moves.SPLASH);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
@ -183,48 +288,46 @@ describe("Moves - Instruct", () => {
|
|||||||
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
game.move.select(Moves.DISABLE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
game.move.select(Moves.DISABLE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||||
await game.forceEnemyMove(Moves.SONIC_BOOM, BattlerIndex.PLAYER);
|
await game.forceEnemyMove(Moves.SONIC_BOOM, BattlerIndex.PLAYER);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY_2 ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getPlayerField()[0].getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
expect(game.scene.getPlayerField()[0].getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
|
||||||
const enemyMove = game.scene.getEnemyPokemon()!.getLastXMoves()[0];
|
const enemyMove = game.scene.getEnemyField()[0]!.getLastXMoves()[0];
|
||||||
expect(enemyMove.result).toBe(MoveResult.FAIL);
|
expect(enemyMove.result).toBe(MoveResult.FAIL);
|
||||||
expect(game.scene.getEnemyPokemon()!.getMoveset().find(m => m?.moveId === Moves.SONIC_BOOM)?.ppUsed).toBe(1);
|
expect(game.scene.getEnemyField()[0].getMoveset().find(m => m?.moveId === Moves.SONIC_BOOM)?.ppUsed).toBe(1);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not repeat enemy's move through protect", async () => {
|
it("should not repeat enemy's move through protect", async () => {
|
||||||
|
game.override.moveset([ Moves.INSTRUCT ]);
|
||||||
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
await game.classicMode.startBattle([ Species.AMOONGUSS ]);
|
||||||
|
|
||||||
const MoveToUse = Moves.PROTECT;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
game.move.changeMoveset(enemy, Moves.PROTECT);
|
||||||
game.move.changeMoveset(enemyPokemon, MoveToUse);
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.forceEnemyMove(Moves.PROTECT);
|
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(enemyPokemon.getLastXMoves(-1)[0].move).toBe(Moves.PROTECT);
|
expect(enemy.getLastXMoves(-1)[0].move).toBe(Moves.PROTECT);
|
||||||
expect(enemyPokemon.getLastXMoves(-1)[1]).toBeUndefined(); // undefined because protect failed
|
expect(enemy.getLastXMoves(-1)[1]).toBeUndefined(); // undefined because instruct failed and didn't repeat
|
||||||
expect(enemyPokemon.getMoveset().find(m => m?.moveId === Moves.PROTECT)?.ppUsed).toBe(1);
|
expect(enemy.getMoveset().find(m => m?.moveId === Moves.PROTECT)?.ppUsed).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not repeat enemy's charging move", async () => {
|
it("should not repeat enemy's charging move", async () => {
|
||||||
game.override
|
game.override
|
||||||
.enemyMoveset([ Moves.SONIC_BOOM, Moves.HYPER_BEAM ])
|
.moveset([ Moves.INSTRUCT ])
|
||||||
.enemyLevel(5);
|
.enemyMoveset([ Moves.SONIC_BOOM, Moves.HYPER_BEAM ]);
|
||||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||||
|
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const player = game.scene.getPlayerPokemon()!;
|
||||||
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
const enemy = game.scene.getEnemyPokemon()!;
|
||||||
enemyPokemon.battleSummonData.moveHistory = [{ move: Moves.SONIC_BOOM, targets: [ BattlerIndex.PLAYER ], result: MoveResult.SUCCESS, virtual: false }];
|
enemy.battleSummonData.moveHistory = [{ move: Moves.SONIC_BOOM, targets: [ BattlerIndex.PLAYER ], result: MoveResult.SUCCESS, virtual: false }];
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.forceEnemyMove(Moves.HYPER_BEAM);
|
await game.forceEnemyMove(Moves.HYPER_BEAM);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
// instruct fails at copying last move due to charging turn (rather than instructing sonic boom)
|
||||||
expect(player.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
expect(player.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
@ -234,31 +337,162 @@ describe("Moves - Instruct", () => {
|
|||||||
expect(player.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
expect(player.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not repeat dance move not known by target", async () => {
|
it("should not repeat move since forgotten by target", async () => {
|
||||||
game.override
|
game.override
|
||||||
.battleType("double")
|
.enemyLevel(5)
|
||||||
.moveset([ Moves.INSTRUCT, Moves.FIERY_DANCE ])
|
.xpMultiplier(0)
|
||||||
.enemyMoveset(Moves.SPLASH)
|
.enemySpecies(Species.WURMPLE)
|
||||||
.enemyAbility(Abilities.DANCER);
|
.enemyMoveset(Moves.INSTRUCT);
|
||||||
await game.classicMode.startBattle([ Species.SHUCKLE, Species.SHUCKLE ]);
|
await game.classicMode.startBattle([ Species.REGIELEKI ]);
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
const regieleki = game.scene.getPlayerPokemon()!;
|
||||||
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
// fill out moveset with random moves
|
||||||
|
game.move.changeMoveset(regieleki, [ Moves.ELECTRO_DRIFT, Moves.SPLASH, Moves.ICE_BEAM, Moves.ANCIENT_POWER ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.ELECTRO_DRIFT);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to("FaintPhase");
|
||||||
|
await game.move.learnMove(Moves.ELECTROWEB);
|
||||||
|
await game.toNextWave();
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
expect(game.scene.getEnemyField()[0].getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should disregard priority of instructed move on use", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyMoveset([ Moves.SPLASH, Moves.WHIRLWIND ])
|
||||||
|
.moveset(Moves.INSTRUCT);
|
||||||
|
await game.classicMode.startBattle([ Species.LUCARIO, Species.BANETTE ]);
|
||||||
|
|
||||||
|
const enemyPokemon = game.scene.getEnemyPokemon()!;
|
||||||
|
enemyPokemon.battleSummonData.moveHistory = [{ move: Moves.WHIRLWIND, targets: [ BattlerIndex.PLAYER ], result: MoveResult.SUCCESS, virtual: false }];
|
||||||
|
|
||||||
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
|
// lucario instructed enemy whirlwind at 0 priority to switch itself out
|
||||||
|
const instructedMove = enemyPokemon.getLastXMoves(-1)[1];
|
||||||
|
expect(instructedMove.result).toBe(MoveResult.SUCCESS);
|
||||||
|
expect(instructedMove.move).toBe(Moves.WHIRLWIND);
|
||||||
|
expect(game.scene.getPlayerPokemon()?.species.speciesId).toBe(Species.BANETTE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should respect moves' original priority for psychic terrain", async () => {
|
||||||
|
game.override.
|
||||||
|
battleType("double")
|
||||||
|
.moveset([ Moves.QUICK_ATTACK, Moves.SPLASH, Moves.INSTRUCT ])
|
||||||
|
.enemyMoveset([ Moves.SPLASH, Moves.PSYCHIC_TERRAIN ]);
|
||||||
|
await game.classicMode.startBattle([ Species.BANETTE, Species.KLEFKI ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.QUICK_ATTACK, BattlerIndex.PLAYER, BattlerIndex.ENEMY); // succeeds due to terrain no
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.forceEnemyMove(Moves.PSYCHIC_TERRAIN);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER);
|
||||||
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
await game.phaseInterceptor.to("TurnEndPhase", false);
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
|
||||||
expect(game.scene.getPlayerField()[0].getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
// quick attack failed when instructed
|
||||||
|
const banette = game.scene.getPlayerPokemon()!;
|
||||||
|
expect(banette.getLastXMoves(-1)[1].move).toBe(Moves.QUICK_ATTACK);
|
||||||
|
expect(banette.getLastXMoves(-1)[1].result).toBe(MoveResult.FAIL);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should still work w/ prankster in psychic terrain", async () => {
|
||||||
|
game.override.
|
||||||
|
battleType("double")
|
||||||
|
.enemyMoveset([ Moves.SPLASH, Moves.PSYCHIC_TERRAIN ]);
|
||||||
|
await game.classicMode.startBattle([ Species.BANETTE, Species.KLEFKI ]);
|
||||||
|
|
||||||
|
const [ banette, klefki ] = game.scene.getPlayerField()!;
|
||||||
|
game.move.changeMoveset(banette, [ Moves.VINE_WHIP, Moves.SPLASH ]);
|
||||||
|
game.move.changeMoveset(klefki, [ Moves.INSTRUCT, Moves.SPLASH ]);
|
||||||
|
|
||||||
|
game.move.select(Moves.VINE_WHIP, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
|
await game.forceEnemyMove(Moves.PSYCHIC_TERRAIN);
|
||||||
|
await game.toNextTurn();
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER); // copies vine whip
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
expect(banette.getLastXMoves(-1)[1].move).toBe(Moves.VINE_WHIP);
|
||||||
|
expect(banette.getLastXMoves(-1)[2].move).toBe(Moves.VINE_WHIP);
|
||||||
|
expect(banette.getMoveset().find(m => m?.moveId === Moves.VINE_WHIP )?.ppUsed).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should cause spread moves to correctly hit targets in doubles after singles", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("even-doubles")
|
||||||
|
.moveset([ Moves.BREAKING_SWIPE, Moves.INSTRUCT, Moves.SPLASH ])
|
||||||
|
.enemyMoveset(Moves.SONIC_BOOM)
|
||||||
|
.enemySpecies(Species.AXEW)
|
||||||
|
.startingLevel(500);
|
||||||
|
await game.classicMode.startBattle([ Species.KORAIDON, Species.KLEFKI ]);
|
||||||
|
|
||||||
|
const koraidon = game.scene.getPlayerField()[0]!;
|
||||||
|
|
||||||
|
game.move.select(Moves.BREAKING_SWIPE);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
expect(koraidon.getInverseHp()).toBe(0);
|
||||||
|
expect(koraidon.getLastXMoves(-1)[0].targets).toEqual([ BattlerIndex.ENEMY ]);
|
||||||
|
await game.toNextWave();
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
// did not take damage since enemies died beforehand;
|
||||||
|
// last move used hit both enemies
|
||||||
|
expect(koraidon.getInverseHp()).toBe(0);
|
||||||
|
expect(koraidon.getLastXMoves(-1)[1].targets?.sort()).toEqual([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should cause AoE moves to correctly hit everyone in doubles after singles", async () => {
|
||||||
|
game.override
|
||||||
|
.battleType("even-doubles")
|
||||||
|
.moveset([ Moves.BRUTAL_SWING, Moves.INSTRUCT, Moves.SPLASH ])
|
||||||
|
.enemySpecies(Species.AXEW)
|
||||||
|
.enemyMoveset(Moves.SONIC_BOOM)
|
||||||
|
.startingLevel(500);
|
||||||
|
await game.classicMode.startBattle([ Species.KORAIDON, Species.KLEFKI ]);
|
||||||
|
|
||||||
|
const koraidon = game.scene.getPlayerField()[0]!;
|
||||||
|
|
||||||
|
game.move.select(Moves.BRUTAL_SWING);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
expect(koraidon.getInverseHp()).toBe(0);
|
||||||
|
expect(koraidon.getLastXMoves(-1)[0].targets).toEqual([ BattlerIndex.ENEMY ]);
|
||||||
|
await game.toNextWave();
|
||||||
|
|
||||||
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.PLAYER);
|
||||||
|
await game.setTurnOrder([ BattlerIndex.PLAYER_2, BattlerIndex.PLAYER, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
|
await game.phaseInterceptor.to("TurnEndPhase", false);
|
||||||
|
// did not take damage since enemies died beforehand;
|
||||||
|
// last move used hit everything around it
|
||||||
|
expect(koraidon.getInverseHp()).toBe(0);
|
||||||
|
expect(koraidon.getLastXMoves(-1)[1].targets?.sort()).toEqual([ BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should cause multi-hit moves to hit the appropriate number of times in singles", async () => {
|
it("should cause multi-hit moves to hit the appropriate number of times in singles", async () => {
|
||||||
game.override
|
game.override
|
||||||
.enemyAbility(Abilities.SKILL_LINK)
|
.enemyAbility(Abilities.SKILL_LINK)
|
||||||
|
.moveset([ Moves.SPLASH, Moves.INSTRUCT ])
|
||||||
.enemyMoveset(Moves.BULLET_SEED);
|
.enemyMoveset(Moves.BULLET_SEED);
|
||||||
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
|
||||||
const player = game.scene.getPlayerPokemon()!;
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
game.move.select(Moves.SPLASH);
|
game.move.select(Moves.SPLASH);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
@ -267,34 +501,35 @@ describe("Moves - Instruct", () => {
|
|||||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
expect(player.turnData.attacksReceived.length).toBe(10);
|
expect(bulbasaur.turnData.attacksReceived.length).toBe(10);
|
||||||
|
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
game.move.select(Moves.INSTRUCT);
|
game.move.select(Moves.INSTRUCT);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
expect(player.turnData.attacksReceived.length).toBe(10);
|
expect(bulbasaur.turnData.attacksReceived.length).toBe(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should cause multi-hit moves to hit the appropriate number of times in doubles", async () => {
|
it("should cause multi-hit moves to hit the appropriate number of times in doubles", async () => {
|
||||||
game.override
|
game.override
|
||||||
.battleType("double")
|
.battleType("double")
|
||||||
.enemyAbility(Abilities.SKILL_LINK)
|
.enemyAbility(Abilities.SKILL_LINK)
|
||||||
|
.moveset([ Moves.SPLASH, Moves.INSTRUCT ])
|
||||||
.enemyMoveset([ Moves.BULLET_SEED, Moves.SPLASH ])
|
.enemyMoveset([ Moves.BULLET_SEED, Moves.SPLASH ])
|
||||||
.enemyLevel(5);
|
.enemyLevel(5);
|
||||||
await game.classicMode.startBattle([ Species.BULBASAUR, Species.IVYSAUR ]);
|
await game.classicMode.startBattle([ Species.BULBASAUR, Species.IVYSAUR ]);
|
||||||
|
|
||||||
const [ , ivysaur ] = game.scene.getPlayerField();
|
const [ , ivysaur ] = game.scene.getPlayerField();
|
||||||
|
|
||||||
game.move.select(Moves.SPLASH);
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||||
game.move.select(Moves.SPLASH, 1);
|
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER_2);
|
||||||
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
|
|
||||||
game.move.select(Moves.INSTRUCT, 0, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
game.move.select(Moves.INSTRUCT, 1, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||||
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2 ]);
|
||||||
@ -303,8 +538,8 @@ describe("Moves - Instruct", () => {
|
|||||||
expect(ivysaur.turnData.attacksReceived.length).toBe(15);
|
expect(ivysaur.turnData.attacksReceived.length).toBe(15);
|
||||||
|
|
||||||
await game.toNextTurn();
|
await game.toNextTurn();
|
||||||
game.move.select(Moves.INSTRUCT, 0, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER, BattlerIndex.ENEMY);
|
||||||
game.move.select(Moves.INSTRUCT, 1, BattlerIndex.ENEMY);
|
game.move.select(Moves.INSTRUCT, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||||
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
await game.forceEnemyMove(Moves.BULLET_SEED, BattlerIndex.PLAYER_2);
|
||||||
await game.forceEnemyMove(Moves.SPLASH);
|
await game.forceEnemyMove(Moves.SPLASH);
|
||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.ENEMY_2, BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ]);
|
||||||
|
@ -4,6 +4,8 @@ import GameManager from "#test/utils/gameManager";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||||
|
import { Mode } from "#app/ui/ui";
|
||||||
|
import { Button } from "#app/enums/buttons";
|
||||||
|
|
||||||
describe("Learn Move Phase", () => {
|
describe("Learn Move Phase", () => {
|
||||||
let phaserGame: Phaser.Game;
|
let phaserGame: Phaser.Game;
|
||||||
@ -26,7 +28,7 @@ describe("Learn Move Phase", () => {
|
|||||||
|
|
||||||
it("If Pokemon has less than 4 moves, its newest move will be added to the lowest empty index", async () => {
|
it("If Pokemon has less than 4 moves, its newest move will be added to the lowest empty index", async () => {
|
||||||
game.override.moveset([ Moves.SPLASH ]);
|
game.override.moveset([ Moves.SPLASH ]);
|
||||||
await game.startBattle([ Species.BULBASAUR ]);
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
const pokemon = game.scene.getPlayerPokemon()!;
|
const pokemon = game.scene.getPlayerPokemon()!;
|
||||||
const newMovePos = pokemon?.getMoveset().length;
|
const newMovePos = pokemon?.getMoveset().length;
|
||||||
game.move.select(Moves.SPLASH);
|
game.move.select(Moves.SPLASH);
|
||||||
@ -36,12 +38,113 @@ describe("Learn Move Phase", () => {
|
|||||||
const levelReq = levelMove[0];
|
const levelReq = levelMove[0];
|
||||||
const levelMoveId = levelMove[1];
|
const levelMoveId = levelMove[1];
|
||||||
expect(pokemon.level).toBeGreaterThanOrEqual(levelReq);
|
expect(pokemon.level).toBeGreaterThanOrEqual(levelReq);
|
||||||
expect(pokemon?.getMoveset()[newMovePos]?.moveId).toBe(levelMoveId);
|
expect(pokemon?.moveset[newMovePos]?.moveId).toBe(levelMoveId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("If a pokemon has 4 move slots filled, the chosen move will be deleted and replaced", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
const prevMoveset = [ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ];
|
||||||
|
const moveSlotNum = 3;
|
||||||
|
|
||||||
|
game.move.changeMoveset(bulbasaur, prevMoveset);
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.doKillOpponents();
|
||||||
|
|
||||||
|
// queue up inputs to confirm dialog boxes
|
||||||
|
game.onNextPrompt("LearnMovePhase", Mode.CONFIRM, () => {
|
||||||
|
game.scene.ui.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
game.onNextPrompt("LearnMovePhase", Mode.SUMMARY, () => {
|
||||||
|
for (let x = 0; x < moveSlotNum; x++) {
|
||||||
|
game.scene.ui.processInput(Button.DOWN);
|
||||||
|
}
|
||||||
|
game.scene.ui.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.to(LearnMovePhase);
|
||||||
|
|
||||||
|
const levelMove = bulbasaur.getLevelMoves(5)[0];
|
||||||
|
const levelReq = levelMove[0];
|
||||||
|
const levelMoveId = levelMove[1];
|
||||||
|
expect(bulbasaur.level).toBeGreaterThanOrEqual(levelReq);
|
||||||
|
// Check each of mr mime's moveslots to make sure the changed move (and ONLY the changed move) is different
|
||||||
|
bulbasaur.getMoveset().forEach((move, index) => {
|
||||||
|
const expectedMove: Moves = (index === moveSlotNum ? levelMoveId : prevMoveset[index]);
|
||||||
|
expect(move?.moveId).toBe(expectedMove);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("selecting the newly deleted move will reject it and keep old moveset", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
const prevMoveset = [ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ];
|
||||||
|
|
||||||
|
game.move.changeMoveset(bulbasaur, [ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ]);
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.doKillOpponents();
|
||||||
|
|
||||||
|
// queue up inputs to confirm dialog boxes
|
||||||
|
game.onNextPrompt("LearnMovePhase", Mode.CONFIRM, () => {
|
||||||
|
game.scene.ui.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
game.onNextPrompt("LearnMovePhase", Mode.SUMMARY, () => {
|
||||||
|
for (let x = 0; x < 4; x++) {
|
||||||
|
game.scene.ui.processInput(Button.DOWN); // moves down 4 times to the 5th move slot
|
||||||
|
}
|
||||||
|
game.scene.ui.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
game.onNextPrompt("LearnMovePhase", Mode.CONFIRM, () => {
|
||||||
|
game.scene.ui.processInput(Button.ACTION);
|
||||||
|
});
|
||||||
|
await game.phaseInterceptor.to(LearnMovePhase);
|
||||||
|
|
||||||
|
const levelReq = bulbasaur.getLevelMoves(5)[0][0];
|
||||||
|
expect(bulbasaur.level).toBeGreaterThanOrEqual(levelReq);
|
||||||
|
expect(bulbasaur.getMoveset().map(m => m?.moveId)).toEqual(prevMoveset);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("macro should add moves in free slots normally", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
|
game.move.changeMoveset(bulbasaur, [ Moves.SPLASH, Moves.ABSORB, Moves.ACID ]);
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.move.learnMove(Moves.SACRED_FIRE, 0, 1);
|
||||||
|
expect(bulbasaur.getMoveset().map(m => m?.moveId)).toEqual([ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.SACRED_FIRE ]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("macro should replace moves", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
|
game.move.changeMoveset(bulbasaur, [ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ]);
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.move.learnMove(Moves.SACRED_FIRE, 0, 1);
|
||||||
|
expect(bulbasaur.getMoveset().map(m => m?.moveId)).toEqual([ Moves.SPLASH, Moves.SACRED_FIRE, Moves.ACID, Moves.VINE_WHIP ]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("macro should allow for cancelling move learning", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR ]);
|
||||||
|
const bulbasaur = game.scene.getPlayerPokemon()!;
|
||||||
|
|
||||||
|
game.move.changeMoveset(bulbasaur, [ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ]);
|
||||||
|
game.move.select(Moves.SPLASH);
|
||||||
|
await game.move.learnMove(Moves.SACRED_FIRE, 0, 4);
|
||||||
|
expect(bulbasaur.getMoveset().map(m => m?.moveId)).toEqual([ Moves.SPLASH, Moves.ABSORB, Moves.ACID, Moves.VINE_WHIP ]);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("macro works on off-field party members", async () => {
|
||||||
|
await game.classicMode.startBattle([ Species.BULBASAUR, Species.SQUIRTLE ]);
|
||||||
|
const squirtle = game.scene.getPlayerParty()[1]!;
|
||||||
|
|
||||||
|
game.move.changeMoveset(squirtle, [ Moves.SPLASH, Moves.WATER_GUN, Moves.FREEZE_DRY, Moves.GROWL ]);
|
||||||
|
game.move.select(Moves.TACKLE);
|
||||||
|
await game.move.learnMove(Moves.SHELL_SMASH, 1, 0);
|
||||||
|
expect(squirtle.getMoveset().map(m => m?.moveId)).toEqual([ Moves.SHELL_SMASH, Moves.WATER_GUN, Moves.FREEZE_DRY, Moves.GROWL ]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Future Tests:
|
|
||||||
* If a Pokemon has four moves, the user can specify an old move to be forgotten and a new move will take its place.
|
|
||||||
* If a Pokemon has four moves, the user can reject the new move, keeping the moveset the same.
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
@ -362,8 +362,9 @@ describe("UI - Starter select", () => {
|
|||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.LEFT);
|
handler.processInput(Button.LEFT);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
game.phaseInterceptor.unlock();
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
@ -423,7 +424,8 @@ describe("UI - Starter select", () => {
|
|||||||
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
const handler = game.scene.ui.getHandler() as StarterSelectUiHandler;
|
||||||
handler.processInput(Button.RIGHT);
|
handler.processInput(Button.RIGHT);
|
||||||
handler.processInput(Button.LEFT);
|
handler.processInput(Button.LEFT);
|
||||||
handler.processInput(Button.V);
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
|
handler.processInput(Button.CYCLE_SHINY);
|
||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
game.phaseInterceptor.unlock();
|
game.phaseInterceptor.unlock();
|
||||||
});
|
});
|
||||||
|
@ -129,9 +129,10 @@ export default class GameManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an action to be executed on the next prompt.
|
* Adds an action to be executed on the next prompt.
|
||||||
|
* This can be used to (among other things) simulate inputs or run functions mid-phase.
|
||||||
* @param phaseTarget - The target phase.
|
* @param phaseTarget - The target phase.
|
||||||
* @param mode - The mode to wait for.
|
* @param mode - The mode to wait for.
|
||||||
* @param callback - The callback to execute.
|
* @param callback - The callback function to execute on next prompt.
|
||||||
* @param expireFn - Optional function to determine if the prompt has expired.
|
* @param expireFn - Optional function to determine if the prompt has expired.
|
||||||
*/
|
*/
|
||||||
onNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn?: () => void, awaitingActionInput: boolean = false) {
|
onNextPrompt(phaseTarget: string, mode: Mode, callback: () => void, expireFn?: () => void, awaitingActionInput: boolean = false) {
|
||||||
@ -400,6 +401,11 @@ export default class GameManager {
|
|||||||
return updateUserInfo();
|
return updateUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Faints a player or enemy pokemon instantly by setting their HP to 0.
|
||||||
|
* @param pokemon The player/enemy pokemon being fainted
|
||||||
|
* @returns A promise that resolves once the fainted pokemon's FaintPhase finishes running.
|
||||||
|
*/
|
||||||
async killPokemon(pokemon: PlayerPokemon | EnemyPokemon) {
|
async killPokemon(pokemon: PlayerPokemon | EnemyPokemon) {
|
||||||
return new Promise<void>(async (resolve, reject) => {
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
pokemon.hp = 0;
|
pokemon.hp = 0;
|
||||||
@ -453,8 +459,9 @@ export default class GameManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercepts `TurnStartPhase` and mocks the getSpeedOrder's return value {@linkcode TurnStartPhase.getSpeedOrder}
|
* Intercepts `TurnStartPhase` and mocks {@linkcode TurnStartPhase.getSpeedOrder}'s return value.
|
||||||
* Used to modify the turn order.
|
* Used to manually modify Pokemon turn order.
|
||||||
|
* Note: This *DOES NOT* account for priority, only speed.
|
||||||
* @param {BattlerIndex[]} order The turn order to set
|
* @param {BattlerIndex[]} order The turn order to set
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
@ -468,7 +475,7 @@ export default class GameManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all held items from enemy pokemon
|
* Removes all held items from enemy pokemon.
|
||||||
*/
|
*/
|
||||||
removeEnemyHeldItems(): void {
|
removeEnemyHeldItems(): void {
|
||||||
this.scene.clearEnemyHeldItemModifiers();
|
this.scene.clearEnemyHeldItemModifiers();
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import type { BattlerIndex } from "#app/battle";
|
import type { BattlerIndex } from "#app/battle";
|
||||||
|
import { Button } from "#app/enums/buttons";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import type { CommandPhase } from "#app/phases/command-phase";
|
import type { CommandPhase } from "#app/phases/command-phase";
|
||||||
|
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { Command } from "#app/ui/command-ui-handler";
|
import { Command } from "#app/ui/command-ui-handler";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
@ -75,9 +77,10 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used when the normal moveset override can't be used (such as when it's necessary to check updated properties of the moveset).
|
* Changes a pokemon's moveset to the given move(s).
|
||||||
* @param pokemon - The pokemon being modified
|
* Used when the normal moveset override can't be used (such as when it's necessary to check or update properties of the moveset).
|
||||||
* @param moveset - The moveset to use
|
* @param pokemon - The {@linkcode Pokemon} being modified
|
||||||
|
* @param moveset - The {@linkcode Moves} (single or array) to change the Pokemon's moveset to
|
||||||
*/
|
*/
|
||||||
public changeMoveset(pokemon: Pokemon, moveset: Moves | Moves[]): void {
|
public changeMoveset(pokemon: Pokemon, moveset: Moves | Moves[]): void {
|
||||||
if (!Array.isArray(moveset)) {
|
if (!Array.isArray(moveset)) {
|
||||||
@ -90,4 +93,40 @@ export class MoveHelper extends GameManagerHelper {
|
|||||||
const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", ");
|
const movesetStr = moveset.map((moveId) => Moves[moveId]).join(", ");
|
||||||
console.log(`Pokemon ${pokemon.species.name}'s moveset manually set to ${movesetStr} (=[${moveset.join(", ")}])!`);
|
console.log(`Pokemon ${pokemon.species.name}'s moveset manually set to ${movesetStr} (=[${moveset.join(", ")}])!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulates learning a move for a player pokemon.
|
||||||
|
* @param move The {@linkcode Moves} being learnt
|
||||||
|
* @param partyIndex The party position of the {@linkcode PlayerPokemon} learning the move (defaults to 0)
|
||||||
|
* @param moveSlotIndex The INDEX (0-4) of the move slot to replace if existent move slots are full;
|
||||||
|
* defaults to 0 (first slot) and 4 aborts the procedure
|
||||||
|
* @returns a promise that resolves once the move has been successfully learnt
|
||||||
|
*/
|
||||||
|
public async learnMove(move: Moves | integer, partyIndex: integer = 0, moveSlotIndex: integer = 0) {
|
||||||
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
|
this.game.scene.pushPhase(new LearnMovePhase(partyIndex, move));
|
||||||
|
|
||||||
|
// if slots are full, queue up inputs to replace existing moves
|
||||||
|
if (this.game.scene.getPlayerParty()[partyIndex].moveset.filter(m => m).length === 4) {
|
||||||
|
this.game.onNextPrompt("LearnMovePhase", Mode.CONFIRM, () => {
|
||||||
|
this.game.scene.ui.processInput(Button.ACTION); // "Should a move be forgotten and replaced with XXX?"
|
||||||
|
});
|
||||||
|
this.game.onNextPrompt("LearnMovePhase", Mode.SUMMARY, () => {
|
||||||
|
for (let x = 0; x < (moveSlotIndex ?? 0); x++) {
|
||||||
|
this.game.scene.ui.processInput(Button.DOWN); // Scrolling in summary pane to move position
|
||||||
|
}
|
||||||
|
this.game.scene.ui.processInput(Button.ACTION);
|
||||||
|
if (moveSlotIndex === 4) {
|
||||||
|
this.game.onNextPrompt("LearnMovePhase", Mode.CONFIRM, () => {
|
||||||
|
this.game.scene.ui.processInput(Button.ACTION); // "Give up on learning XXX?"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.game.phaseInterceptor.to(LearnMovePhase).catch(e => reject(e));
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,26 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the wave level cap
|
||||||
|
* @param cap the level cap value to set; 0 uses normal level caps and negative values
|
||||||
|
* disable it completely
|
||||||
|
* @returns `this`
|
||||||
|
*/
|
||||||
|
public levelCap(cap: number): this {
|
||||||
|
vi.spyOn(Overrides, "LEVEL_CAP_OVERRIDE", "get").mockReturnValue(cap);
|
||||||
|
let capStr: string;
|
||||||
|
if (cap > 0) {
|
||||||
|
capStr = `Level cap set to ${cap}!`;
|
||||||
|
} else if (cap < 0) {
|
||||||
|
capStr = "Level cap disabled!";
|
||||||
|
} else {
|
||||||
|
capStr = "Level cap reset to default value for wave.";
|
||||||
|
}
|
||||||
|
this.log(capStr);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) starting held items
|
* Override the player (pokemon) starting held items
|
||||||
* @param items the items to hold
|
* @param items the items to hold
|
||||||
@ -140,7 +160,7 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the player (pokemon) {@linkcode Abilities | ability}
|
* Override the player (pokemon) {@linkcode Abilities | ability}.
|
||||||
* @param ability the (pokemon) {@linkcode Abilities | ability} to set
|
* @param ability the (pokemon) {@linkcode Abilities | ability} to set
|
||||||
* @returns `this`
|
* @returns `this`
|
||||||
*/
|
*/
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER } from "#app/data/balance/starters";
|
||||||
import { TimedEventManager } from "#app/timed-event-manager";
|
import { TimedEventManager } from "#app/timed-event-manager";
|
||||||
|
|
||||||
/** Mock TimedEventManager so that ongoing events don't impact tests */
|
/** Mock TimedEventManager so that ongoing events don't impact tests */
|
||||||
@ -8,8 +9,8 @@ export class MockTimedEventManager extends TimedEventManager {
|
|||||||
override isEventActive(): boolean {
|
override isEventActive(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
override getFriendshipMultiplier(): number {
|
override getClassicFriendshipMultiplier(): number {
|
||||||
return 1;
|
return CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER;
|
||||||
}
|
}
|
||||||
override getShinyMultiplier(): number {
|
override getShinyMultiplier(): number {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { TextStyle, addTextObject } from "#app/ui/text";
|
import { TextStyle, addTextObject } from "#app/ui/text";
|
||||||
import type { nil } from "#app/utils";
|
import type { nil } from "#app/utils";
|
||||||
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import type { WeatherPoolEntry } from "#app/data/weather";
|
import type { WeatherPoolEntry } from "#app/data/weather";
|
||||||
import { WeatherType } from "#enums/weather-type";
|
import { WeatherType } from "#enums/weather-type";
|
||||||
|
import { CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER } from "./data/balance/starters";
|
||||||
|
import { MysteryEncounterType } from "./enums/mystery-encounter-type";
|
||||||
|
import { MysteryEncounterTier } from "./enums/mystery-encounter-tier";
|
||||||
|
|
||||||
export enum EventType {
|
export enum EventType {
|
||||||
SHINY,
|
SHINY,
|
||||||
NO_TIMER_DISPLAY
|
NO_TIMER_DISPLAY,
|
||||||
|
LUCK
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EventBanner {
|
interface EventBanner {
|
||||||
@ -21,19 +26,29 @@ interface EventBanner {
|
|||||||
|
|
||||||
interface EventEncounter {
|
interface EventEncounter {
|
||||||
species: Species;
|
species: Species;
|
||||||
allowEvolution?: boolean;
|
blockEvolution?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EventMysteryEncounterTier {
|
||||||
|
mysteryEncounter: MysteryEncounterType;
|
||||||
|
tier?: MysteryEncounterTier;
|
||||||
|
disable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TimedEvent extends EventBanner {
|
interface TimedEvent extends EventBanner {
|
||||||
name: string;
|
name: string;
|
||||||
eventType: EventType;
|
eventType: EventType;
|
||||||
shinyMultiplier?: number;
|
shinyMultiplier?: number;
|
||||||
friendshipMultiplier?: number;
|
classicFriendshipMultiplier?: number;
|
||||||
|
luckBoost?: number;
|
||||||
|
upgradeUnlockedVouchers?: boolean;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
endDate: Date;
|
endDate: Date;
|
||||||
uncommonBreedEncounters?: EventEncounter[];
|
eventEncounters?: EventEncounter[];
|
||||||
delibirdyBuff?: string[];
|
delibirdyBuff?: string[];
|
||||||
weather?: WeatherPoolEntry[];
|
weather?: WeatherPoolEntry[];
|
||||||
|
mysteryEncounterTierChanges?: EventMysteryEncounterTier[];
|
||||||
|
luckBoostedSpecies?: Species[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const timedEvents: TimedEvent[] = [
|
const timedEvents: TimedEvent[] = [
|
||||||
@ -41,36 +56,94 @@ const timedEvents: TimedEvent[] = [
|
|||||||
name: "Winter Holiday Update",
|
name: "Winter Holiday Update",
|
||||||
eventType: EventType.SHINY,
|
eventType: EventType.SHINY,
|
||||||
shinyMultiplier: 2,
|
shinyMultiplier: 2,
|
||||||
friendshipMultiplier: 1,
|
upgradeUnlockedVouchers: true,
|
||||||
startDate: new Date(Date.UTC(2024, 11, 21, 0)),
|
startDate: new Date(Date.UTC(2024, 11, 21, 0)),
|
||||||
endDate: new Date(Date.UTC(2025, 0, 4, 0)),
|
endDate: new Date(Date.UTC(2025, 0, 4, 0)),
|
||||||
bannerKey: "winter_holidays2024-event-",
|
bannerKey: "winter_holidays2024-event-",
|
||||||
scale: 0.21,
|
scale: 0.21,
|
||||||
availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ],
|
availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ],
|
||||||
uncommonBreedEncounters: [
|
eventEncounters: [
|
||||||
{ species: Species.GIMMIGHOUL },
|
{ species: Species.GIMMIGHOUL, blockEvolution: true },
|
||||||
{ species: Species.DELIBIRD },
|
{ species: Species.DELIBIRD },
|
||||||
{ species: Species.STANTLER, allowEvolution: true },
|
{ species: Species.STANTLER },
|
||||||
{ species: Species.CYNDAQUIL, allowEvolution: true },
|
{ species: Species.CYNDAQUIL },
|
||||||
{ species: Species.PIPLUP, allowEvolution: true },
|
{ species: Species.PIPLUP },
|
||||||
{ species: Species.CHESPIN, allowEvolution: true },
|
{ species: Species.CHESPIN },
|
||||||
{ species: Species.BALTOY, allowEvolution: true },
|
{ species: Species.BALTOY },
|
||||||
{ species: Species.SNOVER, allowEvolution: true },
|
{ species: Species.SNOVER },
|
||||||
{ species: Species.CHINGLING, allowEvolution: true },
|
{ species: Species.CHINGLING },
|
||||||
{ species: Species.LITWICK, allowEvolution: true },
|
{ species: Species.LITWICK },
|
||||||
{ species: Species.CUBCHOO, allowEvolution: true },
|
{ species: Species.CUBCHOO },
|
||||||
{ species: Species.SWIRLIX, allowEvolution: true },
|
{ species: Species.SWIRLIX },
|
||||||
{ species: Species.AMAURA, allowEvolution: true },
|
{ species: Species.AMAURA },
|
||||||
{ species: Species.MUDBRAY, allowEvolution: true },
|
{ species: Species.MUDBRAY },
|
||||||
{ species: Species.ROLYCOLY, allowEvolution: true },
|
{ species: Species.ROLYCOLY },
|
||||||
{ species: Species.MILCERY, allowEvolution: true },
|
{ species: Species.MILCERY },
|
||||||
{ species: Species.SMOLIV, allowEvolution: true },
|
{ species: Species.SMOLIV },
|
||||||
{ species: Species.ALOLA_VULPIX, allowEvolution: true },
|
{ species: Species.ALOLA_VULPIX },
|
||||||
{ species: Species.GALAR_DARUMAKA, allowEvolution: true },
|
{ species: Species.GALAR_DARUMAKA },
|
||||||
{ species: Species.IRON_BUNDLE }
|
{ species: Species.IRON_BUNDLE }
|
||||||
],
|
],
|
||||||
delibirdyBuff: [ "CATCHING_CHARM", "SHINY_CHARM", "ABILITY_CHARM", "EXP_CHARM", "SUPER_EXP_CHARM", "HEALING_CHARM" ],
|
delibirdyBuff: [ "CATCHING_CHARM", "SHINY_CHARM", "ABILITY_CHARM", "EXP_CHARM", "SUPER_EXP_CHARM", "HEALING_CHARM" ],
|
||||||
weather: [{ weatherType: WeatherType.SNOW, weight: 1 }]
|
weather: [{ weatherType: WeatherType.SNOW, weight: 1 }],
|
||||||
|
mysteryEncounterTierChanges: [
|
||||||
|
{ mysteryEncounter: MysteryEncounterType.DELIBIRDY, tier: MysteryEncounterTier.COMMON },
|
||||||
|
{ mysteryEncounter: MysteryEncounterType.PART_TIMER, disable: true },
|
||||||
|
{ mysteryEncounter: MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, disable: true },
|
||||||
|
{ mysteryEncounter: MysteryEncounterType.FIELD_TRIP, disable: true },
|
||||||
|
{ mysteryEncounter: MysteryEncounterType.DEPARTMENT_STORE_SALE, disable: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Year of the Snake",
|
||||||
|
eventType: EventType.LUCK,
|
||||||
|
luckBoost: 1,
|
||||||
|
startDate: new Date(Date.UTC(2025, 0, 29, 0)),
|
||||||
|
endDate: new Date(Date.UTC(2025, 1, 3, 0)),
|
||||||
|
bannerKey: "yearofthesnakeevent-",
|
||||||
|
scale: 0.21,
|
||||||
|
availableLangs: [ "en", "de", "it", "fr", "ja", "ko", "es-ES", "pt-BR", "zh-CN" ],
|
||||||
|
eventEncounters: [
|
||||||
|
{ species: Species.EKANS },
|
||||||
|
{ species: Species.ONIX },
|
||||||
|
{ species: Species.DRATINI },
|
||||||
|
{ species: Species.CLEFFA },
|
||||||
|
{ species: Species.UMBREON },
|
||||||
|
{ species: Species.DUNSPARCE },
|
||||||
|
{ species: Species.TEDDIURSA },
|
||||||
|
{ species: Species.SEVIPER },
|
||||||
|
{ species: Species.LUNATONE },
|
||||||
|
{ species: Species.CHINGLING },
|
||||||
|
{ species: Species.SNIVY },
|
||||||
|
{ species: Species.DARUMAKA },
|
||||||
|
{ species: Species.DRAMPA },
|
||||||
|
{ species: Species.SILICOBRA },
|
||||||
|
{ species: Species.BLOODMOON_URSALUNA }
|
||||||
|
],
|
||||||
|
luckBoostedSpecies: [
|
||||||
|
Species.EKANS, Species.ARBOK,
|
||||||
|
Species.ONIX, Species.STEELIX,
|
||||||
|
Species.DRATINI, Species.DRAGONAIR, Species.DRAGONITE,
|
||||||
|
Species.CLEFFA, Species.CLEFAIRY, Species.CLEFABLE,
|
||||||
|
Species.UMBREON,
|
||||||
|
Species.DUNSPARCE, Species.DUDUNSPARCE,
|
||||||
|
Species.TEDDIURSA, Species.URSARING, Species.URSALUNA,
|
||||||
|
Species.SEVIPER,
|
||||||
|
Species.LUNATONE,
|
||||||
|
Species.RAYQUAZA,
|
||||||
|
Species.CHINGLING, Species.CHIMECHO,
|
||||||
|
Species.CRESSELIA,
|
||||||
|
Species.DARKRAI,
|
||||||
|
Species.SNIVY, Species.SERVINE, Species.SERPERIOR,
|
||||||
|
Species.DARUMAKA, Species.DARMANITAN,
|
||||||
|
Species.ZYGARDE,
|
||||||
|
Species.DRAMPA,
|
||||||
|
Species.LUNALA,
|
||||||
|
Species.BLACEPHALON,
|
||||||
|
Species.SILICOBRA, Species.SANDACONDA,
|
||||||
|
Species.ROARING_MOON,
|
||||||
|
Species.BLOODMOON_URSALUNA
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -97,16 +170,6 @@ export class TimedEventManager {
|
|||||||
return activeEvents.length > 0;
|
return activeEvents.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFriendshipMultiplier(): number {
|
|
||||||
let multiplier = 1;
|
|
||||||
const friendshipEvents = timedEvents.filter((te) => this.isActive(te));
|
|
||||||
friendshipEvents.forEach((fe) => {
|
|
||||||
multiplier *= fe.friendshipMultiplier ?? 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
return multiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
getShinyMultiplier(): number {
|
getShinyMultiplier(): number {
|
||||||
let multiplier = 1;
|
let multiplier = 1;
|
||||||
const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te));
|
const shinyEvents = timedEvents.filter((te) => te.eventType === EventType.SHINY && this.isActive(te));
|
||||||
@ -120,6 +183,120 @@ export class TimedEventManager {
|
|||||||
getEventBannerFilename(): string {
|
getEventBannerFilename(): string {
|
||||||
return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey ?? "";
|
return timedEvents.find((te: TimedEvent) => this.isActive(te))?.bannerKey ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEventEncounters(): EventEncounter[] {
|
||||||
|
const ret: EventEncounter[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te)).map((te) => {
|
||||||
|
if (!isNullOrUndefined(te.eventEncounters)) {
|
||||||
|
ret.push(...te.eventEncounters);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For events that change the classic candy friendship multiplier
|
||||||
|
* @returns The highest classic friendship multiplier among the active events, or the default CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER
|
||||||
|
*/
|
||||||
|
getClassicFriendshipMultiplier(): number {
|
||||||
|
let multiplier = CLASSIC_CANDY_FRIENDSHIP_MULTIPLIER;
|
||||||
|
const classicFriendshipEvents = timedEvents.filter((te) => this.isActive(te));
|
||||||
|
classicFriendshipEvents.forEach((fe) => {
|
||||||
|
if (!isNullOrUndefined(fe.classicFriendshipMultiplier) && fe.classicFriendshipMultiplier > multiplier) {
|
||||||
|
multiplier = fe.classicFriendshipMultiplier;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For events where defeated bosses (Gym Leaders, E4 etc) give out Voucher Plus even if they were defeated before
|
||||||
|
* @returns Whether vouchers should be upgraded
|
||||||
|
*/
|
||||||
|
getUpgradeUnlockedVouchers(): boolean {
|
||||||
|
return timedEvents.some((te) => this.isActive(te) && (te.upgradeUnlockedVouchers ?? false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For events where Delibirdy gives extra items
|
||||||
|
* @returns list of ids of {@linkcode ModifierType}s that Delibirdy hands out as a bonus
|
||||||
|
*/
|
||||||
|
getDelibirdyBuff(): string[] {
|
||||||
|
const ret: string[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te)).map((te) => {
|
||||||
|
if (!isNullOrUndefined(te.delibirdyBuff)) {
|
||||||
|
ret.push(...te.delibirdyBuff);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For events where there's a set weather for town biome (other biomes are hard)
|
||||||
|
* @returns Event weathers for town
|
||||||
|
*/
|
||||||
|
getWeather(): WeatherPoolEntry[] {
|
||||||
|
const ret: WeatherPoolEntry[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te)).map((te) => {
|
||||||
|
if (!isNullOrUndefined(te.weather)) {
|
||||||
|
ret.push(...te.weather);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllMysteryEncounterChanges(): EventMysteryEncounterTier[] {
|
||||||
|
const ret: EventMysteryEncounterTier[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te)).map((te) => {
|
||||||
|
if (!isNullOrUndefined(te.mysteryEncounterTierChanges)) {
|
||||||
|
ret.push(...te.mysteryEncounterTierChanges);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEventMysteryEncountersDisabled(): MysteryEncounterType[] {
|
||||||
|
const ret: MysteryEncounterType[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te) && !isNullOrUndefined(te.mysteryEncounterTierChanges)).map((te) => {
|
||||||
|
te.mysteryEncounterTierChanges?.map((metc) => {
|
||||||
|
if (metc.disable) {
|
||||||
|
ret.push(metc.mysteryEncounter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getMysteryEncounterTierForEvent(encounterType: MysteryEncounterType, normal: MysteryEncounterTier): MysteryEncounterTier {
|
||||||
|
let ret = normal;
|
||||||
|
timedEvents.filter((te) => this.isActive(te) && !isNullOrUndefined(te.mysteryEncounterTierChanges)).map((te) => {
|
||||||
|
te.mysteryEncounterTierChanges?.map((metc) => {
|
||||||
|
if (metc.mysteryEncounter === encounterType) {
|
||||||
|
ret = metc.tier ?? normal;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEventLuckBoost(): number {
|
||||||
|
let ret = 0;
|
||||||
|
const luckEvents = timedEvents.filter((te) => this.isActive(te) && !isNullOrUndefined(te.luckBoost));
|
||||||
|
luckEvents.forEach((le) => {
|
||||||
|
ret += le.luckBoost!;
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
getEventLuckBoostedSpecies(): Species[] {
|
||||||
|
const ret: Species[] = [];
|
||||||
|
timedEvents.filter((te) => this.isActive(te)).map((te) => {
|
||||||
|
if (!isNullOrUndefined(te.luckBoostedSpecies)) {
|
||||||
|
ret.push(...te.luckBoostedSpecies.filter(s => !ret.includes(s)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
export class TimedEventDisplay extends Phaser.GameObjects.Container {
|
||||||
|
@ -111,7 +111,7 @@ export default class MenuUiHandler extends MessageUiHandler {
|
|||||||
render() {
|
render() {
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
this.excludedMenus = () => [
|
this.excludedMenus = () => [
|
||||||
{ condition: globalScene.getCurrentPhase() instanceof SelectModifierPhase, options: [ MenuOptions.EGG_GACHA, MenuOptions.EGG_LIST ]},
|
{ condition: globalScene.getCurrentPhase() instanceof SelectModifierPhase, options: [ MenuOptions.EGG_GACHA ]},
|
||||||
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ]}
|
{ condition: bypassLogin, options: [ MenuOptions.LOG_OUT ]}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import { pokemonFormLevelMoves, pokemonSpeciesLevelMoves } from "#app/data/balan
|
|||||||
import type PokemonSpecies from "#app/data/pokemon-species";
|
import type PokemonSpecies from "#app/data/pokemon-species";
|
||||||
import { allSpecies, getPokemonSpeciesForm, getPokerusStarters } from "#app/data/pokemon-species";
|
import { allSpecies, getPokemonSpeciesForm, getPokerusStarters } from "#app/data/pokemon-species";
|
||||||
import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUNT } from "#app/data/balance/starters";
|
||||||
import { starterPassiveAbilities } from "#app/data/balance/passives";
|
|
||||||
import { Type } from "#enums/type";
|
import { Type } from "#enums/type";
|
||||||
import { GameModes } from "#app/game-mode";
|
import { GameModes } from "#app/game-mode";
|
||||||
import type { DexAttrProps, DexEntry, StarterMoveset, StarterAttributes, StarterPreferences } from "#app/system/game-data";
|
import type { DexAttrProps, DexEntry, StarterMoveset, StarterAttributes, StarterPreferences } from "#app/system/game-data";
|
||||||
@ -276,14 +275,12 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
private abilityIconElement: Phaser.GameObjects.Sprite;
|
private abilityIconElement: Phaser.GameObjects.Sprite;
|
||||||
private genderIconElement: Phaser.GameObjects.Sprite;
|
private genderIconElement: Phaser.GameObjects.Sprite;
|
||||||
private natureIconElement: Phaser.GameObjects.Sprite;
|
private natureIconElement: Phaser.GameObjects.Sprite;
|
||||||
private variantIconElement: Phaser.GameObjects.Sprite;
|
|
||||||
private goFilterIconElement: Phaser.GameObjects.Sprite;
|
private goFilterIconElement: Phaser.GameObjects.Sprite;
|
||||||
private shinyLabel: Phaser.GameObjects.Text;
|
private shinyLabel: Phaser.GameObjects.Text;
|
||||||
private formLabel: Phaser.GameObjects.Text;
|
private formLabel: Phaser.GameObjects.Text;
|
||||||
private genderLabel: Phaser.GameObjects.Text;
|
private genderLabel: Phaser.GameObjects.Text;
|
||||||
private abilityLabel: Phaser.GameObjects.Text;
|
private abilityLabel: Phaser.GameObjects.Text;
|
||||||
private natureLabel: Phaser.GameObjects.Text;
|
private natureLabel: Phaser.GameObjects.Text;
|
||||||
private variantLabel: Phaser.GameObjects.Text;
|
|
||||||
private goFilterLabel: Phaser.GameObjects.Text;
|
private goFilterLabel: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
private starterSelectMessageBox: Phaser.GameObjects.NineSlice;
|
||||||
@ -319,7 +316,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
private canCycleGender: boolean;
|
private canCycleGender: boolean;
|
||||||
private canCycleAbility: boolean;
|
private canCycleAbility: boolean;
|
||||||
private canCycleNature: boolean;
|
private canCycleNature: boolean;
|
||||||
private canCycleVariant: boolean;
|
|
||||||
|
|
||||||
private assetLoadCancelled: BooleanHolder | null;
|
private assetLoadCancelled: BooleanHolder | null;
|
||||||
public cursorObj: Phaser.GameObjects.Image;
|
public cursorObj: Phaser.GameObjects.Image;
|
||||||
@ -875,13 +871,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.natureLabel = addTextObject(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleNature"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
this.natureLabel = addTextObject(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleNature"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
||||||
this.natureLabel.setName("text-nature-label");
|
this.natureLabel.setName("text-nature-label");
|
||||||
|
|
||||||
this.variantIconElement = new Phaser.GameObjects.Sprite(globalScene, this.instructionRowX, this.instructionRowY, "keyboard", "V.png");
|
|
||||||
this.variantIconElement.setName("sprite-variant-icon-element");
|
|
||||||
this.variantIconElement.setScale(0.675);
|
|
||||||
this.variantIconElement.setOrigin(0.0, 0.0);
|
|
||||||
this.variantLabel = addTextObject(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY, i18next.t("starterSelectUiHandler:cycleVariant"), TextStyle.PARTY, { fontSize: instructionTextSize });
|
|
||||||
this.variantLabel.setName("text-variant-label");
|
|
||||||
|
|
||||||
this.goFilterIconElement = new Phaser.GameObjects.Sprite(globalScene, this.filterInstructionRowX, this.filterInstructionRowY, "keyboard", "C.png");
|
this.goFilterIconElement = new Phaser.GameObjects.Sprite(globalScene, this.filterInstructionRowX, this.filterInstructionRowY, "keyboard", "C.png");
|
||||||
this.goFilterIconElement.setName("sprite-goFilter-icon-element");
|
this.goFilterIconElement.setName("sprite-goFilter-icon-element");
|
||||||
this.goFilterIconElement.setScale(0.675);
|
this.goFilterIconElement.setScale(0.675);
|
||||||
@ -1858,7 +1847,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
if (!(passiveAttr & PassiveAttr.UNLOCKED)) {
|
if (!(passiveAttr & PassiveAttr.UNLOCKED)) {
|
||||||
const passiveCost = getPassiveCandyCount(speciesStarterCosts[this.lastSpecies.speciesId]);
|
const passiveCost = getPassiveCandyCount(speciesStarterCosts[this.lastSpecies.speciesId]);
|
||||||
options.push({
|
options.push({
|
||||||
label: `x${passiveCost} ${i18next.t("starterSelectUiHandler:unlockPassive")} (${allAbilities[starterPassiveAbilities[this.lastSpecies.speciesId]].name})`,
|
label: `x${passiveCost} ${i18next.t("starterSelectUiHandler:unlockPassive")} (${allAbilities[this.lastSpecies.getPassiveAbility()].name})`,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= passiveCost) {
|
if (Overrides.FREE_CANDY_UPGRADE_OVERRIDE || candyCount >= passiveCost) {
|
||||||
starterData.passiveAttr |= PassiveAttr.UNLOCKED | PassiveAttr.ENABLED;
|
starterData.passiveAttr |= PassiveAttr.UNLOCKED | PassiveAttr.ENABLED;
|
||||||
@ -2003,29 +1992,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
switch (button) {
|
switch (button) {
|
||||||
case Button.CYCLE_SHINY:
|
case Button.CYCLE_SHINY:
|
||||||
if (this.canCycleShiny) {
|
if (this.canCycleShiny) {
|
||||||
starterAttributes.shiny = starterAttributes.shiny !== undefined ? !starterAttributes.shiny : false;
|
if (starterAttributes.shiny === false) {
|
||||||
|
// If not shiny, we change to shiny and get the proper default variant
|
||||||
if (starterAttributes.shiny) {
|
|
||||||
// Change to shiny, we need to get the proper default variant
|
|
||||||
const newProps = globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId));
|
const newProps = globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId));
|
||||||
const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : newProps.variant;
|
const newVariant = starterAttributes.variant ? starterAttributes.variant as Variant : newProps.variant;
|
||||||
this.setSpeciesDetails(this.lastSpecies, { shiny: true, variant: newVariant });
|
this.setSpeciesDetails(this.lastSpecies, { shiny: true, variant: newVariant });
|
||||||
|
|
||||||
globalScene.playSound("se/sparkle");
|
globalScene.playSound("se/sparkle");
|
||||||
// Set the variant label to the shiny tint
|
// Cycle tint based on current sprite tint
|
||||||
const tint = getVariantTint(newVariant);
|
const tint = getVariantTint(newVariant);
|
||||||
this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant));
|
this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant));
|
||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
this.pokemonShinyIcon.setVisible(true);
|
this.pokemonShinyIcon.setVisible(true);
|
||||||
|
|
||||||
|
starterAttributes.shiny = true;
|
||||||
} else {
|
} else {
|
||||||
this.setSpeciesDetails(this.lastSpecies, { shiny: false, variant: 0 });
|
// If shiny, we update the variant
|
||||||
this.pokemonShinyIcon.setVisible(false);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Button.V:
|
|
||||||
if (this.canCycleVariant) {
|
|
||||||
let newVariant = props.variant;
|
let newVariant = props.variant;
|
||||||
do {
|
do {
|
||||||
newVariant = (newVariant + 1) % 3;
|
newVariant = (newVariant + 1) % 3;
|
||||||
@ -2044,12 +2026,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
}
|
}
|
||||||
} while (newVariant !== props.variant);
|
} while (newVariant !== props.variant);
|
||||||
starterAttributes.variant = newVariant; // store the selected variant
|
starterAttributes.variant = newVariant; // store the selected variant
|
||||||
|
// If going to a higher variant, display that
|
||||||
|
if (newVariant > props.variant) {
|
||||||
this.setSpeciesDetails(this.lastSpecies, { variant: newVariant as Variant });
|
this.setSpeciesDetails(this.lastSpecies, { variant: newVariant as Variant });
|
||||||
// Cycle tint based on current sprite tint
|
// Cycle tint based on current sprite tint
|
||||||
const tint = getVariantTint(newVariant as Variant);
|
const tint = getVariantTint(newVariant as Variant);
|
||||||
this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant as Variant));
|
this.pokemonShinyIcon.setFrame(getVariantIcon(newVariant as Variant));
|
||||||
this.pokemonShinyIcon.setTint(tint);
|
this.pokemonShinyIcon.setTint(tint);
|
||||||
success = true;
|
success = true;
|
||||||
|
// If we have run out of variants, go back to non shiny
|
||||||
|
} else {
|
||||||
|
this.setSpeciesDetails(this.lastSpecies, { shiny: false, variant: 0 });
|
||||||
|
this.pokemonShinyIcon.setVisible(false);
|
||||||
|
success = true;
|
||||||
|
starterAttributes.shiny = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Button.CYCLE_FORM:
|
case Button.CYCLE_FORM:
|
||||||
@ -2376,9 +2368,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
case SettingKeyboard.Button_Cycle_Nature:
|
case SettingKeyboard.Button_Cycle_Nature:
|
||||||
iconPath = "N.png";
|
iconPath = "N.png";
|
||||||
break;
|
break;
|
||||||
case SettingKeyboard.Button_Cycle_Variant:
|
|
||||||
iconPath = "V.png";
|
|
||||||
break;
|
|
||||||
case SettingKeyboard.Button_Stats:
|
case SettingKeyboard.Button_Stats:
|
||||||
iconPath = "C.png";
|
iconPath = "C.png";
|
||||||
break;
|
break;
|
||||||
@ -2459,9 +2448,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
if (this.canCycleNature) {
|
if (this.canCycleNature) {
|
||||||
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Nature, gamepadType, this.natureIconElement, this.natureLabel);
|
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Nature, gamepadType, this.natureIconElement, this.natureLabel);
|
||||||
}
|
}
|
||||||
if (this.canCycleVariant) {
|
|
||||||
this.updateButtonIcon(SettingKeyboard.Button_Cycle_Variant, gamepadType, this.variantIconElement, this.variantLabel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if filter mode is inactivated and gamepadType is not undefined, update the button icons
|
// if filter mode is inactivated and gamepadType is not undefined, update the button icons
|
||||||
@ -3266,12 +3252,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
|
|
||||||
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
const isNonShinyCaught = !!(caughtAttr & DexAttr.NON_SHINY);
|
||||||
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
const isShinyCaught = !!(caughtAttr & DexAttr.SHINY);
|
||||||
const isVariant1Caught = isShinyCaught && !!(caughtAttr & DexAttr.DEFAULT_VARIANT);
|
|
||||||
const isVariant2Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_2);
|
|
||||||
const isVariant3Caught = isShinyCaught && !!(caughtAttr & DexAttr.VARIANT_3);
|
|
||||||
|
|
||||||
this.canCycleShiny = isNonShinyCaught && isShinyCaught;
|
this.canCycleShiny = isNonShinyCaught && isShinyCaught;
|
||||||
this.canCycleVariant = !!shiny && [ isVariant1Caught, isVariant2Caught, isVariant3Caught ].filter(v => v).length > 1;
|
|
||||||
|
|
||||||
const isMaleCaught = !!(caughtAttr & DexAttr.MALE);
|
const isMaleCaught = !!(caughtAttr & DexAttr.MALE);
|
||||||
const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE);
|
const isFemaleCaught = !!(caughtAttr & DexAttr.FEMALE);
|
||||||
@ -3316,7 +3298,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.pokemonAbilityText.setShadowColor(this.getTextColor(!isHidden ? TextStyle.SUMMARY_ALT : TextStyle.SUMMARY_GOLD, true));
|
this.pokemonAbilityText.setShadowColor(this.getTextColor(!isHidden ? TextStyle.SUMMARY_ALT : TextStyle.SUMMARY_GOLD, true));
|
||||||
|
|
||||||
const passiveAttr = globalScene.gameData.starterData[species.speciesId].passiveAttr;
|
const passiveAttr = globalScene.gameData.starterData[species.speciesId].passiveAttr;
|
||||||
const passiveAbility = allAbilities[starterPassiveAbilities[this.lastSpecies.speciesId]];
|
const passiveAbility = allAbilities[this.lastSpecies.getPassiveAbility(formIndex)];
|
||||||
|
|
||||||
if (this.pokemonAbilityText.visible) {
|
if (this.pokemonAbilityText.visible) {
|
||||||
if (this.activeTooltip === "ABILITY") {
|
if (this.activeTooltip === "ABILITY") {
|
||||||
@ -3830,8 +3812,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
|||||||
this.abilityLabel.setVisible(false);
|
this.abilityLabel.setVisible(false);
|
||||||
this.natureIconElement.setVisible(false);
|
this.natureIconElement.setVisible(false);
|
||||||
this.natureLabel.setVisible(false);
|
this.natureLabel.setVisible(false);
|
||||||
this.variantIconElement.setVisible(false);
|
|
||||||
this.variantLabel.setVisible(false);
|
|
||||||
this.goFilterIconElement.setVisible(false);
|
this.goFilterIconElement.setVisible(false);
|
||||||
this.goFilterLabel.setVisible(false);
|
this.goFilterLabel.setVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([ Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE ].includes(this.mode)) {
|
if ([ Mode.CONFIRM, Mode.COMMAND, Mode.FIGHT, Mode.MESSAGE, Mode.TARGET_SELECT ].includes(this.mode)) {
|
||||||
globalScene?.processInfoButton(pressed);
|
globalScene?.processInfoButton(pressed);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -277,6 +277,11 @@ export default class UI extends Phaser.GameObjects.Container {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a player input of a button (delivering it to the current UI handler for processing)
|
||||||
|
* @param button The {@linkcode Button} being inputted
|
||||||
|
* @returns true if the input attempt succeeds
|
||||||
|
*/
|
||||||
processInput(button: Button): boolean {
|
processInput(button: Button): boolean {
|
||||||
if (this.overlayActive) {
|
if (this.overlayActive) {
|
||||||
return false;
|
return false;
|
||||||
|