This commit is contained in:
AJ Fontaine 2025-03-27 19:21:13 -04:00
parent 11e1bf25c4
commit 552fa24720
6 changed files with 66 additions and 37 deletions

View File

@ -57,6 +57,7 @@ import { allMoves } from "#app/data/moves/move";
import { ModifierTier } from "#app/modifier/modifier-tier";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { Challenges } from "#enums/challenges";
/** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/bugTypeSuperfan";
@ -193,6 +194,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter = MysteryEncounterBuilde
)
.withMaxAllowedEncounters(1)
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
.withDisallowedChallenges(Challenges.METRONOME)
.withIntroSpriteConfigs([]) // These are set in onInit()
.withAutoHideIntroVisuals(false)
.withIntroDialogue([

View File

@ -41,6 +41,7 @@ import { PokeballType } from "#enums/pokeball";
import { Species } from "#enums/species";
import { Stat } from "#enums/stat";
import i18next from "i18next";
import { Challenges } from "#enums/challenges";
/** the i18n namespace for this encounter */
const namespace = "mysteryEncounters/dancingLessons";
@ -99,6 +100,7 @@ export const DancingLessonsEncounter: MysteryEncounter = MysteryEncounterBuilder
)
.withEncounterTier(MysteryEncounterTier.GREAT)
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
.withDisallowedChallenges(Challenges.METRONOME)
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
.withAnimations(EncounterAnim.DANCE)
.withHideWildIntroMessage(true)

View File

@ -11,6 +11,10 @@ import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounte
import { MysteryEncounterBuilder } from "#app/data/mystery-encounters/mystery-encounter";
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
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 { CompatibleMoveRequirement } from "../mystery-encounter-requirements";
import { Moves } from "#enums/moves";
/** i18n namespace for encounter */
const namespace = "mysteryEncounters/departmentStoreSale";
@ -55,34 +59,37 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter = MysteryEncounterBu
.withTitle(`${namespace}:title`)
.withDescription(`${namespace}:description`)
.withQuery(`${namespace}:query`)
.withSimpleOption(
{
buttonLabel: `${namespace}:option.1.label`,
buttonTooltip: `${namespace}:option.1.tooltip`,
},
async () => {
// Choose TMs
const modifiers: ModifierTypeFunc[] = [];
let i = 0;
while (i < 5) {
// 2/2/1 weight on TM rarity
const roll = randSeedInt(5);
if (roll < 2) {
modifiers.push(modifierTypes.TM_COMMON);
} else if (roll < 4) {
modifiers.push(modifierTypes.TM_GREAT);
} else {
modifiers.push(modifierTypes.TM_ULTRA);
.withOption(
MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
.withPrimaryPokemonRequirement(new CompatibleMoveRequirement(Moves.PROTECT)) // Check Protect in compatible tms yeah this sucks
.withDialogue({
buttonLabel: `${namespace}:option.1.label`,
buttonTooltip: `${namespace}:option.1.tooltip`,
})
.withOptionPhase(async () => {
// Choose TMs
const modifiers: ModifierTypeFunc[] = [];
let i = 0;
while (i < 5) {
// 2/2/1 weight on TM rarity
const roll = randSeedInt(5);
if (roll < 2) {
modifiers.push(modifierTypes.TM_COMMON);
} else if (roll < 4) {
modifiers.push(modifierTypes.TM_GREAT);
} else {
modifiers.push(modifierTypes.TM_ULTRA);
}
i++;
}
i++;
}
setEncounterRewards({
guaranteedModifierTypeFuncs: modifiers,
fillRemaining: false,
});
leaveEncounterWithoutBattle();
},
setEncounterRewards({
guaranteedModifierTypeFuncs: modifiers,
fillRemaining: false,
});
leaveEncounterWithoutBattle();
})
.build(),
)
.withSimpleOption(
{

View File

@ -22,6 +22,7 @@ import type { PlayerPokemon } from "#app/field/pokemon";
import type Pokemon from "#app/field/pokemon";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import { isPokemonValidForEncounterOptionSelection } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { Challenges } from "#enums/challenges";
/** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/partTimer";
@ -36,6 +37,7 @@ export const PartTimerEncounter: MysteryEncounter = MysteryEncounterBuilder.with
)
.withEncounterTier(MysteryEncounterTier.COMMON)
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
.withDisallowedChallenges(Challenges.METRONOME)
.withIntroSpriteConfigs([
{
spriteKey: "part_timer_crate",

View File

@ -51,17 +51,23 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
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[] {
if (!this.invertQuery) {
return partyPokemon.filter(pokemon =>
// every required move should be included
this.requiredMoves.every(requiredMove => this.getAllPokemonMoves(pokemon).includes(requiredMove)),
return partyPokemon.filter(
pokemon =>
// every required move should be included
this.requiredMoves.length === this.getAllPokemonMoves(pokemon).length,
);
}
return partyPokemon.filter(
pokemon =>
// 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);
}
/**
* 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[] {
const allPokemonMoves: Moves[] = [];
if (!this.excludeLevelMoves) {
allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm) ?? []));
allPokemonMoves.push(...(this.getPokemonLevelMoves(pkm).filter(m => this.requiredMoves.includes(m)) ?? []));
}
if (!this.excludeTmMoves) {
allPokemonMoves.push(...(pkm.compatibleTms ?? []));
allPokemonMoves.push(...pkm.generateCompatibleTms(false, false).filter(m => this.requiredMoves.includes(m)));
}
if (!this.excludeEggMoves) {
allPokemonMoves.push(...(pkm.getEggMoves() ?? []));
allPokemonMoves.push(...(pkm.getEggMoves()?.filter(m => this.requiredMoves.includes(m)) ?? []));
}
return allPokemonMoves;

View File

@ -6318,8 +6318,8 @@ export class PlayerPokemon extends Pokemon {
return this.getFieldIndex();
}
generateCompatibleTms(): void {
this.compatibleTms = [];
generateCompatibleTms(alsoSet: boolean = true, applyChal: boolean = true): Moves[] {
const ret: Moves[] = [];
const tms = Object.keys(tmSpecies);
for (const tm of tms) {
@ -6347,10 +6347,15 @@ export class PlayerPokemon extends Pokemon {
if (reverseCompatibleTms.indexOf(moveId) > -1) {
compatible = !compatible;
}
if (compatible && !applyChallenges(ChallengeType.BAN_MOVE_LEARNING, this, moveId)) {
this.compatibleTms.push(moveId);
if (compatible && (!applyChal || !applyChallenges(ChallengeType.BAN_MOVE_LEARNING, this, moveId))) {
ret.push(moveId);
}
}
if (alsoSet) {
this.compatibleTms = ret;
}
return ret;
}
tryPopulateMoveset(moveset: StarterMoveset): boolean {