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 { 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";
@ -193,6 +194,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([

View File

@ -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)

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 { 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 { CompatibleMoveRequirement } from "../mystery-encounter-requirements";
import { Moves } from "#enums/moves";
/** i18n namespace for encounter */ /** i18n namespace for encounter */
const namespace = "mysteryEncounters/departmentStoreSale"; const namespace = "mysteryEncounters/departmentStoreSale";
@ -55,34 +59,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 CompatibleMoveRequirement(Moves.PROTECT)) // Check Protect in compatible tms yeah this sucks
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(
{ {

View File

@ -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",

View File

@ -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;

View File

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