mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-20 15:22:19 +02:00
Compare commits
17 Commits
282eee8dd8
...
bb21de335f
Author | SHA1 | Date | |
---|---|---|---|
|
bb21de335f | ||
|
1533af5b5d | ||
|
6159d938b6 | ||
|
9ccb15ee8b | ||
|
ae88966a11 | ||
|
cc0220e30a | ||
|
2970ca530b | ||
|
894d71631d | ||
|
550fe76eb1 | ||
|
393b733cc9 | ||
|
f8f157a319 | ||
|
d4565158b1 | ||
|
28dd929da2 | ||
|
d51f294c03 | ||
|
e232fc0f52 | ||
|
36e3a0d2a9 | ||
|
0e7f9dc723 |
@ -265,7 +265,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
public money: integer;
|
public money: integer;
|
||||||
public pokemonInfoContainer: PokemonInfoContainer;
|
public pokemonInfoContainer: PokemonInfoContainer;
|
||||||
private party: PlayerPokemon[];
|
private party: PlayerPokemon[];
|
||||||
|
/** Session save data that pertains to Mystery Encounters */
|
||||||
public mysteryEncounterSaveData: MysteryEncounterSaveData = new MysteryEncounterSaveData();
|
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;
|
public lastMysteryEncounter?: MysteryEncounter;
|
||||||
/** Combined Biome and Wave count text */
|
/** Combined Biome and Wave count text */
|
||||||
private biomeWaveText: Phaser.GameObjects.Text;
|
private biomeWaveText: Phaser.GameObjects.Text;
|
||||||
|
@ -80,6 +80,7 @@ export default class Battle {
|
|||||||
public playerFaintsHistory: FaintLogEntry[] = [];
|
public playerFaintsHistory: FaintLogEntry[] = [];
|
||||||
public enemyFaintsHistory: FaintLogEntry[] = [];
|
public enemyFaintsHistory: FaintLogEntry[] = [];
|
||||||
|
|
||||||
|
/** If the current battle is a Mystery Encounter, this will always be defined */
|
||||||
public mysteryEncounter?: MysteryEncounter;
|
public mysteryEncounter?: MysteryEncounter;
|
||||||
|
|
||||||
private rngCounter: number = 0;
|
private rngCounter: number = 0;
|
||||||
|
@ -9,6 +9,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { SubstituteTag } from "./battler-tags";
|
import { SubstituteTag } from "./battler-tags";
|
||||||
import { isNullOrUndefined } from "../utils";
|
import { isNullOrUndefined } from "../utils";
|
||||||
import Phaser from "phaser";
|
import Phaser from "phaser";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
//import fs from 'vite-plugin-fs/browser';
|
//import fs from 'vite-plugin-fs/browser';
|
||||||
|
|
||||||
export enum AnimFrameTarget {
|
export enum AnimFrameTarget {
|
||||||
@ -105,18 +106,6 @@ export enum CommonAnim {
|
|||||||
LOCK_ON = 2120
|
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 {
|
export class AnimConfig {
|
||||||
public id: integer;
|
public id: integer;
|
||||||
public graphic: string;
|
public graphic: string;
|
||||||
|
@ -2315,10 +2315,12 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
|||||||
super(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, BattlerTagLapseType.CUSTOM, 1);
|
super(BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON, BattlerTagLapseType.CUSTOM, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Event when tag is added */
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
super.onAdd(pokemon);
|
super.onAdd(pokemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Performs post-summon effects through {@linkcode Pokemon.mysteryEncounterBattleEffects} */
|
||||||
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
const ret = super.lapse(pokemon, lapseType);
|
const ret = super.lapse(pokemon, lapseType);
|
||||||
|
|
||||||
@ -2335,6 +2337,7 @@ export class MysteryEncounterPostSummonTag extends BattlerTag {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Event when tag is removed */
|
||||||
onRemove(pokemon: Pokemon): void {
|
onRemove(pokemon: Pokemon): void {
|
||||||
super.onRemove(pokemon);
|
super.onRemove(pokemon);
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ export interface IEggOptions {
|
|||||||
*/
|
*/
|
||||||
overrideHiddenAbility?: boolean,
|
overrideHiddenAbility?: boolean,
|
||||||
|
|
||||||
/** If Egg is of {@link EggSourceType.EVENT}, can customize the message displayed for where the egg was obtained */
|
/** Can customize the message displayed for where the egg was obtained */
|
||||||
eventEggTypeDescriptor?: string;
|
eggDescriptor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Egg {
|
export class Egg {
|
||||||
@ -86,7 +86,7 @@ export class Egg {
|
|||||||
|
|
||||||
private _overrideHiddenAbility: boolean;
|
private _overrideHiddenAbility: boolean;
|
||||||
|
|
||||||
private _eventEggTypeDescriptor?: string;
|
private _eggDescriptor?: string;
|
||||||
|
|
||||||
////
|
////
|
||||||
// #endregion
|
// #endregion
|
||||||
@ -197,7 +197,7 @@ export class Egg {
|
|||||||
generateEggProperties(eggOptions);
|
generateEggProperties(eggOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._eventEggTypeDescriptor = eggOptions?.eventEggTypeDescriptor;
|
this._eggDescriptor = eggOptions?.eggDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
@ -299,15 +299,15 @@ export class Egg {
|
|||||||
public getEggTypeDescriptor(scene: BattleScene): string {
|
public getEggTypeDescriptor(scene: BattleScene): string {
|
||||||
switch (this.sourceType) {
|
switch (this.sourceType) {
|
||||||
case EggSourceType.SAME_SPECIES_EGG:
|
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:
|
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:
|
case EggSourceType.GACHA_SHINY:
|
||||||
return i18next.t("egg:gachaTypeShiny");
|
return this._eggDescriptor ?? i18next.t("egg:gachaTypeShiny");
|
||||||
case EggSourceType.GACHA_MOVE:
|
case EggSourceType.GACHA_MOVE:
|
||||||
return i18next.t("egg:gachaTypeMove");
|
return this._eggDescriptor ?? i18next.t("egg:gachaTypeMove");
|
||||||
case EggSourceType.EVENT:
|
case EggSourceType.EVENT:
|
||||||
return this._eventEggTypeDescriptor ?? i18next.t("egg:eventType");
|
return this._eggDescriptor ?? i18next.t("egg:eventType");
|
||||||
default:
|
default:
|
||||||
console.warn("getEggTypeDescriptor case not defined. Returning default empty string");
|
console.warn("getEggTypeDescriptor case not defined. Returning default empty string");
|
||||||
return "";
|
return "";
|
||||||
|
@ -96,7 +96,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription };
|
encounter.misc = { trainerType, trainerNameKey, trainerEggDescription: eggDescription };
|
||||||
|
|
||||||
// Trainer config
|
// Trainer config
|
||||||
const trainerConfig = trainerConfigs[trainerType].copy();
|
const trainerConfig = trainerConfigs[trainerType].clone();
|
||||||
const trainerSpriteKey = trainerConfig.getSpriteKey();
|
const trainerSpriteKey = trainerConfig.getSpriteKey();
|
||||||
encounter.enemyPartyConfigs.push({
|
encounter.enemyPartyConfigs.push({
|
||||||
levelAdditiveMultiplier: 1,
|
levelAdditiveMultiplier: 1,
|
||||||
@ -147,7 +147,7 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
scene,
|
scene,
|
||||||
pulled: false,
|
pulled: false,
|
||||||
sourceType: EggSourceType.EVENT,
|
sourceType: EggSourceType.EVENT,
|
||||||
eventEggTypeDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.ULTRA
|
tier: EggTier.ULTRA
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.epic`));
|
||||||
@ -170,11 +170,11 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
scene,
|
scene,
|
||||||
pulled: false,
|
pulled: false,
|
||||||
sourceType: EggSourceType.EVENT,
|
sourceType: EggSourceType.EVENT,
|
||||||
eventEggTypeDescriptor: encounter.misc.trainerEggDescription,
|
eggDescriptor: encounter.misc.trainerEggDescription,
|
||||||
tier: EggTier.GREAT
|
tier: EggTier.GREAT
|
||||||
};
|
};
|
||||||
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`));
|
encounter.setDialogueToken("eggType", i18next.t(`${namespace}.eggTypes.rare`));
|
||||||
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: 0 }, [eggOptions]);
|
setEncounterRewards(scene, { fillRemaining: false, rerollMultiplier: -1 }, [eggOptions]);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,7 @@ import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
|||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:absoluteAvarice";
|
const namespace = "mysteryEncounter:absoluteAvarice";
|
||||||
@ -35,7 +36,7 @@ const namespace = "mysteryEncounter:absoluteAvarice";
|
|||||||
export const AbsoluteAvariceEncounter: MysteryEncounter =
|
export const AbsoluteAvariceEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.ABSOLUTE_AVARICE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.ABSOLUTE_AVARICE)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.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
|
.withSceneRequirement(new PersistentModifierRequirement("BerryModifier", 4)) // Must have at least 4 berries to spawn
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:offerYouCantRefuse";
|
const namespace = "mysteryEncounter:offerYouCantRefuse";
|
||||||
@ -24,7 +25,7 @@ const namespace = "mysteryEncounter:offerYouCantRefuse";
|
|||||||
export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@ import i18next from "#app/plugins/i18n";
|
|||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
import { PERMANENT_STATS, Stat } from "#enums/stat";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
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 */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:berriesAbound";
|
const namespace = "mysteryEncounter:berriesAbound";
|
||||||
@ -42,7 +43,7 @@ const namespace = "mysteryEncounter:berriesAbound";
|
|||||||
export const BerriesAboundEncounter: MysteryEncounter =
|
export const BerriesAboundEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BERRIES_ABOUND)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.BERRIES_ABOUND)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
|
@ -49,6 +49,7 @@ import i18next from "i18next";
|
|||||||
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
import MoveInfoOverlay from "#app/ui/move-info-overlay";
|
||||||
import { allMoves } from "#app/data/move";
|
import { allMoves } from "#app/data/move";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
const namespace = "mysteryEncounter:bugTypeSuperfan";
|
||||||
@ -191,7 +192,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
new AttackTypeBoosterHeldItemTypeRequirement(Type.BUG, 1),
|
||||||
new TypeRequirement(Type.BUG, false, 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()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
@ -439,7 +440,7 @@ export const BugTypeSuperfanEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
function getTrainerConfigForWave(waveIndex: number) {
|
function getTrainerConfigForWave(waveIndex: number) {
|
||||||
// Bug type superfan trainer config
|
// Bug type superfan trainer config
|
||||||
const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].copy();
|
const config = trainerConfigs[TrainerType.BUG_TYPE_SUPERFAN].clone();
|
||||||
config.name = i18next.t("trainerNames:bug_type_superfan");
|
config.name = i18next.t("trainerNames:bug_type_superfan");
|
||||||
|
|
||||||
const pool3Copy = POOL_3_POKEMON.slice(0);
|
const pool3Copy = POOL_3_POKEMON.slice(0);
|
||||||
|
@ -26,10 +26,11 @@ import { BerryModifier } from "#app/modifier/modifier";
|
|||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { Moves } from "#enums/moves";
|
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 { MoveCategory } from "#app/data/move";
|
||||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
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 */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:clowningAround";
|
const namespace = "mysteryEncounter:clowningAround";
|
||||||
@ -61,7 +62,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.CLOWNING_AROUND)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
.withDisabledGameModes(GameModes.CHALLENGE)
|
.withDisabledGameModes(GameModes.CHALLENGE)
|
||||||
.withSceneWaveRangeRequirement(80, 180)
|
.withSceneWaveRangeRequirement(80, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withAnimations(EncounterAnim.SMOKESCREEN)
|
.withAnimations(EncounterAnim.SMOKESCREEN)
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
@ -107,7 +108,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter!;
|
const encounter = scene.currentBattle.mysteryEncounter!;
|
||||||
|
|
||||||
const clownTrainerType = TrainerType.HARLEQUIN;
|
const clownTrainerType = TrainerType.HARLEQUIN;
|
||||||
const clownConfig = trainerConfigs[clownTrainerType].copy();
|
const clownConfig = trainerConfigs[clownTrainerType].clone();
|
||||||
const clownPartyTemplate = new TrainerPartyCompoundTemplate(
|
const clownPartyTemplate = new TrainerPartyCompoundTemplate(
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONG),
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER));
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER));
|
||||||
|
@ -12,7 +12,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { Biome } from "#enums/biome";
|
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 { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { getEncounterText, queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter-requirements";
|
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 { LearnMovePhase } from "#app/phases/learn-move-phase";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { Stat } from "#enums/stat";
|
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 */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:dancingLessons";
|
const namespace = "mysteryEncounter:dancingLessons";
|
||||||
@ -81,7 +83,7 @@ const SENSU_STYLE_BIOMES = [
|
|||||||
export const DancingLessonsEncounter: MysteryEncounter =
|
export const DancingLessonsEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DANCING_LESSONS)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DANCING_LESSONS)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
.withIntroSpriteConfigs([]) // Uses a real Pokemon sprite instead of ME Intro Visuals
|
||||||
.withAnimations(EncounterAnim.DANCE)
|
.withAnimations(EncounterAnim.DANCE)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
|
@ -13,6 +13,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:darkDeal";
|
const namespace = "mysteryEncounter:darkDeal";
|
||||||
@ -100,7 +101,7 @@ export const DarkDealEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}.intro_dialogue`,
|
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
|
.withScenePartySizeRequirement(2, 6) // Must have at least 2 pokemon in party
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withTitle(`${namespace}.title`)
|
.withTitle(`${namespace}.title`)
|
||||||
|
@ -16,6 +16,7 @@ import { applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/u
|
|||||||
import i18next from "#app/plugins/i18n";
|
import i18next from "#app/plugins/i18n";
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
import { getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:delibirdy";
|
const namespace = "mysteryEncounter:delibirdy";
|
||||||
@ -40,7 +41,7 @@ const OPTION_3_DISALLOWED_MODIFIERS = [
|
|||||||
export const DelibirdyEncounter: MysteryEncounter =
|
export const DelibirdyEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.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
|
.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
|
.withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn
|
||||||
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS),
|
||||||
|
@ -11,6 +11,7 @@ import MysteryEncounter, {
|
|||||||
MysteryEncounterBuilder,
|
MysteryEncounterBuilder,
|
||||||
} from "../mystery-encounter";
|
} from "../mystery-encounter";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:departmentStoreSale";
|
const namespace = "mysteryEncounter:departmentStoreSale";
|
||||||
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:departmentStoreSale";
|
|||||||
export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DEPARTMENT_STORE_SALE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DEPARTMENT_STORE_SALE)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 100)
|
.withSceneWaveRangeRequirement(CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[0], 100)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "b2w2_lady",
|
spriteKey: "b2w2_lady",
|
||||||
|
@ -11,6 +11,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for the encounter */
|
/** i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fieldTrip";
|
const namespace = "mysteryEncounter:fieldTrip";
|
||||||
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:fieldTrip";
|
|||||||
export const FieldTripEncounter: MysteryEncounter =
|
export const FieldTripEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIELD_TRIP)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIELD_TRIP)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "preschooler_m",
|
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.DEF])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
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.SPDEF])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
generateModifierTypeOption(scene, modifierTypes.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
generateModifierTypeOption(scene, modifierTypes.DIRE_HIT)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
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.TEMP_STAT_STAGE_BOOSTER, [Stat.SPD])!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
generateModifierTypeOption(scene, modifierTypes.GREAT_BALL)!,
|
||||||
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
generateModifierTypeOption(scene, modifierTypes.IV_SCANNER)!,
|
||||||
|
generateModifierTypeOption(scene, modifierTypes.RARER_CANDY)!,
|
||||||
];
|
];
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: modifiers, fillRemaining: false });
|
||||||
|
@ -12,7 +12,7 @@ import { Type } from "#app/data/type";
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import { Moves } from "#enums/moves";
|
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 { WeatherType } from "#app/data/weather";
|
||||||
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
import { isNullOrUndefined, randSeedInt } from "#app/utils";
|
||||||
import { StatusEffect } from "#app/data/status-effect";
|
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 { applyDamageToPokemon, applyModifierTypeToPlayerPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
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 */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fieryFallout";
|
const namespace = "mysteryEncounter:fieryFallout";
|
||||||
@ -39,7 +41,7 @@ const DAMAGE_PERCENTAGE: number = 20;
|
|||||||
export const FieryFalloutEncounter: MysteryEncounter =
|
export const FieryFalloutEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIERY_FALLOUT)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIERY_FALLOUT)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(40, 180)
|
.withSceneWaveRangeRequirement(40, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
.withAnimations(EncounterAnim.MAGMA_BG, EncounterAnim.MAGMA_SPOUT)
|
.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 { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { randSeedInt } from "#app/utils";
|
import { randSeedInt } from "#app/utils";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
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 */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:fightOrFlight";
|
const namespace = "mysteryEncounter:fightOrFlight";
|
||||||
@ -40,7 +41,7 @@ const namespace = "mysteryEncounter:fightOrFlight";
|
|||||||
export const FightOrFlightEncounter: MysteryEncounter =
|
export const FightOrFlightEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FIGHT_OR_FLIGHT)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.withIntroSpriteConfigs([]) // Set in onInit()
|
||||||
|
@ -21,6 +21,7 @@ import { SpeciesFormChangeActiveTrigger } from "#app/data/pokemon-forms";
|
|||||||
import { PostSummonPhase } from "#app/phases/post-summon-phase";
|
import { PostSummonPhase } from "#app/phases/post-summon-phase";
|
||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:funAndGames";
|
const namespace = "mysteryEncounter:funAndGames";
|
||||||
@ -33,7 +34,7 @@ const namespace = "mysteryEncounter:funAndGames";
|
|||||||
export const FunAndGamesEncounter: MysteryEncounter =
|
export const FunAndGamesEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FUN_AND_GAMES)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.FUN_AND_GAMES)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.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
|
.withSceneRequirement(new MoneyRequirement(0, 1.5)) // Cost equal to 1 Max Potion to play
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
// Allows using move without a visible enemy pokemon
|
// 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 { getPokeballAtlasKey, getPokeballTintColor, PokeballType } from "#app/data/pokeball";
|
||||||
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { getEncounterText, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { trainerNamePools } from "#app/data/trainer-names";
|
import { trainerNamePools } from "#app/data/trainer-names";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:globalTradeSystem";
|
const namespace = "mysteryEncounter:globalTradeSystem";
|
||||||
@ -70,7 +71,7 @@ const EXCLUDED_TRADE_SPECIES = [
|
|||||||
export const GlobalTradeSystemEncounter: MysteryEncounter =
|
export const GlobalTradeSystemEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.GLOBAL_TRADE_SYSTEM)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.GLOBAL_TRADE_SYSTEM)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ import { leaveEncounterWithoutBattle, setEncounterExp } from "../utils/encounter
|
|||||||
import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { applyDamageToPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
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_1_REQUIRED_MOVE = Moves.SURF;
|
||||||
const OPTION_2_REQUIRED_MOVE = Moves.FLY;
|
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)
|
export const LostAtSeaEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.LOST_AT_SEA)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(11, 179)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "buoy",
|
spriteKey: "buoy",
|
||||||
|
@ -17,6 +17,7 @@ import BattleScene from "#app/battle-scene";
|
|||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:mysteriousChallengers";
|
const namespace = "mysteryEncounter:mysteriousChallengers";
|
||||||
@ -29,7 +30,7 @@ const namespace = "mysteryEncounter:mysteriousChallengers";
|
|||||||
export const MysteriousChallengersEncounter: MysteryEncounter =
|
export const MysteriousChallengersEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHALLENGERS)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHALLENGERS)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([]) // These are set in onInit()
|
.withIntroSpriteConfigs([]) // These are set in onInit()
|
||||||
.withIntroDialogue([
|
.withIntroDialogue([
|
||||||
{
|
{
|
||||||
@ -42,7 +43,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Normal difficulty trainer is randomly pulled from biome
|
// Normal difficulty trainer is randomly pulled from biome
|
||||||
const normalTrainerType = scene.arena.randomTrainerType(scene.currentBattle.waveIndex);
|
const normalTrainerType = scene.arena.randomTrainerType(scene.currentBattle.waveIndex);
|
||||||
const normalConfig = trainerConfigs[normalTrainerType].copy();
|
const normalConfig = trainerConfigs[normalTrainerType].clone();
|
||||||
let female = false;
|
let female = false;
|
||||||
if (normalConfig.hasGenders) {
|
if (normalConfig.hasGenders) {
|
||||||
female = !!Utils.randSeedInt(2);
|
female = !!Utils.randSeedInt(2);
|
||||||
@ -65,7 +66,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const hardConfig = trainerConfigs[hardTrainerType].copy();
|
const hardConfig = trainerConfigs[hardTrainerType].clone();
|
||||||
hardConfig.setPartyTemplates(hardTemplate);
|
hardConfig.setPartyTemplates(hardTemplate);
|
||||||
female = false;
|
female = false;
|
||||||
if (hardConfig.hasGenders) {
|
if (hardConfig.hasGenders) {
|
||||||
@ -85,7 +86,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
const e4Template = trainerPartyTemplates.ELITE_FOUR;
|
const e4Template = trainerPartyTemplates.ELITE_FOUR;
|
||||||
const brutalConfig = trainerConfigs[brutalTrainerType].copy();
|
const brutalConfig = trainerConfigs[brutalTrainerType].clone();
|
||||||
brutalConfig.setPartyTemplates(e4Template);
|
brutalConfig.setPartyTemplates(e4Template);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func
|
brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func
|
||||||
|
@ -13,6 +13,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { GameOverPhase } from "#app/phases/game-over-phase";
|
import { GameOverPhase } from "#app/phases/game-over-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for encounter */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:mysteriousChest";
|
const namespace = "mysteryEncounter:mysteriousChest";
|
||||||
@ -31,7 +32,7 @@ const MASTER_REWARDS_WEIGHT = 65; // 5%
|
|||||||
export const MysteriousChestEncounter: MysteryEncounter =
|
export const MysteriousChestEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHEST)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.MYSTERIOUS_CHEST)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withIntroSpriteConfigs([
|
.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 { getEncounterText, showEncounterDialogue, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:partTimer";
|
const namespace = "mysteryEncounter:partTimer";
|
||||||
@ -23,7 +24,7 @@ const namespace = "mysteryEncounter:partTimer";
|
|||||||
export const PartTimerEncounter: MysteryEncounter =
|
export const PartTimerEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.PART_TIMER)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.PART_TIMER)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "warehouse_crate",
|
spriteKey: "warehouse_crate",
|
||||||
|
@ -18,6 +18,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { ScanIvsPhase } from "#app/phases/scan-ivs-phase";
|
import { ScanIvsPhase } from "#app/phases/scan-ivs-phase";
|
||||||
import { SummonPhase } from "#app/phases/summon-phase";
|
import { SummonPhase } from "#app/phases/summon-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:safariZone";
|
const namespace = "mysteryEncounter:safariZone";
|
||||||
@ -34,7 +35,7 @@ const SAFARI_MONEY_MULTIPLIER = 2.75;
|
|||||||
export const SafariZoneEncounter: MysteryEncounter =
|
export const SafariZoneEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SAFARI_ZONE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SAFARI_ZONE)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.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
|
.withSceneRequirement(new MoneyRequirement(0, SAFARI_MONEY_MULTIPLIER)) // Cost equal to 1 Max Revive
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -14,6 +14,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { Nature } from "#enums/nature";
|
import { Nature } from "#enums/nature";
|
||||||
import { getNatureName } from "#app/data/nature";
|
import { getNatureName } from "#app/data/nature";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:shadyVitaminDealer";
|
const namespace = "mysteryEncounter:shadyVitaminDealer";
|
||||||
@ -26,7 +27,7 @@ const namespace = "mysteryEncounter:shadyVitaminDealer";
|
|||||||
export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.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
|
.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
|
.withPrimaryPokemonHealthRatioRequirement([0.5, 1]) // At least 1 Pokemon must have above half HP
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -16,6 +16,7 @@ import { getPokemonSpecies } from "#app/data/pokemon-species";
|
|||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
import { PartyHealPhase } from "#app/phases/party-heal-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** i18n namespace for the encounter */
|
/** i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:slumberingSnorlax";
|
const namespace = "mysteryEncounter:slumberingSnorlax";
|
||||||
@ -28,7 +29,7 @@ const namespace = "mysteryEncounter:slumberingSnorlax";
|
|||||||
export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SLUMBERING_SNORLAX)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SLUMBERING_SNORLAX)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.withEncounterTier(MysteryEncounterTier.GREAT)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -19,6 +19,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
|||||||
import { getPokemonNameWithAffix } from "#app/messages";
|
import { getPokemonNameWithAffix } from "#app/messages";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:teleportingHijinks";
|
const namespace = "mysteryEncounter:teleportingHijinks";
|
||||||
@ -35,7 +36,7 @@ const MACHINE_INTERFACING_TYPES = [Type.ELECTRIC, Type.STEEL];
|
|||||||
export const TeleportingHijinksEncounter: MysteryEncounter =
|
export const TeleportingHijinksEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.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 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
|
.withSceneRequirement(new MoneyRequirement(undefined, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
|
@ -14,6 +14,7 @@ import { showEncounterDialogue } from "#app/data/mystery-encounters/utils/encoun
|
|||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:pokemonSalesman";
|
const namespace = "mysteryEncounter:pokemonSalesman";
|
||||||
@ -28,7 +29,7 @@ const MAX_POKEMON_PRICE_MULTIPLIER = 6;
|
|||||||
export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_POKEMON_SALESMAN)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_POKEMON_SALESMAN)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.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
|
.withSceneRequirement(new MoneyRequirement(undefined, MAX_POKEMON_PRICE_MULTIPLIER)) // Some costs may not be as significant, this is the max you'd pay
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -17,6 +17,7 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
import { MysteryEncounterPokemonData } from "#app/data/mystery-encounters/mystery-encounter-pokemon-data";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
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 */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:theStrongStuff";
|
const namespace = "mysteryEncounter:theStrongStuff";
|
||||||
@ -33,7 +34,7 @@ const BST_INCREASE_VALUE = 10;
|
|||||||
export const TheStrongStuffEncounter: MysteryEncounter =
|
export const TheStrongStuffEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_STRONG_STUFF)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_STRONG_STUFF)
|
||||||
.withEncounterTier(MysteryEncounterTier.GREAT)
|
.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
|
.withScenePartySizeRequirement(3, 6) // Must have at least 3 pokemon in party
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
|
@ -22,6 +22,7 @@ import { ShowTrainerPhase } from "#app/phases/show-trainer-phase";
|
|||||||
import { ReturnPhase } from "#app/phases/return-phase";
|
import { ReturnPhase } from "#app/phases/return-phase";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:theWinstrateChallenge";
|
const namespace = "mysteryEncounter:theWinstrateChallenge";
|
||||||
@ -34,7 +35,7 @@ const namespace = "mysteryEncounter:theWinstrateChallenge";
|
|||||||
export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
export const TheWinstrateChallengeEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_WINSTRATE_CHALLENGE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.THE_WINSTRATE_CHALLENGE)
|
||||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
.withSceneWaveRangeRequirement(100, 180)
|
.withSceneWaveRangeRequirement(100, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "vito",
|
spriteKey: "vito",
|
||||||
|
@ -19,6 +19,7 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
|
|||||||
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { getStatKey } from "#enums/stat";
|
import { getStatKey } from "#enums/stat";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** The i18n namespace for the encounter */
|
/** The i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:trainingSession";
|
const namespace = "mysteryEncounter:trainingSession";
|
||||||
@ -31,7 +32,7 @@ const namespace = "mysteryEncounter:trainingSession";
|
|||||||
export const TrainingSessionEncounter: MysteryEncounter =
|
export const TrainingSessionEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRAINING_SESSION)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRAINING_SESSION)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.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
|
.withScenePartySizeRequirement(2, 6, true) // Must have at least 2 unfainted pokemon in party
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
|
@ -17,6 +17,7 @@ import { Moves } from "#enums/moves";
|
|||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
import { ModifierRewardPhase } from "#app/phases/modifier-reward-phase";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:trashToTreasure";
|
const namespace = "mysteryEncounter:trashToTreasure";
|
||||||
@ -31,7 +32,7 @@ const SOUND_EFFECT_WAIT_TIME = 700;
|
|||||||
export const TrashToTreasureEncounter: MysteryEncounter =
|
export const TrashToTreasureEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRASH_TO_TREASURE)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TRASH_TO_TREASURE)
|
||||||
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
.withEncounterTier(MysteryEncounterTier.ULTRA)
|
||||||
.withSceneWaveRangeRequirement(60, 180)
|
.withSceneWaveRangeRequirement(60, CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES[1])
|
||||||
.withMaxAllowedEncounters(1)
|
.withMaxAllowedEncounters(1)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,7 @@ import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encoun
|
|||||||
import { BerryModifier } from "#app/modifier/modifier";
|
import { BerryModifier } from "#app/modifier/modifier";
|
||||||
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
|
||||||
import { Stat } from "#enums/stat";
|
import { Stat } from "#enums/stat";
|
||||||
|
import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode";
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:uncommonBreed";
|
const namespace = "mysteryEncounter:uncommonBreed";
|
||||||
@ -35,7 +36,7 @@ const namespace = "mysteryEncounter:uncommonBreed";
|
|||||||
export const UncommonBreedEncounter: MysteryEncounter =
|
export const UncommonBreedEncounter: MysteryEncounter =
|
||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.UNCOMMON_BREED)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.UNCOMMON_BREED)
|
||||||
.withEncounterTier(MysteryEncounterTier.COMMON)
|
.withEncounterTier(MysteryEncounterTier.COMMON)
|
||||||
.withSceneWaveRangeRequirement(10, 180) // waves 10 to 180
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withHideWildIntroMessage(true)
|
.withHideWildIntroMessage(true)
|
||||||
.withIntroSpriteConfigs([]) // Set in onInit()
|
.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 { doPokemonTransformationSequence, TransformationScreenPosition } from "#app/data/mystery-encounters/utils/encounter-transformation-sequence";
|
||||||
import { getLevelTotalExp } from "#app/data/exp";
|
import { getLevelTotalExp } from "#app/data/exp";
|
||||||
import { Stat } from "#enums/stat";
|
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 */
|
/** i18n namespace for encounter */
|
||||||
const namespace = "mysteryEncounter:weirdDream";
|
const namespace = "mysteryEncounter:weirdDream";
|
||||||
@ -82,10 +82,16 @@ const SUPER_LEGENDARY_BST_THRESHOLD = 600;
|
|||||||
const NON_LEGENDARY_BST_THRESHOLD = 570;
|
const NON_LEGENDARY_BST_THRESHOLD = 570;
|
||||||
const GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD = 450;
|
const GAIN_OLD_GATEAU_ITEM_BST_THRESHOLD = 450;
|
||||||
|
|
||||||
/** Value ranges of the resulting species BST transformations after adding values to original species */
|
/**
|
||||||
|
* Value ranges of the resulting species BST transformations after adding values to original species
|
||||||
const HIGH_BST_TRANSFORM_BASE_VALUES = [90, 110];
|
* 2 Pokemon in the party use this range
|
||||||
const STANDARD_BST_TRANSFORM_BASE_VALUES = [40, 50];
|
*/
|
||||||
|
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.
|
* Weird Dream encounter.
|
||||||
@ -96,7 +102,7 @@ export const WeirdDreamEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM)
|
MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.WEIRD_DREAM)
|
||||||
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
.withEncounterTier(MysteryEncounterTier.ROGUE)
|
||||||
.withDisabledGameModes(GameModes.CHALLENGE)
|
.withDisabledGameModes(GameModes.CHALLENGE)
|
||||||
.withSceneWaveRangeRequirement(10, 180)
|
.withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES)
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: "weird_dream_woman",
|
spriteKey: "weird_dream_woman",
|
||||||
@ -252,7 +258,7 @@ function getTeamTransformations(scene: BattleScene): PokemonTransformation[] {
|
|||||||
scene.removePokemonFromPlayerParty(removed, false);
|
scene.removePokemonFromPlayerParty(removed, false);
|
||||||
|
|
||||||
const bst = removed.calculateBaseStats().reduce((a, b) => a + b, 0);
|
const bst = removed.calculateBaseStats().reduce((a, b) => a + b, 0);
|
||||||
let newBstRange;
|
let newBstRange: [number, number];
|
||||||
if (i < 2) {
|
if (i < 2) {
|
||||||
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
newBstRange = HIGH_BST_TRANSFORM_BASE_VALUES;
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,7 +20,8 @@ export class EncounterOptionsDialogue {
|
|||||||
title?: string;
|
title?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
query?: string;
|
query?: string;
|
||||||
options?: [...OptionTextDisplay[]]; // Options array with minimum 2 options
|
/** Options array with minimum 2 options */
|
||||||
|
options?: [...OptionTextDisplay[]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +44,7 @@ export default class MysteryEncounterOption implements IMysteryEncounterOption {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialogue object containing all the dialogue, messages, tooltips, etc. for this option
|
* Dialogue object containing all the dialogue, messages, tooltips, etc. for this option
|
||||||
* Will be populated on MysteryEncounter initialization
|
* Will be populated on {@linkcode MysteryEncounter} initialization
|
||||||
*/
|
*/
|
||||||
dialogue?: OptionTextDisplay;
|
dialogue?: OptionTextDisplay;
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ import { Abilities } from "#enums/abilities";
|
|||||||
import { Type } from "#app/data/type";
|
import { Type } from "#app/data/type";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
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 {
|
export class MysteryEncounterPokemonData {
|
||||||
public spriteScale: number;
|
public spriteScale: number;
|
||||||
public ability: Abilities | -1;
|
public ability: Abilities | -1;
|
||||||
|
@ -53,7 +53,7 @@ export class CombinationSceneRequirement extends EncounterSceneRequirement {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
for (const req of this.orRequirements) {
|
for (const req of this.orRequirements) {
|
||||||
if (req.meetsRequirement(scene)) {
|
if (req.meetsRequirement(scene)) {
|
||||||
return req.getDialogueToken(scene, pokemon);
|
return req.getDialogueToken(scene, pokemon);
|
||||||
@ -99,7 +99,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||||||
this.orRequirements = orRequirements;
|
this.orRequirements = orRequirements;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
for (const req of this.orRequirements) {
|
for (const req of this.orRequirements) {
|
||||||
if (req.meetsRequirement(scene)) {
|
if (req.meetsRequirement(scene)) {
|
||||||
return true;
|
return true;
|
||||||
@ -108,7 +108,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
for (const req of this.orRequirements) {
|
for (const req of this.orRequirements) {
|
||||||
const result = req.queryParty(partyPokemon);
|
const result = req.queryParty(partyPokemon);
|
||||||
if (result?.length > 0) {
|
if (result?.length > 0) {
|
||||||
@ -119,7 +119,7 @@ export class CombinationPokemonRequirement extends EncounterPokemonRequirement {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
for (const req of this.orRequirements) {
|
for (const req of this.orRequirements) {
|
||||||
if (req.meetsRequirement(scene)) {
|
if (req.meetsRequirement(scene)) {
|
||||||
return req.getDialogueToken(scene, pokemon);
|
return req.getDialogueToken(scene, pokemon);
|
||||||
@ -142,11 +142,11 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
|
|||||||
this.previousEncounterRequirement = previousEncounterRequirement;
|
this.previousEncounterRequirement = previousEncounterRequirement;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
return scene.mysteryEncounterSaveData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
|
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() ?? ""];
|
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;
|
this.waveRange = waveRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
if (!isNullOrUndefined(this.waveRange) && this.waveRange?.[0] <= this.waveRange?.[1]) {
|
if (!isNullOrUndefined(this.waveRange) && this.waveRange?.[0] <= this.waveRange?.[1]) {
|
||||||
const waveIndex = scene.currentBattle.waveIndex;
|
const waveIndex = scene.currentBattle.waveIndex;
|
||||||
if (waveIndex >= 0 && (this.waveRange?.[0] >= 0 && this.waveRange?.[0] > waveIndex) || (this.waveRange?.[1] >= 0 && this.waveRange?.[1] < 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,11 +199,11 @@ export class WaveModulusRequirement extends EncounterSceneRequirement {
|
|||||||
this.modulusValue = modulusValue;
|
this.modulusValue = modulusValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
return this.waveModuli.includes(scene.currentBattle.waveIndex % this.modulusValue);
|
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()];
|
return ["waveIndex", scene.currentBattle.waveIndex.toString()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||||||
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay];
|
this.requiredTimeOfDay = Array.isArray(timeOfDay) ? timeOfDay : [timeOfDay];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const timeOfDay = scene.arena?.getTimeOfDay();
|
const timeOfDay = scene.arena?.getTimeOfDay();
|
||||||
if (!isNullOrUndefined(timeOfDay) && this.requiredTimeOfDay?.length > 0 && !this.requiredTimeOfDay.includes(timeOfDay)) {
|
if (!isNullOrUndefined(timeOfDay) && this.requiredTimeOfDay?.length > 0 && !this.requiredTimeOfDay.includes(timeOfDay)) {
|
||||||
return false;
|
return false;
|
||||||
@ -225,7 +225,7 @@ export class TimeOfDayRequirement extends EncounterSceneRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()];
|
return ["timeOfDay", TimeOfDay[scene.arena.getTimeOfDay()].toLocaleLowerCase()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||||||
this.requiredWeather = Array.isArray(weather) ? weather : [weather];
|
this.requiredWeather = Array.isArray(weather) ? weather : [weather];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const currentWeather = scene.arena.weather?.weatherType;
|
const currentWeather = scene.arena.weather?.weatherType;
|
||||||
if (!isNullOrUndefined(currentWeather) && this.requiredWeather?.length > 0 && !this.requiredWeather.includes(currentWeather!)) {
|
if (!isNullOrUndefined(currentWeather) && this.requiredWeather?.length > 0 && !this.requiredWeather.includes(currentWeather!)) {
|
||||||
return false;
|
return false;
|
||||||
@ -247,7 +247,7 @@ export class WeatherRequirement extends EncounterSceneRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const currentWeather = scene.arena.weather?.weatherType;
|
const currentWeather = scene.arena.weather?.weatherType;
|
||||||
let token = "";
|
let token = "";
|
||||||
if (!isNullOrUndefined(currentWeather)) {
|
if (!isNullOrUndefined(currentWeather)) {
|
||||||
@ -273,7 +273,7 @@ export class PartySizeRequirement extends EncounterSceneRequirement {
|
|||||||
this.excludeFainted = excludeFainted;
|
this.excludeFainted = excludeFainted;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
if (!isNullOrUndefined(this.partySizeRange) && this.partySizeRange?.[0] <= this.partySizeRange?.[1]) {
|
if (!isNullOrUndefined(this.partySizeRange) && this.partySizeRange?.[0] <= this.partySizeRange?.[1]) {
|
||||||
const partySize = this.excludeFainted ? scene.getParty().filter(p => p.isAllowedInBattle()).length : scene.getParty().length;
|
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)) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["partySize", scene.getParty().length.toString()];
|
return ["partySize", scene.getParty().length.toString()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||||||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredHeldItemModifiers?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -317,7 +317,7 @@ export class PersistentModifierRequirement extends EncounterSceneRequirement {
|
|||||||
return modifierCount >= this.minNumberOfItems;
|
return modifierCount >= this.minNumberOfItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["requiredItem", this.requiredHeldItemModifiers[0]];
|
return ["requiredItem", this.requiredHeldItemModifiers[0]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||||||
this.scalingMultiplier = scalingMultiplier ?? 0;
|
this.scalingMultiplier = scalingMultiplier ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const money = scene.money;
|
const money = scene.money;
|
||||||
if (isNullOrUndefined(money)) {
|
if (isNullOrUndefined(money)) {
|
||||||
return false;
|
return false;
|
||||||
@ -344,7 +344,7 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||||||
return !(this.requiredMoney > 0 && this.requiredMoney > money);
|
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();
|
const value = this.scalingMultiplier > 0 ? scene.getWaveMoneyAmount(this.scalingMultiplier).toString() : this.requiredMoney.toString();
|
||||||
return ["money", value];
|
return ["money", value];
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredSpecies = Array.isArray(species) ? species : [species];
|
this.requiredSpecies = Array.isArray(species) ? species : [species];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredSpecies?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredSpecies?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -370,7 +370,7 @@ export class SpeciesRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredSpecies.filter((species) => pokemon.species.speciesId === species).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredSpecies.filter((species) => pokemon.species.speciesId === species).length > 0);
|
||||||
} else {
|
} 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)) {
|
if (pokemon?.species.speciesId && this.requiredSpecies.includes(pokemon.species.speciesId)) {
|
||||||
return ["species", Species[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];
|
this.requiredNature = Array.isArray(nature) ? nature : [nature];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredNature?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredNature?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -408,7 +408,7 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredNature.filter((nature) => pokemon.nature === nature).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredNature.filter((nature) => pokemon.nature === nature).length > 0);
|
||||||
} else {
|
} 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)) {
|
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon!.nature)) {
|
||||||
return ["nature", Nature[pokemon!.nature]];
|
return ["nature", Nature[pokemon!.nature]];
|
||||||
}
|
}
|
||||||
@ -439,7 +439,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredType = Array.isArray(type) ? type : [type];
|
this.requiredType = Array.isArray(type) ? type : [type];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
let partyPokemon = scene.getParty();
|
let partyPokemon = scene.getParty();
|
||||||
|
|
||||||
if (isNullOrUndefined(partyPokemon)) {
|
if (isNullOrUndefined(partyPokemon)) {
|
||||||
@ -453,7 +453,7 @@ export class TypeRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredType.filter((type) => pokemon.getTypes().includes(type)).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredType.filter((type) => pokemon.getTypes().includes(type)).length > 0);
|
||||||
} else {
|
} 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));
|
const includedTypes = this.requiredType.filter((ty) => pokemon?.getTypes().includes(ty));
|
||||||
if (includedTypes.length > 0) {
|
if (includedTypes.length > 0) {
|
||||||
return ["type", Type[includedTypes[0]]];
|
return ["type", Type[includedTypes[0]]];
|
||||||
@ -484,7 +484,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredMoves = Array.isArray(moves) ? moves : [moves];
|
this.requiredMoves = Array.isArray(moves) ? moves : [moves];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -492,7 +492,7 @@ export class MoveRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move?.moveId === reqMove).length > 0).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((reqMove) => pokemon.moveset.filter((move) => move?.moveId === reqMove).length > 0).length > 0);
|
||||||
} else {
|
} 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));
|
const includedMoves = pokemon?.moveset.filter((move) => move?.moveId && this.requiredMoves.includes(move.moveId));
|
||||||
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
|
if (includedMoves && includedMoves.length > 0 && includedMoves[0]) {
|
||||||
return ["move", includedMoves[0].getName()];
|
return ["move", includedMoves[0].getName()];
|
||||||
@ -528,7 +528,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove];
|
this.requiredMoves = Array.isArray(learnableMove) ? learnableMove : [learnableMove];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredMoves?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -536,7 +536,7 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
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);
|
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove)).length > 0);
|
||||||
} else {
|
} 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));
|
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
|
||||||
if (includedCompatMoves.length > 0) {
|
if (includedCompatMoves.length > 0) {
|
||||||
return ["compatibleMove", Moves[includedCompatMoves[0]]];
|
return ["compatibleMove", Moves[includedCompatMoves[0]]];
|
||||||
@ -555,46 +555,6 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
export class EvolutionTargetSpeciesRequirement extends EncounterPokemonRequirement {
|
|
||||||
requiredEvolutionTargetSpecies: Species[];
|
|
||||||
minNumberOfPokemon:number;
|
|
||||||
invertQuery:boolean;
|
|
||||||
|
|
||||||
constructor(evolutionTargetSpecies: Species | Species[], minNumberOfPokemon: number = 1, invertQuery: boolean = false) {
|
|
||||||
super();
|
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
|
||||||
this.invertQuery = invertQuery;
|
|
||||||
this.requiredEvolutionTargetSpecies = Array.isArray(evolutionTargetSpecies) ? evolutionTargetSpecies : [evolutionTargetSpecies];
|
|
||||||
}
|
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
|
||||||
const partyPokemon = scene.getParty();
|
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionTargetSpecies?.length < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
|
||||||
}
|
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
|
||||||
if (!this.invertQuery) {
|
|
||||||
return partyPokemon.filter((pokemon) => this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution()?.speciesId === evolutionTargetSpecies).length > 0);
|
|
||||||
} else {
|
|
||||||
// for an inverted query, we only want to get the pokemon that don't have ANY of the listed evolutionTargetSpeciess
|
|
||||||
return partyPokemon.filter((pokemon) => this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution()?.speciesId === evolutionTargetSpecies).length === 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getMatchingDialogueToken(str:string, pokemon: PlayerPokemon): [RegExp, string] {
|
|
||||||
const evos = this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution().speciesId === evolutionTargetSpecies);
|
|
||||||
if (evos.length > 0) {
|
|
||||||
return ["evolution", Species[evos[0]]];
|
|
||||||
}
|
|
||||||
return ["evolution", ""];
|
|
||||||
}
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
export class AbilityRequirement extends EncounterPokemonRequirement {
|
export class AbilityRequirement extends EncounterPokemonRequirement {
|
||||||
requiredAbilities: Abilities[];
|
requiredAbilities: Abilities[];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
@ -607,7 +567,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities];
|
this.requiredAbilities = Array.isArray(abilities) ? abilities : [abilities];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredAbilities?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredAbilities?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -615,7 +575,7 @@ export class AbilityRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredAbilities.some((ability) => pokemon.getAbility().id === ability));
|
return partyPokemon.filter((pokemon) => this.requiredAbilities.some((ability) => pokemon.getAbility().id === ability));
|
||||||
} else {
|
} else {
|
||||||
@ -624,7 +584,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)) {
|
if (pokemon?.getAbility().id && this.requiredAbilities.some(a => pokemon.getAbility().id === a)) {
|
||||||
return ["ability", pokemon.getAbility().name];
|
return ["ability", pokemon.getAbility().name];
|
||||||
}
|
}
|
||||||
@ -644,7 +604,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect];
|
this.requiredStatusEffect = Array.isArray(statusEffect) ? statusEffect : [statusEffect];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredStatusEffect?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredStatusEffect?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -654,7 +614,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => {
|
return partyPokemon.filter((pokemon) => {
|
||||||
return this.requiredStatusEffect.some((statusEffect) => {
|
return this.requiredStatusEffect.some((statusEffect) => {
|
||||||
@ -682,7 +642,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) => {
|
const reqStatus = this.requiredStatusEffect.filter((a) => {
|
||||||
if (a === StatusEffect.NONE) {
|
if (a === StatusEffect.NONE) {
|
||||||
return isNullOrUndefined(pokemon?.status) || isNullOrUndefined(pokemon!.status!.effect) || pokemon!.status!.effect === a;
|
return isNullOrUndefined(pokemon?.status) || isNullOrUndefined(pokemon!.status!.effect) || pokemon!.status!.effect === a;
|
||||||
@ -714,7 +674,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||||||
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem];
|
this.requiredFormChangeItem = Array.isArray(formChangeItem) ? formChangeItem : [formChangeItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredFormChangeItem?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredFormChangeItem?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -735,7 +695,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem)).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem)).length > 0);
|
||||||
} else {
|
} else {
|
||||||
@ -744,7 +704,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));
|
const requiredItems = this.requiredFormChangeItem.filter((formChangeItem) => this.filterByForm(pokemon, formChangeItem));
|
||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
||||||
@ -766,7 +726,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems];
|
this.requiredEvolutionItem = Array.isArray(evolutionItems) ? evolutionItems : [evolutionItems];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionItem?.length < 0) {
|
if (isNullOrUndefined(partyPokemon) || this.requiredEvolutionItem?.length < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -785,7 +745,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredEvolutionItem.filter((evolutionItem) => this.filterByEvo(pokemon, evolutionItem)).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredEvolutionItem.filter((evolutionItem) => this.filterByEvo(pokemon, evolutionItem)).length > 0);
|
||||||
} else {
|
} else {
|
||||||
@ -794,7 +754,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));
|
const requiredItems = this.requiredEvolutionItem.filter((evoItem) => this.filterByEvo(pokemon, evoItem));
|
||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
||||||
@ -815,7 +775,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
this.requiredHeldItemModifiers = Array.isArray(heldItem) ? heldItem : [heldItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon)) {
|
if (isNullOrUndefined(partyPokemon)) {
|
||||||
return false;
|
return false;
|
||||||
@ -823,7 +783,7 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredHeldItemModifiers.some((heldItem) => {
|
return partyPokemon.filter((pokemon) => this.requiredHeldItemModifiers.some((heldItem) => {
|
||||||
return pokemon.getHeldItems().some((it) => {
|
return pokemon.getHeldItems().some((it) => {
|
||||||
@ -839,7 +799,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) => {
|
const requiredItems = pokemon?.getHeldItems().filter((it) => {
|
||||||
return this.requiredHeldItemModifiers.some(heldItem => it.constructor.name === heldItem);
|
return this.requiredHeldItemModifiers.some(heldItem => it.constructor.name === heldItem);
|
||||||
});
|
});
|
||||||
@ -862,7 +822,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||||||
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
|
this.requiredHeldItemTypes = Array.isArray(heldItemTypes) ? heldItemTypes : [heldItemTypes];
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
if (isNullOrUndefined(partyPokemon)) {
|
if (isNullOrUndefined(partyPokemon)) {
|
||||||
return false;
|
return false;
|
||||||
@ -870,7 +830,7 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
|||||||
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
return this.queryParty(partyPokemon).length >= this.minNumberOfPokemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredHeldItemTypes.some((heldItemType) => {
|
return partyPokemon.filter((pokemon) => this.requiredHeldItemTypes.some((heldItemType) => {
|
||||||
return pokemon.getHeldItems().some((it) => {
|
return pokemon.getHeldItems().some((it) => {
|
||||||
@ -886,7 +846,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) => {
|
const requiredItems = pokemon?.getHeldItems().filter((it) => {
|
||||||
return this.requiredHeldItemTypes.some(heldItemType => it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType);
|
return this.requiredHeldItemTypes.some(heldItemType => it instanceof AttackTypeBoosterModifier && (it.type as AttackTypeBoosterModifierType).moveType === heldItemType);
|
||||||
});
|
});
|
||||||
@ -909,7 +869,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredLevelRange = requiredLevelRange;
|
this.requiredLevelRange = requiredLevelRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required level range
|
// Party Pokemon inside required level range
|
||||||
if (!isNullOrUndefined(this.requiredLevelRange) && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) {
|
if (!isNullOrUndefined(this.requiredLevelRange) && this.requiredLevelRange[0] <= this.requiredLevelRange[1]) {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
@ -921,7 +881,7 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => pokemon.level >= this.requiredLevelRange[0] && pokemon.level <= this.requiredLevelRange[1]);
|
return partyPokemon.filter((pokemon) => pokemon.level >= this.requiredLevelRange[0] && pokemon.level <= this.requiredLevelRange[1]);
|
||||||
} else {
|
} else {
|
||||||
@ -930,7 +890,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() ?? ""];
|
return ["level", pokemon?.level.toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,7 +907,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredFriendshipRange = requiredFriendshipRange;
|
this.requiredFriendshipRange = requiredFriendshipRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required friendship range
|
// Party Pokemon inside required friendship range
|
||||||
if (!isNullOrUndefined(this.requiredFriendshipRange) && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1]) {
|
if (!isNullOrUndefined(this.requiredFriendshipRange) && this.requiredFriendshipRange[0] <= this.requiredFriendshipRange[1]) {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
@ -959,7 +919,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => pokemon.friendship >= this.requiredFriendshipRange[0] && pokemon.friendship <= this.requiredFriendshipRange[1]);
|
return partyPokemon.filter((pokemon) => pokemon.friendship >= this.requiredFriendshipRange[0] && pokemon.friendship <= this.requiredFriendshipRange[1]);
|
||||||
} else {
|
} else {
|
||||||
@ -968,7 +928,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() ?? ""];
|
return ["friendship", pokemon?.friendship.toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -990,8 +950,8 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredHealthRange = requiredHealthRange;
|
this.requiredHealthRange = requiredHealthRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required level range
|
// Party Pokemon's health inside required health range
|
||||||
if (!isNullOrUndefined(this.requiredHealthRange) && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) {
|
if (!isNullOrUndefined(this.requiredHealthRange) && this.requiredHealthRange[0] <= this.requiredHealthRange[1]) {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
const pokemonInRange = this.queryParty(partyPokemon);
|
const pokemonInRange = this.queryParty(partyPokemon);
|
||||||
@ -1002,7 +962,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => {
|
return partyPokemon.filter((pokemon) => {
|
||||||
return pokemon.getHpRatio() >= this.requiredHealthRange[0] && pokemon.getHpRatio() <= this.requiredHealthRange[1];
|
return pokemon.getHpRatio() >= this.requiredHealthRange[0] && pokemon.getHpRatio() <= this.requiredHealthRange[1];
|
||||||
@ -1013,7 +973,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())) {
|
if (!isNullOrUndefined(pokemon?.getHpRatio())) {
|
||||||
return ["healthRatio", Math.floor(pokemon!.getHpRatio() * 100).toString() + "%"];
|
return ["healthRatio", Math.floor(pokemon!.getHpRatio() * 100).toString() + "%"];
|
||||||
}
|
}
|
||||||
@ -1033,8 +993,8 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
this.requiredWeightRange = requiredWeightRange;
|
this.requiredWeightRange = requiredWeightRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required friendship range
|
// Party Pokemon's weight inside required weight range
|
||||||
if (!isNullOrUndefined(this.requiredWeightRange) && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) {
|
if (!isNullOrUndefined(this.requiredWeightRange) && this.requiredWeightRange[0] <= this.requiredWeightRange[1]) {
|
||||||
const partyPokemon = scene.getParty();
|
const partyPokemon = scene.getParty();
|
||||||
const pokemonInRange = this.queryParty(partyPokemon);
|
const pokemonInRange = this.queryParty(partyPokemon);
|
||||||
@ -1045,7 +1005,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => pokemon.getWeight() >= this.requiredWeightRange[0] && pokemon.getWeight() <= this.requiredWeightRange[1]);
|
return partyPokemon.filter((pokemon) => pokemon.getWeight() >= this.requiredWeightRange[0] && pokemon.getWeight() <= this.requiredWeightRange[1]);
|
||||||
} else {
|
} else {
|
||||||
@ -1054,7 +1014,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() ?? ""];
|
return ["weight", pokemon?.getWeight().toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@ import MysteryEncounterDialogue, { OptionTextDisplay } from "./mystery-encounter
|
|||||||
import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option";
|
import MysteryEncounterOption, { MysteryEncounterOptionBuilder, OptionPhaseCallback } from "./mystery-encounter-option";
|
||||||
import { EncounterPokemonRequirement, EncounterSceneRequirement, HealthRatioRequirement, PartySizeRequirement, StatusEffectRequirement, WaveRangeRequirement } from "./mystery-encounter-requirements";
|
import { EncounterPokemonRequirement, EncounterSceneRequirement, HealthRatioRequirement, PartySizeRequirement, StatusEffectRequirement, WaveRangeRequirement } from "./mystery-encounter-requirements";
|
||||||
import { BattlerIndex } from "#app/battle";
|
import { BattlerIndex } from "#app/battle";
|
||||||
import { EncounterAnim } from "#app/data/battle-anims";
|
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { GameModes } from "#app/game-mode";
|
import { GameModes } from "#app/game-mode";
|
||||||
|
import { EncounterAnim } from "#enums/encounter-anims";
|
||||||
|
|
||||||
export interface EncounterStartOfBattleEffect {
|
export interface EncounterStartOfBattleEffect {
|
||||||
sourcePokemon?: Pokemon;
|
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
|
* Unless you know what you're doing, you should use MysteryEncounterBuilder to create an instance for this class
|
||||||
*/
|
*/
|
||||||
export default class MysteryEncounter implements IMysteryEncounter {
|
export default class MysteryEncounter implements IMysteryEncounter {
|
||||||
/**
|
// #region Required params
|
||||||
* Required params
|
|
||||||
*/
|
|
||||||
encounterType: MysteryEncounterType;
|
encounterType: MysteryEncounterType;
|
||||||
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
||||||
spriteConfigs: MysteryEncounterSpriteConfig[];
|
spriteConfigs: MysteryEncounterSpriteConfig[];
|
||||||
/**
|
|
||||||
* Optional params
|
// #region Optional params
|
||||||
*/
|
|
||||||
encounterTier: MysteryEncounterTier;
|
encounterTier: MysteryEncounterTier;
|
||||||
/**
|
/**
|
||||||
* Custom battle animations that are configured for encounter effects and visuals
|
* Custom battle animations that are configured for encounter effects and visuals
|
||||||
@ -88,7 +87,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
*/
|
*/
|
||||||
encounterAnimations?: EncounterAnim[];
|
encounterAnimations?: EncounterAnim[];
|
||||||
/**
|
/**
|
||||||
* If specified, defines any game modes where the MysteryEncounter should *NOT* spawn
|
* If specified, defines any game modes where the {@linkcode MysteryEncounter} should *NOT* spawn
|
||||||
*/
|
*/
|
||||||
disabledGameModes?: GameModes[];
|
disabledGameModes?: GameModes[];
|
||||||
/**
|
/**
|
||||||
@ -137,9 +136,8 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
*/
|
*/
|
||||||
skipToFightInput: boolean;
|
skipToFightInput: boolean;
|
||||||
|
|
||||||
/**
|
// #region Event callback functions
|
||||||
* Event callback functions
|
|
||||||
*/
|
|
||||||
/** Event when Encounter is first loaded, use it for data conditioning */
|
/** Event when Encounter is first loaded, use it for data conditioning */
|
||||||
onInit?: (scene: BattleScene) => boolean;
|
onInit?: (scene: BattleScene) => boolean;
|
||||||
/** Event when battlefield visuals have finished sliding in and the encounter dialogue begins */
|
/** 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;
|
primaryPokemon?: PlayerPokemon;
|
||||||
secondaryPokemon?: PlayerPokemon[];
|
secondaryPokemon?: PlayerPokemon[];
|
||||||
|
|
||||||
/**
|
// #region Post-construct / Auto-populated params
|
||||||
* Post-construct / Auto-populated params
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter
|
* Dialogue object containing all the dialogue, messages, tooltips, etc. for an encounter
|
||||||
@ -192,9 +188,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
*/
|
*/
|
||||||
introVisuals?: MysteryEncounterIntroVisuals;
|
introVisuals?: MysteryEncounterIntroVisuals;
|
||||||
|
|
||||||
/**
|
// #region Flags
|
||||||
* Flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be set for uses programatic dialogue during an encounter (storing the name of one of the party's pokemon, etc.)
|
* Can be set for uses programatic dialogue during an encounter (storing the name of one of the party's pokemon, etc.)
|
||||||
@ -274,7 +268,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the current scene state meets the requirements for the MysteryEncounter to spawn
|
* Checks if the current scene state meets the requirements for the {@linkcode MysteryEncounter} to spawn
|
||||||
* This is used to filter the pool of encounters down to only the ones with all requirements met
|
* This is used to filter the pool of encounters down to only the ones with all requirements met
|
||||||
* @param scene
|
* @param scene
|
||||||
* @returns
|
* @returns
|
||||||
@ -497,7 +491,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintains seed offset for RNG consistency
|
* Maintains seed offset for RNG consistency
|
||||||
* Increments if the same MysteryEncounter has multiple option select cycles
|
* Increments if the same {@linkcode MysteryEncounter} has multiple option select cycles
|
||||||
* @param scene
|
* @param scene
|
||||||
*/
|
*/
|
||||||
updateSeedOffset(scene: BattleScene) {
|
updateSeedOffset(scene: BattleScene) {
|
||||||
@ -540,7 +534,7 @@ export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @statif Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType
|
* @statif Defines the type of encounter which is used as an identifier, should be tied to a unique MysteryEncounterType
|
||||||
* NOTE: if new functions are added to MysteryEncounter class
|
* NOTE: if new functions are added to {@linkcode MysteryEncounter} class
|
||||||
* @param encounterType
|
* @param encounterType
|
||||||
* @returns this
|
* @returns this
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Abilities } from "#enums/abilities";
|
import { Abilities } from "#enums/abilities";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves that "steal" things
|
||||||
|
*/
|
||||||
export const STEALING_MOVES = [
|
export const STEALING_MOVES = [
|
||||||
Moves.PLUCK,
|
Moves.PLUCK,
|
||||||
Moves.COVET,
|
Moves.COVET,
|
||||||
@ -10,6 +13,9 @@ export const STEALING_MOVES = [
|
|||||||
Moves.SWITCHEROO
|
Moves.SWITCHEROO
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves that "charm" someone
|
||||||
|
*/
|
||||||
export const CHARMING_MOVES = [
|
export const CHARMING_MOVES = [
|
||||||
Moves.CHARM,
|
Moves.CHARM,
|
||||||
Moves.FLATTER,
|
Moves.FLATTER,
|
||||||
@ -39,6 +45,9 @@ export const DANCING_MOVES = [
|
|||||||
Moves.VICTORY_DANCE
|
Moves.VICTORY_DANCE
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves that can distract someone/something
|
||||||
|
*/
|
||||||
export const DISTRACTION_MOVES = [
|
export const DISTRACTION_MOVES = [
|
||||||
Moves.FAKE_OUT,
|
Moves.FAKE_OUT,
|
||||||
Moves.FOLLOW_ME,
|
Moves.FOLLOW_ME,
|
||||||
@ -54,6 +63,9 @@ export const DISTRACTION_MOVES = [
|
|||||||
Moves.SHED_TAIL
|
Moves.SHED_TAIL
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves that protect in some way
|
||||||
|
*/
|
||||||
export const PROTECTING_MOVES = [
|
export const PROTECTING_MOVES = [
|
||||||
Moves.PROTECT,
|
Moves.PROTECT,
|
||||||
Moves.WIDE_GUARD,
|
Moves.WIDE_GUARD,
|
||||||
@ -70,6 +82,9 @@ export const PROTECTING_MOVES = [
|
|||||||
Moves.DETECT
|
Moves.DETECT
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves that (loosely) can be used to trap/rob someone
|
||||||
|
*/
|
||||||
export const EXTORTION_MOVES = [
|
export const EXTORTION_MOVES = [
|
||||||
Moves.BIND,
|
Moves.BIND,
|
||||||
Moves.CLAMP,
|
Moves.CLAMP,
|
||||||
@ -93,6 +108,9 @@ export const EXTORTION_MOVES = [
|
|||||||
Moves.STRING_SHOT,
|
Moves.STRING_SHOT,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abilities that (loosely) can be used to trap/rob someone
|
||||||
|
*/
|
||||||
export const EXTORTION_ABILITIES = [
|
export const EXTORTION_ABILITIES = [
|
||||||
Abilities.INTIMIDATE,
|
Abilities.INTIMIDATE,
|
||||||
Abilities.ARENA_TRAP,
|
Abilities.ARENA_TRAP,
|
||||||
|
@ -88,13 +88,18 @@ export interface EnemyPokemonConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface EnemyPartyConfig {
|
export interface EnemyPartyConfig {
|
||||||
levelAdditiveMultiplier?: number; // Formula for enemy: level += waveIndex / 10 * levelAdditive
|
/** Formula for enemy: level += waveIndex / 10 * levelAdditive */
|
||||||
|
levelAdditiveMultiplier?: number;
|
||||||
doubleBattle?: boolean;
|
doubleBattle?: boolean;
|
||||||
trainerType?: TrainerType; // Generates trainer battle solely off trainer type
|
/** Generates trainer battle solely off trainer type */
|
||||||
trainerConfig?: TrainerConfig; // More customizable option for configuring trainer battle
|
trainerType?: TrainerType;
|
||||||
|
/** More customizable option for configuring trainer battle */
|
||||||
|
trainerConfig?: TrainerConfig;
|
||||||
pokemonConfigs?: EnemyPokemonConfig[];
|
pokemonConfigs?: EnemyPokemonConfig[];
|
||||||
female?: boolean; // True for female trainer, false for male
|
/** True for female trainer, false for male */
|
||||||
disableSwitch?: boolean; // True will prevent player from switching
|
female?: boolean;
|
||||||
|
/** True will prevent player from switching */
|
||||||
|
disableSwitch?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -589,7 +594,7 @@ export function selectOptionThenPokemon(scene: BattleScene, options: OptionSelec
|
|||||||
* @param scene - Battle Scene
|
* @param scene - Battle Scene
|
||||||
* @param customShopRewards - adds a shop phase with the specified rewards / reward tiers
|
* @param customShopRewards - adds a shop phase with the specified rewards / reward tiers
|
||||||
* @param eggRewards
|
* @param eggRewards
|
||||||
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before MysteryEncounterRewardsPhase)
|
* @param preRewardsCallback - can execute an arbitrary callback before the new phases if necessary (useful for updating items/party/injecting new phases before {@linkcode MysteryEncounterRewardsPhase})
|
||||||
*/
|
*/
|
||||||
export function setEncounterRewards(scene: BattleScene, customShopRewards?: CustomModifierSettings, eggRewards?: IEggOptions[], preRewardsCallback?: Function) {
|
export function setEncounterRewards(scene: BattleScene, customShopRewards?: CustomModifierSettings, eggRewards?: IEggOptions[], preRewardsCallback?: Function) {
|
||||||
scene.currentBattle.mysteryEncounter!.doEncounterRewards = (scene: BattleScene) => {
|
scene.currentBattle.mysteryEncounter!.doEncounterRewards = (scene: BattleScene) => {
|
||||||
@ -766,7 +771,7 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Will queue moves for any pokemon to use before the first CommandPhase of a battle
|
* Will queue moves for any pokemon to use before the first CommandPhase of a battle
|
||||||
* Mostly useful for allowing MysteryEncounter enemies to "cheat" and use moves before the first turn
|
* Mostly useful for allowing {@linkcode MysteryEncounter} enemies to "cheat" and use moves before the first turn
|
||||||
* @param scene
|
* @param scene
|
||||||
*/
|
*/
|
||||||
export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) {
|
export function handleMysteryEncounterBattleStartEffects(scene: BattleScene) {
|
||||||
|
@ -355,9 +355,9 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the configuration for trainers with genders, including the female name and encounter background music (BGM).
|
* Sets the configuration for trainers with genders, including the female name and encounter background music (BGM).
|
||||||
* @param {string} [nameFemale] - The name of the female trainer. If 'Ivy', a localized name will be assigned.
|
* @param {string} [nameFemale] The name of the female trainer. If 'Ivy', a localized name will be assigned.
|
||||||
* @param {TrainerType | string} [femaleEncounterBgm] - The encounter BGM for the female trainer, which can be a TrainerType or a string.
|
* @param {TrainerType | string} [femaleEncounterBgm] The encounter BGM for the female trainer, which can be a TrainerType or a string.
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
**/
|
**/
|
||||||
setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig {
|
setHasGenders(nameFemale?: string, femaleEncounterBgm?: TrainerType | string): TrainerConfig {
|
||||||
// If the female name is 'Ivy' (the rival), assign a localized name.
|
// If the female name is 'Ivy' (the rival), assign a localized name.
|
||||||
@ -392,9 +392,9 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the configuration for trainers with double battles, including the name of the double trainer and the encounter BGM.
|
* Sets the configuration for trainers with double battles, including the name of the double trainer and the encounter BGM.
|
||||||
* @param nameDouble - The name of the double trainer (e.g., "Ace Duo" for Trainer Class Doubles or "red_blue_double" for NAMED trainer doubles).
|
* @param nameDouble The name of the double trainer (e.g., "Ace Duo" for Trainer Class Doubles or "red_blue_double" for NAMED trainer doubles).
|
||||||
* @param doubleEncounterBgm - The encounter BGM for the double trainer, which can be a TrainerType or a string.
|
* @param doubleEncounterBgm The encounter BGM for the double trainer, which can be a TrainerType or a string.
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
*/
|
*/
|
||||||
setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig {
|
setHasDouble(nameDouble: string, doubleEncounterBgm?: TrainerType | string): TrainerConfig {
|
||||||
this.hasDouble = true;
|
this.hasDouble = true;
|
||||||
@ -407,8 +407,8 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the trainer type for double battles.
|
* Sets the trainer type for double battles.
|
||||||
* @param trainerTypeDouble - The TrainerType of the partner in a double battle.
|
* @param trainerTypeDouble The TrainerType of the partner in a double battle.
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
*/
|
*/
|
||||||
setDoubleTrainerType(trainerTypeDouble: TrainerType): TrainerConfig {
|
setDoubleTrainerType(trainerTypeDouble: TrainerType): TrainerConfig {
|
||||||
this.trainerTypeDouble = trainerTypeDouble;
|
this.trainerTypeDouble = trainerTypeDouble;
|
||||||
@ -432,8 +432,8 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title for double trainers
|
* Sets the title for double trainers
|
||||||
* @param titleDouble - the key for the title in the i18n file. (e.g., "champion_double").
|
* @param titleDouble The key for the title in the i18n file. (e.g., "champion_double").
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
*/
|
*/
|
||||||
setDoubleTitle(titleDouble: string): TrainerConfig {
|
setDoubleTitle(titleDouble: string): TrainerConfig {
|
||||||
// First check if i18n is initialized
|
// First check if i18n is initialized
|
||||||
@ -625,10 +625,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for an evil team admin.
|
* Initializes the trainer configuration for an evil team admin.
|
||||||
* @param title - The title of the evil team admin.
|
* @param title The title of the evil team admin.
|
||||||
* @param poolName - The evil team the admin belongs to.
|
* @param poolName The evil team the admin belongs to.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the evil team leader.
|
* @param {Species | Species[]} signatureSpecies The signature species for the evil team leader.
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
* **/
|
* **/
|
||||||
initForEvilTeamAdmin(title: string, poolName: string, signatureSpecies: (Species | Species[])[],): TrainerConfig {
|
initForEvilTeamAdmin(title: string, poolName: string, signatureSpecies: (Species | Species[])[],): TrainerConfig {
|
||||||
if (!getIsInitialized()) {
|
if (!getIsInitialized()) {
|
||||||
@ -661,10 +661,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter.
|
* Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the Elite Four member.
|
* @param {Species | Species[]} signatureSpecies The signature species for the Elite Four member.
|
||||||
* @param {Type[]} specialtyTypes - The specialty types for the Stat Trainer.
|
* @param {Type[]} specialtyTypes The specialty types for the Stat Trainer.
|
||||||
* @param isMale - Whether the Elite Four Member is Male or Female (for localization of the title).
|
* @param isMale Whether the Elite Four Member is Male or Female (for localization of the title).
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
**/
|
**/
|
||||||
initForStatTrainer(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
initForStatTrainer(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
||||||
if (!getIsInitialized()) {
|
if (!getIsInitialized()) {
|
||||||
@ -698,10 +698,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though.
|
* Initializes the trainer configuration for an evil team leader. Temporarily hardcoding evil leader teams though.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the evil team leader.
|
* @param {Species | Species[]} signatureSpecies The signature species for the evil team leader.
|
||||||
* @param {Type[]} specialtyTypes - The specialty types for the evil team Leader.
|
* @param {Type[]} specialtyTypes The specialty types for the evil team Leader.
|
||||||
* @param boolean whether or not this is the rematch fight
|
* @param boolean Whether or not this is the rematch fight
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
* **/
|
* **/
|
||||||
initForEvilTeamLeader(title: string, signatureSpecies: (Species | Species[])[], rematch: boolean = false, ...specialtyTypes: Type[]): TrainerConfig {
|
initForEvilTeamLeader(title: string, signatureSpecies: (Species | Species[])[], rematch: boolean = false, ...specialtyTypes: Type[]): TrainerConfig {
|
||||||
if (!getIsInitialized()) {
|
if (!getIsInitialized()) {
|
||||||
@ -737,10 +737,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for a Gym Leader.
|
* Initializes the trainer configuration for a Gym Leader.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the Gym Leader.
|
* @param {Species | Species[]} signatureSpecies The signature species for the Gym Leader.
|
||||||
* @param {Type[]} specialtyTypes - The specialty types for the Gym Leader.
|
* @param {Type[]} specialtyTypes The specialty types for the Gym Leader.
|
||||||
* @param isMale - Whether the Gym Leader is Male or Not (for localization of the title).
|
* @param isMale Whether the Gym Leader is Male or Not (for localization of the title).
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
* **/
|
* **/
|
||||||
initForGymLeader(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
initForGymLeader(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
||||||
// Check if the internationalization (i18n) system is initialized.
|
// Check if the internationalization (i18n) system is initialized.
|
||||||
@ -794,10 +794,10 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for an Elite Four member.
|
* Initializes the trainer configuration for an Elite Four member.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the Elite Four member.
|
* @param {Species | Species[]} signatureSpecies The signature species for the Elite Four member.
|
||||||
* @param {Type[]} specialtyTypes - The specialty types for the Elite Four member.
|
* @param {Type[]} specialtyTypes The specialty types for the Elite Four member.
|
||||||
* @param isMale - Whether the Elite Four Member is Male or Female (for localization of the title).
|
* @param isMale Whether the Elite Four Member is Male or Female (for localization of the title).
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
**/
|
**/
|
||||||
initForEliteFour(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
initForEliteFour(signatureSpecies: (Species | Species[])[], isMale: boolean, ...specialtyTypes: Type[]): TrainerConfig {
|
||||||
// Check if the internationalization (i18n) system is initialized.
|
// Check if the internationalization (i18n) system is initialized.
|
||||||
@ -850,9 +850,9 @@ export class TrainerConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the trainer configuration for a Champion.
|
* Initializes the trainer configuration for a Champion.
|
||||||
* @param {Species | Species[]} signatureSpecies - The signature species for the Champion.
|
* @param {Species | Species[]} signatureSpecies The signature species for the Champion.
|
||||||
* @param isMale - Whether the Champion is Male or Female (for localization of the title).
|
* @param isMale Whether the Champion is Male or Female (for localization of the title).
|
||||||
* @returns {TrainerConfig} - The updated TrainerConfig instance.
|
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||||
**/
|
**/
|
||||||
initForChampion(signatureSpecies: (Species | Species[])[], isMale: boolean): TrainerConfig {
|
initForChampion(signatureSpecies: (Species | Species[])[], isMale: boolean): TrainerConfig {
|
||||||
// Check if the internationalization (i18n) system is initialized.
|
// Check if the internationalization (i18n) system is initialized.
|
||||||
@ -995,63 +995,63 @@ export class TrainerConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a copy of a trainer config so that it can be modified without affecting the {@link trainerConfigs} source map
|
* Creates a shallow copy of a trainer config so that it can be modified without affecting the {@link trainerConfigs} source map
|
||||||
*/
|
*/
|
||||||
copy(): TrainerConfig {
|
clone(): TrainerConfig {
|
||||||
let copy = new TrainerConfig(this.trainerType);
|
let clone = new TrainerConfig(this.trainerType);
|
||||||
copy = this.trainerTypeDouble ? copy.setDoubleTrainerType(this.trainerTypeDouble) : copy;
|
clone = this.trainerTypeDouble ? clone.setDoubleTrainerType(this.trainerTypeDouble) : clone;
|
||||||
copy = this.name ? copy.setName(this.name) : copy;
|
clone = this.name ? clone.setName(this.name) : clone;
|
||||||
copy = this.hasGenders ? copy.setHasGenders(this.nameFemale, this.femaleEncounterBgm) : copy;
|
clone = this.hasGenders ? clone.setHasGenders(this.nameFemale, this.femaleEncounterBgm) : clone;
|
||||||
copy = this.hasDouble ? copy.setHasDouble(this.nameDouble, this.doubleEncounterBgm) : copy;
|
clone = this.hasDouble ? clone.setHasDouble(this.nameDouble, this.doubleEncounterBgm) : clone;
|
||||||
copy = this.title ? copy.setTitle(this.title) : copy;
|
clone = this.title ? clone.setTitle(this.title) : clone;
|
||||||
copy = this.titleDouble ? copy.setDoubleTitle(this.titleDouble) : copy;
|
clone = this.titleDouble ? clone.setDoubleTitle(this.titleDouble) : clone;
|
||||||
copy = this.hasCharSprite ? copy.setHasCharSprite() : copy;
|
clone = this.hasCharSprite ? clone.setHasCharSprite() : clone;
|
||||||
copy = this.doubleOnly ? copy.setDoubleOnly() : copy;
|
clone = this.doubleOnly ? clone.setDoubleOnly() : clone;
|
||||||
copy = this.moneyMultiplier ? copy.setMoneyMultiplier(this.moneyMultiplier) : copy;
|
clone = this.moneyMultiplier ? clone.setMoneyMultiplier(this.moneyMultiplier) : clone;
|
||||||
copy = this.isBoss ? copy.setBoss() : copy;
|
clone = this.isBoss ? clone.setBoss() : clone;
|
||||||
copy = this.hasStaticParty ? copy.setStaticParty() : copy;
|
clone = this.hasStaticParty ? clone.setStaticParty() : clone;
|
||||||
copy = this.useSameSeedForAllMembers ? copy.setUseSameSeedForAllMembers() : copy;
|
clone = this.useSameSeedForAllMembers ? clone.setUseSameSeedForAllMembers() : clone;
|
||||||
copy = this.battleBgm ? copy.setBattleBgm(this.battleBgm) : copy;
|
clone = this.battleBgm ? clone.setBattleBgm(this.battleBgm) : clone;
|
||||||
copy = this.encounterBgm ? copy.setEncounterBgm(this.encounterBgm) : copy;
|
clone = this.encounterBgm ? clone.setEncounterBgm(this.encounterBgm) : clone;
|
||||||
copy = this.victoryBgm ? copy.setVictoryBgm(this.victoryBgm) : copy;
|
clone = this.victoryBgm ? clone.setVictoryBgm(this.victoryBgm) : clone;
|
||||||
copy = this.genModifiersFunc ? copy.setGenModifiersFunc(this.genModifiersFunc) : copy;
|
clone = this.genModifiersFunc ? clone.setGenModifiersFunc(this.genModifiersFunc) : clone;
|
||||||
|
|
||||||
if (this.modifierRewardFuncs) {
|
if (this.modifierRewardFuncs) {
|
||||||
// Clones array instead of passing ref
|
// Clones array instead of passing ref
|
||||||
copy.modifierRewardFuncs = this.modifierRewardFuncs.slice(0);
|
clone.modifierRewardFuncs = this.modifierRewardFuncs.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.partyTemplates) {
|
if (this.partyTemplates) {
|
||||||
copy.partyTemplates = this.partyTemplates.slice(0);
|
clone.partyTemplates = this.partyTemplates.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy = this.partyTemplateFunc ? copy.setPartyTemplateFunc(this.partyTemplateFunc) : copy;
|
clone = this.partyTemplateFunc ? clone.setPartyTemplateFunc(this.partyTemplateFunc) : clone;
|
||||||
|
|
||||||
if (this.partyMemberFuncs) {
|
if (this.partyMemberFuncs) {
|
||||||
Object.keys(this.partyMemberFuncs).forEach((index) => {
|
Object.keys(this.partyMemberFuncs).forEach((index) => {
|
||||||
copy = copy.setPartyMemberFunc(parseInt(index, 10), this.partyMemberFuncs[index]);
|
clone = clone.setPartyMemberFunc(parseInt(index, 10), this.partyMemberFuncs[index]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
copy = this.speciesPools ? copy.setSpeciesPools(this.speciesPools) : copy;
|
clone = this.speciesPools ? clone.setSpeciesPools(this.speciesPools) : clone;
|
||||||
copy = this.speciesFilter ? copy.setSpeciesFilter(this.speciesFilter) : copy;
|
clone = this.speciesFilter ? clone.setSpeciesFilter(this.speciesFilter) : clone;
|
||||||
if (this.specialtyTypes) {
|
if (this.specialtyTypes) {
|
||||||
copy.specialtyTypes = this.specialtyTypes.slice(0);
|
clone.specialtyTypes = this.specialtyTypes.slice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.encounterMessages = this.encounterMessages?.slice(0);
|
clone.encounterMessages = this.encounterMessages?.slice(0);
|
||||||
copy.victoryMessages = this.victoryMessages?.slice(0);
|
clone.victoryMessages = this.victoryMessages?.slice(0);
|
||||||
copy.defeatMessages = this.defeatMessages?.slice(0);
|
clone.defeatMessages = this.defeatMessages?.slice(0);
|
||||||
|
|
||||||
copy.femaleEncounterMessages = this.femaleEncounterMessages?.slice(0);
|
clone.femaleEncounterMessages = this.femaleEncounterMessages?.slice(0);
|
||||||
copy.femaleVictoryMessages = this.femaleVictoryMessages?.slice(0);
|
clone.femaleVictoryMessages = this.femaleVictoryMessages?.slice(0);
|
||||||
copy.femaleDefeatMessages = this.femaleDefeatMessages?.slice(0);
|
clone.femaleDefeatMessages = this.femaleDefeatMessages?.slice(0);
|
||||||
|
|
||||||
copy.doubleEncounterMessages = this.doubleEncounterMessages?.slice(0);
|
clone.doubleEncounterMessages = this.doubleEncounterMessages?.slice(0);
|
||||||
copy.doubleVictoryMessages = this.doubleVictoryMessages?.slice(0);
|
clone.doubleVictoryMessages = this.doubleVictoryMessages?.slice(0);
|
||||||
copy.doubleDefeatMessages = this.doubleDefeatMessages?.slice(0);
|
clone.doubleDefeatMessages = this.doubleDefeatMessages?.slice(0);
|
||||||
|
|
||||||
return copy;
|
return clone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/enums/encounter-anims.ts
Normal file
11
src/enums/encounter-anims.ts
Normal file
@ -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
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
export enum MysteryEncounterMode {
|
export enum MysteryEncounterMode {
|
||||||
/** MysteryEncounter will always begin in this mode, but will always swap modes when an option is selected */
|
/** {@linkcode MysteryEncounter} will always begin in this mode, but will always swap modes when an option is selected */
|
||||||
DEFAULT,
|
DEFAULT,
|
||||||
/** If the MysteryEncounter battle is a trainer type battle */
|
/** If the {@linkcode MysteryEncounter} battle is a trainer type battle */
|
||||||
TRAINER_BATTLE,
|
TRAINER_BATTLE,
|
||||||
/** If the MysteryEncounter battle is a wild type battle */
|
/** If the {@linkcode MysteryEncounter} battle is a wild type battle */
|
||||||
WILD_BATTLE,
|
WILD_BATTLE,
|
||||||
/** Enables special boss music during encounter */
|
/** Enables special boss music during encounter */
|
||||||
BOSS_BATTLE,
|
BOSS_BATTLE,
|
||||||
/** If there is no battle in the MysteryEncounter or option selected */
|
/** If there is no battle in the {@linkcode MysteryEncounter} or option selected */
|
||||||
NO_BATTLE
|
NO_BATTLE
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ interface GameModeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Describes min and max waves for MEs in specific game modes
|
// Describes min and max waves for MEs in specific game modes
|
||||||
const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
export const CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||||
const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
export const CHALLENGE_MODE_MYSTERY_ENCOUNTER_WAVES: [number, number] = [10, 180];
|
||||||
|
|
||||||
export class GameMode implements GameModeConfig {
|
export class GameMode implements GameModeConfig {
|
||||||
public modeId: GameModes;
|
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] {
|
getMysteryEncounterLegalWaves(): [number, number] {
|
||||||
switch (this.modeId) {
|
switch (this.modeId) {
|
||||||
default:
|
default:
|
||||||
|
@ -122,7 +122,7 @@ export class ModifierType {
|
|||||||
* Populates item tier for ModifierType instance
|
* Populates item tier for ModifierType instance
|
||||||
* Tier is a necessary field for items that appear in player shop (determines the Pokeball visual they use)
|
* Tier is a necessary field for items that appear in player shop (determines the Pokeball visual they use)
|
||||||
* To find the tier, this function performs a reverse lookup of the item type in modifier pools
|
* To find the tier, this function performs a reverse lookup of the item type in modifier pools
|
||||||
* @param poolType - Default 'ModifierPoolType.PLAYER'. Which pool to lookup item tier from
|
* @param poolType Default 'ModifierPoolType.PLAYER'. Which pool to lookup item tier from
|
||||||
*/
|
*/
|
||||||
withTierFromPool(poolType: ModifierPoolType = ModifierPoolType.PLAYER): ModifierType {
|
withTierFromPool(poolType: ModifierPoolType = ModifierPoolType.PLAYER): ModifierType {
|
||||||
for (const tier of Object.values(getModifierPoolForType(poolType))) {
|
for (const tier of Object.values(getModifierPoolForType(poolType))) {
|
||||||
@ -2048,6 +2048,7 @@ export interface CustomModifierSettings {
|
|||||||
guaranteedModifierTypeOptions?: ModifierTypeOption[];
|
guaranteedModifierTypeOptions?: ModifierTypeOption[];
|
||||||
guaranteedModifierTypeFuncs?: ModifierTypeFunc[];
|
guaranteedModifierTypeFuncs?: ModifierTypeFunc[];
|
||||||
fillRemaining?: boolean;
|
fillRemaining?: boolean;
|
||||||
|
/** Set to negative value to disable rerolls completely in shop */
|
||||||
rerollMultiplier?: number;
|
rerollMultiplier?: number;
|
||||||
allowLuckUpgrades?: boolean;
|
allowLuckUpgrades?: boolean;
|
||||||
}
|
}
|
||||||
@ -2057,20 +2058,20 @@ export function getModifierTypeFuncById(id: string): ModifierTypeFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates modifier options for a SelectModifierPhase
|
* Generates modifier options for a {@linkcode SelectModifierPhase}
|
||||||
* @param count - Determines the number of items to generate
|
* @param count Determines the number of items to generate
|
||||||
* @param party - Party is required for generating proper modifier pools
|
* @param party Party is required for generating proper modifier pools
|
||||||
* @param modifierTiers - (Optional) If specified, rolls items in the specified tiers. Commonly used for tier-locking with Lock Capsule.
|
* @param modifierTiers (Optional) If specified, rolls items in the specified tiers. Commonly used for tier-locking with Lock Capsule.
|
||||||
* @param customModifierSettings - (Optional) If specified, can customize the item shop rewards further.
|
* @param customModifierSettings (Optional) If specified, can customize the item shop rewards further.
|
||||||
* - `guaranteedModifierTypeOptions?: ModifierTypeOption[]` - If specified, will override the first X items to be specific modifier options (these should be pre-genned).
|
* - `guaranteedModifierTypeOptions?: ModifierTypeOption[]` If specified, will override the first X items to be specific modifier options (these should be pre-genned).
|
||||||
* - `guaranteedModifierTypeFuncs?: ModifierTypeFunc[]` - If specified, will override the next X items to be auto-generated from specific modifier functions (these don't have to be pre-genned).
|
* - `guaranteedModifierTypeFuncs?: ModifierTypeFunc[]` If specified, will override the next X items to be auto-generated from specific modifier functions (these don't have to be pre-genned).
|
||||||
* - `guaranteedModifierTiers?: ModifierTier[]` - If specified, will override the next X items to be the specified tier. These can upgrade with luck.
|
* - `guaranteedModifierTiers?: ModifierTier[]` If specified, will override the next X items to be the specified tier. These can upgrade with luck.
|
||||||
* - `fillRemaining?: boolean` - Default 'false'. If set to true, will fill the remainder of shop items that were not overridden by the 3 options above, up to the 'count' param value.
|
* - `fillRemaining?: boolean` Default 'false'. If set to true, will fill the remainder of shop items that were not overridden by the 3 options above, up to the 'count' param value.
|
||||||
* - Example: `count = 4`, `customModifierSettings = { guaranteedModifierTiers: [ModifierTier.GREAT], fillRemaining: true }`,
|
* - Example: `count = 4`, `customModifierSettings = { guaranteedModifierTiers: [ModifierTier.GREAT], fillRemaining: true }`,
|
||||||
* - The first item in the shop will be `GREAT` tier, and the remaining 3 items will be generated normally.
|
* - The first item in the shop will be `GREAT` tier, and the remaining 3 items will be generated normally.
|
||||||
* - If `fillRemaining = false` in the same scenario, only 1 `GREAT` tier item will appear in the shop (regardless of `count` value).
|
* - If `fillRemaining = false` in the same scenario, only 1 `GREAT` tier item will appear in the shop (regardless of `count` value).
|
||||||
* - `rerollMultiplier?: number` - If specified, can adjust the amount of money required for a shop reroll. If set to 0, the shop will not allow rerolls at all.
|
* - `rerollMultiplier?: number` If specified, can adjust the amount of money required for a shop reroll. If set to a negative value, the shop will not allow rerolls at all.
|
||||||
* - `allowLuckUpgrades?: boolean` - Default true, if false will prevent set item tiers from upgrading via luck
|
* - `allowLuckUpgrades?: boolean` Default `true`, if `false` will prevent set item tiers from upgrading via luck
|
||||||
*/
|
*/
|
||||||
export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[], modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings): ModifierTypeOption[] {
|
export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemon[], modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings): ModifierTypeOption[] {
|
||||||
const options: ModifierTypeOption[] = [];
|
const options: ModifierTypeOption[] = [];
|
||||||
@ -2126,12 +2127,12 @@ export function getPlayerModifierTypeOptions(count: integer, party: PlayerPokemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will generate a ModifierType from the ModifierPoolType.PLAYER pool, attempting to retry duplicated items up to retryCount
|
* Will generate a {@linkcode ModifierType} from the {@linkcode ModifierPoolType.PLAYER} pool, attempting to retry duplicated items up to retryCount
|
||||||
* @param existingOptions - currently generated options
|
* @param existingOptions Currently generated options
|
||||||
* @param retryCount - how many times to retry before allowing a dupe item
|
* @param retryCount How many times to retry before allowing a dupe item
|
||||||
* @param party - current player party, used to calculate items in the pool
|
* @param party Current player party, used to calculate items in the pool
|
||||||
* @param tier - If specified will generate item of tier
|
* @param tier If specified will generate item of tier
|
||||||
* @param allowLuckUpgrades - allow items to upgrade tiers (the little animation that plays and is affected by luck)
|
* @param allowLuckUpgrades `true` to allow items to upgrade tiers (the little animation that plays and is affected by luck)
|
||||||
*/
|
*/
|
||||||
function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: integer, party: PlayerPokemon[], tier?: ModifierTier, allowLuckUpgrades?: boolean): ModifierTypeOption {
|
function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], retryCount: integer, party: PlayerPokemon[], tier?: ModifierTier, allowLuckUpgrades?: boolean): ModifierTypeOption {
|
||||||
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
||||||
@ -2270,12 +2271,12 @@ export function getDailyRunStarterModifiers(party: PlayerPokemon[]): Modifiers.P
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a ModifierType from the specified pool
|
* Generates a ModifierType from the specified pool
|
||||||
* @param party - party of the trainer using the item
|
* @param party party of the trainer using the item
|
||||||
* @param poolType - PLAYER/WILD/TRAINER
|
* @param poolType PLAYER/WILD/TRAINER
|
||||||
* @param tier - If specified, will override the initial tier of an item (can still upgrade with luck)
|
* @param tier If specified, will override the initial tier of an item (can still upgrade with luck)
|
||||||
* @param upgradeCount - If defined, means that this is a new ModifierType being generated to override another via luck upgrade. Used for recursive logic
|
* @param upgradeCount If defined, means that this is a new ModifierType being generated to override another via luck upgrade. Used for recursive logic
|
||||||
* @param retryCount - Max allowed tries before the next tier down is checked for a valid ModifierType
|
* @param retryCount Max allowed tries before the next tier down is checked for a valid ModifierType
|
||||||
* @param allowLuckUpgrades - Default true. If false, will not allow ModifierType to randomly upgrade to next tier
|
* @param allowLuckUpgrades Default true. If false, will not allow ModifierType to randomly upgrade to next tier
|
||||||
*/
|
*/
|
||||||
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0, allowLuckUpgrades: boolean = true): ModifierTypeOption | null {
|
function getNewModifierTypeOption(party: Pokemon[], poolType: ModifierPoolType, tier?: ModifierTier, upgradeCount?: integer, retryCount: integer = 0, allowLuckUpgrades: boolean = true): ModifierTypeOption | null {
|
||||||
const player = !poolType;
|
const player = !poolType;
|
||||||
|
@ -98,7 +98,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
} else {
|
} else {
|
||||||
let enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true);
|
let enemySpecies = this.scene.randomSpecies(battle.waveIndex, level, true);
|
||||||
// If player has golden bug net, rolls 10% chance to replace with species from the golden bug net bug pool
|
// If player has golden bug net, rolls 10% chance to replace with species from the golden bug net bug pool
|
||||||
if (!!this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) && randSeedInt(10) === 0) {
|
if (this.scene.findModifier(m => m instanceof BoostBugSpawnModifier) && randSeedInt(10) === 0) {
|
||||||
enemySpecies = getGoldenBugNetSpecies();
|
enemySpecies = getGoldenBugNetSpecies();
|
||||||
}
|
}
|
||||||
battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
|
battle.enemyParty[e] = this.scene.addEnemyPokemon(enemySpecies, level, TrainerSlot.NONE, !!this.scene.getEncounterBossSegments(battle.waveIndex, level, enemySpecies));
|
||||||
|
@ -30,19 +30,18 @@ import { SeenEncounterData } from "#app/data/mystery-encounters/mystery-encounte
|
|||||||
* - Clearing of phase queues to enter the Mystery Encounter game state
|
* - Clearing of phase queues to enter the Mystery Encounter game state
|
||||||
* - Management of session data related to MEs
|
* - Management of session data related to MEs
|
||||||
* - Initialization of ME option select menu and UI
|
* - Initialization of ME option select menu and UI
|
||||||
* - Execute onPreOptionPhase() logic if it exists for the selected option
|
* - Execute {@linkcode MysteryEncounter.onPreOptionPhase} logic if it exists for the selected option
|
||||||
* - Display any OptionTextDisplay.selected type dialogue that is set in the MysteryEncounterDialogue dialogue tree for selected option
|
* - Display any `OptionTextDisplay.selected` type dialogue that is set in the {@linkcode MysteryEncounterDialogue} dialogue tree for selected option
|
||||||
* - Queuing of the MysteryEncounterOptionSelectedPhase
|
* - Queuing of the {@linkcode MysteryEncounterOptionSelectedPhase}
|
||||||
*/
|
*/
|
||||||
export class MysteryEncounterPhase extends Phase {
|
export class MysteryEncounterPhase extends Phase {
|
||||||
private readonly FIRST_DIALOGUE_PROMPT_DELAY = 300;
|
private readonly FIRST_DIALOGUE_PROMPT_DELAY = 300;
|
||||||
optionSelectSettings?: OptionSelectSettings;
|
optionSelectSettings?: OptionSelectSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param scene
|
|
||||||
* @param optionSelectSettings - allows overriding the typical options of an encounter with new ones
|
|
||||||
* Mostly useful for having repeated queries during a single encounter, where the queries and options may differ each time
|
* Mostly useful for having repeated queries during a single encounter, where the queries and options may differ each time
|
||||||
|
* @param scene
|
||||||
|
* @param optionSelectSettings allows overriding the typical options of an encounter with new ones
|
||||||
*/
|
*/
|
||||||
constructor(scene: BattleScene, optionSelectSettings?: OptionSelectSettings) {
|
constructor(scene: BattleScene, optionSelectSettings?: OptionSelectSettings) {
|
||||||
super(scene);
|
super(scene);
|
||||||
@ -114,7 +113,7 @@ export class MysteryEncounterPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues MysteryEncounterOptionSelectedPhase, displays option.selected dialogue and ends phase
|
* Queues {@linkcode MysteryEncounterOptionSelectedPhase}, displays option.selected dialogue and ends phase
|
||||||
*/
|
*/
|
||||||
continueEncounter() {
|
continueEncounter() {
|
||||||
const endDialogueAndContinueEncounter = () => {
|
const endDialogueAndContinueEncounter = () => {
|
||||||
@ -161,7 +160,7 @@ export class MysteryEncounterPhase extends Phase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Will handle (in order):
|
* Will handle (in order):
|
||||||
* - Execute onOptionSelect() logic if it exists for the selected option
|
* - Execute {@linkcode MysteryEncounter.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
|
* 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
|
* Any phase that is meant to follow this one MUST be queued via the onOptionSelect() logic of the selected option
|
||||||
@ -174,6 +173,13 @@ export class MysteryEncounterOptionSelectedPhase extends Phase {
|
|||||||
this.onOptionSelect = this.scene.currentBattle.mysteryEncounter!.selectedOption!.onOptionPhase;
|
this.onOptionSelect = this.scene.currentBattle.mysteryEncounter!.selectedOption!.onOptionPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will handle (in order):
|
||||||
|
* - Execute {@linkcode MysteryEncounter.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 {@linkcode MysteryEncounter.onOptionSelect} logic of the selected option.
|
||||||
|
*/
|
||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
if (this.scene.currentBattle.mysteryEncounter?.autoHideIntroVisuals) {
|
if (this.scene.currentBattle.mysteryEncounter?.autoHideIntroVisuals) {
|
||||||
@ -196,9 +202,9 @@ export class MysteryEncounterOptionSelectedPhase extends Phase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs at the beginning of an Encounter's battle
|
* Runs at the beginning of an Encounter's battle
|
||||||
* Will clean up any residual flinches, Endure, etc. that are left over from startOfBattleEffects
|
* Will clean up any residual flinches, Endure, etc. that are left over from {@linkcode MysteryEncounter.startOfBattleEffects}
|
||||||
* Will also handle Game Overs, switches, etc. that could happen from handleMysteryEncounterBattleStartEffects
|
* Will also handle Game Overs, switches, etc. that could happen from {@linkcode handleMysteryEncounterBattleStartEffects}
|
||||||
* See [TurnEndPhase](../phases.ts) for more details
|
* See {@linkcode TurnEndPhase} for more details
|
||||||
*/
|
*/
|
||||||
export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
@ -206,7 +212,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up TURN_END tags, any PostTurnEffectPhases, checks for Pokemon switches, then continues
|
* Cleans up `TURN_END` tags, any {@linkcode PostTurnStatusEffectPhase}s, checks for Pokemon switches, then continues
|
||||||
*/
|
*/
|
||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
@ -253,7 +259,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
|||||||
* - Setting BGM
|
* - Setting BGM
|
||||||
* - Showing intro dialogue for an enemy trainer or wild Pokemon
|
* - Showing intro dialogue for an enemy trainer or wild Pokemon
|
||||||
* - Sliding in the visuals for enemy trainer or wild Pokemon, as well as handling summoning animations
|
* - Sliding in the visuals for enemy trainer or wild Pokemon, as well as handling summoning animations
|
||||||
* - Queue the SummonPhases, PostSummonPhases, etc., required to initialize the phase queue for a battle
|
* - Queue the {@linkcode SummonPhase}s, {@linkcode PostSummonPhase}s, etc., required to initialize the phase queue for a battle
|
||||||
*/
|
*/
|
||||||
export class MysteryEncounterBattlePhase extends Phase {
|
export class MysteryEncounterBattlePhase extends Phase {
|
||||||
disableSwitch: boolean;
|
disableSwitch: boolean;
|
||||||
@ -300,7 +306,7 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues SummonPhases for the new battle, and handles trainer animations/dialogue if Trainer battle
|
* Queues {@linkcode SummonPhase}s for the new battle, and handles trainer animations/dialogue if it's a Trainer battle
|
||||||
* @param scene
|
* @param scene
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@ -369,7 +375,7 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate SummonPhases, scanner phases, PostSummon phases, etc.
|
* Initiate {@linkcode SummonPhase}s, {@linkcode ScanIvsPhase}, {@linkcode PostSummonPhase}s, etc.
|
||||||
* @param scene
|
* @param scene
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@ -465,10 +471,10 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
*
|
*
|
||||||
* OR
|
* OR
|
||||||
*
|
*
|
||||||
* - Any encounter reward logic that is set within MysteryEncounter doEncounterExp
|
* - Any encounter reward logic that is set within {@linkcode MysteryEncounter.doEncounterExp}
|
||||||
* - Any encounter reward logic that is set within MysteryEncounter doEncounterRewards
|
* - Any encounter reward logic that is set within {@linkcode MysteryEncounter.doEncounterRewards}
|
||||||
* - Otherwise, can add a no-reward-item shop with only Potions, etc. if addHealPhase is true
|
* - Otherwise, can add a no-reward-item shop with only Potions, etc. if addHealPhase is true
|
||||||
* - Queuing of the PostMysteryEncounterPhase
|
* - Queuing of the {@linkcode PostMysteryEncounterPhase}
|
||||||
*/
|
*/
|
||||||
export class MysteryEncounterRewardsPhase extends Phase {
|
export class MysteryEncounterRewardsPhase extends Phase {
|
||||||
addHealPhase: boolean;
|
addHealPhase: boolean;
|
||||||
@ -479,7 +485,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs {@link MysteryEncounter.doContinueEncounter} and ends phase, OR {@link MysteryEncounter.onRewards} then continues encounter
|
* Runs {@linkcode MysteryEncounter.doContinueEncounter} and ends phase, OR {@linkcode MysteryEncounter.onRewards} then continues encounter
|
||||||
*/
|
*/
|
||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
@ -504,7 +510,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues encounter EXP and rewards phases, PostMysteryEncounterPhase, and ends phase
|
* Queues encounter EXP and rewards phases, {@linkcode PostMysteryEncounterPhase}, and ends phase
|
||||||
*/
|
*/
|
||||||
doEncounterRewardsAndContinue() {
|
doEncounterRewardsAndContinue() {
|
||||||
const encounter = this.scene.currentBattle.mysteryEncounter!;
|
const encounter = this.scene.currentBattle.mysteryEncounter!;
|
||||||
@ -517,7 +523,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
encounter.doEncounterRewards(this.scene);
|
encounter.doEncounterRewards(this.scene);
|
||||||
} else if (this.addHealPhase) {
|
} else if (this.addHealPhase) {
|
||||||
this.scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
this.scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
||||||
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, 0, undefined, { fillRemaining: false, rerollMultiplier: 0 }));
|
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, 0, undefined, { fillRemaining: false, rerollMultiplier: -1 }));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scene.pushPhase(new PostMysteryEncounterPhase(this.scene));
|
this.scene.pushPhase(new PostMysteryEncounterPhase(this.scene));
|
||||||
@ -527,7 +533,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Will handle (in order):
|
* Will handle (in order):
|
||||||
* - onPostOptionSelect logic (based on an option that was selected)
|
* - {@linkcode MysteryEncounter.onPostOptionSelect} logic (based on an option that was selected)
|
||||||
* - Showing any outro dialogue messages
|
* - Showing any outro dialogue messages
|
||||||
* - Cleanup of any leftover intro visuals
|
* - Cleanup of any leftover intro visuals
|
||||||
* - Queuing of the next wave
|
* - Queuing of the next wave
|
||||||
@ -542,7 +548,7 @@ export class PostMysteryEncounterPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs {@link MysteryEncounter.onPostOptionSelect} then continues encounter
|
* Runs {@linkcode MysteryEncounter.onPostOptionSelect} then continues encounter
|
||||||
*/
|
*/
|
||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
@ -562,7 +568,7 @@ export class PostMysteryEncounterPhase extends Phase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues NewBattlePhase, plays outro dialogue and ends phase
|
* Queues {@linkcode NewBattlePhase}, plays outro dialogue and ends phase
|
||||||
*/
|
*/
|
||||||
continueEncounter() {
|
continueEncounter() {
|
||||||
const endPhase = () => {
|
const endPhase = () => {
|
||||||
|
@ -18,6 +18,9 @@ export class PartyExpPhase extends Phase {
|
|||||||
this.pokemonParticipantIds = pokemonParticipantIds;
|
this.pokemonParticipantIds = pokemonParticipantIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives EXP to the party
|
||||||
|
*/
|
||||||
start() {
|
start() {
|
||||||
super.start();
|
super.start();
|
||||||
|
|
||||||
|
@ -14,14 +14,14 @@ import { isNullOrUndefined } from "#app/utils";
|
|||||||
|
|
||||||
export class SelectModifierPhase extends BattlePhase {
|
export class SelectModifierPhase extends BattlePhase {
|
||||||
private rerollCount: integer;
|
private rerollCount: integer;
|
||||||
private modifierTiers: ModifierTier[];
|
private modifierTiers?: ModifierTier[];
|
||||||
private customModifierSettings?: CustomModifierSettings;
|
private customModifierSettings?: CustomModifierSettings;
|
||||||
|
|
||||||
constructor(scene: BattleScene, rerollCount: integer = 0, modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings) {
|
constructor(scene: BattleScene, rerollCount: integer = 0, modifierTiers?: ModifierTier[], customModifierSettings?: CustomModifierSettings) {
|
||||||
super(scene);
|
super(scene);
|
||||||
|
|
||||||
this.rerollCount = rerollCount;
|
this.rerollCount = rerollCount;
|
||||||
this.modifierTiers = modifierTiers!; // TODO: is this bang correct?
|
this.modifierTiers = modifierTiers;
|
||||||
this.customModifierSettings = customModifierSettings;
|
this.customModifierSettings = customModifierSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
switch (cursor) {
|
switch (cursor) {
|
||||||
case 0:
|
case 0:
|
||||||
const rerollCost = this.getRerollCost(typeOptions, this.scene.lockModifierTiers);
|
const rerollCost = this.getRerollCost(typeOptions, this.scene.lockModifierTiers);
|
||||||
if (rerollCost === 0 || this.scene.money < rerollCost) {
|
if (rerollCost < 0 || this.scene.money < rerollCost) {
|
||||||
this.scene.ui.playError();
|
this.scene.ui.playError();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -241,7 +241,17 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
} else {
|
} else {
|
||||||
baseValue = 250;
|
baseValue = 250;
|
||||||
}
|
}
|
||||||
const multiplier = !isNullOrUndefined(this.customModifierSettings?.rerollMultiplier) ? this.customModifierSettings!.rerollMultiplier! : 1;
|
|
||||||
|
let multiplier = 1;
|
||||||
|
if (!isNullOrUndefined(this.customModifierSettings?.rerollMultiplier)) {
|
||||||
|
if (this.customModifierSettings!.rerollMultiplier! < 0) {
|
||||||
|
// Completely overrides reroll cost to -1 and early exits
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, continue with custom multiplier
|
||||||
|
multiplier = this.customModifierSettings!.rerollMultiplier!;
|
||||||
|
}
|
||||||
return Math.min(Math.ceil(this.scene.currentBattle.waveIndex / 10) * baseValue * Math.pow(2, this.rerollCount) * multiplier, Number.MAX_SAFE_INTEGER);
|
return Math.min(Math.ceil(this.scene.currentBattle.waveIndex / 10) * baseValue * Math.pow(2, this.rerollCount) * multiplier, Number.MAX_SAFE_INTEGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,18 @@ export async function initI18n(): Promise<void> {
|
|||||||
// If you don't want the BBCode tag applied, just use 'number' formatter
|
// If you don't want the BBCode tag applied, just use 'number' formatter
|
||||||
i18next.services.formatter?.add("money", (value, lng, options) => {
|
i18next.services.formatter?.add("money", (value, lng, options) => {
|
||||||
const numberFormattedString = Intl.NumberFormat(lng, options).format(value);
|
const numberFormattedString = Intl.NumberFormat(lng, options).format(value);
|
||||||
return `@[MONEY]{₽${numberFormattedString}}`;
|
switch (lng) {
|
||||||
|
case "ja":
|
||||||
|
return `@[MONEY]{${numberFormattedString}}円`;
|
||||||
|
case "de":
|
||||||
|
case "es":
|
||||||
|
case "fr":
|
||||||
|
case "it":
|
||||||
|
return `@[MONEY]{${numberFormattedString} ₽}`;
|
||||||
|
default:
|
||||||
|
// English and other languages that use same format
|
||||||
|
return `@[MONEY]{₽${numberFormattedString}}`;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await initFonts(localStorage.getItem("prLang") ?? undefined);
|
await initFonts(localStorage.getItem("prLang") ?? undefined);
|
||||||
|
@ -1561,7 +1561,7 @@ export class GameData {
|
|||||||
* @param incrementCount
|
* @param incrementCount
|
||||||
* @param fromEgg
|
* @param fromEgg
|
||||||
* @param showMessage
|
* @param showMessage
|
||||||
* @returns - true if Pokemon catch unlocked a new starter, false if Pokemon catch did not unlock a starter
|
* @returns `true` if Pokemon catch unlocked a new starter, `false` if Pokemon catch did not unlock a starter
|
||||||
*/
|
*/
|
||||||
setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<boolean> {
|
setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<boolean> {
|
||||||
return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage);
|
return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage);
|
||||||
@ -1573,7 +1573,7 @@ export class GameData {
|
|||||||
* @param incrementCount
|
* @param incrementCount
|
||||||
* @param fromEgg
|
* @param fromEgg
|
||||||
* @param showMessage
|
* @param showMessage
|
||||||
* @returns - true if Pokemon catch unlocked a new starter, false if Pokemon catch did not unlock a starter
|
* @returns `true` if Pokemon catch unlocked a new starter, `false` if Pokemon catch did not unlock a starter
|
||||||
*/
|
*/
|
||||||
setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<boolean> {
|
setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
@ -1694,8 +1694,8 @@ export class GameData {
|
|||||||
*
|
*
|
||||||
* @param species
|
* @param species
|
||||||
* @param eggMoveIndex
|
* @param eggMoveIndex
|
||||||
* @param showMessage - Default true. If true, will display message for unlocked egg move
|
* @param showMessage Default true. If true, will display message for unlocked egg move
|
||||||
* @param prependSpeciesToMessage - Default false. If true, will change message from "X Egg Move Unlocked!" to "Bulbasaur X Egg Move Unlocked!"
|
* @param prependSpeciesToMessage Default false. If true, will change message from "X Egg Move Unlocked!" to "Bulbasaur X Egg Move Unlocked!"
|
||||||
*/
|
*/
|
||||||
setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer, showMessage: boolean = true, prependSpeciesToMessage: boolean = false): Promise<boolean> {
|
setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer, showMessage: boolean = true, prependSpeciesToMessage: boolean = false): Promise<boolean> {
|
||||||
return new Promise<boolean>(resolve => {
|
return new Promise<boolean>(resolve => {
|
||||||
|
@ -57,6 +57,7 @@ export default class PokemonData {
|
|||||||
public bossSegments?: integer;
|
public bossSegments?: integer;
|
||||||
|
|
||||||
public summonData: PokemonSummonData;
|
public summonData: PokemonSummonData;
|
||||||
|
/** Data that can customize a Pokemon in non-standard ways from its Species */
|
||||||
public mysteryEncounterPokemonData: MysteryEncounterPokemonData;
|
public mysteryEncounterPokemonData: MysteryEncounterPokemonData;
|
||||||
|
|
||||||
constructor(source: Pokemon | any, forHistory: boolean = false) {
|
constructor(source: Pokemon | any, forHistory: boolean = false) {
|
||||||
|
@ -15,11 +15,11 @@ import { VictoryPhase } from "#app/phases/victory-phase";
|
|||||||
import { MessagePhase } from "#app/phases/message-phase";
|
import { MessagePhase } from "#app/phases/message-phase";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a MysteryEncounter to either the start of a battle, or to the MysteryEncounterRewardsPhase, depending on the option selected
|
* Runs a {@linkcode MysteryEncounter} to either the start of a battle, or to the {@linkcode MysteryEncounterRewardsPhase}, depending on the option selected
|
||||||
* @param game
|
* @param game
|
||||||
* @param optionNo - human number, not index
|
* @param optionNo Human number, not index
|
||||||
* @param secondaryOptionSelect -
|
* @param secondaryOptionSelect
|
||||||
* @param isBattle - if selecting option should lead to battle, set to true
|
* @param isBattle If selecting option should lead to battle, set to `true`
|
||||||
*/
|
*/
|
||||||
export async function runMysteryEncounterToEnd(game: GameManager, optionNo: number, secondaryOptionSelect?: { pokemonNo: number, optionNo?: number }, isBattle: boolean = false) {
|
export async function runMysteryEncounterToEnd(game: GameManager, optionNo: number, secondaryOptionSelect?: { pokemonNo: number, optionNo?: number }, isBattle: boolean = false) {
|
||||||
vi.spyOn(EncounterPhaseUtils, "selectPokemonForOption");
|
vi.spyOn(EncounterPhaseUtils, "selectPokemonForOption");
|
||||||
@ -157,7 +157,7 @@ async function handleSecondaryOptionSelect(game: GameManager, pokemonNo: number,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For any MysteryEncounter that has a battle, can call this to skip battle and proceed to MysteryEncounterRewardsPhase
|
* For any {@linkcode MysteryEncounter} that has a battle, can call this to skip battle and proceed to {@linkcode MysteryEncounterRewardsPhase}
|
||||||
* @param game
|
* @param game
|
||||||
* @param runRewardsPhase
|
* @param runRewardsPhase
|
||||||
*/
|
*/
|
||||||
|
@ -117,11 +117,12 @@ describe("Field Trip - Mystery Encounter", () => {
|
|||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
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[0].modifierTypeOption.type.name).toBe("X Attack");
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Defense");
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Defense");
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("Dire Hit");
|
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 () => {
|
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);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
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[0].modifierTypeOption.type.name).toBe("X Sp. Atk");
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Sp. Def");
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Sp. Def");
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("X Speed");
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("Dire Hit");
|
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 () => {
|
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);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
const modifierSelectHandler = scene.ui.handlers.find(h => h instanceof ModifierSelectUiHandler) as ModifierSelectUiHandler;
|
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[0].modifierTypeOption.type.name).toBe("X Accuracy");
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Speed");
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.name).toBe("X Speed");
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("5x Great Ball");
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.name).toBe("5x Great Ball");
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.name).toBe("IV Scanner");
|
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 () => {
|
it("should leave encounter without battle", async () => {
|
||||||
|
@ -363,7 +363,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For any MysteryEncounter that has a battle, can call this to skip battle and proceed to MysteryEncounterRewardsPhase
|
* For any {@linkcode MysteryEncounter} that has a battle, can call this to skip battle and proceed to MysteryEncounterRewardsPhase
|
||||||
* @param game
|
* @param game
|
||||||
* @param isFinalBattle
|
* @param isFinalBattle
|
||||||
*/
|
*/
|
||||||
|
@ -14,6 +14,7 @@ import Overrides from "#app/overrides";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
|
||||||
import { IntegerHolder } from "./../utils";
|
import { IntegerHolder } from "./../utils";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
|
||||||
export const SHOP_OPTIONS_ROW_LIMIT = 6;
|
export const SHOP_OPTIONS_ROW_LIMIT = 6;
|
||||||
|
|
||||||
@ -31,6 +32,10 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
|
|
||||||
private rowCursor: integer = 0;
|
private rowCursor: integer = 0;
|
||||||
private player: boolean;
|
private player: boolean;
|
||||||
|
/**
|
||||||
|
* If reroll cost is negative, it is assumed there are 0 items in the shop.
|
||||||
|
* It will cause reroll button to be disabled, and a "Continue" button to show in the place of shop items
|
||||||
|
*/
|
||||||
private rerollCost: integer;
|
private rerollCost: integer;
|
||||||
private transferButtonWidth: integer;
|
private transferButtonWidth: integer;
|
||||||
private checkButtonWidth: integer;
|
private checkButtonWidth: integer;
|
||||||
@ -111,6 +116,11 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
this.continueButtonContainer.setVisible(false);
|
this.continueButtonContainer.setVisible(false);
|
||||||
ui.add(this.continueButtonContainer);
|
ui.add(this.continueButtonContainer);
|
||||||
|
|
||||||
|
// Create continue button
|
||||||
|
const continueButtonText = addTextObject(this.scene, -24, 5, i18next.t("modifierSelectUiHandler:continueNextWaveButton"), TextStyle.MESSAGE);
|
||||||
|
continueButtonText.setName("text-continue-btn");
|
||||||
|
this.continueButtonContainer.add(continueButtonText);
|
||||||
|
|
||||||
// prepare move overlay
|
// prepare move overlay
|
||||||
const overlayScale = 1;
|
const overlayScale = 1;
|
||||||
this.moveInfoOverlay = new MoveInfoOverlay(this.scene, {
|
this.moveInfoOverlay = new MoveInfoOverlay(this.scene, {
|
||||||
@ -192,12 +202,10 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
this.options.push(option);
|
this.options.push(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add continue button
|
// Set "Continue" button height based on number of rows in healing items shop
|
||||||
if (this.options.length === 0) {
|
const continueButton = this.continueButtonContainer.getAt<Phaser.GameObjects.Text>(0);
|
||||||
const continueButtonText = addTextObject(this.scene, -24, optionsYOffset - 5, i18next.t("modifierSelectUiHandler:continueNextWaveButton"), TextStyle.MESSAGE);
|
continueButton.y = optionsYOffset - 5;
|
||||||
continueButtonText.setName("text-continue-btn");
|
continueButton.setVisible(this.options.length === 0);
|
||||||
this.continueButtonContainer.add(continueButtonText);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let m = 0; m < shopTypeOptions.length; m++) {
|
for (let m = 0; m < shopTypeOptions.length; m++) {
|
||||||
const row = m < SHOP_OPTIONS_ROW_LIMIT ? 0 : 1;
|
const row = m < SHOP_OPTIONS_ROW_LIMIT ? 0 : 1;
|
||||||
@ -265,7 +273,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
this.continueButtonContainer.setAlpha(0);
|
this.continueButtonContainer.setAlpha(0);
|
||||||
this.rerollButtonContainer.setVisible(true);
|
this.rerollButtonContainer.setVisible(true);
|
||||||
this.checkButtonContainer.setVisible(true);
|
this.checkButtonContainer.setVisible(true);
|
||||||
this.continueButtonContainer.setVisible(this.rerollCost === 0);
|
this.continueButtonContainer.setVisible(this.rerollCost < 0);
|
||||||
this.lockRarityButtonContainer.setVisible(canLockRarities);
|
this.lockRarityButtonContainer.setVisible(canLockRarities);
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
@ -276,7 +284,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: [this.rerollButtonContainer],
|
targets: [this.rerollButtonContainer],
|
||||||
alpha: this.rerollCost === 0 ? 0.5 : 1,
|
alpha: this.rerollCost < 0 ? 0.5 : 1,
|
||||||
duration: 250
|
duration: 250
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -537,6 +545,13 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateRerollCostText(): void {
|
updateRerollCostText(): void {
|
||||||
|
const rerollDisabled = this.rerollCost < 0;
|
||||||
|
if (rerollDisabled) {
|
||||||
|
this.rerollCostText.setVisible(false);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.rerollCostText.setVisible(true);
|
||||||
|
}
|
||||||
const canReroll = this.scene.money >= this.rerollCost;
|
const canReroll = this.scene.money >= this.rerollCost;
|
||||||
|
|
||||||
const formattedMoney = Utils.formatMoney(this.scene.moneyFormat, this.rerollCost);
|
const formattedMoney = Utils.formatMoney(this.scene.moneyFormat, this.rerollCost);
|
||||||
|
Loading…
Reference in New Issue
Block a user