more PR feedback and update field trip with Rarer Candy
This commit is contained in:
parent
282eee8dd8
commit
0e7f9dc723
|
@ -265,7 +265,9 @@ export default class BattleScene extends SceneBase {
|
|||
public money: integer;
|
||||
public pokemonInfoContainer: PokemonInfoContainer;
|
||||
private party: PlayerPokemon[];
|
||||
/** Session save data that pertains to Mystery Encounters */
|
||||
public mysteryEncounterSaveData: MysteryEncounterSaveData = new MysteryEncounterSaveData();
|
||||
/** If the previous wave was a MysteryEncounter, tracks the object with this variable. Mostly used for visual object cleanup */
|
||||
public lastMysteryEncounter?: MysteryEncounter;
|
||||
/** Combined Biome and Wave count text */
|
||||
private biomeWaveText: Phaser.GameObjects.Text;
|
||||
|
|
|
@ -80,6 +80,7 @@ export default class Battle {
|
|||
public playerFaintsHistory: FaintLogEntry[] = [];
|
||||
public enemyFaintsHistory: FaintLogEntry[] = [];
|
||||
|
||||
/** If the current battle is a Mystery Encounter, this will always be defined */
|
||||
public mysteryEncounter?: MysteryEncounter;
|
||||
|
||||
private rngCounter: number = 0;
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Moves } from "#enums/moves";
|
|||
import { SubstituteTag } from "./battler-tags";
|
||||
import { isNullOrUndefined } from "../utils";
|
||||
import Phaser from "phaser";
|
||||
import { EncounterAnim } from "#enums/encounter-anims";
|
||||
//import fs from 'vite-plugin-fs/browser';
|
||||
|
||||
export enum AnimFrameTarget {
|
||||
|
@ -105,18 +106,6 @@ export enum CommonAnim {
|
|||
LOCK_ON = 2120
|
||||
}
|
||||
|
||||
/**
|
||||
* Animations used for Mystery Encounters
|
||||
* These are custom animations that may or may not work in any other circumstance
|
||||
* Use at your own risk
|
||||
*/
|
||||
export enum EncounterAnim {
|
||||
MAGMA_BG,
|
||||
MAGMA_SPOUT,
|
||||
SMOKESCREEN,
|
||||
DANCE
|
||||
}
|
||||
|
||||
export class AnimConfig {
|
||||
public id: integer;
|
||||
public graphic: string;
|
||||
|
|
|
@ -2315,10 +2315,12 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
|||
super(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, BattlerTagLapseType.CUSTOM, 1);
|
||||
}
|
||||
|
||||
/** Event when tag is added */
|
||||
onAdd(pokemon: Pokemon): void {
|
||||
super.onAdd(pokemon);
|
||||
}
|
||||
|
||||
/** Performs post-summon effects through {@linkcode Pokemon.mysteryEncounterBattleEffects} */
|
||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||
const ret = super.lapse(pokemon, lapseType);
|
||||
|
||||
|
@ -2335,6 +2337,7 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/** Event when tag is removed */
|
||||
onRemove(pokemon: Pokemon): void {
|
||||
super.onRemove(pokemon);
|
||||
}
|
||||
|
|
|
@ -63,8 +63,8 @@ export interface IEggOptions {
|
|||
*/
|
||||
overrideHiddenAbility?: boolean,
|
||||
|
||||
/** If Egg is of {@link EggSourceType.EVENT}, can customize the message displayed for where the egg was obtained */
|
||||
eventEggTypeDescriptor?: string;
|
||||
/** Can customize the message displayed for where the egg was obtained */
|
||||
eggDescriptor?: string;
|
||||
}
|
||||
|
||||
export class Egg {
|
||||
|
@ -86,7 +86,7 @@ export class Egg {
|
|||
|
||||
private _overrideHiddenAbility: boolean;
|
||||
|
||||
private _eventEggTypeDescriptor?: string;
|
||||
private _eggDescriptor?: string;
|
||||
|
||||
////
|
||||
// #endregion
|
||||
|
@ -197,7 +197,7 @@ export class Egg {
|
|||
generateEggProperties(eggOptions);
|
||||
}
|
||||
|
||||
this._eventEggTypeDescriptor = eggOptions?.eventEggTypeDescriptor;
|
||||
this._eggDescriptor = eggOptions?.eggDescriptor;
|
||||
}
|
||||
|
||||
////
|
||||
|
@ -299,15 +299,15 @@ export class Egg {
|
|||
public getEggTypeDescriptor(scene: BattleScene): string {
|
||||
switch (this.sourceType) {
|
||||
case EggSourceType.SAME_SPECIES_EGG:
|
||||
return i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
|
||||
return this._eggDescriptor ?? i18next.t("egg:sameSpeciesEgg", { species: getPokemonSpecies(this._species).getName()});
|
||||
case EggSourceType.GACHA_LEGENDARY:
|
||||
return `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
||||
return this._eggDescriptor ?? `${i18next.t("egg:gachaTypeLegendary")} (${getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(scene, this.timestamp)).getName()})`;
|
||||
case EggSourceType.GACHA_SHINY:
|
||||
return i18next.t("egg:gachaTypeShiny");
|
||||
return this._eggDescriptor ?? i18next.t("egg:gachaTypeShiny");
|
||||
case EggSourceType.GACHA_MOVE:
|
||||
return i18next.t("egg:gachaTypeMove");
|
||||
return this._eggDescriptor ?? i18next.t("egg:gachaTypeMove");
|
||||
case EggSourceType.EVENT:
|
||||
return this._eventEggTypeDescriptor ?? i18next.t("egg:eventType");
|
||||
return this._eggDescriptor ?? i18next.t("egg:eventType");
|
||||
default:
|
||||
console.warn("getEggTypeDescriptor case not defined. Returning default empty string");
|
||||
return "";
|
||||
|
|
|
@ -147,7 +147,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||
scene,
|
||||
pulled: false,
|
||||
sourceType: EggSourceType.EVENT,
|
||||
eventEggTypeDescriptor: encounter.misc.trainerEggDescription,
|
||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||
tier: EggTier.ULTRA
|
||||
};
|
||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
||||
|
@ -170,7 +170,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||
scene,
|
||||
pulled: false,
|
||||
sourceType: EggSourceType.EVENT,
|
||||
eventEggTypeDescriptor: encounter.misc.trainerEggDescription,
|
||||
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||
tier: EggTier.GREAT
|
||||
};
|
||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`));
|
||||
|
|
|
@ -23,6 +23,7 @@ import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
|||
import { BerryType } from "#enums/berry-type";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:absoluteAvarice";
|
||||
|
@ -35,7 +36,7 @@ const namespace = "mysteryEncounter:absoluteAvarice";
|
|||
export const AbsoluteAvariceEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.ABSOLUTE_AVARICE)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:offerYouCantRefuse";
|
||||
|
@ -24,7 +25,7 @@ const namespace = "mysteryEncounter:offerYouCantRefuse";
|
|||
export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ import i18next from "#app/plugins/i18n";
|
|||
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";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:berriesAbound";
|
||||
|
@ -42,7 +43,7 @@ const namespace = "mysteryEncounter:berriesAbound";
|
|||
export const BerriesAboundEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BERRIES_ABOUND)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withCatchAllowed(true)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||
|
|
|
@ -49,6 +49,7 @@ import i18next from "i18next";
|
|||
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
||||
import { allMoves } from "#app/data/move";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
||||
|
@ -191,7 +192,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||
new TypeRequirement(Type.BUG, false, 1)
|
||||
))
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroDialogue([
|
||||
|
|
|
@ -26,10 +26,11 @@ import { BerryModifier } from "#app/modifier/modifier";
|
|||
import { BerryType } from "#enums/berry-type";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { MoveCategory } from "#app/data/move";
|
||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||
import { GameModes } from "#app/game-mode";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES, GameModes } from "#app/game-mode";
|
||||
import { EncounterAnim } from "#enums/encounter-anims";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:clowningAround";
|
||||
|
@ -61,7 +62,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withDisabledGameModes(GameModes.CHALLENGE)
|
||||
.withSceneWaveRangeRequirement(80, 180)
|
||||
.withSceneWaveRangeRequirement(80, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withAnimations(EncounterAnim.SMOKESCREEN)
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Moves } from "#enums/moves";
|
|||
import { TrainerSlot } from "#app/data/trainer-config";
|
||||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { Biome } from "#enums/biome";
|
||||
import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||
import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
||||
|
@ -25,6 +25,8 @@ import { modifierTypes } from "#app/modifier/modifier-type";
|
|||
import { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { EncounterAnim } from "#enums/encounter-anims";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:dancingLessons";
|
||||
|
@ -81,7 +83,7 @@ const SENSU_STYLE_BIOMES = [
|
|||
export const DancingLessonsEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DANCING_LESSONS)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
||||
.withAnimations(EncounterAnim.DANCE)
|
||||
.withHideWildIntroMessage(true)
|
||||
|
|
|
@ -13,6 +13,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:darkDeal";
|
||||
|
@ -100,7 +101,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||
text: `${namespace}.intro_dialogue`,
|
||||
},
|
||||
])
|
||||
.withSceneWaveRangeRequirement(30, 180) // waves 30 to 180
|
||||
.withSceneWaveRangeRequirement(30, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||
.withCatchAllowed(true)
|
||||
.withTitle(`${namespace}.title`)
|
||||
|
|
|
@ -16,6 +16,7 @@ import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/u
|
|||
import i18next from "#app/plugins/i18n";
|
||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:delibirdy";
|
||||
|
@ -40,7 +41,7 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
|||
export const DelibirdyEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, 2)) // Must have enough money for it to spawn at the very least
|
||||
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn
|
||||
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||
|
|
|
@ -11,6 +11,7 @@ import MysteryEncounter, {
|
|||
MysteryEncounterBuilder,
|
||||
} from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:departmentStoreSale";
|
||||
|
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:departmentStoreSale";
|
|||
export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DEPARTMENT_STORE_SALE)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 100)
|
||||
.withSceneWaveRangeRequirement(CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[0], 100)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "b2w2_lady",
|
||||
|
|
|
@ -11,6 +11,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { Stat } from "#enums/stat";
|
||||
import i18next from "i18next";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:fieldTrip";
|
||||
|
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:fieldTrip";
|
|||
export const FieldTripEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIELD_TRIP)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "preschooler_m",
|
||||
|
@ -90,6 +91,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.DEF])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
|
@ -135,6 +137,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPDEF])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
|
@ -180,6 +183,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
||||
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||
];
|
||||
|
||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Type } from "#app/data/type";
|
|||
import { BattlerIndex } from "#app/battle";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { EncounterBattleAnim } from "#app/data/battle-anims";
|
||||
import { WeatherType } from "#app/data/weather";
|
||||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||
import { StatusEffect } from "#app/data/status-effect";
|
||||
|
@ -20,6 +20,8 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
|
|||
import { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { EncounterAnim } from "#enums/encounter-anims";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:fieryFallout";
|
||||
|
@ -39,7 +41,7 @@ const DAMAGE_PERCENTAGE: number = 20;
|
|||
export const FieryFalloutEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIERY_FALLOUT)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(40, 180)
|
||||
.withSceneWaveRangeRequirement(40, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withCatchAllowed(true)
|
||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||
.withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT)
|
||||
|
|
|
@ -28,6 +28,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
|||
import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { randSeedInt } from "#app/utils";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:fightOrFlight";
|
||||
|
@ -40,7 +41,7 @@ const namespace = "mysteryEncounter:fightOrFlight";
|
|||
export const FightOrFlightEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withCatchAllowed(true)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||
|
|
|
@ -21,6 +21,7 @@ import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
|||
import { PostSummonPhase } from "#app/phases/post-summon-phase";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||
import { Nature } from "#enums/nature";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:funAndGames";
|
||||
|
@ -33,7 +34,7 @@ const namespace = "mysteryEncounter:funAndGames";
|
|||
export const FunAndGamesEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FUN_AND_GAMES)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Cost equal to 1 Max Potion to play
|
||||
.withAutoHideIntroVisuals(false)
|
||||
// Allows using move without a visible enemy pokemon
|
||||
|
|
|
@ -22,6 +22,7 @@ import { getNatureName } from "#app/data/nature";
|
|||
import { getPokeballAtlasKey, getPokeballTintColor, PokeballType } from "#app/data/pokeball";
|
||||
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import { trainerNamePools } from "#app/data/trainer-names";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:globalTradeSystem";
|
||||
|
@ -70,7 +71,7 @@ const EXCLUDED_TRADE_SPECIES = [
|
|||
export const GlobalTradeSystemEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.GLOBAL_TRADE_SYSTEM)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ import { leaveEncounterWithoutBattle, setEncounterExp } from "../utils/encounter
|
|||
import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
const OPTION_1_REQUIRED_MOVE = Moves.SURF;
|
||||
const OPTION_2_REQUIRED_MOVE = Moves.FLY;
|
||||
|
@ -28,7 +29,7 @@ const namespace = "mysteryEncounter:lostAtSea";
|
|||
*/
|
||||
export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.LOST_AT_SEA)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(11, 179)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "buoy",
|
||||
|
|
|
@ -17,6 +17,7 @@ import BattleScene from "#app/battle-scene";
|
|||
import * as Utils from "#app/utils";
|
||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:mysteriousChallengers";
|
||||
|
@ -29,7 +30,7 @@ const namespace = "mysteryEncounter:mysteriousChallengers";
|
|||
export const MysteriousChallengersEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHALLENGERS)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||
.withIntroDialogue([
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||
import { Species } from "#enums/species";
|
||||
import { Moves } from "#enums/moves";
|
||||
import { GameOverPhase } from "#app/phases/game-over-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:mysteriousChest";
|
||||
|
@ -31,7 +32,7 @@ const MASTER_REWARDS_WEIGHT = 65; // 5%
|
|||
export const MysteriousChestEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHEST)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withCatchAllowed(true)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -11,6 +11,7 @@ import { CHARMING_MOVES } from "#app/data/mystery-encounters/requirements/requir
|
|||
import { getEncounterText, showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||
import i18next from "i18next";
|
||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:partTimer";
|
||||
|
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:partTimer";
|
|||
export const PartTimerEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.PART_TIMER)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "warehouse_crate",
|
||||
|
|
|
@ -18,6 +18,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { ScanIvsPhase } from "#app/phases/scan-ivs-phase";
|
||||
import { SummonPhase } from "#app/phases/summon-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:safariZone";
|
||||
|
@ -34,7 +35,7 @@ const SAFARI_MONEY_MULTIPLIER = 2.75;
|
|||
export const SafariZoneEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SAFARI_ZONE)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, SAFARI_MONEY_MULTIPLIER)) // Cost equal to 1 Max Revive
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -14,6 +14,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { Nature } from "#enums/nature";
|
||||
import { getNatureName } from "#app/data/nature";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:shadyVitaminDealer";
|
||||
|
@ -26,7 +27,7 @@ const namespace = "mysteryEncounter:shadyVitaminDealer";
|
|||
export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Must have the money for at least the cheap deal
|
||||
.withPrimaryPokemonHealthRatioRequirement([0.5, 1]) // At least 1 Pokemon must have above half HP
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -16,6 +16,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:slumberingSnorlax";
|
||||
|
@ -28,7 +29,7 @@ const namespace = "mysteryEncounter:slumberingSnorlax";
|
|||
export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SLUMBERING_SNORLAX)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withCatchAllowed(true)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -19,6 +19,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
|||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:teleportingHijinks";
|
||||
|
@ -35,7 +36,7 @@ const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
|
|||
export const TeleportingHijinksEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave
|
||||
.withSceneRequirement(new MoneyRequirement(undefined, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost
|
||||
.withAutoHideIntroVisuals(false)
|
||||
|
|
|
@ -14,6 +14,7 @@ import { showEncounterDialogue } from "#app/data/mystery-encounters/utils/encoun
|
|||
import PokemonData from "#app/system/pokemon-data";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:pokemonSalesman";
|
||||
|
@ -28,7 +29,7 @@ const MAX_POKEMON_PRICE_MULTIPLIER = 6;
|
|||
export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_POKEMON_SALESMAN)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withSceneRequirement(new MoneyRequirement(undefined, MAX_POKEMON_PRICE_MULTIPLIER)) // Some costs may not be as significant, this is the max you'd pay
|
||||
.withAutoHideIntroVisuals(false)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -17,6 +17,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:theStrongStuff";
|
||||
|
@ -33,7 +34,7 @@ const BST_INCREASE_VALUE = 10;
|
|||
export const TheStrongStuffEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_STRONG_STUFF)
|
||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
||||
.withHideWildIntroMessage(true)
|
||||
.withAutoHideIntroVisuals(false)
|
||||
|
|
|
@ -22,6 +22,7 @@ import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
|
|||
import { ReturnPhase } from "#app/phases/return-phase";
|
||||
import i18next from "i18next";
|
||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:theWinstrateChallenge";
|
||||
|
@ -34,7 +35,7 @@ const namespace = "mysteryEncounter:theWinstrateChallenge";
|
|||
export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_WINSTRATE_CHALLENGE)
|
||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||
.withSceneWaveRangeRequirement(100, 180)
|
||||
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "vito",
|
||||
|
|
|
@ -19,6 +19,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
|
|||
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import i18next from "i18next";
|
||||
import { getStatKey } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** The i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:trainingSession";
|
||||
|
@ -31,7 +32,7 @@ const namespace = "mysteryEncounter:trainingSession";
|
|||
export const TrainingSessionEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRAINING_SESSION)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 unfainted pokemon in party
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([
|
||||
|
|
|
@ -17,6 +17,7 @@ import { Moves } from "#enums/moves";
|
|||
import { BattlerIndex } from "#app/battle";
|
||||
import { PokemonMove } from "#app/field/pokemon";
|
||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for this encounter */
|
||||
const namespace = "mysteryEncounter:trashToTreasure";
|
||||
|
@ -31,7 +32,7 @@ const SOUND_EFFECT_WAIT_TIME = 700;
|
|||
export const TrashToTreasureEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRASH_TO_TREASURE)
|
||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||
.withSceneWaveRangeRequirement(60, 180)
|
||||
.withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||
.withMaxAllowedEncounters(1)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
|
|||
import { BerryModifier } from "#app/modifier/modifier";
|
||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||
|
||||
/** the i18n namespace for the encounter */
|
||||
const namespace = "mysteryEncounter:uncommonBreed";
|
||||
|
@ -35,7 +36,7 @@ const namespace = "mysteryEncounter:uncommonBreed";
|
|||
export const UncommonBreedEncounter: MysteryEncounter =
|
||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.UNCOMMON_BREED)
|
||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withCatchAllowed(true)
|
||||
.withHideWildIntroMessage(true)
|
||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||
|
|
|
@ -20,7 +20,7 @@ import i18next from "#app/plugins/i18n";
|
|||
import { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence";
|
||||
import { getLevelTotalExp } from "#app/data/exp";
|
||||
import { Stat } from "#enums/stat";
|
||||
import { GameModes } from "#app/game-mode";
|
||||
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES, GameModes } from "#app/game-mode";
|
||||
|
||||
/** i18n namespace for encounter */
|
||||
const namespace = "mysteryEncounter:weirdDream";
|
||||
|
@ -82,10 +82,16 @@ const SUPER_LEGENDARY_BST_THRESHOLD = 600;
|
|||
const NON_LEGENDARY_BST_THRESHOLD = 570;
|
||||
const GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD = 450;
|
||||
|
||||
/** Value ranges of the resulting species BST transformations after adding values to original species */
|
||||
|
||||
const HIGH_BST_TRANSFORM_BASE_VALUES = [90, 110];
|
||||
const STANDARD_BST_TRANSFORM_BASE_VALUES = [40, 50];
|
||||
/**
|
||||
* Value ranges of the resulting species BST transformations after adding values to original species
|
||||
* 2 Pokemon in the party use this range
|
||||
*/
|
||||
const HIGH_BST_TRANSFORM_BASE_VALUES: [number, number] = [90, 110];
|
||||
/**
|
||||
* Value ranges of the resulting species BST transformations after adding values to original species
|
||||
* All remaining Pokemon in the party use this range
|
||||
*/
|
||||
const STANDARD_BST_TRANSFORM_BASE_VALUES: [number, number] = [40, 50];
|
||||
|
||||
/**
|
||||
* Weird Dream encounter.
|
||||
|
@ -96,7 +102,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM)
|
||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||
.withDisabledGameModes(GameModes.CHALLENGE)
|
||||
.withSceneWaveRangeRequirement(10, 180)
|
||||
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||
.withIntroSpriteConfigs([
|
||||
{
|
||||
spriteKey: "weird_dream_woman",
|
||||
|
@ -252,7 +258,7 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] {
|
|||
scene.removePokemonFromPlayerParty(removed, false);
|
||||
|
||||
const bst = removed.calculateBaseStats().reduce((a, b) => a + b, 0);
|
||||
let newBstRange;
|
||||
let newBstRange: [number, number];
|
||||
if (i < 2) {
|
||||
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,8 @@ export class EncounterOptionsDialogue {
|
|||
title?: string;
|
||||
description?: string;
|
||||
query?: string;
|
||||
options?: [...OptionTextDisplay[]]; // Options array with minimum 2 options
|
||||
/** Options array with minimum 2 options */
|
||||
options?: [...OptionTextDisplay[]];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,10 @@ import { Abilities } from "#enums/abilities";
|
|||
import { Type } from "#app/data/type";
|
||||
import { isNullOrUndefined } from "#app/utils";
|
||||
|
||||
/**
|
||||
* Data that can customize a Pokemon in non-standard ways from its Species
|
||||
* Currently only used by Mystery Encounters, may need to be renamed if it becomes more widely used
|
||||
*/
|
||||
export class MysteryEncounterPokemonData {
|
||||
public spriteScale: number;
|
||||
public ability: Abilities | -1;
|
||||
|
|
|
@ -53,7 +53,7 @@ export class CombinationSceneRequirement extends EncounterSceneRequirement {
|
|||
return false;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
|
@ -99,7 +99,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||
this.orRequirements = orRequirements;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return true;
|
||||
|
@ -108,7 +108,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||
return false;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
for (const req of this.orRequirements) {
|
||||
const result = req.queryParty(partyPokemon);
|
||||
if (result?.length > 0) {
|
||||
|
@ -119,7 +119,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||
return [];
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
for (const req of this.orRequirements) {
|
||||
if (req.meetsRequirement(scene)) {
|
||||
return req.getDialogueToken(scene, pokemon);
|
||||
|
@ -142,11 +142,11 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
|
|||
this.previousEncounterRequirement = previousEncounterRequirement;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
return scene.mysteryEncounterSaveData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""];
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
|
|||
this.waveRange = waveRange;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
if (!isNullOrUndefined(this.waveRange) && this.waveRange?.[0] <= this.waveRange?.[1]) {
|
||||
const waveIndex = scene.currentBattle.waveIndex;
|
||||
if (waveIndex >= 0 && (this.waveRange?.[0] >= 0 && this.waveRange?.[0] > waveIndex) || (this.waveRange?.[1] >= 0 && this.waveRange?.[1] < waveIndex)) {
|
||||
|
@ -174,7 +174,7 @@ export class WaveRangeRequirement extends EncounterSceneRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
||||
}
|
||||
}
|
||||
|
@ -199,11 +199,11 @@ export class WaveModulusRequirement extends EncounterSceneRequirement {
|
|||
this.modulusValue = modulusValue;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
return this.waveModuli.includes(scene.currentBattle.waveIndex % this.modulusValue);
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const timeOfDay = scene.arena?.getTimeOfDay();
|
||||
if (!isNullOrUndefined(timeOfDay) && this.requiredTimeOfDay?.length > 0 && !this.requiredTimeOfDay.includes(timeOfDay)) {
|
||||
return false;
|
||||
|
@ -225,7 +225,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()];
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||
this.requiredWeather = Array.isArray(weather) ? weather : [weather];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const currentWeather = scene.arena.weather?.weatherType;
|
||||
if (!isNullOrUndefined(currentWeather) && this.requiredWeather?.length > 0 && !this.requiredWeather.includes(currentWeather!)) {
|
||||
return false;
|
||||
|
@ -247,7 +247,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const currentWeather = scene.arena.weather?.weatherType;
|
||||
let token = "";
|
||||
if (!isNullOrUndefined(currentWeather)) {
|
||||
|
@ -273,7 +273,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
|
|||
this.excludeFainted = excludeFainted;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
if (!isNullOrUndefined(this.partySizeRange) && this.partySizeRange?.[0] <= this.partySizeRange?.[1]) {
|
||||
const partySize = this.excludeFainted ? scene.getParty().filter(p => p.isAllowedInBattle()).length : scene.getParty().length;
|
||||
if (partySize >= 0 && (this.partySizeRange?.[0] >= 0 && this.partySizeRange?.[0] > partySize) || (this.partySizeRange?.[1] >= 0 && this.partySizeRange?.[1] < partySize)) {
|
||||
|
@ -284,7 +284,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["partySize", scene.getParty().length.toString()];
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) {
|
||||
return false;
|
||||
|
@ -317,7 +317,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||
return modifierCount >= this.minNumberOfItems;
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["requiredItem", this.requiredHeldItemModifiers[0]];
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||
this.scalingMultiplier = scalingMultiplier ?? 0;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const money = scene.money;
|
||||
if (isNullOrUndefined(money)) {
|
||||
return false;
|
||||
|
@ -344,7 +344,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||
return !(this.requiredMoney > 0 && this.requiredMoney > money);
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
|
||||
return ["money", value];
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredSpecies = Array.isArray(species) ? species : [species];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredSpecies?.length < 0) {
|
||||
return false;
|
||||
|
@ -370,7 +370,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredSpecies.filter((species) => pokemon.species.speciesId === species).length > 0);
|
||||
} else {
|
||||
|
@ -379,7 +379,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) {
|
||||
return ["species", Species[pokemon.species.speciesId]];
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredNature = Array.isArray(nature) ? nature : [nature];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredNature?.length < 0) {
|
||||
return false;
|
||||
|
@ -408,7 +408,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredNature.filter((nature) => pokemon.nature === nature).length > 0);
|
||||
} else {
|
||||
|
@ -417,7 +417,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon!.nature)) {
|
||||
return ["nature", Nature[pokemon!.nature]];
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredType = Array.isArray(type) ? type : [type];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
let partyPokemon = scene.getParty();
|
||||
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
|
@ -453,7 +453,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredType.filter((type) => pokemon.getTypes().includes(type)).length > 0);
|
||||
} else {
|
||||
|
@ -462,7 +462,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty));
|
||||
if (includedTypes.length > 0) {
|
||||
return ["type", Type[includedTypes[0]]];
|
||||
|
@ -484,7 +484,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredMoves = Array.isArray(moves) ? moves : [moves];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
||||
return false;
|
||||
|
@ -492,7 +492,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move?.moveId === reqMove).length > 0).length > 0);
|
||||
} else {
|
||||
|
@ -501,7 +501,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId));
|
||||
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
|
||||
return ["move", includedMoves[0].getName()];
|
||||
|
@ -528,7 +528,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
||||
return false;
|
||||
|
@ -536,7 +536,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove)).length > 0);
|
||||
} else {
|
||||
|
@ -545,7 +545,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
|
||||
if (includedCompatMoves.length > 0) {
|
||||
return ["compatibleMove", Moves[includedCompatMoves[0]]];
|
||||
|
@ -568,7 +568,7 @@ export class EvolutionTargetSpeciesRequirement extends EncounterPokemonRequireme
|
|||
this.requiredEvolutionTargetSpecies = Array.isArray(evolutionTargetSpecies) ? evolutionTargetSpecies : [evolutionTargetSpecies];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionTargetSpecies?.length < 0) {
|
||||
return false;
|
||||
|
@ -576,7 +576,7 @@ export class EvolutionTargetSpeciesRequirement extends EncounterPokemonRequireme
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution()?.speciesId === evolutionTargetSpecies).length > 0);
|
||||
} else {
|
||||
|
@ -607,7 +607,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredAbilities?.length < 0) {
|
||||
return false;
|
||||
|
@ -615,7 +615,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredAbilities.some((ability) => pokemon.getAbility().id === ability));
|
||||
} else {
|
||||
|
@ -624,7 +624,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) {
|
||||
return ["ability", pokemon.getAbility().name];
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredStatusEffect?.length < 0) {
|
||||
return false;
|
||||
|
@ -654,7 +654,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||
return x;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => {
|
||||
return this.requiredStatusEffect.some((statusEffect) => {
|
||||
|
@ -682,7 +682,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const reqStatus = this.requiredStatusEffect.filter((a) => {
|
||||
if (a === StatusEffect.NONE) {
|
||||
return isNullOrUndefined(pokemon?.status) || isNullOrUndefined(pokemon!.status!.effect) || pokemon!.status!.effect === a;
|
||||
|
@ -714,7 +714,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredFormChangeItem?.length < 0) {
|
||||
return false;
|
||||
|
@ -735,7 +735,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||
}
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem)).length > 0);
|
||||
} else {
|
||||
|
@ -744,7 +744,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem));
|
||||
if (requiredItems.length > 0) {
|
||||
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
||||
|
@ -766,7 +766,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionItem?.length < 0) {
|
||||
return false;
|
||||
|
@ -785,7 +785,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||
return false;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredEvolutionItem.filter((evolutionItem) => this.filterByEvo(pokemon, evolutionItem)).length > 0);
|
||||
} else {
|
||||
|
@ -794,7 +794,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem));
|
||||
if (requiredItems.length > 0) {
|
||||
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
||||
|
@ -815,7 +815,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
return false;
|
||||
|
@ -823,7 +823,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredHeldItemModifiers.some((heldItem) => {
|
||||
return pokemon.getHeldItems().some((it) => {
|
||||
|
@ -839,7 +839,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const requiredItems = pokemon?.getHeldItems().filter((it) => {
|
||||
return this.requiredHeldItemModifiers.some(heldItem => it.constructor.name === heldItem);
|
||||
});
|
||||
|
@ -862,7 +862,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
const partyPokemon = scene.getParty();
|
||||
if (isNullOrUndefined(partyPokemon)) {
|
||||
return false;
|
||||
|
@ -870,7 +870,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => this.requiredHeldItemTypes.some((heldItemType) => {
|
||||
return pokemon.getHeldItems().some((it) => {
|
||||
|
@ -886,7 +886,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
const requiredItems = pokemon?.getHeldItems().filter((it) => {
|
||||
return this.requiredHeldItemTypes.some(heldItemType => it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType);
|
||||
});
|
||||
|
@ -909,7 +909,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredLevelRange = requiredLevelRange;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
// Party Pokemon inside required level range
|
||||
if (!isNullOrUndefined(this.requiredLevelRange) && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) {
|
||||
const partyPokemon = scene.getParty();
|
||||
|
@ -921,7 +921,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => pokemon.level >= this.requiredLevelRange[0] && pokemon.level <= this.requiredLevelRange[1]);
|
||||
} else {
|
||||
|
@ -930,7 +930,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["level", pokemon?.level.toString() ?? ""];
|
||||
}
|
||||
}
|
||||
|
@ -947,7 +947,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredFriendshipRange = requiredFriendshipRange;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
// Party Pokemon inside required friendship range
|
||||
if (!isNullOrUndefined(this.requiredFriendshipRange) && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1]) {
|
||||
const partyPokemon = scene.getParty();
|
||||
|
@ -959,7 +959,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => pokemon.friendship >= this.requiredFriendshipRange[0] && pokemon.friendship <= this.requiredFriendshipRange[1]);
|
||||
} else {
|
||||
|
@ -968,7 +968,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["friendship", pokemon?.friendship.toString() ?? ""];
|
||||
}
|
||||
}
|
||||
|
@ -990,7 +990,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredHealthRange = requiredHealthRange;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
// Party Pokemon inside required level range
|
||||
if (!isNullOrUndefined(this.requiredHealthRange) && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) {
|
||||
const partyPokemon = scene.getParty();
|
||||
|
@ -1002,7 +1002,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => {
|
||||
return pokemon.getHpRatio() >= this.requiredHealthRange[0] && pokemon.getHpRatio() <= this.requiredHealthRange[1];
|
||||
|
@ -1013,7 +1013,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
if (!isNullOrUndefined(pokemon?.getHpRatio())) {
|
||||
return ["healthRatio", Math.floor(pokemon!.getHpRatio() * 100).toString() + "%"];
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||
this.requiredWeightRange = requiredWeightRange;
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
override meetsRequirement(scene: BattleScene): boolean {
|
||||
// Party Pokemon inside required friendship range
|
||||
if (!isNullOrUndefined(this.requiredWeightRange) && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) {
|
||||
const partyPokemon = scene.getParty();
|
||||
|
@ -1045,7 +1045,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||
return true;
|
||||
}
|
||||
|
||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||
if (!this.invertQuery) {
|
||||
return partyPokemon.filter((pokemon) => pokemon.getWeight() >= this.requiredWeightRange[0] && pokemon.getWeight() <= this.requiredWeightRange[1]);
|
||||
} else {
|
||||
|
@ -1054,7 +1054,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||
}
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["weight", pokemon?.getWeight().toString() ?? ""];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ import MysteryEncounterDialogue, { OptionTextDisplay } from "./mystery-encounter
|
|||
import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option";
|
||||
import { EncounterPokemonRequirement, EncounterSceneRequirement, HealthRatioRequirement, PartySizeRequirement, StatusEffectRequirement, WaveRangeRequirement } from "./mystery-encounter-requirements";
|
||||
import { BattlerIndex } from "#app/battle";
|
||||
import { EncounterAnim } from "#app/data/battle-anims";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||
import { GameModes } from "#app/game-mode";
|
||||
import { EncounterAnim } from "#enums/encounter-anims";
|
||||
|
||||
export interface EncounterStartOfBattleEffect {
|
||||
sourcePokemon?: Pokemon;
|
||||
|
@ -72,15 +72,14 @@ export interface IMysteryEncounter {
|
|||
* Unless you know what you're doing, you should use MysteryEncounterBuilder to create an instance for this class
|
||||
*/
|
||||
export default class MysteryEncounter implements IMysteryEncounter {
|
||||
/**
|
||||
* Required params
|
||||
*/
|
||||
// #region Required params
|
||||
|
||||
encounterType: MysteryEncounterType;
|
||||
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
||||
spriteConfigs: MysteryEncounterSpriteConfig[];
|
||||
/**
|
||||
* Optional params
|
||||
*/
|
||||
|
||||
// #region Optional params
|
||||
|
||||
encounterTier: MysteryEncounterTier;
|
||||
/**
|
||||
* Custom battle animations that are configured for encounter effects and visuals
|
||||
|
@ -137,9 +136,8 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||
*/
|
||||
skipToFightInput: boolean;
|
||||
|
||||
/**
|
||||
* Event callback functions
|
||||
*/
|
||||
// #region Event callback functions
|
||||
|
||||
/** Event when Encounter is first loaded, use it for data conditioning */
|
||||
onInit?: (scene: BattleScene) => boolean;
|
||||
/** Event when battlefield visuals have finished sliding in and the encounter dialogue begins */
|
||||
|
@ -171,9 +169,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||
primaryPokemon?: PlayerPokemon;
|
||||
secondaryPokemon?: PlayerPokemon[];
|
||||
|
||||
/**
|
||||
* Post-construct / Auto-populated params
|
||||
*/
|
||||
// #region Post-construct / Auto-populated params
|
||||
|
||||
/**
|
||||
* Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter
|
||||
|
@ -192,9 +188,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||
*/
|
||||
introVisuals?: MysteryEncounterIntroVisuals;
|
||||
|
||||
/**
|
||||
* Flags
|
||||
*/
|
||||
// #region Flags
|
||||
|
||||
/**
|
||||
* Can be set for uses programatic dialogue during an encounter (storing the name of one of the party's pokemon, etc.)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { Moves } from "#enums/moves";
|
||||
import { Abilities } from "#enums/abilities";
|
||||
|
||||
/**
|
||||
* Moves that "steal" things
|
||||
*/
|
||||
export const STEALING_MOVES = [
|
||||
Moves.PLUCK,
|
||||
Moves.COVET,
|
||||
|
@ -10,6 +13,9 @@ export const STEALING_MOVES = [
|
|||
Moves.SWITCHEROO
|
||||
];
|
||||
|
||||
/**
|
||||
* Moves that "charm" someone
|
||||
*/
|
||||
export const CHARMING_MOVES = [
|
||||
Moves.CHARM,
|
||||
Moves.FLATTER,
|
||||
|
@ -39,6 +45,9 @@ export const DANCING_MOVES = [
|
|||
Moves.VICTORY_DANCE
|
||||
];
|
||||
|
||||
/**
|
||||
* Moves that can distract someone/something
|
||||
*/
|
||||
export const DISTRACTION_MOVES = [
|
||||
Moves.FAKE_OUT,
|
||||
Moves.FOLLOW_ME,
|
||||
|
@ -54,6 +63,9 @@ export const DISTRACTION_MOVES = [
|
|||
Moves.SHED_TAIL
|
||||
];
|
||||
|
||||
/**
|
||||
* Moves that protect in some way
|
||||
*/
|
||||
export const PROTECTING_MOVES = [
|
||||
Moves.PROTECT,
|
||||
Moves.WIDE_GUARD,
|
||||
|
@ -70,6 +82,9 @@ export const PROTECTING_MOVES = [
|
|||
Moves.DETECT
|
||||
];
|
||||
|
||||
/**
|
||||
* Moves that (loosely) can be used to trap/rob someone
|
||||
*/
|
||||
export const EXTORTION_MOVES = [
|
||||
Moves.BIND,
|
||||
Moves.CLAMP,
|
||||
|
@ -93,6 +108,9 @@ export const EXTORTION_MOVES = [
|
|||
Moves.STRING_SHOT,
|
||||
];
|
||||
|
||||
/**
|
||||
* Abilities that (loosely) can be used to trap/rob someone
|
||||
*/
|
||||
export const EXTORTION_ABILITIES = [
|
||||
Abilities.INTIMIDATE,
|
||||
Abilities.ARENA_TRAP,
|
||||
|
|
|
@ -88,13 +88,18 @@ export interface EnemyPokemonConfig {
|
|||
}
|
||||
|
||||
export interface EnemyPartyConfig {
|
||||
levelAdditiveMultiplier?: number; // Formula for enemy: level += waveIndex / 10 * levelAdditive
|
||||
/** Formula for enemy: level += waveIndex / 10 * levelAdditive */
|
||||
levelAdditiveMultiplier?: number;
|
||||
doubleBattle?: boolean;
|
||||
trainerType?: TrainerType; // Generates trainer battle solely off trainer type
|
||||
trainerConfig?: TrainerConfig; // More customizable option for configuring trainer battle
|
||||
/** Generates trainer battle solely off trainer type */
|
||||
trainerType?: TrainerType;
|
||||
/** More customizable option for configuring trainer battle */
|
||||
trainerConfig?: TrainerConfig;
|
||||
pokemonConfigs?: EnemyPokemonConfig[];
|
||||
female?: boolean; // True for female trainer, false for male
|
||||
disableSwitch?: boolean; // True will prevent player from switching
|
||||
/** True for female trainer, false for male */
|
||||
female?: boolean;
|
||||
/** True will prevent player from switching */
|
||||
disableSwitch?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Animations used for Mystery Encounters
|
||||
* These are custom animations that may or may not work in any other circumstance
|
||||
* Use at your own risk
|
||||
*/
|
||||
export enum EncounterAnim {
|
||||
MAGMA_BG,
|
||||
MAGMA_SPOUT,
|
||||
SMOKESCREEN,
|
||||
DANCE
|
||||
}
|
|
@ -33,8 +33,8 @@ interface GameModeConfig {
|
|||
}
|
||||
|
||||
// Describes min and max waves for MEs in specific game modes
|
||||
const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||
const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||
|
||||
export class GameMode implements GameModeConfig {
|
||||
public modeId: GameModes;
|
||||
|
@ -325,6 +325,9 @@ export class GameMode implements GameModeConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wave range where MEs can spawn for the game mode [min, max]
|
||||
*/
|
||||
getMysteryEncounterLegalWaves(): [number, number] {
|
||||
switch (this.modeId) {
|
||||
default:
|
||||
|
|
|
@ -174,6 +174,13 @@ export class MysteryEncounterOptionSelectedPhase extends Phase {
|
|||
this.onOptionSelect = this.scene.currentBattle.mysteryEncounter!.selectedOption!.onOptionPhase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will handle (in order):
|
||||
* - Execute onOptionSelect() logic if it exists for the selected option
|
||||
*
|
||||
* It is important to point out that no phases are directly queued by any logic within this phase
|
||||
* Any phase that is meant to follow this one MUST be queued via the onOptionSelect() logic of the selected option
|
||||
*/
|
||||
start() {
|
||||
super.start();
|
||||
if (this.scene.currentBattle.mysteryEncounter?.autoHideIntroVisuals) {
|
||||
|
|
|
@ -18,6 +18,9 @@ export class PartyExpPhase extends Phase {
|
|||
this.pokemonParticipantIds = pokemonParticipantIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives EXP to the party
|
||||
*/
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ export default class PokemonData {
|
|||
public bossSegments?: integer;
|
||||
|
||||
public summonData: PokemonSummonData;
|
||||
/** Data that can customize a Pokemon in non-standard ways from its Species */
|
||||
public mysteryEncounterPokemonData: MysteryEncounterPokemonData;
|
||||
|
||||
constructor(source: Pokemon | any, forHistory: boolean = false) {
|
||||
|
|
|
@ -117,11 +117,12 @@ describe("Field Trip - Mystery Encounter", () => {
|
|||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(4);
|
||||
expect(modifierSelectHandler.options.length).toEqual(5);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("X Attack");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Defense");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("Dire Hit");
|
||||
expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("Rarer Candy");
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
|
@ -163,11 +164,12 @@ describe("Field Trip - Mystery Encounter", () => {
|
|||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(4);
|
||||
expect(modifierSelectHandler.options.length).toEqual(5);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("X Sp. Atk");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Sp. Def");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("Dire Hit");
|
||||
expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("Dire Hit");
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
|
@ -209,11 +211,12 @@ describe("Field Trip - Mystery Encounter", () => {
|
|||
|
||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
||||
expect(modifierSelectHandler.options.length).toEqual(4);
|
||||
expect(modifierSelectHandler.options.length).toEqual(5);
|
||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.name).toBe("X Accuracy");
|
||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Speed");
|
||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("5x Great Ball");
|
||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("IV Scanner");
|
||||
expect(modifierSelectHandler.options[4].modifierTypeOption.type.name).toBe("Rarer Candy");
|
||||
});
|
||||
|
||||
it("should leave encounter without battle", async () => {
|
||||
|
|
Loading…
Reference in New Issue