mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-19 14:52:19 +02:00
Metronome challenge
This commit is contained in:
parent
585f040057
commit
16df3fd806
@ -16,7 +16,7 @@ import { Challenges } from "#enums/challenges";
|
||||
import { Species } from "#enums/species";
|
||||
import { TrainerType } from "#enums/trainer-type";
|
||||
import { Nature } from "#enums/nature";
|
||||
import type { Moves } from "#enums/moves";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { TypeColor, TypeShadow } from "#enums/color";
|
||||
import { pokemonEvolutions } from "#app/data/balance/pokemon-evolutions";
|
||||
import { pokemonFormChanges } from "#app/data/pokemon-forms";
|
||||
@ -93,6 +93,18 @@ export enum ChallengeType {
|
||||
* Modifies what the pokemon stats for Flip Stat Mode.
|
||||
*/
|
||||
FLIP_STAT,
|
||||
/**
|
||||
* Modifies movesets of generated enemy mons
|
||||
*/
|
||||
MOVESET_MODIFY,
|
||||
/**
|
||||
* Prevents the learning of moves
|
||||
*/
|
||||
NO_MOVE_LEARNING,
|
||||
/**
|
||||
* Negates PP Usage
|
||||
*/
|
||||
NO_PP_USE,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -433,6 +445,18 @@ export abstract class Challenge {
|
||||
applyFlipStat(_pokemon: Pokemon, _baseStats: number[]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
applyMovesetModify(_pokemon: Pokemon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
applyNoMoveLearning(_valid: Utils.BooleanHolder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
applyNoPPUsage(_valid: Utils.BooleanHolder) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
type ChallengeCondition = (data: GameData) => boolean;
|
||||
@ -917,6 +941,14 @@ export class InverseBattleChallenge extends Challenge {
|
||||
return 0;
|
||||
}
|
||||
|
||||
override applyMovesetModify(pokemon: Pokemon): boolean {
|
||||
if (pokemon.species.speciesId === Species.ETERNATUS) {
|
||||
pokemon.moveset[2] = new PokemonMove(Moves.THUNDERBOLT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
applyTypeEffectiveness(effectiveness: Utils.NumberHolder): boolean {
|
||||
if (effectiveness.value < 1) {
|
||||
effectiveness.value = 2;
|
||||
@ -958,6 +990,41 @@ export class FlipStatChallenge extends Challenge {
|
||||
}
|
||||
}
|
||||
|
||||
export class MetronomeChallenge extends Challenge {
|
||||
constructor() {
|
||||
super(Challenges.METRONOME, 1);
|
||||
}
|
||||
|
||||
override applyStarterModify(_pokemon: Pokemon): boolean {
|
||||
return this.applyMovesetModify(_pokemon);
|
||||
}
|
||||
|
||||
override applyMovesetModify(pokemon: Pokemon): boolean {
|
||||
pokemon.setMove(0, Moves.METRONOME);
|
||||
pokemon.setMove(1, Moves.NONE);
|
||||
pokemon.setMove(2, Moves.NONE);
|
||||
pokemon.setMove(3, Moves.NONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
override applyNoMoveLearning(valid: Utils.BooleanHolder): boolean {
|
||||
valid.value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
override applyNoPPUsage(valid: Utils.BooleanHolder): boolean {
|
||||
valid.value = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -1216,6 +1283,24 @@ export function applyChallenges(
|
||||
baseStats: number[],
|
||||
): boolean;
|
||||
|
||||
export function applyChallenges(
|
||||
gameMode: GameMode,
|
||||
challengeType: ChallengeType.MOVESET_MODIFY,
|
||||
pokemon: Pokemon,
|
||||
): boolean;
|
||||
|
||||
export function applyChallenges(
|
||||
gameMode: GameMode,
|
||||
challengeType: ChallengeType.NO_MOVE_LEARNING,
|
||||
valid: Utils.BooleanHolder,
|
||||
): boolean;
|
||||
|
||||
export function applyChallenges(
|
||||
gameMode: GameMode,
|
||||
challengeType: ChallengeType.NO_PP_USE,
|
||||
valid: Utils.BooleanHolder,
|
||||
): boolean;
|
||||
|
||||
export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType, ...args: any[]): boolean {
|
||||
let ret = false;
|
||||
gameMode.challenges.forEach(c => {
|
||||
@ -1263,6 +1348,15 @@ export function applyChallenges(gameMode: GameMode, challengeType: ChallengeType
|
||||
case ChallengeType.FLIP_STAT:
|
||||
ret ||= c.applyFlipStat(args[0], args[1]);
|
||||
break;
|
||||
case ChallengeType.MOVESET_MODIFY:
|
||||
ret ||= c.applyMovesetModify(args[0]);
|
||||
break;
|
||||
case ChallengeType.NO_MOVE_LEARNING:
|
||||
ret ||= c.applyNoMoveLearning(args[0]);
|
||||
break;
|
||||
case ChallengeType.NO_PP_USE:
|
||||
ret ||= c.applyNoPPUsage(args[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1290,6 +1384,8 @@ export function copyChallenge(source: Challenge | any): Challenge {
|
||||
return InverseBattleChallenge.loadChallenge(source);
|
||||
case Challenges.FLIP_STAT:
|
||||
return FlipStatChallenge.loadChallenge(source);
|
||||
case Challenges.METRONOME:
|
||||
return MetronomeChallenge.loadChallenge(source);
|
||||
}
|
||||
throw new Error("Unknown challenge copied");
|
||||
}
|
||||
@ -1303,5 +1399,6 @@ export function initChallenges() {
|
||||
new FreshStartChallenge(),
|
||||
new InverseBattleChallenge(),
|
||||
new FlipStatChallenge(),
|
||||
new MetronomeChallenge(),
|
||||
);
|
||||
}
|
||||
|
@ -6,4 +6,5 @@ export enum Challenges {
|
||||
FRESH_START,
|
||||
INVERSE_BATTLE,
|
||||
FLIP_STAT,
|
||||
METRONOME,
|
||||
}
|
||||
|
@ -7024,14 +7024,12 @@ export class EnemyPokemon extends Pokemon {
|
||||
new PokemonMove(Moves.FLAMETHROWER),
|
||||
new PokemonMove(Moves.COSMIC_POWER),
|
||||
];
|
||||
if (globalScene.gameMode.hasChallenge(Challenges.INVERSE_BATTLE)) {
|
||||
this.moveset[2] = new PokemonMove(Moves.THUNDERBOLT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.generateAndPopulateMoveset();
|
||||
break;
|
||||
}
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.MOVESET_MODIFY, this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,6 +106,7 @@ import type { PokemonMoveSelectFilter, PokemonSelectFilter } from "#app/ui/party
|
||||
import PartyUiHandler from "#app/ui/party-ui-handler";
|
||||
import { getModifierTierTextTint } from "#app/ui/text";
|
||||
import {
|
||||
BooleanHolder,
|
||||
formatMoney,
|
||||
getEnumKeys,
|
||||
getEnumValues,
|
||||
@ -126,6 +127,7 @@ import type { PermanentStat, TempBattleStat } from "#enums/stat";
|
||||
import { getStatKey, Stat, TEMP_BATTLE_STATS } from "#enums/stat";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import i18next from "i18next";
|
||||
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||
|
||||
const outputModifierData = false;
|
||||
const useMaxWeightForOutput = false;
|
||||
@ -2028,6 +2030,8 @@ export const modifierTypes = {
|
||||
if (pregenArgs && pregenArgs.length === 1 && pregenArgs[0] in BerryType) {
|
||||
return new BerryModifierType(pregenArgs[0] as BerryType);
|
||||
}
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, noMoveLearning); // Yeah this is kind of dumb
|
||||
const berryTypes = getEnumValues(BerryType);
|
||||
let randBerryType: BerryType;
|
||||
const rand = randSeedInt(12);
|
||||
@ -2035,7 +2039,7 @@ export const modifierTypes = {
|
||||
randBerryType = BerryType.SITRUS;
|
||||
} else if (rand < 4) {
|
||||
randBerryType = BerryType.LUM;
|
||||
} else if (rand < 6) {
|
||||
} else if (rand < 6 && !noMoveLearning.value) {
|
||||
randBerryType = BerryType.LEPPA;
|
||||
} else {
|
||||
randBerryType = berryTypes[randSeedInt(berryTypes.length - 3) + 2];
|
||||
@ -2464,14 +2468,30 @@ const modifierPool: ModifierPool = {
|
||||
new WeightedModifierType(modifierTypes.LURE, lureWeightFunc(10, 2)),
|
||||
new WeightedModifierType(modifierTypes.TEMP_STAT_STAGE_BOOSTER, 4),
|
||||
new WeightedModifierType(modifierTypes.BERRY, 2),
|
||||
new WeightedModifierType(modifierTypes.TM_COMMON, 2),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.TM_COMMON,
|
||||
() => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, noMoveLearning);
|
||||
return noMoveLearning.value ? 0 : 2;
|
||||
},
|
||||
2,
|
||||
),
|
||||
].map(m => {
|
||||
m.setTier(ModifierTier.COMMON);
|
||||
return m;
|
||||
}),
|
||||
[ModifierTier.GREAT]: [
|
||||
new WeightedModifierType(modifierTypes.GREAT_BALL, () => (hasMaximumBalls(PokeballType.GREAT_BALL) ? 0 : 6), 6),
|
||||
new WeightedModifierType(modifierTypes.PP_UP, 2),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.PP_UP,
|
||||
() => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_PP_USE, noMoveLearning);
|
||||
return noMoveLearning.value ? 0 : 2;
|
||||
},
|
||||
2,
|
||||
),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.FULL_HEAL,
|
||||
(party: Pokemon[]) => {
|
||||
@ -2567,6 +2587,11 @@ const modifierPool: ModifierPool = {
|
||||
new WeightedModifierType(
|
||||
modifierTypes.ELIXIR,
|
||||
(party: Pokemon[]) => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_PP_USE, noMoveLearning);
|
||||
if (noMoveLearning.value) {
|
||||
return 0;
|
||||
}
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -2586,6 +2611,11 @@ const modifierPool: ModifierPool = {
|
||||
new WeightedModifierType(
|
||||
modifierTypes.MAX_ELIXIR,
|
||||
(party: Pokemon[]) => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_PP_USE, noMoveLearning);
|
||||
if (noMoveLearning.value) {
|
||||
return 0;
|
||||
}
|
||||
const thresholdPartyMemberCount = Math.min(
|
||||
party.filter(
|
||||
p =>
|
||||
@ -2618,11 +2648,21 @@ const modifierPool: ModifierPool = {
|
||||
2,
|
||||
),
|
||||
new WeightedModifierType(modifierTypes.SOOTHE_BELL, 2),
|
||||
new WeightedModifierType(modifierTypes.TM_GREAT, 3),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.TM_GREAT,
|
||||
() => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, noMoveLearning);
|
||||
return noMoveLearning.value ? 0 : 3;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.MEMORY_MUSHROOM,
|
||||
(party: Pokemon[]) => {
|
||||
if (!party.find(p => p.getLearnableLevelMoves().length)) {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, noMoveLearning); // Yeah this is kind of dumb
|
||||
if (noMoveLearning.value || !party.find(p => p.getLearnableLevelMoves().length)) {
|
||||
return 0;
|
||||
}
|
||||
const highestPartyLevel = party
|
||||
@ -2668,7 +2708,15 @@ const modifierPool: ModifierPool = {
|
||||
new WeightedModifierType(modifierTypes.ULTRA_BALL, () => (hasMaximumBalls(PokeballType.ULTRA_BALL) ? 0 : 15), 15),
|
||||
new WeightedModifierType(modifierTypes.MAX_LURE, lureWeightFunc(30, 4)),
|
||||
new WeightedModifierType(modifierTypes.BIG_NUGGET, skipInLastClassicWaveOrDefault(12)),
|
||||
new WeightedModifierType(modifierTypes.PP_MAX, 3),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.PP_MAX,
|
||||
() => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_PP_USE, noMoveLearning); // Yeah this is kind of dumb
|
||||
return noMoveLearning.value ? 0 : 3;
|
||||
},
|
||||
3,
|
||||
),
|
||||
new WeightedModifierType(modifierTypes.MINT, 4),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.RARE_EVOLUTION_ITEM,
|
||||
@ -2813,7 +2861,15 @@ const modifierPool: ModifierPool = {
|
||||
new WeightedModifierType(modifierTypes.REVIVER_SEED, 4),
|
||||
new WeightedModifierType(modifierTypes.CANDY_JAR, skipInLastClassicWaveOrDefault(5)),
|
||||
new WeightedModifierType(modifierTypes.ATTACK_TYPE_BOOSTER, 9),
|
||||
new WeightedModifierType(modifierTypes.TM_ULTRA, 11),
|
||||
new WeightedModifierType(
|
||||
modifierTypes.TM_ULTRA,
|
||||
() => {
|
||||
const noMoveLearning = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, noMoveLearning); // Yeah this is kind of dumb
|
||||
return noMoveLearning.value ? 0 : 11;
|
||||
},
|
||||
11,
|
||||
),
|
||||
new WeightedModifierType(modifierTypes.RARER_CANDY, 4),
|
||||
new WeightedModifierType(modifierTypes.GOLDEN_PUNCH, skipInLastClassicWaveOrDefault(2)),
|
||||
new WeightedModifierType(modifierTypes.IV_SCANNER, skipInLastClassicWaveOrDefault(4)),
|
||||
|
@ -17,6 +17,8 @@ import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||
import { EndEvolutionPhase } from "#app/phases/end-evolution-phase";
|
||||
import { EVOLVE_MOVE } from "#app/data/balance/pokemon-level-moves";
|
||||
import { BooleanHolder } from "#app/utils";
|
||||
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||
|
||||
export class EvolutionPhase extends Phase {
|
||||
protected pokemon: PlayerPokemon;
|
||||
@ -343,6 +345,9 @@ export class EvolutionPhase extends Phase {
|
||||
this.evolutionHandler.canCancel = false;
|
||||
|
||||
this.pokemon.evolve(this.evolution, this.pokemon.species).then(() => {
|
||||
const skipMoveLearn = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, skipMoveLearn);
|
||||
if (!skipMoveLearn.value) {
|
||||
const learnSituation: LearnMoveSituation = this.fusionSpeciesEvolved
|
||||
? LearnMoveSituation.EVOLUTION_FUSED
|
||||
: this.pokemon.fusionSpecies
|
||||
@ -354,6 +359,7 @@ export class EvolutionPhase extends Phase {
|
||||
for (const lm of levelMoves) {
|
||||
globalScene.unshiftPhase(new LearnMovePhase(globalScene.getPlayerParty().indexOf(this.pokemon), lm[1]));
|
||||
}
|
||||
}
|
||||
globalScene.unshiftPhase(new EndEvolutionPhase());
|
||||
|
||||
globalScene.playSound("se/shine");
|
||||
|
@ -6,8 +6,9 @@ import { EvolutionPhase } from "#app/phases/evolution-phase";
|
||||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||
import { PlayerPartyMemberPokemonPhase } from "#app/phases/player-party-member-pokemon-phase";
|
||||
import { LevelAchv } from "#app/system/achv";
|
||||
import { NumberHolder } from "#app/utils";
|
||||
import { BooleanHolder, NumberHolder } from "#app/utils";
|
||||
import i18next from "i18next";
|
||||
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||
|
||||
export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
|
||||
protected lastLevel: number;
|
||||
@ -63,11 +64,15 @@ export class LevelUpPhase extends PlayerPartyMemberPokemonPhase {
|
||||
public override end() {
|
||||
if (this.lastLevel < 100) {
|
||||
// this feels like an unnecessary optimization
|
||||
const skipMoveLearn = new BooleanHolder(false);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_MOVE_LEARNING, skipMoveLearn);
|
||||
if (!skipMoveLearn.value) {
|
||||
const levelMoves = this.getPokemon().getLevelMoves(this.lastLevel + 1);
|
||||
for (const lm of levelMoves) {
|
||||
globalScene.unshiftPhase(new LearnMovePhase(this.partyMemberIndex, lm[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.pokemon.pauseEvolutions) {
|
||||
const evolution = this.pokemon.getEvolution();
|
||||
if (evolution) {
|
||||
|
@ -43,13 +43,14 @@ import { MoveChargePhase } from "#app/phases/move-charge-phase";
|
||||
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
|
||||
import { MoveEndPhase } from "#app/phases/move-end-phase";
|
||||
import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
|
||||
import { NumberHolder } from "#app/utils";
|
||||
import { BooleanHolder, NumberHolder } from "#app/utils";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { StatusEffect } from "#enums/status-effect";
|
||||
import i18next from "i18next";
|
||||
import { applyChallenges, ChallengeType } from "#app/data/challenge";
|
||||
|
||||
export class MovePhase extends BattlePhase {
|
||||
protected _pokemon: Pokemon;
|
||||
@ -104,11 +105,14 @@ export class MovePhase extends BattlePhase {
|
||||
) {
|
||||
super();
|
||||
|
||||
const ignorePPChallenge = new BooleanHolder(ignorePp);
|
||||
applyChallenges(globalScene.gameMode, ChallengeType.NO_PP_USE, ignorePPChallenge);
|
||||
|
||||
this.pokemon = pokemon;
|
||||
this.targets = targets;
|
||||
this.move = move;
|
||||
this.followUp = followUp;
|
||||
this.ignorePp = ignorePp;
|
||||
this.ignorePp = ignorePPChallenge.value;
|
||||
this.reflected = reflected;
|
||||
this.forcedLast = forcedLast;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user