more ME bug fixes

This commit is contained in:
ImperialSympathizer 2024-10-08 23:56:58 -04:00
parent 7489bfda17
commit c30f873dae
12 changed files with 47 additions and 32 deletions

View File

@ -2357,6 +2357,19 @@ export default class BattleScene extends SceneBase {
return false;
}
/**
* Will search for a specific phase via filter, and remove the first result if a match is found.
* @param phaseFilter
*/
tryRemoveUnshiftedPhase(phaseFilter: (phase: Phase) => boolean): boolean {
const phaseIndex = this.phaseQueuePrepend.findIndex(phaseFilter);
if (phaseIndex > -1) {
this.phaseQueuePrepend.splice(phaseIndex, 1);
return true;
}
return false;
}
/**
* Tries to add the input phase to index before target phase in the phaseQueue, else simply calls unshiftPhase()
* @param phase {@linkcode Phase} the phase to be added

View File

@ -132,8 +132,8 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement(
new MoveRequirement(EXTORTION_MOVES),
new AbilityRequirement(EXTORTION_ABILITIES))
new MoveRequirement(EXTORTION_MOVES, true),
new AbilityRequirement(EXTORTION_ABILITIES, true))
)
.withDialogue({
buttonLabel: `${namespace}:option.2.label`,

View File

@ -8,7 +8,6 @@ import {
import Pokemon, { EnemyPokemon, PlayerPokemon } from "#app/field/pokemon";
import {
BerryModifierType,
getPartyLuckValue,
ModifierPoolType,
ModifierTypeOption, modifierTypes,
regenerateModifierPoolThresholds,
@ -31,6 +30,8 @@ import { BerryType } from "#enums/berry-type";
import { PERMANENT_STATS, Stat } from "#enums/stat";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
import { getPokemonSpecies } from "#app/data/pokemon-species";
import { Species } from "#enums/species";
/** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/berriesAbound";
@ -58,7 +59,8 @@ export const BerriesAboundEncounter: MysteryEncounter =
// Calculate boss mon
const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER);
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
// const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true);
const bossSpecies = getPokemonSpecies(Species.KELDEO);
const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true);
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
const config: EnemyPartyConfig = {

View File

@ -235,7 +235,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
.withOption(
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
.withPrimaryPokemonRequirement(new MoveRequirement(DANCING_MOVES, true)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
.withDialogue({
buttonLabel: `${namespace}:option.3.label`,
buttonTooltip: `${namespace}:option.3.tooltip`,

View File

@ -144,7 +144,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
.withOption(
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES, true)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
.withDialogue({
buttonLabel: `${namespace}:option.2.label`,
buttonTooltip: `${namespace}:option.2.tooltip`,

View File

@ -226,7 +226,7 @@ export const PartTimerEncounter: MysteryEncounter =
.withOption(
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES, true)) // Will set option3PrimaryName and option3PrimaryMove dialogue tokens automatically
.withDialogue({
buttonLabel: `${namespace}:option.3.label`,
buttonTooltip: `${namespace}:option.3.tooltip`,

View File

@ -142,7 +142,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
.withOption(
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES))
.withPrimaryPokemonRequirement(new MoveRequirement(STEALING_MOVES, true))
.withDialogue({
buttonLabel: `${namespace}:option.3.label`,
buttonTooltip: `${namespace}:option.3.tooltip`,

View File

@ -25,6 +25,7 @@ import { achvs } from "#app/system/achv";
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
import { Type } from "#app/data/type";
import { getPokeballTintColor } from "#app/data/pokeball";
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
/** the i18n namespace for the encounter */
const namespace = "mysteryEncounters/theExpertPokemonBreeder";
@ -220,7 +221,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.misc.chosenPokemon = pokemon1;
encounter.setDialogueToken("chosenPokemon", pokemon1.getNameToRender());
const eggOptions = getEggOptions(scene, pokemon1CommonEggs, pokemon1RareEggs);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions, () => doPostEncounterCleanup(scene));
// Remove all Pokemon from the party except the chosen Pokemon
removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon1);
@ -246,9 +247,6 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.onGameOver = onGameOver;
initBattleWithEnemyConfig(scene, config);
})
.withPostOptionPhase(async (scene: BattleScene) => {
await doPostEncounterCleanup(scene);
})
.build()
)
.withOption(
@ -272,7 +270,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.misc.chosenPokemon = pokemon2;
encounter.setDialogueToken("chosenPokemon", pokemon2.getNameToRender());
const eggOptions = getEggOptions(scene, pokemon2CommonEggs, pokemon2RareEggs);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions, () => doPostEncounterCleanup(scene));
// Remove all Pokemon from the party except the chosen Pokemon
removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon2);
@ -298,9 +296,6 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.onGameOver = onGameOver;
initBattleWithEnemyConfig(scene, config);
})
.withPostOptionPhase(async (scene: BattleScene) => {
await doPostEncounterCleanup(scene);
})
.build()
)
.withOption(
@ -324,7 +319,7 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.misc.chosenPokemon = pokemon3;
encounter.setDialogueToken("chosenPokemon", pokemon3.getNameToRender());
const eggOptions = getEggOptions(scene, pokemon3CommonEggs, pokemon3RareEggs);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions);
setEncounterRewards(scene, { fillRemaining: true }, eggOptions, () => doPostEncounterCleanup(scene));
// Remove all Pokemon from the party except the chosen Pokemon
removePokemonFromPartyAndStoreHeldItems(scene, encounter, pokemon3);
@ -350,9 +345,6 @@ export const TheExpertPokemonBreederEncounter: MysteryEncounter =
encounter.onGameOver = onGameOver;
initBattleWithEnemyConfig(scene, config);
})
.withPostOptionPhase(async (scene: BattleScene) => {
await doPostEncounterCleanup(scene);
})
.build()
)
.withOutroDialogue([
@ -520,19 +512,19 @@ function checkAchievement(scene: BattleScene) {
}
}
async function restorePartyAndHeldItems(scene: BattleScene) {
function restorePartyAndHeldItems(scene: BattleScene) {
const encounter = scene.currentBattle.mysteryEncounter!;
// Restore original party
scene.getParty().push(...encounter.misc.originalParty);
// Restore held items
const originalHeldItems = encounter.misc.originalPartyHeldItems;
originalHeldItems.forEach(pokemonHeldItemsList => {
originalHeldItems.forEach((pokemonHeldItemsList: PokemonHeldItemModifier[]) => {
pokemonHeldItemsList.forEach(heldItem => {
scene.addModifier(heldItem, true, false, false, true);
});
});
await scene.updateModifiers(true);
scene.updateModifiers(true);
}
function onGameOver(scene: BattleScene) {
@ -608,13 +600,13 @@ function onGameOver(scene: BattleScene) {
return false;
}
async function doPostEncounterCleanup(scene: BattleScene) {
function doPostEncounterCleanup(scene: BattleScene) {
const encounter = scene.currentBattle.mysteryEncounter!;
if (!encounter.misc.encounterFailed) {
// Give achievement if in Space biome
checkAchievement(scene);
// Give 20 friendship to the chosen pokemon
encounter.misc.chosenPokemon.addFriendship(FRIENDSHIP_ADDED);
await restorePartyAndHeldItems(scene);
restorePartyAndHeldItems(scene);
}
}

View File

@ -209,7 +209,7 @@ export const UncommonBreedEncounter: MysteryEncounter =
.withOption(
MysteryEncounterOptionBuilder
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
.withPrimaryPokemonRequirement(new MoveRequirement(CHARMING_MOVES, true)) // Will set option2PrimaryName and option2PrimaryMove dialogue tokens automatically
.withDialogue({
buttonLabel: `${namespace}:option.3.label`,
buttonTooltip: `${namespace}:option.3.tooltip`,

View File

@ -476,9 +476,11 @@ export class MoveRequirement extends EncounterPokemonRequirement {
requiredMoves: Moves[] = [];
minNumberOfPokemon: number;
invertQuery: boolean;
excludeDisallowedPokemon: boolean;
constructor(moves: Moves | Moves[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
constructor(moves: Moves | Moves[], excludeDisallowedPokemon: boolean, minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
super();
this.excludeDisallowedPokemon = excludeDisallowedPokemon;
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredMoves = Array.isArray(moves) ? moves : [ moves ];
@ -559,9 +561,11 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
requiredAbilities: Abilities[];
minNumberOfPokemon: number;
invertQuery: boolean;
excludeDisallowedPokemon: boolean;
constructor(abilities: Abilities | Abilities[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
constructor(abilities: Abilities | Abilities[], excludeDisallowedPokemon: boolean, minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
super();
this.excludeDisallowedPokemon = excludeDisallowedPokemon;
this.minNumberOfPokemon = minNumberOfPokemon;
this.invertQuery = invertQuery;
this.requiredAbilities = Array.isArray(abilities) ? abilities : [ abilities ];

View File

@ -31,10 +31,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
* }
* ```
*/
const overrides = {
MYSTERY_ENCOUNTER_RATE_OVERRIDE: 256,
MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType.WEIRD_DREAM
} satisfies Partial<InstanceType<typeof DefaultOverrides>>;
const overrides = {} satisfies Partial<InstanceType<typeof DefaultOverrides>>;
/**
* If you need to add Overrides values for local testing do that inside {@linkcode overrides}

View File

@ -36,6 +36,7 @@ import { MysteryEncounterPhase } from "#app/phases/mystery-encounter-phases";
import { getGoldenBugNetSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
import { Biome } from "#enums/biome";
import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
import { QuietFormChangePhase } from "#app/phases/quiet-form-change-phase";
export class EncounterPhase extends BattlePhase {
private loaded: boolean;
@ -384,6 +385,12 @@ export class EncounterPhase extends BattlePhase {
encounter.onVisualsStart(this.scene);
}
// Clear any lingering QuietFormChangePhases which can be inadvertently added by certain wild Pokemon forms
let phaseRemoved: boolean = true;
while (phaseRemoved) {
phaseRemoved = this.scene.tryRemoveUnshiftedPhase(phase => phase instanceof QuietFormChangePhase);
}
const doEncounter = () => {
const doShowEncounterOptions = () => {
this.scene.ui.clearText();