mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-19 06:42:20 +02:00
Merge 68016ca9c6
into 6add614e1c
This commit is contained in:
commit
b7cfb46a9a
@ -170,6 +170,7 @@ import { StatusEffect } from "#enums/status-effect";
|
|||||||
import { initGlobalScene } from "#app/global-scene";
|
import { initGlobalScene } from "#app/global-scene";
|
||||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||||
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
|
import { HideAbilityPhase } from "#app/phases/hide-ability-phase";
|
||||||
|
import { applyChallenges, ChallengeType } from "./data/challenge";
|
||||||
|
|
||||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||||
|
|
||||||
@ -1082,6 +1083,8 @@ export default class BattleScene extends SceneBase {
|
|||||||
postProcess(pokemon);
|
postProcess(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, pokemon);
|
||||||
|
|
||||||
for (let i = 0; i < pokemon.ivs.length; i++) {
|
for (let i = 0; i < pokemon.ivs.length; i++) {
|
||||||
if (OPP_IVS_OVERRIDE_VALIDATED[i] > -1) {
|
if (OPP_IVS_OVERRIDE_VALIDATED[i] > -1) {
|
||||||
pokemon.ivs[i] = OPP_IVS_OVERRIDE_VALIDATED[i];
|
pokemon.ivs[i] = OPP_IVS_OVERRIDE_VALIDATED[i];
|
||||||
|
@ -14,6 +14,8 @@ import { DamageMoneyRewardModifier, ExtraModifierModifier, MoneyMultiplierModifi
|
|||||||
import { SpeciesFormKey } from "#enums/species-form-key";
|
import { SpeciesFormKey } from "#enums/species-form-key";
|
||||||
import { speciesStarterCosts } from "./starters";
|
import { speciesStarterCosts } from "./starters";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
import { Stat } from "#enums/stat";
|
||||||
|
|
||||||
|
|
||||||
export enum SpeciesWildEvolutionDelay {
|
export enum SpeciesWildEvolutionDelay {
|
||||||
@ -90,7 +92,7 @@ export class SpeciesFormEvolution {
|
|||||||
public evoFormKey: string | null;
|
public evoFormKey: string | null;
|
||||||
public level: number;
|
public level: number;
|
||||||
public item: EvolutionItem | null;
|
public item: EvolutionItem | null;
|
||||||
public condition: SpeciesEvolutionCondition | null;
|
public condition: SpeciesEvolutionCondition | null; // TODO: Add a ChallengeType to change evolution conditions based on what kind of condition it is (use an enum)
|
||||||
public wildDelay: SpeciesWildEvolutionDelay;
|
public wildDelay: SpeciesWildEvolutionDelay;
|
||||||
public description = "";
|
public description = "";
|
||||||
|
|
||||||
@ -179,7 +181,8 @@ class TimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
class MoveEvolutionCondition extends SpeciesEvolutionCondition {
|
class MoveEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
public move: Moves;
|
public move: Moves;
|
||||||
constructor(move: Moves) {
|
constructor(move: Moves) {
|
||||||
super(p => p.moveset.filter(m => m.moveId === move).length > 0);
|
// TODO: Remove deprecated Challenge check
|
||||||
|
super(p => p.moveset.filter(m => m.moveId === move).length > 0 || globalScene.gameMode.hasChallenge(Challenges.METRONOME));
|
||||||
this.move = 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("");
|
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`) });
|
this.description = i18next.t("pokemonEvolutions:move", { move: i18next.t(`move:${moveKey}.name`) });
|
||||||
@ -218,7 +221,13 @@ class FriendshipMoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
public amount: number;
|
public amount: number;
|
||||||
public type: PokemonType;
|
public type: PokemonType;
|
||||||
constructor(amount: number, type: PokemonType) {
|
constructor(amount: number, type: PokemonType) {
|
||||||
super(p => p.friendship >= amount && !!p.getMoveset().find(m => m?.getMove().type === type));
|
// TODO: Remove deprecated Challenge check
|
||||||
|
super(p =>
|
||||||
|
p.friendship >= amount &&
|
||||||
|
(!!p.getMoveset().find(m => m?.getMove().type === type ||
|
||||||
|
(globalScene.gameMode.hasChallenge(Challenges.METRONOME) &&
|
||||||
|
!!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(type) > -1)
|
||||||
|
))));
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.description = i18next.t("pokemonEvolutions:friendshipMoveType", { type: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) });
|
this.description = i18next.t("pokemonEvolutions:friendshipMoveType", { type: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) });
|
||||||
@ -262,7 +271,10 @@ class WeatherEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
class MoveTypeEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
public type: PokemonType;
|
public type: PokemonType;
|
||||||
constructor(type: PokemonType) {
|
constructor(type: PokemonType) {
|
||||||
super(p => p.moveset.filter(m => m?.getMove().type === type).length > 0);
|
// TODO: Remove deprecated Challenge check
|
||||||
|
super(p => p.moveset.filter(m => m?.getMove().type === type).length > 0 ||
|
||||||
|
(globalScene.gameMode.hasChallenge(Challenges.METRONOME) &&
|
||||||
|
!!globalScene.getPlayerParty().find(p => p.getTypes(false, false, true).indexOf(type) > -1)));
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.description = i18next.t("pokemonEvolutions:moveType", { type: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) });
|
this.description = i18next.t("pokemonEvolutions:moveType", { type: i18next.t(`pokemonInfo:Type.${PokemonType[this.type]}`) });
|
||||||
}
|
}
|
||||||
@ -281,7 +293,13 @@ class TreasureEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
class TyrogueEvolutionCondition extends SpeciesEvolutionCondition {
|
class TyrogueEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
public move: Moves;
|
public move: Moves;
|
||||||
constructor(move: Moves) {
|
constructor(move: Moves) {
|
||||||
|
// TODO: Remove deprecated Challenge check
|
||||||
super(p =>
|
super(p =>
|
||||||
|
(globalScene.gameMode.hasChallenge(Challenges.METRONOME) && ( // Metronome mode = no moves, do it the old fashioned way
|
||||||
|
(move === Moves.LOW_SWEEP && p.stats[Stat.ATK] > p.stats[Stat.DEF]) ||
|
||||||
|
(move === Moves.MACH_PUNCH && p.stats[Stat.DEF] > p.stats[Stat.ATK]) ||
|
||||||
|
(move === Moves.RAPID_SPIN && p.stats[Stat.DEF] === p.stats[Stat.ATK])
|
||||||
|
)) ||
|
||||||
p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m.moveId))?.moveId === move);
|
p.getMoveset(true).find(m => m && [ Moves.LOW_SWEEP, Moves.MACH_PUNCH, Moves.RAPID_SPIN ].includes(m.moveId))?.moveId === move);
|
||||||
this.move = 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("");
|
const moveKey = Moves[this.move].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("");
|
||||||
@ -302,12 +320,19 @@ class MoveTimeOfDayEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
public move: Moves;
|
public move: Moves;
|
||||||
public timesOfDay: TimeOfDay[];
|
public timesOfDay: TimeOfDay[];
|
||||||
constructor(move: Moves, tod: "day" | "night") {
|
constructor(move: Moves, tod: "day" | "night") {
|
||||||
|
// TODO: Remove deprecated Challenge check
|
||||||
if (tod === "day") {
|
if (tod === "day") {
|
||||||
super(p => p.moveset.filter(m => m.moveId === move).length > 0 && (globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY));
|
super(p =>
|
||||||
|
(p.moveset.filter(m => m.moveId === move).length > 0 ||
|
||||||
|
globalScene.gameMode.hasChallenge(Challenges.METRONOME)) &&
|
||||||
|
(globalScene.arena.getTimeOfDay() === TimeOfDay.DAWN || globalScene.arena.getTimeOfDay() === TimeOfDay.DAY));
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ];
|
this.timesOfDay = [ TimeOfDay.DAWN, TimeOfDay.DAY ];
|
||||||
} else if (tod === "night") {
|
} 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));
|
super(p =>
|
||||||
|
(p.moveset.filter(m => m.moveId === move).length > 0 ||
|
||||||
|
globalScene.gameMode.hasChallenge(Challenges.METRONOME)) &&
|
||||||
|
(globalScene.arena.getTimeOfDay() === TimeOfDay.DUSK || globalScene.arena.getTimeOfDay() === TimeOfDay.NIGHT));
|
||||||
this.move = move;
|
this.move = move;
|
||||||
this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ];
|
this.timesOfDay = [ TimeOfDay.DUSK, TimeOfDay.NIGHT ];
|
||||||
} else {
|
} else {
|
||||||
@ -330,9 +355,10 @@ class BiomeEvolutionCondition extends SpeciesEvolutionCondition {
|
|||||||
|
|
||||||
class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
|
class DunsparceEvolutionCondition extends SpeciesEvolutionCondition {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
// TODO: Remove deprecated Challenge check
|
||||||
super(p => {
|
super(p => {
|
||||||
let ret = false;
|
let ret = false;
|
||||||
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) {
|
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0 || globalScene.gameMode.hasChallenge(Challenges.METRONOME)) {
|
||||||
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
globalScene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -6,7 +6,7 @@ import type PokemonSpecies from "#app/data/pokemon-species";
|
|||||||
import { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
import { getPokemonSpecies, getPokemonSpeciesForm } from "#app/data/pokemon-species";
|
||||||
import { speciesStarterCosts } from "#app/data/balance/starters";
|
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 { type EnemyPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import type { FixedBattleConfig } from "#app/battle";
|
import type { FixedBattleConfig } from "#app/battle";
|
||||||
import { ClassicFixedBossWaves, BattleType, getRandomTrainerFunc } from "#app/battle";
|
import { ClassicFixedBossWaves, BattleType, getRandomTrainerFunc } from "#app/battle";
|
||||||
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
import Trainer, { TrainerVariant } from "#app/field/trainer";
|
||||||
@ -15,12 +15,14 @@ import { Challenges } from "#enums/challenges";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import type { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { TypeColor, TypeShadow } from "#enums/color";
|
import { TypeColor, TypeShadow } from "#enums/color";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import { pokemonFormChanges } from "./pokemon-forms";
|
import { pokemonFormChanges } from "./pokemon-forms";
|
||||||
import { pokemonEvolutions } from "./balance/pokemon-evolutions";
|
import { pokemonEvolutions } from "./balance/pokemon-evolutions";
|
||||||
|
import { ModifierPoolType, type ModifierPool, type ModifierTypeOption } from "#app/modifier/modifier-type";
|
||||||
|
import type { LearnMoveType } from "#app/phases/learn-move-phase";
|
||||||
|
|
||||||
/** 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;
|
||||||
@ -93,6 +95,26 @@ export enum ChallengeType {
|
|||||||
* Modifies what the pokemon stats for Flip Stat Mode.
|
* Modifies what the pokemon stats for Flip Stat Mode.
|
||||||
*/
|
*/
|
||||||
FLIP_STAT,
|
FLIP_STAT,
|
||||||
|
/**
|
||||||
|
* Modifies enemy mons AFTER post process function
|
||||||
|
*/
|
||||||
|
ENEMY_POKEMON_MODIFY,
|
||||||
|
/**
|
||||||
|
* Prevents the learning of moves
|
||||||
|
*/
|
||||||
|
BAN_MOVE_LEARNING,
|
||||||
|
/**
|
||||||
|
* Negates PP Usage
|
||||||
|
*/
|
||||||
|
MODIFY_PP_USE,
|
||||||
|
/**
|
||||||
|
* Modifies modifier pools of specified type
|
||||||
|
*/
|
||||||
|
MODIFIER_POOL_MODIFY,
|
||||||
|
/**
|
||||||
|
* Modifies the shop options
|
||||||
|
*/
|
||||||
|
SHOP_MODIFY,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,6 +448,57 @@ export abstract class Challenge {
|
|||||||
applyFlipStat(_pokemon: Pokemon, _baseStats: number[]) {
|
applyFlipStat(_pokemon: Pokemon, _baseStats: number[]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for ENEMY_POKEMON_MODIFY. Derived classes should alter this.
|
||||||
|
* @param _pokemon {@link EnemyPokemon} the mon to be modified
|
||||||
|
* @returns {@link boolean} Whether this function did anything.
|
||||||
|
*/
|
||||||
|
applyEnemyPokemonModify(_pokemon: EnemyPokemon) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for BAN_MOVE_LEARNING. Derived classes should alter this.
|
||||||
|
* @param _pokemon {@link Pokemon} Pokemon who wants to learn the move
|
||||||
|
* @param _move {@link Moves} Move being learned
|
||||||
|
* @param _learnType {@link LearnMoveType} How the move is being learned
|
||||||
|
* @param _valid: {@link BooleanHolder} Whether the move is valid for this challenge
|
||||||
|
* @returns {@link boolean} Whether the move should be restricted from learning
|
||||||
|
*/
|
||||||
|
applyBanMoveLearning(_pokemon: Pokemon, _move: Moves, _learnType: LearnMoveType, _valid: Utils.BooleanHolder) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for MODIFY_PP_USE. Derived classes should alter this.
|
||||||
|
* @param _pokemon {@link Pokemon} Pokemon using the move
|
||||||
|
* @param _move {@link Moves} Move being used
|
||||||
|
* @param _usedPP {@link Utils.NumberHolder} Holds the value associated with how much PP should be used
|
||||||
|
* @returns {@link boolean} Whether this function did anything.
|
||||||
|
*/
|
||||||
|
applyModifyPPUsage(_pokemon: Pokemon, _move: Moves, _usedPP: Utils.NumberHolder) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for MODIFIER_POOL_MODIFY. Derived classes should alter this.
|
||||||
|
* @param _poolType {@link ModifierPoolType} What kind of item pool
|
||||||
|
* @param _modifierPool {@link ModifierPool} Pool to modify
|
||||||
|
* @returns {@link boolean} Whether this function did anything.
|
||||||
|
*/
|
||||||
|
applyModifierPoolModify(_poolType: ModifierPoolType, _modifierPool: ModifierPool) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An apply function for SHOP_MODIFY. Derived classes should alter this.
|
||||||
|
* @param _options {@link ModifierTypeOption} Array of shop options
|
||||||
|
* @returns {@link boolean} Whether this function did anything.
|
||||||
|
*/
|
||||||
|
applyShopModify(_options: ModifierTypeOption[]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChallengeCondition = (data: GameData) => boolean;
|
type ChallengeCondition = (data: GameData) => boolean;
|
||||||
@ -833,6 +906,29 @@ export class FreshStartChallenge extends Challenge {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override applyModifierPoolModify(poolType: ModifierPoolType, modifierPool: ModifierPool): boolean {
|
||||||
|
if (poolType !== ModifierPoolType.PLAYER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let ret = false;
|
||||||
|
|
||||||
|
let idx;
|
||||||
|
const bans = ["EVIOLITE", "MINI_BLACK_HOLE"];
|
||||||
|
const t = [ModifierTier.COMMON, ModifierTier.GREAT, ModifierTier.ULTRA, ModifierTier.ROGUE, ModifierTier.MASTER];
|
||||||
|
for (let i = 0; i < t.length; i++) {
|
||||||
|
idx = 0;
|
||||||
|
while (idx > -1) {
|
||||||
|
idx = modifierPool[t[i]].findIndex(p => bans.includes(p.modifierType.id));
|
||||||
|
if (idx > -1) {
|
||||||
|
modifierPool[t[i]].splice(idx, 1);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
override getDifficulty(): number {
|
override getDifficulty(): number {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -864,6 +960,14 @@ export class InverseBattleChallenge extends Challenge {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override applyEnemyPokemonModify(pokemon: EnemyPokemon): boolean {
|
||||||
|
if (pokemon.species.speciesId === Species.ETERNATUS) {
|
||||||
|
pokemon.moveset[2] = new PokemonMove(Moves.THUNDERBOLT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
applyTypeEffectiveness(effectiveness: Utils.NumberHolder): boolean {
|
applyTypeEffectiveness(effectiveness: Utils.NumberHolder): boolean {
|
||||||
if (effectiveness.value < 1) {
|
if (effectiveness.value < 1) {
|
||||||
effectiveness.value = 2;
|
effectiveness.value = 2;
|
||||||
@ -905,6 +1009,97 @@ export class FlipStatChallenge extends Challenge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MetronomeChallenge extends Challenge {
|
||||||
|
constructor() {
|
||||||
|
super(Challenges.METRONOME, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
override applyStarterModify(pokemon: Pokemon): boolean {
|
||||||
|
pokemon.moveset = [new PokemonMove(Moves.METRONOME, 0, 3)];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override applyEnemyPokemonModify(pokemon: EnemyPokemon): boolean {
|
||||||
|
pokemon.moveset = [new PokemonMove(Moves.METRONOME, 0, 3)];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override applyBanMoveLearning(
|
||||||
|
_pokemon: Pokemon,
|
||||||
|
_move: Moves,
|
||||||
|
_learnType: LearnMoveType,
|
||||||
|
valid: Utils.BooleanHolder,
|
||||||
|
): boolean {
|
||||||
|
valid.value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure 0 PP is used, called when applying other PP usage modifiers such as Pressure
|
||||||
|
* @param _pokemon {@link Pokemon} unused
|
||||||
|
* @param _move {@link Moves} unused
|
||||||
|
* @param usedPP
|
||||||
|
* @returns true
|
||||||
|
*/
|
||||||
|
override applyModifyPPUsage(_pokemon: Pokemon, _move: Moves, usedPP: Utils.NumberHolder): boolean {
|
||||||
|
usedPP.value = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
override applyModifierPoolModify(poolType: ModifierPoolType, modifierPool: ModifierPool): boolean {
|
||||||
|
if (poolType !== ModifierPoolType.PLAYER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let ret = false;
|
||||||
|
|
||||||
|
let idx;
|
||||||
|
const bans = [
|
||||||
|
"TM_COMMON",
|
||||||
|
"ETHER",
|
||||||
|
"MAX_ETHER",
|
||||||
|
"ELIXIR",
|
||||||
|
"MAX_ELIXIR",
|
||||||
|
"PP_UP",
|
||||||
|
"MEMORY_MUSHROOM",
|
||||||
|
"TM_GREAT",
|
||||||
|
"TM_ULTRA",
|
||||||
|
"PP_MAX",
|
||||||
|
];
|
||||||
|
const t = [ModifierTier.COMMON, ModifierTier.GREAT, ModifierTier.ULTRA, ModifierTier.ROGUE, ModifierTier.MASTER];
|
||||||
|
for (let i = 0; i < t.length; i++) {
|
||||||
|
idx = 0;
|
||||||
|
while (idx > -1) {
|
||||||
|
idx = modifierPool[t[i]].findIndex(p => bans.includes(p.modifierType.id));
|
||||||
|
if (idx > -1) {
|
||||||
|
modifierPool[t[i]].splice(idx, 1);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
override applyShopModify(options: ModifierTypeOption[]): boolean {
|
||||||
|
const removals = ["ETHER", "MAX_ETHER", "ELIXIR", "MAX_ELIXIR", "MEMORY_MUSHROOM"]; // Pending rework, these need to match locale key
|
||||||
|
const opstart = options.length;
|
||||||
|
removals.map(r => {
|
||||||
|
const idx = options.findIndex(o => o.type.localeKey.split(".")[1] === r); // Currently the quickest way to get the id
|
||||||
|
if (idx >= 0) {
|
||||||
|
options.splice(idx, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return opstart > options.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static loadChallenge(source: MetronomeChallenge | any): MetronomeChallenge {
|
||||||
|
const newChallenge = new MetronomeChallenge();
|
||||||
|
newChallenge.value = source.value;
|
||||||
|
newChallenge.severity = source.severity;
|
||||||
|
return newChallenge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lowers the amount of starter points available.
|
* Lowers the amount of starter points available.
|
||||||
*/
|
*/
|
||||||
@ -1125,6 +1320,66 @@ export function applyChallenges(
|
|||||||
|
|
||||||
export function applyChallenges(challengeType: ChallengeType.FLIP_STAT, pokemon: Pokemon, baseStats: number[]): boolean;
|
export function applyChallenges(challengeType: ChallengeType.FLIP_STAT, pokemon: Pokemon, baseStats: number[]): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all challenges that modify Enemy Pokemon generation (after post process funcs)
|
||||||
|
* @param challengeType {@link ChallengeType} ChallengeType.ENEMY_POKEMON_MODIFY
|
||||||
|
* @param pokemon {@link EnemyPokemon} Pokemon to be modified
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(challengeType: ChallengeType.ENEMY_POKEMON_MODIFY, pokemon: EnemyPokemon): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all challenges that restrict Pokemon from learning certain moves
|
||||||
|
* @param challengeType {@link ChallengeType} ChallengeType.BAN_MOVE_LEARNING
|
||||||
|
* @param pokemon {@link Pokemon} The mon attempting to learn
|
||||||
|
* @param move {@link Moves} The move being learned
|
||||||
|
* @param learnType {@link LearnMoveType} how the move is being learned
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(
|
||||||
|
challengeType: ChallengeType.BAN_MOVE_LEARNING,
|
||||||
|
pokemon: Pokemon,
|
||||||
|
move: Moves,
|
||||||
|
learnType: LearnMoveType,
|
||||||
|
valid: Utils.BooleanHolder,
|
||||||
|
): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all challenges that modify how much PP is used
|
||||||
|
* @param challengeType {@link ChallengeType} ChallengeType.MODIFY_PP_USE
|
||||||
|
* @param pokemon {@link Pokemon} Pokemon using the move
|
||||||
|
* @param move {@link Moves} Move being used
|
||||||
|
* @param usedPP {@link Utils.NumberHolder} Holds the value associated with how much PP should be used
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(
|
||||||
|
challengeType: ChallengeType.MODIFY_PP_USE,
|
||||||
|
pokemon: Pokemon,
|
||||||
|
move: Moves,
|
||||||
|
usedPP: Utils.NumberHolder,
|
||||||
|
): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all challenges that modify modifier pools //TODO: Modifier rework will need to look at this
|
||||||
|
* @param challengeType {@link ChallengeType} ChallengeType.MODIFIER_POOL_MODIFY
|
||||||
|
* @param poolType {@link ModifierPoolType} Which kind of pool is being changed (wild held items, player rewards etc)
|
||||||
|
* @param modifierPool {@link ModifierPool} The item pool the challenge may attempt to modify
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(
|
||||||
|
challengeType: ChallengeType.MODIFIER_POOL_MODIFY,
|
||||||
|
poolType: ModifierPoolType,
|
||||||
|
modifierPool: ModifierPool,
|
||||||
|
): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply all challenges that modify the shop
|
||||||
|
* @param challengeType ChallengeType.SHOP_MODIFY
|
||||||
|
* @param options {@link ModifierTypeOption} List of shop options including the prices
|
||||||
|
* @returns True if any challenge was successfully applied.
|
||||||
|
*/
|
||||||
|
export function applyChallenges(challengeType: ChallengeType.SHOP_MODIFY, options: ModifierTypeOption[]): boolean;
|
||||||
|
|
||||||
export function applyChallenges(challengeType: ChallengeType, ...args: any[]): boolean {
|
export function applyChallenges(challengeType: ChallengeType, ...args: any[]): boolean {
|
||||||
let ret = false;
|
let ret = false;
|
||||||
globalScene.gameMode.challenges.forEach(c => {
|
globalScene.gameMode.challenges.forEach(c => {
|
||||||
@ -1172,6 +1427,21 @@ export function applyChallenges(challengeType: ChallengeType, ...args: any[]): b
|
|||||||
case ChallengeType.FLIP_STAT:
|
case ChallengeType.FLIP_STAT:
|
||||||
ret ||= c.applyFlipStat(args[0], args[1]);
|
ret ||= c.applyFlipStat(args[0], args[1]);
|
||||||
break;
|
break;
|
||||||
|
case ChallengeType.ENEMY_POKEMON_MODIFY:
|
||||||
|
ret ||= c.applyEnemyPokemonModify(args[0]);
|
||||||
|
break;
|
||||||
|
case ChallengeType.BAN_MOVE_LEARNING:
|
||||||
|
ret ||= c.applyBanMoveLearning(args[0], args[1], args[2], args[3]);
|
||||||
|
break;
|
||||||
|
case ChallengeType.MODIFY_PP_USE:
|
||||||
|
ret ||= c.applyModifyPPUsage(args[0], args[1], args[2]);
|
||||||
|
break;
|
||||||
|
case ChallengeType.MODIFIER_POOL_MODIFY:
|
||||||
|
ret ||= c.applyModifierPoolModify(args[0], args[1]);
|
||||||
|
break;
|
||||||
|
case ChallengeType.SHOP_MODIFY:
|
||||||
|
ret ||= c.applyShopModify(args[0]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1199,6 +1469,8 @@ export function copyChallenge(source: Challenge | any): Challenge {
|
|||||||
return InverseBattleChallenge.loadChallenge(source);
|
return InverseBattleChallenge.loadChallenge(source);
|
||||||
case Challenges.FLIP_STAT:
|
case Challenges.FLIP_STAT:
|
||||||
return FlipStatChallenge.loadChallenge(source);
|
return FlipStatChallenge.loadChallenge(source);
|
||||||
|
case Challenges.METRONOME:
|
||||||
|
return MetronomeChallenge.loadChallenge(source);
|
||||||
}
|
}
|
||||||
throw new Error("Unknown challenge copied");
|
throw new Error("Unknown challenge copied");
|
||||||
}
|
}
|
||||||
@ -1212,6 +1484,7 @@ export function initChallenges() {
|
|||||||
new FreshStartChallenge(),
|
new FreshStartChallenge(),
|
||||||
new InverseBattleChallenge(),
|
new InverseBattleChallenge(),
|
||||||
new FlipStatChallenge(),
|
new FlipStatChallenge(),
|
||||||
|
new MetronomeChallenge(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8090,7 +8090,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const userTypes = user.getTypes();
|
const userTypes = user.getTypes();
|
||||||
const validTypes = this.getTypeResistances(globalScene.gameMode, moveData.type).filter(t => !userTypes.includes(t)); // valid types are ones that are not already the user's types
|
const validTypes = this.getTypeResistances(moveData.type).filter(t => !userTypes.includes(t)); // valid types are ones that are not already the user's types
|
||||||
if (!validTypes.length) {
|
if (!validTypes.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -8106,7 +8106,7 @@ export class ResistLastMoveTypeAttr extends MoveEffectAttr {
|
|||||||
* Retrieve the types resisting a given type. Used by Conversion 2
|
* Retrieve the types resisting a given type. Used by Conversion 2
|
||||||
* @returns An array populated with Types, or an empty array if no resistances exist (Unknown or Stellar type)
|
* @returns An array populated with Types, or an empty array if no resistances exist (Unknown or Stellar type)
|
||||||
*/
|
*/
|
||||||
getTypeResistances(gameMode: GameMode, type: number): PokemonType[] {
|
getTypeResistances(type: number): PokemonType[] {
|
||||||
const typeResistances: PokemonType[] = [];
|
const typeResistances: PokemonType[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < Object.keys(PokemonType).length; i++) {
|
for (let i = 0; i < Object.keys(PokemonType).length; i++) {
|
||||||
|
@ -54,6 +54,7 @@ import { allMoves } from "#app/data/moves/move";
|
|||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/bugTypeSuperfan";
|
const namespace = "mysteryEncounters/bugTypeSuperfan";
|
||||||
@ -190,6 +191,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
)
|
)
|
||||||
.withMaxAllowedEncounters(1)
|
.withMaxAllowedEncounters(1)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
|
@ -80,7 +80,7 @@ export const ClowningAroundEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
MysteryEncounterType.CLOWNING_AROUND,
|
MysteryEncounterType.CLOWNING_AROUND,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
.withDisallowedChallenges(Challenges.SINGLE_TYPE)
|
.withDisallowedChallenges(Challenges.SINGLE_TYPE, Challenges.METRONOME)
|
||||||
.withSceneWaveRangeRequirement(80, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
.withSceneWaveRangeRequirement(80, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withAnimations(EncounterAnim.SMOKESCREEN)
|
.withAnimations(EncounterAnim.SMOKESCREEN)
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
|
@ -41,6 +41,7 @@ import { PokeballType } from "#enums/pokeball";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounters/dancingLessons";
|
const namespace = "mysteryEncounters/dancingLessons";
|
||||||
@ -99,6 +100,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
||||||
.withAnimations(EncounterAnim.DANCE)
|
.withAnimations(EncounterAnim.DANCE)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
|
@ -11,6 +11,11 @@ import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounte
|
|||||||
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
||||||
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { CanLearnTMRequirement } from "../mystery-encounter-requirements";
|
||||||
|
import { globalScene } from "#app/global-scene";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounters/departmentStoreSale";
|
const namespace = "mysteryEncounters/departmentStoreSale";
|
||||||
@ -55,34 +60,37 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
.withTitle(`${namespace}:title`)
|
.withTitle(`${namespace}:title`)
|
||||||
.withDescription(`${namespace}:description`)
|
.withDescription(`${namespace}:description`)
|
||||||
.withQuery(`${namespace}:query`)
|
.withQuery(`${namespace}:query`)
|
||||||
.withSimpleOption(
|
.withOption(
|
||||||
{
|
MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
buttonLabel: `${namespace}:option.1.label`,
|
.withPrimaryPokemonRequirement(new CanLearnTMRequirement())
|
||||||
buttonTooltip: `${namespace}:option.1.tooltip`,
|
.withDialogue({
|
||||||
},
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
async () => {
|
buttonTooltip: `${namespace}:option.1.tooltip`,
|
||||||
// Choose TMs
|
})
|
||||||
const modifiers: ModifierTypeFunc[] = [];
|
.withOptionPhase(async () => {
|
||||||
let i = 0;
|
// Choose TMs
|
||||||
while (i < 5) {
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
// 2/2/1 weight on TM rarity
|
let i = 0;
|
||||||
const roll = randSeedInt(5);
|
while (i < 5) {
|
||||||
if (roll < 2) {
|
// 2/2/1 weight on TM rarity
|
||||||
modifiers.push(modifierTypes.TM_COMMON);
|
const roll = randSeedInt(5);
|
||||||
} else if (roll < 4) {
|
if (roll < 2) {
|
||||||
modifiers.push(modifierTypes.TM_GREAT);
|
modifiers.push(modifierTypes.TM_COMMON);
|
||||||
} else {
|
} else if (roll < 4) {
|
||||||
modifiers.push(modifierTypes.TM_ULTRA);
|
modifiers.push(modifierTypes.TM_GREAT);
|
||||||
|
} else {
|
||||||
|
modifiers.push(modifierTypes.TM_ULTRA);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
setEncounterRewards({
|
setEncounterRewards({
|
||||||
guaranteedModifierTypeFuncs: modifiers,
|
guaranteedModifierTypeFuncs: modifiers,
|
||||||
fillRemaining: false,
|
fillRemaining: false,
|
||||||
});
|
});
|
||||||
leaveEncounterWithoutBattle();
|
leaveEncounterWithoutBattle();
|
||||||
},
|
})
|
||||||
|
.build(),
|
||||||
)
|
)
|
||||||
.withSimpleOption(
|
.withSimpleOption(
|
||||||
{
|
{
|
||||||
@ -96,7 +104,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
|
|||||||
while (i < 3) {
|
while (i < 3) {
|
||||||
// 2/1 weight on base stat booster vs PP Up
|
// 2/1 weight on base stat booster vs PP Up
|
||||||
const roll = randSeedInt(3);
|
const roll = randSeedInt(3);
|
||||||
if (roll === 0) {
|
if (roll === 0 && !globalScene.gameMode.hasChallenge(Challenges.METRONOME)) {
|
||||||
modifiers.push(modifierTypes.PP_UP);
|
modifiers.push(modifierTypes.PP_UP);
|
||||||
} else {
|
} else {
|
||||||
modifiers.push(modifierTypes.BASE_STAT_BOOSTER);
|
modifiers.push(modifierTypes.BASE_STAT_BOOSTER);
|
||||||
|
@ -46,6 +46,7 @@ import { addPokemonDataToDexAndValidateAchievements } from "#app/data/mystery-en
|
|||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { doShinySparkleAnim } from "#app/field/anims";
|
import { doShinySparkleAnim } from "#app/field/anims";
|
||||||
import { TrainerType } from "#enums/trainer-type";
|
import { TrainerType } from "#enums/trainer-type";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/globalTradeSystem";
|
const namespace = "mysteryEncounters/globalTradeSystem";
|
||||||
@ -208,6 +209,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
|
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
|
||||||
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
|
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, receivedPokemonData);
|
||||||
const modifiers = tradedPokemon
|
const modifiers = tradedPokemon
|
||||||
.getHeldItems()
|
.getHeldItems()
|
||||||
.filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
|
.filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
|
||||||
@ -329,6 +331,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = MysteryEncounterBuil
|
|||||||
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
const encounter = globalScene.currentBattle.mysteryEncounter!;
|
||||||
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
|
const tradedPokemon: PlayerPokemon = encounter.misc.tradedPokemon;
|
||||||
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
|
const receivedPokemonData: EnemyPokemon = encounter.misc.receivedPokemon;
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, receivedPokemonData);
|
||||||
const modifiers = tradedPokemon
|
const modifiers = tradedPokemon
|
||||||
.getHeldItems()
|
.getHeldItems()
|
||||||
.filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
|
.filter(m => !(m instanceof PokemonFormChangeItemModifier) && !(m instanceof SpeciesStatBoosterModifier));
|
||||||
|
@ -22,6 +22,7 @@ import type { PlayerPokemon } from "#app/field/pokemon";
|
|||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/partTimer";
|
const namespace = "mysteryEncounters/partTimer";
|
||||||
@ -36,6 +37,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
|
|||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "part_timer_crate",
|
spriteKey: "part_timer_crate",
|
||||||
|
@ -30,6 +30,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
|
|||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getPokeballTintColor } from "#app/data/pokeball";
|
import { getPokeballTintColor } from "#app/data/pokeball";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
|
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
|
||||||
@ -123,6 +124,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter = MysteryEncount
|
|||||||
MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER,
|
MysteryEncounterType.THE_EXPERT_POKEMON_BREEDER,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withScenePartySizeRequirement(4, 6, true) // Must have at least 4 legal pokemon in party
|
.withScenePartySizeRequirement(4, 6, true) // Must have at least 4 legal pokemon in party
|
||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
|
@ -29,6 +29,7 @@ import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
|||||||
import { Stat } from "#enums/stat";
|
import { 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 { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/theStrongStuff";
|
const namespace = "mysteryEncounters/theStrongStuff";
|
||||||
@ -46,6 +47,7 @@ export const TheStrongStuffEncounter: MysteryEncounter = MysteryEncounterBuilder
|
|||||||
MysteryEncounterType.THE_STRONG_STUFF,
|
MysteryEncounterType.THE_STRONG_STUFF,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
||||||
.withMaxAllowedEncounters(1)
|
.withMaxAllowedEncounters(1)
|
||||||
|
@ -34,6 +34,7 @@ import i18next from "i18next";
|
|||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounters/theWinstrateChallenge";
|
const namespace = "mysteryEncounters/theWinstrateChallenge";
|
||||||
@ -47,6 +48,7 @@ export const TheWinstrateChallengeEncounter: MysteryEncounter = MysteryEncounter
|
|||||||
MysteryEncounterType.THE_WINSTRATE_CHALLENGE,
|
MysteryEncounterType.THE_WINSTRATE_CHALLENGE,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
import { Challenges } from "#enums/challenges";
|
||||||
import { randSeedInt } from "#app/utils";
|
import { randSeedInt } from "#app/utils";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
@ -46,6 +47,7 @@ export const TrashToTreasureEncounter: MysteryEncounter = MysteryEncounterBuilde
|
|||||||
MysteryEncounterType.TRASH_TO_TREASURE,
|
MysteryEncounterType.TRASH_TO_TREASURE,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
|
.withDisallowedChallenges(Challenges.METRONOME)
|
||||||
.withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
.withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withMaxAllowedEncounters(1)
|
.withMaxAllowedEncounters(1)
|
||||||
.withFleeAllowed(false)
|
.withFleeAllowed(false)
|
||||||
|
@ -129,7 +129,7 @@ export const WeirdDreamEncounter: MysteryEncounter = MysteryEncounterBuilder.wit
|
|||||||
MysteryEncounterType.WEIRD_DREAM,
|
MysteryEncounterType.WEIRD_DREAM,
|
||||||
)
|
)
|
||||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
.withDisallowedChallenges(Challenges.SINGLE_TYPE, Challenges.SINGLE_GENERATION)
|
.withDisallowedChallenges(Challenges.SINGLE_TYPE, Challenges.SINGLE_GENERATION, Challenges.METRONOME)
|
||||||
// TODO: should reset minimum wave to 10 when there are more Rogue tiers in pool. Matching Dark Deal minimum for now.
|
// TODO: should reset minimum wave to 10 when there are more Rogue tiers in pool. Matching Dark Deal minimum for now.
|
||||||
.withSceneWaveRangeRequirement(30, 140)
|
.withSceneWaveRangeRequirement(30, 140)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -650,6 +650,39 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class CanLearnTMRequirement extends EncounterPokemonRequirement {
|
||||||
|
min: number;
|
||||||
|
excludeDisallowedPokemon: boolean;
|
||||||
|
/**
|
||||||
|
* Constructs a new CanLearnTMRequirement
|
||||||
|
* @param min Minimum number of party members who can learn a TM, defaults to 1.
|
||||||
|
* @param excludeDisallowed Whether to exclude ineligible party members, defaults to false
|
||||||
|
*/
|
||||||
|
constructor(min = 1, excludeDisallowed = false) {
|
||||||
|
super();
|
||||||
|
this.min = min;
|
||||||
|
this.excludeDisallowedPokemon = excludeDisallowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
override meetsRequirement(): boolean {
|
||||||
|
const partyPokemon = globalScene.getPlayerParty();
|
||||||
|
if (isNullOrUndefined(partyPokemon)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.queryParty(partyPokemon).length >= this.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
|
return partyPokemon.filter(
|
||||||
|
pokemon => (!this.excludeDisallowedPokemon || pokemon.isAllowedInBattle()) && pokemon.compatibleTms.length >= 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
override getDialogueToken(pokemon?: PlayerPokemon): [string, string] {
|
||||||
|
return ["canLearnTM", ""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class AbilityRequirement extends EncounterPokemonRequirement {
|
export class AbilityRequirement extends EncounterPokemonRequirement {
|
||||||
requiredAbilities: Abilities[];
|
requiredAbilities: Abilities[];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
|
@ -51,17 +51,23 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries party for mons meeting move requirements
|
||||||
|
* @param partyPokemon {@link PlayerPokemon} party to query
|
||||||
|
* @returns list of {@link PlayerPokemon} that match query
|
||||||
|
*/
|
||||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter(pokemon =>
|
return partyPokemon.filter(
|
||||||
// every required move should be included
|
pokemon =>
|
||||||
this.requiredMoves.every(requiredMove => this.getAllPokemonMoves(pokemon).includes(requiredMove)),
|
// every required move should be included
|
||||||
|
this.requiredMoves.length === this.getAllPokemonMoves(pokemon).length,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return partyPokemon.filter(
|
return partyPokemon.filter(
|
||||||
pokemon =>
|
pokemon =>
|
||||||
// none of the "required" moves should be included
|
// none of the "required" moves should be included
|
||||||
!this.requiredMoves.some(requiredMove => this.getAllPokemonMoves(pokemon).includes(requiredMove)),
|
this.getAllPokemonMoves(pokemon).length === 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,19 +79,24 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
return pkm.getLevelMoves().map(([_level, move]) => move);
|
return pkm.getLevelMoves().map(([_level, move]) => move);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the moves with matching criteria
|
||||||
|
* @param pkm {@link PlayerPokemon} to check
|
||||||
|
* @returns list of {@link Moves} moves matching criteria
|
||||||
|
*/
|
||||||
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
|
private getAllPokemonMoves(pkm: PlayerPokemon): Moves[] {
|
||||||
const allPokemonMoves: Moves[] = [];
|
const allPokemonMoves: Moves[] = [];
|
||||||
|
|
||||||
if (!this.excludeLevelMoves) {
|
if (!this.excludeLevelMoves) {
|
||||||
allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm) ?? []));
|
allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm).filter(m => this.requiredMoves.includes(m)) ?? []));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.excludeTmMoves) {
|
if (!this.excludeTmMoves) {
|
||||||
allPokemonMoves.push(...(pkm.compatibleTms ?? []));
|
allPokemonMoves.push(...pkm.generateCompatibleTms(false, false).filter(m => this.requiredMoves.includes(m)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.excludeEggMoves) {
|
if (!this.excludeEggMoves) {
|
||||||
allPokemonMoves.push(...(pkm.getEggMoves() ?? []));
|
allPokemonMoves.push(...(pkm.getEggMoves()?.filter(m => this.requiredMoves.includes(m)) ?? []));
|
||||||
}
|
}
|
||||||
|
|
||||||
return allPokemonMoves;
|
return allPokemonMoves;
|
||||||
|
@ -65,6 +65,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { PokemonType } from "#enums/pokemon-type";
|
import { PokemonType } from "#enums/pokemon-type";
|
||||||
import { getNatureName } from "#app/data/nature";
|
import { getNatureName } from "#app/data/nature";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animates exclamation sprite over trainer's head at start of encounter
|
* Animates exclamation sprite over trainer's head at start of encounter
|
||||||
@ -394,6 +395,8 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
|
|||||||
enemyPokemon.mysteryEncounterBattleEffects = config.mysteryEncounterBattleEffects;
|
enemyPokemon.mysteryEncounterBattleEffects = config.mysteryEncounterBattleEffects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, enemyPokemon);
|
||||||
|
|
||||||
// Requires re-priming summon data to update everything properly
|
// Requires re-priming summon data to update everything properly
|
||||||
enemyPokemon.primeSummonData(enemyPokemon.summonData);
|
enemyPokemon.primeSummonData(enemyPokemon.summonData);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ import { CustomPokemonData } from "#app/data/custom-pokemon-data";
|
|||||||
import type { Abilities } from "#enums/abilities";
|
import type { Abilities } from "#enums/abilities";
|
||||||
import type { PokeballType } from "#enums/pokeball";
|
import type { PokeballType } from "#enums/pokeball";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
|
||||||
/** Will give +1 level every 10 waves */
|
/** Will give +1 level every 10 waves */
|
||||||
export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1;
|
export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1;
|
||||||
@ -643,6 +644,7 @@ export async function catchPokemon(
|
|||||||
showCatchObtainMessage = true,
|
showCatchObtainMessage = true,
|
||||||
isObtain = false,
|
isObtain = false,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, pokemon);
|
||||||
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -6,4 +6,5 @@ export enum Challenges {
|
|||||||
FRESH_START,
|
FRESH_START,
|
||||||
INVERSE_BATTLE,
|
INVERSE_BATTLE,
|
||||||
FLIP_STAT,
|
FLIP_STAT,
|
||||||
|
METRONOME,
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ import { Species } from "#enums/species";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
import { DamageAnimPhase } from "#app/phases/damage-anim-phase";
|
||||||
import { FaintPhase } from "#app/phases/faint-phase";
|
import { FaintPhase } from "#app/phases/faint-phase";
|
||||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
import { LearnMovePhase, LearnMoveType } from "#app/phases/learn-move-phase";
|
||||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||||
import { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase";
|
import { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase";
|
||||||
@ -6360,13 +6360,20 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
return this.getFieldIndex();
|
return this.getFieldIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
generateCompatibleTms(): void {
|
/**
|
||||||
this.compatibleTms = [];
|
* Finds the list of TMs this PlayerPokemon is compatible with based on species, form, and challenges
|
||||||
|
* @param alsoSet Whether this PlayerPokemon's compatibleTms list should be set by this function
|
||||||
|
* @param applyChal Whether to apply challenges which would ban the mon from learning specific moves
|
||||||
|
* @returns {@link Moves} the list of compatible TM moves for this PlayerPokemon
|
||||||
|
*/
|
||||||
|
generateCompatibleTms(alsoSet: boolean = true, applyChal: boolean = true): Moves[] {
|
||||||
|
const ret: Moves[] = [];
|
||||||
|
const compatible = new Utils.BooleanHolder(false);
|
||||||
|
|
||||||
const tms = Object.keys(tmSpecies);
|
const tms = Object.keys(tmSpecies);
|
||||||
for (const tm of tms) {
|
for (const tm of tms) {
|
||||||
const moveId = Number.parseInt(tm) as Moves;
|
const moveId = Number.parseInt(tm) as Moves;
|
||||||
let compatible = false;
|
compatible.value = false;
|
||||||
for (const p of tmSpecies[tm]) {
|
for (const p of tmSpecies[tm]) {
|
||||||
if (Array.isArray(p)) {
|
if (Array.isArray(p)) {
|
||||||
const [pkm, form] = p;
|
const [pkm, form] = p;
|
||||||
@ -6375,24 +6382,32 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
(this.fusionSpecies && pkm === this.fusionSpecies.speciesId)) &&
|
(this.fusionSpecies && pkm === this.fusionSpecies.speciesId)) &&
|
||||||
form === this.getFormKey()
|
form === this.getFormKey()
|
||||||
) {
|
) {
|
||||||
compatible = true;
|
compatible.value = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
p === this.species.speciesId ||
|
p === this.species.speciesId ||
|
||||||
(this.fusionSpecies && p === this.fusionSpecies.speciesId)
|
(this.fusionSpecies && p === this.fusionSpecies.speciesId)
|
||||||
) {
|
) {
|
||||||
compatible = true;
|
compatible.value = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (reverseCompatibleTms.indexOf(moveId) > -1) {
|
if (reverseCompatibleTms.indexOf(moveId) > -1) {
|
||||||
compatible = !compatible;
|
compatible.value = !compatible.value;
|
||||||
}
|
}
|
||||||
if (compatible) {
|
if (compatible.value && applyChal) {
|
||||||
this.compatibleTms.push(moveId);
|
applyChallenges(ChallengeType.BAN_MOVE_LEARNING, this, moveId, LearnMoveType.TM, compatible);
|
||||||
|
}
|
||||||
|
if (compatible.value) {
|
||||||
|
ret.push(moveId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (alsoSet) {
|
||||||
|
this.compatibleTms = ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tryPopulateMoveset(moveset: StarterMoveset): boolean {
|
tryPopulateMoveset(moveset: StarterMoveset): boolean {
|
||||||
@ -7054,14 +7069,12 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
new PokemonMove(Moves.FLAMETHROWER),
|
new PokemonMove(Moves.FLAMETHROWER),
|
||||||
new PokemonMove(Moves.COSMIC_POWER),
|
new PokemonMove(Moves.COSMIC_POWER),
|
||||||
];
|
];
|
||||||
if (globalScene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) {
|
|
||||||
this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
super.generateAndPopulateMoveset();
|
super.generateAndPopulateMoveset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
applyChallenges(ChallengeType.ENEMY_POKEMON_MODIFY, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -127,6 +127,7 @@ import type { PermanentStat, TempBattleStat } from "#enums/stat";
|
|||||||
import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
|
||||||
const outputModifierData = false;
|
const outputModifierData = false;
|
||||||
const useMaxWeightForOutput = false;
|
const useMaxWeightForOutput = false;
|
||||||
@ -2032,10 +2033,12 @@ export const modifierTypes = {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
BERRY: () =>
|
BERRY: () =>
|
||||||
new ModifierTypeGenerator((_party: Pokemon[], pregenArgs?: any[]) => {
|
new ModifierTypeGenerator((party: Pokemon[], pregenArgs?: any[]) => {
|
||||||
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) {
|
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) {
|
||||||
return new BerryModifierType(pregenArgs[0] as BerryType);
|
return new BerryModifierType(pregenArgs[0] as BerryType);
|
||||||
}
|
}
|
||||||
|
const ppReduction = new NumberHolder(1); // How much PP is reduced when using a move in this game mode
|
||||||
|
applyChallenges(ChallengeType.MODIFY_PP_USE, party[0], Moves.NONE, ppReduction);
|
||||||
const berryTypes = getEnumValues(BerryType);
|
const berryTypes = getEnumValues(BerryType);
|
||||||
let randBerryType: BerryType;
|
let randBerryType: BerryType;
|
||||||
const rand = randSeedInt(12);
|
const rand = randSeedInt(12);
|
||||||
@ -2043,7 +2046,8 @@ export const modifierTypes = {
|
|||||||
randBerryType = BerryType.SITRUS;
|
randBerryType = BerryType.SITRUS;
|
||||||
} else if (rand < 4) {
|
} else if (rand < 4) {
|
||||||
randBerryType = BerryType.LUM;
|
randBerryType = BerryType.LUM;
|
||||||
} else if (rand < 6) {
|
} else if (rand < 6 && ppReduction.value !== 0) {
|
||||||
|
// If PP isn't reduced, it doesn't need to be restored
|
||||||
randBerryType = BerryType.LEPPA;
|
randBerryType = BerryType.LEPPA;
|
||||||
} else {
|
} else {
|
||||||
randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2];
|
randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2];
|
||||||
@ -2392,7 +2396,7 @@ export const modifierTypes = {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ModifierPool {
|
export interface ModifierPool {
|
||||||
[tier: string]: WeightedModifierType[];
|
[tier: string]: WeightedModifierType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2691,7 +2695,7 @@ const modifierPool: ModifierPool = {
|
|||||||
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
new WeightedModifierType(modifierTypes.AMULET_COIN, skipInLastClassicWaveOrDefault(3)),
|
||||||
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.EVIOLITE, (party: Pokemon[]) => {
|
||||||
const { gameMode, gameData } = globalScene;
|
const { gameMode, gameData } = globalScene;
|
||||||
if (gameMode.isDaily || (!gameMode.isFreshStartChallenge() && gameData.isUnlocked(Unlockables.EVIOLITE))) {
|
if (gameMode.isDaily || gameData.isUnlocked(Unlockables.EVIOLITE)) {
|
||||||
return party.some(p => {
|
return party.some(p => {
|
||||||
// Check if Pokemon's species (or fusion species, if applicable) can evolve or if they're G-Max'd
|
// Check if Pokemon's species (or fusion species, if applicable) can evolve or if they're G-Max'd
|
||||||
if (
|
if (
|
||||||
@ -2948,11 +2952,7 @@ const modifierPool: ModifierPool = {
|
|||||||
),
|
),
|
||||||
new WeightedModifierType(
|
new WeightedModifierType(
|
||||||
modifierTypes.MINI_BLACK_HOLE,
|
modifierTypes.MINI_BLACK_HOLE,
|
||||||
() =>
|
() => (globalScene.gameMode.isDaily || globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE) ? 1 : 0),
|
||||||
globalScene.gameMode.isDaily ||
|
|
||||||
(!globalScene.gameMode.isFreshStartChallenge() && globalScene.gameData.isUnlocked(Unlockables.MINI_BLACK_HOLE))
|
|
||||||
? 1
|
|
||||||
: 0,
|
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
].map(m => {
|
].map(m => {
|
||||||
@ -3154,6 +3154,7 @@ export function getModifierPoolForType(poolType: ModifierPoolType): ModifierPool
|
|||||||
pool = dailyStarterModifierPool;
|
pool = dailyStarterModifierPool;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
applyChallenges(ChallengeType.MODIFIER_POOL_MODIFY, poolType, pool);
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3165,9 +3166,6 @@ export const itemPoolChecks: Map<ModifierTypeKeys, boolean | undefined> = new Ma
|
|||||||
|
|
||||||
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount = 0) {
|
export function regenerateModifierPoolThresholds(party: Pokemon[], poolType: ModifierPoolType, rerollCount = 0) {
|
||||||
const pool = getModifierPoolForType(poolType);
|
const pool = getModifierPoolForType(poolType);
|
||||||
itemPoolChecks.forEach((_v, k) => {
|
|
||||||
itemPoolChecks.set(k, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
const ignoredIndexes = {};
|
const ignoredIndexes = {};
|
||||||
const modifierTableData = {};
|
const modifierTableData = {};
|
||||||
@ -3452,7 +3450,9 @@ export function getPlayerShopModifierTypeOptionsForWave(waveIndex: number, baseC
|
|||||||
[new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25)],
|
[new ModifierTypeOption(modifierTypes.FULL_RESTORE(), 0, baseCost * 2.25)],
|
||||||
[new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)],
|
[new ModifierTypeOption(modifierTypes.SACRED_ASH(), 0, baseCost * 10)],
|
||||||
];
|
];
|
||||||
return options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
|
const opts = options.slice(0, Math.ceil(Math.max(waveIndex + 10, 0) / 30)).flat();
|
||||||
|
applyChallenges(ChallengeType.SHOP_MODIFY, opts);
|
||||||
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnemyBuffModifierForWave(
|
export function getEnemyBuffModifierForWave(
|
||||||
|
@ -13,6 +13,8 @@ import i18next from "i18next";
|
|||||||
import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase";
|
import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase";
|
||||||
import type Pokemon from "#app/field/pokemon";
|
import type Pokemon from "#app/field/pokemon";
|
||||||
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
import { BooleanHolder } from "#app/utils";
|
||||||
|
|
||||||
export enum LearnMoveType {
|
export enum LearnMoveType {
|
||||||
/** For learning a move via level-up, evolution, or other non-item-based event */
|
/** For learning a move via level-up, evolution, or other non-item-based event */
|
||||||
@ -48,6 +50,13 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
|||||||
const move = allMoves[this.moveId];
|
const move = allMoves[this.moveId];
|
||||||
const currentMoveset = pokemon.getMoveset();
|
const currentMoveset = pokemon.getMoveset();
|
||||||
|
|
||||||
|
const canLearn = new BooleanHolder(true);
|
||||||
|
applyChallenges(ChallengeType.BAN_MOVE_LEARNING, pokemon, this.moveId, 0, canLearn);
|
||||||
|
|
||||||
|
if (!canLearn.value) {
|
||||||
|
return this.end();
|
||||||
|
}
|
||||||
|
|
||||||
// The game first checks if the Pokemon already has the move and ends the phase if it does.
|
// The game first checks if the Pokemon already has the move and ends the phase if it does.
|
||||||
const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== Moves.SKETCH;
|
const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== Moves.SKETCH;
|
||||||
if (hasMoveAlready) {
|
if (hasMoveAlready) {
|
||||||
|
@ -50,6 +50,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { StatusEffect } from "#enums/status-effect";
|
import { StatusEffect } from "#enums/status-effect";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||||
|
|
||||||
export class MovePhase extends BattlePhase {
|
export class MovePhase extends BattlePhase {
|
||||||
protected _pokemon: Pokemon;
|
protected _pokemon: Pokemon;
|
||||||
@ -349,9 +350,11 @@ export class MovePhase extends BattlePhase {
|
|||||||
|
|
||||||
// "commit" to using the move, deducting PP.
|
// "commit" to using the move, deducting PP.
|
||||||
if (!this.ignorePp) {
|
if (!this.ignorePp) {
|
||||||
const ppUsed = 1 + this.getPpIncreaseFromPressure(targets);
|
const ppUsed = new NumberHolder(1 + this.getPpIncreaseFromPressure(targets));
|
||||||
|
|
||||||
this.move.usePp(ppUsed);
|
applyChallenges(ChallengeType.MODIFY_PP_USE, this.pokemon, this.move.moveId, ppUsed);
|
||||||
|
|
||||||
|
this.move.usePp(ppUsed.value);
|
||||||
globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
globalScene.eventTarget.dispatchEvent(new MoveUsedEvent(this.pokemon?.id, this.move.getMove(), this.move.ppUsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +541,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 1 &&
|
c.value === 1 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_TWO_VICTORY: new ChallengeAchv(
|
MONO_GEN_TWO_VICTORY: new ChallengeAchv(
|
||||||
@ -554,7 +554,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 2 &&
|
c.value === 2 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_THREE_VICTORY: new ChallengeAchv(
|
MONO_GEN_THREE_VICTORY: new ChallengeAchv(
|
||||||
@ -567,7 +567,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 3 &&
|
c.value === 3 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_FOUR_VICTORY: new ChallengeAchv(
|
MONO_GEN_FOUR_VICTORY: new ChallengeAchv(
|
||||||
@ -580,7 +580,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 4 &&
|
c.value === 4 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_FIVE_VICTORY: new ChallengeAchv(
|
MONO_GEN_FIVE_VICTORY: new ChallengeAchv(
|
||||||
@ -593,7 +593,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 5 &&
|
c.value === 5 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_SIX_VICTORY: new ChallengeAchv(
|
MONO_GEN_SIX_VICTORY: new ChallengeAchv(
|
||||||
@ -606,7 +606,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 6 &&
|
c.value === 6 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_SEVEN_VICTORY: new ChallengeAchv(
|
MONO_GEN_SEVEN_VICTORY: new ChallengeAchv(
|
||||||
@ -619,7 +619,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 7 &&
|
c.value === 7 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_EIGHT_VICTORY: new ChallengeAchv(
|
MONO_GEN_EIGHT_VICTORY: new ChallengeAchv(
|
||||||
@ -632,7 +632,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 8 &&
|
c.value === 8 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GEN_NINE_VICTORY: new ChallengeAchv(
|
MONO_GEN_NINE_VICTORY: new ChallengeAchv(
|
||||||
@ -645,7 +645,7 @@ export const achvs = {
|
|||||||
c instanceof SingleGenerationChallenge &&
|
c instanceof SingleGenerationChallenge &&
|
||||||
c.value === 9 &&
|
c.value === 9 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_NORMAL: new ChallengeAchv(
|
MONO_NORMAL: new ChallengeAchv(
|
||||||
@ -658,7 +658,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 1 &&
|
c.value === 1 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_FIGHTING: new ChallengeAchv(
|
MONO_FIGHTING: new ChallengeAchv(
|
||||||
@ -671,7 +671,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 2 &&
|
c.value === 2 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_FLYING: new ChallengeAchv(
|
MONO_FLYING: new ChallengeAchv(
|
||||||
@ -684,7 +684,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 3 &&
|
c.value === 3 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_POISON: new ChallengeAchv(
|
MONO_POISON: new ChallengeAchv(
|
||||||
@ -697,7 +697,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 4 &&
|
c.value === 4 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GROUND: new ChallengeAchv(
|
MONO_GROUND: new ChallengeAchv(
|
||||||
@ -710,7 +710,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 5 &&
|
c.value === 5 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_ROCK: new ChallengeAchv(
|
MONO_ROCK: new ChallengeAchv(
|
||||||
@ -723,7 +723,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 6 &&
|
c.value === 6 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_BUG: new ChallengeAchv(
|
MONO_BUG: new ChallengeAchv(
|
||||||
@ -736,7 +736,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 7 &&
|
c.value === 7 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GHOST: new ChallengeAchv(
|
MONO_GHOST: new ChallengeAchv(
|
||||||
@ -749,7 +749,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 8 &&
|
c.value === 8 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_STEEL: new ChallengeAchv(
|
MONO_STEEL: new ChallengeAchv(
|
||||||
@ -762,7 +762,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 9 &&
|
c.value === 9 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_FIRE: new ChallengeAchv(
|
MONO_FIRE: new ChallengeAchv(
|
||||||
@ -775,7 +775,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 10 &&
|
c.value === 10 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_WATER: new ChallengeAchv(
|
MONO_WATER: new ChallengeAchv(
|
||||||
@ -788,7 +788,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 11 &&
|
c.value === 11 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_GRASS: new ChallengeAchv(
|
MONO_GRASS: new ChallengeAchv(
|
||||||
@ -801,7 +801,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 12 &&
|
c.value === 12 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_ELECTRIC: new ChallengeAchv(
|
MONO_ELECTRIC: new ChallengeAchv(
|
||||||
@ -814,7 +814,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 13 &&
|
c.value === 13 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_PSYCHIC: new ChallengeAchv(
|
MONO_PSYCHIC: new ChallengeAchv(
|
||||||
@ -827,7 +827,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 14 &&
|
c.value === 14 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_ICE: new ChallengeAchv(
|
MONO_ICE: new ChallengeAchv(
|
||||||
@ -840,7 +840,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 15 &&
|
c.value === 15 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_DRAGON: new ChallengeAchv(
|
MONO_DRAGON: new ChallengeAchv(
|
||||||
@ -853,7 +853,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 16 &&
|
c.value === 16 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_DARK: new ChallengeAchv(
|
MONO_DARK: new ChallengeAchv(
|
||||||
@ -866,7 +866,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 17 &&
|
c.value === 17 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MONO_FAIRY: new ChallengeAchv(
|
MONO_FAIRY: new ChallengeAchv(
|
||||||
@ -879,7 +879,7 @@ export const achvs = {
|
|||||||
c instanceof SingleTypeChallenge &&
|
c instanceof SingleTypeChallenge &&
|
||||||
c.value === 18 &&
|
c.value === 18 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
FRESH_START: new ChallengeAchv(
|
FRESH_START: new ChallengeAchv(
|
||||||
@ -892,7 +892,7 @@ export const achvs = {
|
|||||||
c instanceof FreshStartChallenge &&
|
c instanceof FreshStartChallenge &&
|
||||||
c.value > 0 &&
|
c.value > 0 &&
|
||||||
!globalScene.gameMode.challenges.some(
|
!globalScene.gameMode.challenges.some(
|
||||||
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT].includes(c.id) && c.value > 0,
|
c => [Challenges.INVERSE_BATTLE, Challenges.FLIP_STAT, Challenges.METRONOME].includes(c.id) && c.value > 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
INVERSE_BATTLE: new ChallengeAchv(
|
INVERSE_BATTLE: new ChallengeAchv(
|
||||||
@ -901,7 +901,10 @@ export const achvs = {
|
|||||||
"INVERSE_BATTLE.description",
|
"INVERSE_BATTLE.description",
|
||||||
"inverse",
|
"inverse",
|
||||||
100,
|
100,
|
||||||
c => c instanceof InverseBattleChallenge && c.value > 0,
|
c =>
|
||||||
|
c instanceof InverseBattleChallenge &&
|
||||||
|
c.value > 0 &&
|
||||||
|
!globalScene.gameMode.challenges.some(c => c.id === Challenges.METRONOME && c.value > 0),
|
||||||
),
|
),
|
||||||
FLIP_STATS: new ChallengeAchv(
|
FLIP_STATS: new ChallengeAchv(
|
||||||
"FLIP_STATS",
|
"FLIP_STATS",
|
||||||
@ -909,7 +912,10 @@ export const achvs = {
|
|||||||
"FLIP_STATS.description",
|
"FLIP_STATS.description",
|
||||||
"dubious_disc",
|
"dubious_disc",
|
||||||
100,
|
100,
|
||||||
c => c instanceof FlipStatChallenge && c.value > 0,
|
c =>
|
||||||
|
c instanceof FlipStatChallenge &&
|
||||||
|
c.value > 0 &&
|
||||||
|
!globalScene.gameMode.challenges.some(c => c.id === Challenges.METRONOME && c.value > 0),
|
||||||
),
|
),
|
||||||
FLIP_INVERSE: new ChallengeAchv(
|
FLIP_INVERSE: new ChallengeAchv(
|
||||||
"FLIP_INVERSE",
|
"FLIP_INVERSE",
|
||||||
@ -920,7 +926,8 @@ export const achvs = {
|
|||||||
c =>
|
c =>
|
||||||
c instanceof FlipStatChallenge &&
|
c instanceof FlipStatChallenge &&
|
||||||
c.value > 0 &&
|
c.value > 0 &&
|
||||||
globalScene.gameMode.challenges.some(c => c.id === Challenges.INVERSE_BATTLE && c.value > 0),
|
globalScene.gameMode.challenges.some(c => c.id === Challenges.INVERSE_BATTLE && c.value > 0) &&
|
||||||
|
!globalScene.gameMode.challenges.some(c => c.id === Challenges.METRONOME && c.value > 0),
|
||||||
).setSecret(),
|
).setSecret(),
|
||||||
BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 50).setSecret(),
|
BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 50).setSecret(),
|
||||||
};
|
};
|
||||||
|
@ -84,7 +84,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
describe("Option 1 - TM Shop", () => {
|
describe("Option 1 - TM Shop", () => {
|
||||||
it("should have the correct properties", () => {
|
it("should have the correct properties", () => {
|
||||||
const option = DepartmentStoreSaleEncounter.options[0];
|
const option = DepartmentStoreSaleEncounter.options[0];
|
||||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT);
|
||||||
expect(option.dialogue).toBeDefined();
|
expect(option.dialogue).toBeDefined();
|
||||||
expect(option.dialogue).toStrictEqual({
|
expect(option.dialogue).toStrictEqual({
|
||||||
buttonLabel: `${namespace}:option.1.label`,
|
buttonLabel: `${namespace}:option.1.label`,
|
||||||
|
Loading…
Reference in New Issue
Block a user