mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2024-11-27 17:26:11 +00:00
fix ME null checks and unit tests with beta update
This commit is contained in:
parent
0b698a04a2
commit
39c6c375f8
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
@ -2474,10 +2474,9 @@ export default class BattleScene extends SceneBase {
|
|||||||
modifier.stackCount = stackCount;
|
modifier.stackCount = stackCount;
|
||||||
// TODO: set isTransferable
|
// TODO: set isTransferable
|
||||||
// modifier.setIsTransferable(isTransferable);
|
// modifier.setIsTransferable(isTransferable);
|
||||||
this.addEnemyModifier(modifier, false, true);
|
this.addEnemyModifier(modifier, true);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
|
||||||
const isBoss = enemyPokemon.isBoss() || (this.currentBattle.battleType === BattleType.TRAINER && !!this.currentBattle.trainer?.config.isBoss);
|
const isBoss = enemyPokemon.isBoss() || (this.currentBattle.battleType === BattleType.TRAINER && !!this.currentBattle.trainer?.config.isBoss);
|
||||||
let upgradeChance = 32;
|
let upgradeChance = 32;
|
||||||
if (isBoss) {
|
if (isBoss) {
|
||||||
@ -2501,7 +2500,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance)
|
getEnemyModifierTypesForWave(difficultyWaveIndex, count, [ enemyPokemon ], this.currentBattle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD, upgradeChance)
|
||||||
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this));
|
.map(mt => mt.newModifier(enemyPokemon).add(this.enemyModifiers, false, this));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
this.updateModifiers(false).then(() => resolve());
|
this.updateModifiers(false).then(() => resolve());
|
||||||
@ -2786,7 +2785,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for queued encounters first
|
// Check for queued encounters first
|
||||||
if (!encounter && this.mysteryEncounterData?.nextEncounterQueue?.length > 0) {
|
if (!encounter && this.mysteryEncounterData?.nextEncounterQueue && this.mysteryEncounterData.nextEncounterQueue.length > 0) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < this.mysteryEncounterData.nextEncounterQueue.length && !!encounter) {
|
while (i < this.mysteryEncounterData.nextEncounterQueue.length && !!encounter) {
|
||||||
const candidate = this.mysteryEncounterData.nextEncounterQueue[i];
|
const candidate = this.mysteryEncounterData.nextEncounterQueue[i];
|
||||||
@ -2801,7 +2800,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
|
|
||||||
if (encounter) {
|
if (encounter) {
|
||||||
encounter = new MysteryEncounter(encounter);
|
encounter = new MysteryEncounter(encounter);
|
||||||
encounter.populateDialogueTokensFromRequirements!(this);
|
encounter.populateDialogueTokensFromRequirements(this);
|
||||||
return encounter;
|
return encounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
|
|||||||
scene.field.add(moveAnim.bgSprite);
|
scene.field.add(moveAnim.bgSprite);
|
||||||
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
|
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon();
|
||||||
if (!isNullOrUndefined(priority)) {
|
if (!isNullOrUndefined(priority)) {
|
||||||
scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority);
|
scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority!);
|
||||||
} else if (fieldPokemon?.isOnField()) {
|
} else if (fieldPokemon?.isOnField()) {
|
||||||
scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
|
scene.field.moveBelow(moveAnim.bgSprite as Phaser.GameObjects.GameObject, fieldPokemon);
|
||||||
}
|
}
|
||||||
@ -540,7 +540,7 @@ export function initMoveAnim(scene: BattleScene, move: Moves): Promise<void> {
|
|||||||
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
|
export async function initEncounterAnims(scene: BattleScene, encounterAnim: EncounterAnim | EncounterAnim[]): Promise<void> {
|
||||||
const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim];
|
const anims = Array.isArray(encounterAnim) ? encounterAnim : [encounterAnim];
|
||||||
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
|
const encounterAnimNames = Utils.getEnumKeys(EncounterAnim);
|
||||||
const encounterAnimFetches = [];
|
const encounterAnimFetches: Promise<Map<EncounterAnim, AnimConfig>>[] = [];
|
||||||
for (const anim of anims) {
|
for (const anim of anims) {
|
||||||
if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) {
|
if (encounterAnims.has(anim) && !isNullOrUndefined(encounterAnims.get(anim))) {
|
||||||
continue;
|
continue;
|
||||||
@ -806,7 +806,7 @@ export abstract class BattleAnim {
|
|||||||
play(scene: BattleScene, callback?: Function) {
|
play(scene: BattleScene, callback?: Function) {
|
||||||
const isOppAnim = this.isOppAnim();
|
const isOppAnim = this.isOppAnim();
|
||||||
const user = !isOppAnim ? this.user! : this.target!; // TODO: are those bangs correct?
|
const user = !isOppAnim ? this.user! : this.target!; // TODO: are those bangs correct?
|
||||||
const target = !isOppAnim ? this.target : this.user;
|
const target = !isOppAnim ? this.target! : this.user!;
|
||||||
|
|
||||||
if (!target?.isOnField() && !this.playOnEmptyField) {
|
if (!target?.isOnField() && !this.playOnEmptyField) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -1052,7 +1052,7 @@ export abstract class BattleAnim {
|
|||||||
y += targetInitialY;
|
y += targetInitialY;
|
||||||
const angle = -frame.angle;
|
const angle = -frame.angle;
|
||||||
const key = frame.target === AnimFrameTarget.GRAPHIC ? g++ : frame.target === AnimFrameTarget.USER ? u++ : t++;
|
const key = frame.target === AnimFrameTarget.GRAPHIC ? g++ : frame.target === AnimFrameTarget.USER ? u++ : t++;
|
||||||
ret.get(frame.target).set(key, { x: x, y: y, scaleX: scaleX, scaleY: scaleY, angle: angle });
|
ret.get(frame.target)?.set(key, { x: x, y: y, scaleX: scaleX, scaleY: scaleY, angle: angle });
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1102,17 +1102,17 @@ export abstract class BattleAnim {
|
|||||||
this.srcLine = [ userFocusX, userFocusY, targetFocusX, targetFocusY ];
|
this.srcLine = [ userFocusX, userFocusY, targetFocusX, targetFocusY ];
|
||||||
this.dstLine = [ 150, 75, targetInitialX, targetInitialY ];
|
this.dstLine = [ 150, 75, targetInitialX, targetInitialY ];
|
||||||
|
|
||||||
let r = anim.frames.length;
|
let r = anim!.frames.length;
|
||||||
let f = 0;
|
let f = 0;
|
||||||
|
|
||||||
const existingFieldSprites = [...scene.field.getAll()];
|
const existingFieldSprites = [...scene.field.getAll()];
|
||||||
|
|
||||||
scene.tweens.addCounter({
|
scene.tweens.addCounter({
|
||||||
duration: Utils.getFrameMs(3) * frameTimeMult,
|
duration: Utils.getFrameMs(3) * frameTimeMult,
|
||||||
repeat: anim.frames.length,
|
repeat: anim!.frames.length,
|
||||||
onRepeat: () => {
|
onRepeat: () => {
|
||||||
const spriteFrames = anim.frames[f];
|
const spriteFrames = anim!.frames[f];
|
||||||
const frameData = this.getGraphicFrameDataWithoutTarget(anim.frames[f], targetInitialX, targetInitialY);
|
const frameData = this.getGraphicFrameDataWithoutTarget(anim!.frames[f], targetInitialX, targetInitialY);
|
||||||
const u = 0;
|
const u = 0;
|
||||||
const t = 0;
|
const t = 0;
|
||||||
let g = 0;
|
let g = 0;
|
||||||
@ -1124,7 +1124,7 @@ export abstract class BattleAnim {
|
|||||||
|
|
||||||
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
|
const sprites = spriteCache[AnimFrameTarget.GRAPHIC];
|
||||||
if (g === sprites.length) {
|
if (g === sprites.length) {
|
||||||
const newSprite: Phaser.GameObjects.Sprite = scene.addFieldSprite(0, 0, anim.graphic, 1);
|
const newSprite: Phaser.GameObjects.Sprite = scene.addFieldSprite(0, 0, anim!.graphic, 1);
|
||||||
sprites.push(newSprite);
|
sprites.push(newSprite);
|
||||||
scene.field.add(newSprite);
|
scene.field.add(newSprite);
|
||||||
spritePriorities.push(1);
|
spritePriorities.push(1);
|
||||||
@ -1147,7 +1147,8 @@ export abstract class BattleAnim {
|
|||||||
}
|
}
|
||||||
moveSprite.setFrame(frame.graphicFrame);
|
moveSprite.setFrame(frame.graphicFrame);
|
||||||
|
|
||||||
const graphicFrameData = frameData.get(frame.target).get(graphicIndex);
|
const graphicFrameData = frameData.get(frame.target)?.get(graphicIndex);
|
||||||
|
if (graphicFrameData) {
|
||||||
moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
|
moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
|
||||||
moveSprite.setAngle(graphicFrameData.angle);
|
moveSprite.setAngle(graphicFrameData.angle);
|
||||||
moveSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
|
moveSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
|
||||||
@ -1156,8 +1157,9 @@ export abstract class BattleAnim {
|
|||||||
moveSprite.setVisible(frame.visible);
|
moveSprite.setVisible(frame.visible);
|
||||||
moveSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
|
moveSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
|
||||||
}
|
}
|
||||||
if (anim.frameTimedEvents.has(f)) {
|
}
|
||||||
for (const event of anim.frameTimedEvents.get(f)) {
|
if (anim?.frameTimedEvents.get(f)) {
|
||||||
|
for (const event of anim.frameTimedEvents.get(f)!) {
|
||||||
r = Math.max((anim.frames.length - f) + event.execute(scene, this, frameTimedEventPriority), r);
|
r = Math.max((anim.frames.length - f) + event.execute(scene, this, frameTimedEventPriority), r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1277,8 +1279,8 @@ export class EncounterBattleAnim extends BattleAnim {
|
|||||||
this.oppAnim = oppAnim ?? false;
|
this.oppAnim = oppAnim ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAnim(): AnimConfig {
|
getAnim(): AnimConfig | null {
|
||||||
return encounterAnims.get(this.encounterAnim);
|
return encounterAnims.get(this.encounterAnim) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isOppAnim(): boolean {
|
isOppAnim(): boolean {
|
||||||
|
@ -86,7 +86,7 @@ export class Egg {
|
|||||||
|
|
||||||
private _overrideHiddenAbility: boolean;
|
private _overrideHiddenAbility: boolean;
|
||||||
|
|
||||||
private _eventEggTypeDescriptor: string;
|
private _eventEggTypeDescriptor?: string;
|
||||||
|
|
||||||
////
|
////
|
||||||
// #endregion
|
// #endregion
|
||||||
@ -186,7 +186,7 @@ export class Egg {
|
|||||||
this.addEggToGameData(eggOptions.scene!); // TODO: is this bang correct?
|
this.addEggToGameData(eggOptions.scene!); // TODO: is this bang correct?
|
||||||
}
|
}
|
||||||
|
|
||||||
this._eventEggTypeDescriptor = eggOptions.eventEggTypeDescriptor ?? null;
|
this._eventEggTypeDescriptor = eggOptions?.eventEggTypeDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
////
|
////
|
||||||
|
@ -76,13 +76,13 @@ export const ATrainersTestEncounter: MysteryEncounter =
|
|||||||
text: `${namespace}.${trainerNameKey}.intro_dialogue`
|
text: `${namespace}.${trainerNameKey}.intro_dialogue`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
encounter.options[0].dialogue.selected = [
|
encounter.options[0].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `trainerNames:${trainerNameKey}`,
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
text: `${namespace}.${trainerNameKey}.accept`
|
text: `${namespace}.${trainerNameKey}.accept`
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
encounter.options[1].dialogue.selected = [
|
encounter.options[1].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
speaker: `trainerNames:${trainerNameKey}`,
|
speaker: `trainerNames:${trainerNameKey}`,
|
||||||
text: `${namespace}.${trainerNameKey}.decline`
|
text: `${namespace}.${trainerNameKey}.decline`
|
||||||
|
@ -22,6 +22,7 @@ import { applyModifierTypeToPlayerPokemon, catchPokemon, getHighestLevelPlayerPo
|
|||||||
import { TrainerSlot } from "#app/data/trainer-config";
|
import { TrainerSlot } from "#app/data/trainer-config";
|
||||||
import { PokeballType } from "#app/data/pokeball";
|
import { PokeballType } from "#app/data/pokeball";
|
||||||
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
|
import { BerryType } from "#enums/berry-type";
|
||||||
|
|
||||||
/** the i18n namespace for this encounter */
|
/** the i18n namespace for this encounter */
|
||||||
const namespace = "mysteryEncounter:absoluteAvarice";
|
const namespace = "mysteryEncounter:absoluteAvarice";
|
||||||
@ -39,8 +40,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
// This sprite has the shadow
|
// This sprite has the shadow
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.GREEDENT,
|
species: Species.GREEDENT,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
alpha: 0.001,
|
alpha: 0.001,
|
||||||
@ -48,8 +49,8 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
x: -5
|
x: -5
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.GREEDENT,
|
species: Species.GREEDENT,
|
||||||
hasShadow: false,
|
hasShadow: false,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
@ -254,7 +255,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
queueEncounterMessage(scene, `${namespace}.option.1.food_stash`);
|
queueEncounterMessage(scene, `${namespace}.option.1.food_stash`);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true }, null, givePartyPokemonReviverSeeds);
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, givePartyPokemonReviverSeeds);
|
||||||
encounter.startOfBattleEffects.push({
|
encounter.startOfBattleEffects.push({
|
||||||
sourceBattlerIndex: BattlerIndex.ENEMY,
|
sourceBattlerIndex: BattlerIndex.ENEMY,
|
||||||
targets: [BattlerIndex.ENEMY],
|
targets: [BattlerIndex.ENEMY],
|
||||||
@ -287,7 +288,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
party.forEach(pokemon => {
|
party.forEach(pokemon => {
|
||||||
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
|
const stolenBerries: BerryModifier[] = berryMap.get(pokemon.id);
|
||||||
const berryTypesAsArray = [];
|
const berryTypesAsArray: BerryType[] = [];
|
||||||
stolenBerries?.forEach(bMod => berryTypesAsArray.push(...new Array(bMod.stackCount).fill(bMod.berryType)));
|
stolenBerries?.forEach(bMod => berryTypesAsArray.push(...new Array(bMod.stackCount).fill(bMod.berryType)));
|
||||||
const returnedBerryCount = Math.floor((berryTypesAsArray.length ?? 0) * 2 / 5);
|
const returnedBerryCount = Math.floor((berryTypesAsArray.length ?? 0) * 2 / 5);
|
||||||
|
|
||||||
@ -330,7 +331,7 @@ export const AbsoluteAvariceEncounter: MysteryEncounter =
|
|||||||
// Let it have the food
|
// Let it have the food
|
||||||
// Greedent joins the team, level equal to 2 below highest party member
|
// Greedent joins the team, level equal to 2 below highest party member
|
||||||
const level = getHighestLevelPlayerPokemon(scene).level - 2;
|
const level = getHighestLevelPlayerPokemon(scene).level - 2;
|
||||||
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false, null);
|
const greedent = new EnemyPokemon(scene, getPokemonSpecies(Species.GREEDENT), level, TrainerSlot.NONE, false);
|
||||||
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
greedent.moveset = [new PokemonMove(Moves.THRASH), new PokemonMove(Moves.BODY_PRESS), new PokemonMove(Moves.STUFF_CHEEKS), new PokemonMove(Moves.SLACK_OFF)];
|
||||||
greedent.passive = true;
|
greedent.passive = true;
|
||||||
|
|
||||||
@ -346,7 +347,7 @@ function doGreedentSpriteSteal(scene: BattleScene) {
|
|||||||
const shakeDelay = 50;
|
const shakeDelay = 50;
|
||||||
const slideDelay = 500;
|
const slideDelay = 500;
|
||||||
|
|
||||||
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1);
|
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals?.getSpriteAtIndex(1);
|
||||||
|
|
||||||
scene.playSound("Follow Me");
|
scene.playSound("Follow Me");
|
||||||
scene.tweens.chain({
|
scene.tweens.chain({
|
||||||
@ -420,7 +421,7 @@ function doGreedentSpriteSteal(scene: BattleScene) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doGreedentEatBerries(scene: BattleScene) {
|
function doGreedentEatBerries(scene: BattleScene) {
|
||||||
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals.getSpriteAtIndex(1);
|
const greedentSprites = scene.currentBattle.mysteryEncounter.introVisuals?.getSpriteAtIndex(1);
|
||||||
let index = 1;
|
let index = 1;
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: greedentSprites,
|
targets: greedentSprites,
|
||||||
@ -455,7 +456,12 @@ function doBerrySpritePile(scene: BattleScene, isEat: boolean = false) {
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
animationOrder.forEach((berry, i) => {
|
animationOrder.forEach((berry, i) => {
|
||||||
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
|
const introVisualsIndex = encounter.spriteConfigs.findIndex(config => config.spriteKey?.includes(berry));
|
||||||
const [ sprite, tintSprite ] = encounter.introVisuals.getSpriteAtIndex(introVisualsIndex);
|
let sprite: Phaser.GameObjects.Sprite, tintSprite: Phaser.GameObjects.Sprite;
|
||||||
|
const sprites = encounter.introVisuals?.getSpriteAtIndex(introVisualsIndex);
|
||||||
|
if (sprites) {
|
||||||
|
sprite = sprites[0];
|
||||||
|
tintSprite = sprites[1];
|
||||||
|
}
|
||||||
scene.time.delayedCall(berryAddDelay * i + 400, () => {
|
scene.time.delayedCall(berryAddDelay * i + 400, () => {
|
||||||
if (sprite) {
|
if (sprite) {
|
||||||
sprite.setVisible(!isEat);
|
sprite.setVisible(!isEat);
|
||||||
|
@ -136,7 +136,7 @@ export const AnOfferYouCantRefuseEncounter: MysteryEncounter =
|
|||||||
// Update money and remove pokemon from party
|
// Update money and remove pokemon from party
|
||||||
updatePlayerMoney(scene, encounter.misc.price);
|
updatePlayerMoney(scene, encounter.misc.price);
|
||||||
|
|
||||||
setEncounterExp(scene, encounter.options[1].primaryPokemon.id, getPokemonSpecies(Species.LIEPARD).baseExp, true);
|
setEncounterExp(scene, encounter.options[1].primaryPokemon!.id, getPokemonSpecies(Species.LIEPARD).baseExp, true);
|
||||||
|
|
||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
})
|
})
|
||||||
|
@ -146,7 +146,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
||||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true, null);
|
const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true);
|
||||||
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon));
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
levelAdditiveMultiplier: 1,
|
levelAdditiveMultiplier: 1,
|
||||||
@ -222,7 +222,7 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
shopOptions.push(generateModifierTypeOption(scene, modifierTypes.BERRY));
|
shopOptions.push(generateModifierTypeOption(scene, modifierTypes.BERRY));
|
||||||
}
|
}
|
||||||
|
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doBerryRewards);
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]);
|
await initBattleWithEnemyConfig(scene, scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0]);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -262,12 +262,12 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const config = scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
const config = scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
||||||
config.pokemonConfigs[0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
|
config.pokemonConfigs![0].tags = [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON];
|
||||||
config.pokemonConfigs[0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
config.pokemonConfigs![0].mysteryEncounterBattleEffects = (pokemon: Pokemon) => {
|
||||||
queueEncounterMessage(pokemon.scene, `${namespace}.option.2.boss_enraged`);
|
queueEncounterMessage(pokemon.scene, `${namespace}.option.2.boss_enraged`);
|
||||||
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1));
|
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1));
|
||||||
};
|
};
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doBerryRewards);
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doBerryRewards);
|
||||||
await showEncounterText(scene, `${namespace}.option.2.selected_bad`);
|
await showEncounterText(scene, `${namespace}.option.2.selected_bad`);
|
||||||
await initBattleWithEnemyConfig(scene, config);
|
await initBattleWithEnemyConfig(scene, config);
|
||||||
return;
|
return;
|
||||||
@ -287,8 +287,8 @@ export const BerriesAboundEncounter: MysteryEncounter =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp);
|
setEncounterExp(scene, fastestPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, null, doFasterBerryRewards);
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: shopOptions, fillRemaining: false }, undefined, doFasterBerryRewards);
|
||||||
await showEncounterText(scene, `${namespace}.option.2.selected`);
|
await showEncounterText(scene, `${namespace}.option.2.selected`);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { EnemyPartyConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, selectPokemonForOption, setEncounterRewards, transitionMysteryEncounterIntroVisuals, } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import { EnemyPartyConfig, generateModifierType, initBattleWithEnemyConfig, leaveEncounterWithoutBattle, loadCustomMovesForEncounter, selectPokemonForOption, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { trainerConfigs, TrainerPartyCompoundTemplate, TrainerPartyTemplate, } from "#app/data/trainer-config";
|
import { trainerConfigs, TrainerPartyCompoundTemplate, TrainerPartyTemplate, } from "#app/data/trainer-config";
|
||||||
import { ModifierTier } from "#app/modifier/modifier-tier";
|
import { ModifierTier } from "#app/modifier/modifier-tier";
|
||||||
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
||||||
@ -28,7 +28,6 @@ import { BattlerIndex } from "#app/battle";
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { EncounterAnim, EncounterBattleAnim } from "#app/data/battle-anims";
|
import { EncounterAnim, 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";
|
|
||||||
|
|
||||||
/** the i18n namespace for the encounter */
|
/** the i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:clowningAround";
|
const namespace = "mysteryEncounter:clowningAround";
|
||||||
@ -129,7 +128,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
|
{ // Blacephalon has the random ability from pool, and 2 entirely random types to fit with the theme of the encounter
|
||||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||||
mysteryEncounterData: new MysteryEncounterPokemonData(null, ability, null, [randSeedInt(18), randSeedInt(18)]),
|
mysteryEncounterData: new MysteryEncounterPokemonData(undefined, ability, undefined, [randSeedInt(18), randSeedInt(18)]),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
||||||
},
|
},
|
||||||
@ -206,7 +205,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
duration: 250
|
duration: 250
|
||||||
});
|
});
|
||||||
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon(), scene.getPlayerPokemon());
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
background.playWithoutTargets(scene, 230, 40, 2);
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
@ -292,7 +291,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withPostOptionPhase(async (scene: BattleScene) => {
|
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||||
// Play animations
|
// Play animations
|
||||||
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon(), scene.getPlayerPokemon());
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
background.playWithoutTargets(scene, 230, 40, 2);
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
await transitionMysteryEncounterIntroVisuals(scene);
|
await transitionMysteryEncounterIntroVisuals(scene);
|
||||||
})
|
})
|
||||||
@ -327,8 +326,8 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
// If the Pokemon has non-status moves that don't match the Pokemon's type, prioritizes those as the new type
|
// If the Pokemon has non-status moves that don't match the Pokemon's type, prioritizes those as the new type
|
||||||
// Makes the "randomness" of the shuffle slightly less punishing
|
// Makes the "randomness" of the shuffle slightly less punishing
|
||||||
let priorityTypes = pokemon.moveset
|
let priorityTypes = pokemon.moveset
|
||||||
.filter(move => !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
|
.filter(move => move && !originalTypes.includes(move.getMove().type) && move.getMove().category !== MoveCategory.STATUS)
|
||||||
.map(move => move.getMove().type);
|
.map(move => move!.getMove().type);
|
||||||
if (priorityTypes?.length > 0) {
|
if (priorityTypes?.length > 0) {
|
||||||
priorityTypes = [...new Set(priorityTypes)];
|
priorityTypes = [...new Set(priorityTypes)];
|
||||||
randSeedShuffle(priorityTypes);
|
randSeedShuffle(priorityTypes);
|
||||||
@ -350,7 +349,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pokemon.mysteryEncounterData) {
|
if (!pokemon.mysteryEncounterData) {
|
||||||
pokemon.mysteryEncounterData = new MysteryEncounterPokemonData(null, null, null, newTypes);
|
pokemon.mysteryEncounterData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||||
} else {
|
} else {
|
||||||
pokemon.mysteryEncounterData.types = newTypes;
|
pokemon.mysteryEncounterData.types = newTypes;
|
||||||
}
|
}
|
||||||
@ -361,7 +360,7 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withPostOptionPhase(async (scene: BattleScene) => {
|
.withPostOptionPhase(async (scene: BattleScene) => {
|
||||||
// Play animations
|
// Play animations
|
||||||
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon(), scene.getPlayerPokemon());
|
const background = new EncounterBattleAnim(EncounterAnim.SMOKESCREEN, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
background.playWithoutTargets(scene, 230, 40, 2);
|
background.playWithoutTargets(scene, 230, 40, 2);
|
||||||
await transitionMysteryEncounterIntroVisuals(scene);
|
await transitionMysteryEncounterIntroVisuals(scene);
|
||||||
})
|
})
|
||||||
@ -441,8 +440,7 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
|
|||||||
[modifierTypes.GOLDEN_PUNCH, 5],
|
[modifierTypes.GOLDEN_PUNCH, 5],
|
||||||
[modifierTypes.ATTACK_TYPE_BOOSTER, 99],
|
[modifierTypes.ATTACK_TYPE_BOOSTER, 99],
|
||||||
[modifierTypes.QUICK_CLAW, 3],
|
[modifierTypes.QUICK_CLAW, 3],
|
||||||
[modifierTypes.WIDE_LENS, 3],
|
[modifierTypes.WIDE_LENS, 3]
|
||||||
[modifierTypes.WHITE_HERB, 2]
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const roguePool = [
|
const roguePool = [
|
||||||
@ -450,7 +448,7 @@ function generateItemsOfTier(scene: BattleScene, pokemon: PlayerPokemon, numItem
|
|||||||
[modifierTypes.SHELL_BELL, 4],
|
[modifierTypes.SHELL_BELL, 4],
|
||||||
[modifierTypes.SOUL_DEW, 10],
|
[modifierTypes.SOUL_DEW, 10],
|
||||||
[modifierTypes.SOOTHE_BELL, 3],
|
[modifierTypes.SOOTHE_BELL, 3],
|
||||||
[modifierTypes.SCOPE_LENS, 5],
|
[modifierTypes.SCOPE_LENS, 1],
|
||||||
[modifierTypes.BATON, 1],
|
[modifierTypes.BATON, 1],
|
||||||
[modifierTypes.FOCUS_BAND, 5],
|
[modifierTypes.FOCUS_BAND, 5],
|
||||||
[modifierTypes.KINGS_ROCK, 3],
|
[modifierTypes.KINGS_ROCK, 3],
|
||||||
|
@ -87,7 +87,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
.withAutoHideIntroVisuals(false)
|
.withAutoHideIntroVisuals(false)
|
||||||
.withCatchAllowed(true)
|
.withCatchAllowed(true)
|
||||||
.withOnVisualsStart((scene: BattleScene) => {
|
.withOnVisualsStart((scene: BattleScene) => {
|
||||||
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon(), scene.getPlayerPokemon());
|
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getPlayerPokemon());
|
||||||
danceAnim.play(scene);
|
danceAnim.play(scene);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -104,8 +104,8 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
|
|
||||||
const species = getPokemonSpecies(Species.ORICORIO);
|
const species = getPokemonSpecies(Species.ORICORIO);
|
||||||
const enemyPokemon = scene.addEnemyPokemon(species, scene.currentBattle.enemyLevels[0], TrainerSlot.NONE, false);
|
const enemyPokemon = scene.addEnemyPokemon(species, scene.currentBattle.enemyLevels![0], TrainerSlot.NONE, false);
|
||||||
if (!enemyPokemon.moveset.some(m => m.getMove().id === Moves.REVELATION_DANCE)) {
|
if (!enemyPokemon.moveset.some(m => m && m.getMove().id === Moves.REVELATION_DANCE)) {
|
||||||
if (enemyPokemon.moveset.length < 4) {
|
if (enemyPokemon.moveset.length < 4) {
|
||||||
enemyPokemon.moveset.push(new PokemonMove(Moves.REVELATION_DANCE));
|
enemyPokemon.moveset.push(new PokemonMove(Moves.REVELATION_DANCE));
|
||||||
} else {
|
} else {
|
||||||
@ -206,7 +206,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
scene.unshiftPhase(new LearnMovePhase(scene, scene.getParty().indexOf(pokemon), Moves.REVELATION_DANCE));
|
scene.unshiftPhase(new LearnMovePhase(scene, scene.getParty().indexOf(pokemon), Moves.REVELATION_DANCE));
|
||||||
|
|
||||||
// Play animation again to "learn" the dance
|
// Play animation again to "learn" the dance
|
||||||
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon(), scene.getPlayerPokemon());
|
const danceAnim = new EncounterBattleAnim(EncounterAnim.DANCE, scene.getEnemyPokemon()!, scene.getPlayerPokemon());
|
||||||
danceAnim.play(scene);
|
danceAnim.play(scene);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||||
// Return the options for nature selection
|
// Return the options for nature selection
|
||||||
return pokemon.moveset
|
return pokemon.moveset
|
||||||
.filter(move => DANCING_MOVES.includes(move.getMove().id))
|
.filter(move => move && DANCING_MOVES.includes(move.getMove().id))
|
||||||
.map((move: PokemonMove) => {
|
.map((move: PokemonMove) => {
|
||||||
const option: OptionSelectItem = {
|
const option: OptionSelectItem = {
|
||||||
label: move.getName(),
|
label: move.getName(),
|
||||||
@ -261,13 +261,13 @@ export const DancingLessonsEncounter: MysteryEncounter =
|
|||||||
// If pokemon meets primary pokemon reqs, it can be selected
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Show the Oricorio a dance, and recruit it
|
// Show the Oricorio a dance, and recruit it
|
||||||
|
@ -47,8 +47,8 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
))
|
))
|
||||||
.withIntroSpriteConfigs([
|
.withIntroSpriteConfigs([
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.DELIBIRD,
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
@ -56,16 +56,16 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
scale: 0.94
|
scale: 0.94
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.DELIBIRD,
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
scale: 1.06
|
scale: 1.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.DELIBIRD,
|
species: Species.DELIBIRD,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
@ -116,7 +116,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||||
} else {
|
} else {
|
||||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ABILITY_CHARM));
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.ABILITY_CHARM));
|
||||||
}
|
}
|
||||||
@ -169,13 +169,13 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
// If pokemon meets primary pokemon reqs, it can be selected
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[1].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
@ -191,7 +191,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||||
} else {
|
} else {
|
||||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.CANDY_JAR));
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.CANDY_JAR));
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||||
} else {
|
} else {
|
||||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM));
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.HEALING_CHARM));
|
||||||
}
|
}
|
||||||
@ -264,13 +264,13 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
// If pokemon meets primary pokemon reqs, it can be selected
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.options[2].pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
@ -284,7 +284,7 @@ export const DelibirdyEncounter: MysteryEncounter =
|
|||||||
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
const shellBell = generateModifierType(scene, modifierTypes.SHELL_BELL) as PokemonHeldItemModifierType;
|
||||||
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
await applyModifierTypeToPlayerPokemon(scene, scene.getParty()[0], shellBell);
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: shellBell.name }), undefined, true);
|
||||||
} else {
|
} else {
|
||||||
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH));
|
scene.unshiftPhase(new ModifierRewardPhase(scene, modifierTypes.BERRY_POUCH));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import {
|
|||||||
leaveEncounterWithoutBattle,
|
leaveEncounterWithoutBattle,
|
||||||
setEncounterRewards,
|
setEncounterRewards,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { modifierTypes } from "#app/modifier/modifier-type";
|
import { ModifierTypeFunc, modifierTypes } from "#app/modifier/modifier-type";
|
||||||
import { randSeedInt } from "#app/utils";
|
import { randSeedInt } from "#app/utils";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
@ -32,8 +32,8 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
x: -20,
|
x: -20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.FURFROU,
|
species: Species.FURFROU,
|
||||||
hasShadow: true,
|
hasShadow: true,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
@ -60,7 +60,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose TMs
|
// Choose TMs
|
||||||
const modifiers = [];
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 4) {
|
while (i < 4) {
|
||||||
// 2/2/1 weight on TM rarity
|
// 2/2/1 weight on TM rarity
|
||||||
@ -86,7 +86,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose Vitamins
|
// Choose Vitamins
|
||||||
const modifiers = [];
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 3) {
|
while (i < 3) {
|
||||||
// 2/1 weight on base stat booster vs PP Up
|
// 2/1 weight on base stat booster vs PP Up
|
||||||
@ -110,7 +110,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose X Items
|
// Choose X Items
|
||||||
const modifiers = [];
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 5) {
|
while (i < 5) {
|
||||||
// 4/1 weight on base stat booster vs Dire Hit
|
// 4/1 weight on base stat booster vs Dire Hit
|
||||||
@ -134,7 +134,7 @@ export const DepartmentStoreSaleEncounter: MysteryEncounter =
|
|||||||
},
|
},
|
||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Choose Pokeballs
|
// Choose Pokeballs
|
||||||
const modifiers = [];
|
const modifiers: ModifierTypeFunc[] = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < 4) {
|
while (i < 4) {
|
||||||
// 10/30/20/5 weight on pokeballs
|
// 10/30/20/5 weight on pokeballs
|
||||||
|
@ -78,7 +78,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const correctMove = move.getMove().category === MoveCategory.PHYSICAL;
|
const correctMove = move.getMove().category === MoveCategory.PHYSICAL;
|
||||||
encounter.setDialogueToken("moveCategory", "Physical");
|
encounter.setDialogueToken("moveCategory", "Physical");
|
||||||
if (!correctMove) {
|
if (!correctMove) {
|
||||||
encounter.options[0].dialogue.selected = [
|
encounter.options[0].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.incorrect`,
|
text: `${namespace}.option.incorrect`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}.speaker`,
|
||||||
@ -97,7 +97,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
} else {
|
} else {
|
||||||
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
||||||
encounter.setDialogueToken("move", move.getName());
|
encounter.setDialogueToken("move", move.getName());
|
||||||
encounter.options[0].dialogue.selected = [
|
encounter.options[0].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}.option.selected`,
|
||||||
},
|
},
|
||||||
@ -164,7 +164,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const correctMove = move.getMove().category === MoveCategory.SPECIAL;
|
const correctMove = move.getMove().category === MoveCategory.SPECIAL;
|
||||||
encounter.setDialogueToken("moveCategory", "Special");
|
encounter.setDialogueToken("moveCategory", "Special");
|
||||||
if (!correctMove) {
|
if (!correctMove) {
|
||||||
encounter.options[1].dialogue.selected = [
|
encounter.options[1].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.incorrect`,
|
text: `${namespace}.option.incorrect`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}.speaker`,
|
||||||
@ -189,7 +189,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
} else {
|
} else {
|
||||||
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
||||||
encounter.setDialogueToken("move", move.getName());
|
encounter.setDialogueToken("move", move.getName());
|
||||||
encounter.options[1].dialogue.selected = [
|
encounter.options[1].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}.option.selected`,
|
||||||
},
|
},
|
||||||
@ -256,7 +256,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
const correctMove = move.getMove().category === MoveCategory.STATUS;
|
const correctMove = move.getMove().category === MoveCategory.STATUS;
|
||||||
encounter.setDialogueToken("moveCategory", "Status");
|
encounter.setDialogueToken("moveCategory", "Status");
|
||||||
if (!correctMove) {
|
if (!correctMove) {
|
||||||
encounter.options[2].dialogue.selected = [
|
encounter.options[2].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.incorrect`,
|
text: `${namespace}.option.incorrect`,
|
||||||
speaker: `${namespace}.speaker`,
|
speaker: `${namespace}.speaker`,
|
||||||
@ -275,7 +275,7 @@ export const FieldTripEncounter: MysteryEncounter =
|
|||||||
} else {
|
} else {
|
||||||
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
encounter.setDialogueToken("pokeName", pokemon.getNameToRender());
|
||||||
encounter.setDialogueToken("move", move.getName());
|
encounter.setDialogueToken("move", move.getName());
|
||||||
encounter.options[2].dialogue.selected = [
|
encounter.options[2].dialogue!.selected = [
|
||||||
{
|
{
|
||||||
text: `${namespace}.option.selected`,
|
text: `${namespace}.option.selected`,
|
||||||
},
|
},
|
||||||
|
@ -75,8 +75,8 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
// Load hidden Volcarona sprites
|
// Load hidden Volcarona sprites
|
||||||
encounter.spriteConfigs = [
|
encounter.spriteConfigs = [
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.VOLCARONA,
|
species: Species.VOLCARONA,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
@ -85,8 +85,8 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
startFrame: 20
|
startFrame: 20
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spriteKey: null,
|
spriteKey: "",
|
||||||
fileRoot: null,
|
fileRoot: "",
|
||||||
species: Species.VOLCARONA,
|
species: Species.VOLCARONA,
|
||||||
repeat: true,
|
repeat: true,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
@ -104,9 +104,9 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withOnVisualsStart((scene: BattleScene) => {
|
.withOnVisualsStart((scene: BattleScene) => {
|
||||||
// Play animations
|
// Play animations
|
||||||
const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, scene.getPlayerPokemon(), scene.getPlayerPokemon());
|
const background = new EncounterBattleAnim(EncounterAnim.MAGMA_BG, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
background.playWithoutTargets(scene, 200, 70, 2, 3);
|
background.playWithoutTargets(scene, 200, 70, 2, 3);
|
||||||
const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, scene.getPlayerPokemon(), scene.getPlayerPokemon());
|
const animation = new EncounterBattleAnim(EncounterAnim.MAGMA_SPOUT, scene.getPlayerPokemon()!, scene.getPlayerPokemon());
|
||||||
animation.playWithoutTargets(scene, 80, 100, 2);
|
animation.playWithoutTargets(scene, 80, 100, 2);
|
||||||
scene.time.delayedCall(600, () => {
|
scene.time.delayedCall(600, () => {
|
||||||
animation.playWithoutTargets(scene, -20, 100, 2);
|
animation.playWithoutTargets(scene, -20, 100, 2);
|
||||||
@ -133,7 +133,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
async (scene: BattleScene) => {
|
async (scene: BattleScene) => {
|
||||||
// Pick battle
|
// Pick battle
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
setEncounterRewards(scene, { fillRemaining: true }, null, () => giveLeadPokemonCharcoal(scene));
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, () => giveLeadPokemonCharcoal(scene));
|
||||||
|
|
||||||
encounter.startOfBattleEffects.push(
|
encounter.startOfBattleEffects.push(
|
||||||
{
|
{
|
||||||
@ -185,7 +185,7 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Burn random member
|
// Burn random member
|
||||||
const burnable = nonFireTypes.filter(p => isNullOrUndefined(p.status) || isNullOrUndefined(p.status.effect) || p.status?.effect === StatusEffect.BURN);
|
const burnable = nonFireTypes.filter(p => isNullOrUndefined(p.status) || isNullOrUndefined(p.status!.effect) || p.status?.effect === StatusEffect.BURN);
|
||||||
if (burnable?.length > 0) {
|
if (burnable?.length > 0) {
|
||||||
const roll = randSeedInt(burnable.length);
|
const roll = randSeedInt(burnable.length);
|
||||||
const chosenPokemon = burnable[roll];
|
const chosenPokemon = burnable[roll];
|
||||||
@ -224,13 +224,13 @@ export const FieryFalloutEncounter: MysteryEncounter =
|
|||||||
transitionMysteryEncounterIntroVisuals(scene);
|
transitionMysteryEncounterIntroVisuals(scene);
|
||||||
setEncounterRewards(scene,
|
setEncounterRewards(scene,
|
||||||
{ fillRemaining: true },
|
{ fillRemaining: true },
|
||||||
null,
|
undefined,
|
||||||
() => {
|
() => {
|
||||||
giveLeadPokemonCharcoal(scene);
|
giveLeadPokemonCharcoal(scene);
|
||||||
});
|
});
|
||||||
|
|
||||||
const primary = encounter.options[2].primaryPokemon;
|
const primary = encounter.options[2].primaryPokemon!;
|
||||||
const secondary = encounter.options[2].secondaryPokemon[0];
|
const secondary = encounter.options[2].secondaryPokemon![0];
|
||||||
|
|
||||||
setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
|
setEncounterExp(scene, [primary.id, secondary.id], getPokemonSpecies(Species.VOLCARONA).baseExp * 2);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
|
@ -50,7 +50,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Calculate boss mon
|
// Calculate boss mon
|
||||||
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, scene.currentBattle.waveIndex, 0, getPartyLuckValue(scene.getParty()), true);
|
||||||
const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true, null);
|
const bossPokemon = new EnemyPokemon(scene, bossSpecies, scene.currentBattle.waveIndex, TrainerSlot.NONE, true);
|
||||||
const config: EnemyPartyConfig = {
|
const config: EnemyPartyConfig = {
|
||||||
levelAdditiveMultiplier: 1,
|
levelAdditiveMultiplier: 1,
|
||||||
pokemonConfigs: [{
|
pokemonConfigs: [{
|
||||||
@ -72,7 +72,7 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
? ModifierTier.ULTRA
|
? ModifierTier.ULTRA
|
||||||
: ModifierTier.GREAT;
|
: ModifierTier.GREAT;
|
||||||
regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0);
|
regenerateModifierPoolThresholds(scene.getParty(), ModifierPoolType.PLAYER, 0);
|
||||||
let item: ModifierTypeOption;
|
let item: ModifierTypeOption | null = null;
|
||||||
// TMs excluded from possible rewards as they're too swingy in value for a singular item reward
|
// TMs excluded from possible rewards as they're too swingy in value for a singular item reward
|
||||||
while (!item || item.type.id.includes("TM_")) {
|
while (!item || item.type.id.includes("TM_")) {
|
||||||
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
|
item = getPlayerModifierTypeOptions(1, scene.getParty(), [], { guaranteedModifierTiers: [tier], allowLuckUpgrades: false })[0];
|
||||||
@ -147,8 +147,8 @@ export const FightOrFlightEncounter: MysteryEncounter =
|
|||||||
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeOptions: [item], fillRemaining: false });
|
||||||
|
|
||||||
// Use primaryPokemon to execute the thievery
|
// Use primaryPokemon to execute the thievery
|
||||||
const primaryPokemon = encounter.options[1].primaryPokemon;
|
const primaryPokemon = encounter.options[1].primaryPokemon!;
|
||||||
setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs[0].species.baseExp);
|
setEncounterExp(scene, primaryPokemon.id, encounter.enemyPartyConfigs[0].pokemonConfigs![0].species.baseExp);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
@ -87,6 +87,7 @@ export const MysteriousChallengersEncounter: MysteryEncounter =
|
|||||||
const e4Template = trainerPartyTemplates.ELITE_FOUR;
|
const e4Template = trainerPartyTemplates.ELITE_FOUR;
|
||||||
const brutalConfig = trainerConfigs[brutalTrainerType].copy();
|
const brutalConfig = trainerConfigs[brutalTrainerType].copy();
|
||||||
brutalConfig.setPartyTemplates(e4Template);
|
brutalConfig.setPartyTemplates(e4Template);
|
||||||
|
// @ts-ignore
|
||||||
brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func
|
brutalConfig.partyTemplateFunc = null; // Overrides gym leader party template func
|
||||||
female = false;
|
female = false;
|
||||||
if (brutalConfig.hasGenders) {
|
if (brutalConfig.hasGenders) {
|
||||||
|
@ -57,7 +57,7 @@ export const MysteriousChestEncounter: MysteryEncounter =
|
|||||||
.withPreOptionPhase(async (scene: BattleScene) => {
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
// Play animation
|
// Play animation
|
||||||
const introVisuals =
|
const introVisuals =
|
||||||
scene.currentBattle.mysteryEncounter.introVisuals;
|
scene.currentBattle.mysteryEncounter.introVisuals!;
|
||||||
introVisuals.spriteConfigs[0].disableAnimation = false;
|
introVisuals.spriteConfigs[0].disableAnimation = false;
|
||||||
introVisuals.playAnim();
|
introVisuals.playAnim();
|
||||||
})
|
})
|
||||||
|
@ -100,8 +100,10 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Reduce all PP to 2 (if they started at greater than 2)
|
// Reduce all PP to 2 (if they started at greater than 2)
|
||||||
pokemon.moveset.forEach(move => {
|
pokemon.moveset.forEach(move => {
|
||||||
|
if (move) {
|
||||||
const newPpUsed = move.getMovePp() - 2;
|
const newPpUsed = move.getMovePp() - 2;
|
||||||
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setEncounterExp(scene, pokemon.id, 100);
|
setEncounterExp(scene, pokemon.id, 100);
|
||||||
@ -115,13 +117,13 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
// Only Pokemon non-KOd pokemon can be selected
|
// Only Pokemon non-KOd pokemon can be selected
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
if (!pokemon.isAllowedInBattle()) {
|
if (!pokemon.isAllowedInBattle()) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Pick Deliveries
|
// Pick Deliveries
|
||||||
@ -179,8 +181,10 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
|
|
||||||
// Reduce all PP to 2 (if they started at greater than 2)
|
// Reduce all PP to 2 (if they started at greater than 2)
|
||||||
pokemon.moveset.forEach(move => {
|
pokemon.moveset.forEach(move => {
|
||||||
|
if (move) {
|
||||||
const newPpUsed = move.getMovePp() - 2;
|
const newPpUsed = move.getMovePp() - 2;
|
||||||
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setEncounterExp(scene, pokemon.id, 100);
|
setEncounterExp(scene, pokemon.id, 100);
|
||||||
@ -194,13 +198,13 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
// Only Pokemon non-KOd pokemon can be selected
|
// Only Pokemon non-KOd pokemon can be selected
|
||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
if (!pokemon.isAllowedInBattle()) {
|
if (!pokemon.isAllowedInBattle()) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Pick Move Warehouse items
|
// Pick Move Warehouse items
|
||||||
@ -241,13 +245,15 @@ export const PartTimerEncounter: MysteryEncounter =
|
|||||||
})
|
})
|
||||||
.withPreOptionPhase(async (scene: BattleScene) => {
|
.withPreOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
const selectedPokemon = encounter.selectedOption.primaryPokemon;
|
const selectedPokemon = encounter.selectedOption?.primaryPokemon!;
|
||||||
encounter.setDialogueToken("selectedPokemon", selectedPokemon.getNameToRender());
|
encounter.setDialogueToken("selectedPokemon", selectedPokemon.getNameToRender());
|
||||||
|
|
||||||
// Reduce all PP to 2 (if they started at greater than 2)
|
// Reduce all PP to 2 (if they started at greater than 2)
|
||||||
selectedPokemon.moveset.forEach(move => {
|
selectedPokemon.moveset.forEach(move => {
|
||||||
|
if (move) {
|
||||||
const newPpUsed = move.getMovePp() - 2;
|
const newPpUsed = move.getMovePp() - 2;
|
||||||
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
move.ppUsed = move.ppUsed < newPpUsed ? newPpUsed : move.ppUsed;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setEncounterExp(scene, selectedPokemon.id, 100);
|
setEncounterExp(scene, selectedPokemon.id, 100);
|
||||||
|
@ -172,9 +172,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
// 80% chance to increase flee stage +1
|
// 80% chance to increase flee stage +1
|
||||||
const fleeChangeResult = tryChangeFleeStage(scene, 1, 8);
|
const fleeChangeResult = tryChangeFleeStage(scene, 1, 8);
|
||||||
if (!fleeChangeResult) {
|
if (!fleeChangeResult) {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.busy_eating`), 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.busy_eating`) ?? "", 1000, false );
|
||||||
} else {
|
} else {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.eating`), 1000, false);
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.eating`) ?? "", 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await doEndTurn(scene, 1);
|
await doEndTurn(scene, 1);
|
||||||
@ -201,9 +201,9 @@ const safariZoneGameOptions: MysteryEncounterOption[] = [
|
|||||||
// 80% chance to decrease catch stage -1
|
// 80% chance to decrease catch stage -1
|
||||||
const catchChangeResult = tryChangeCatchStage(scene, -1, 8);
|
const catchChangeResult = tryChangeCatchStage(scene, -1, 8);
|
||||||
if (!catchChangeResult) {
|
if (!catchChangeResult) {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.beside_itself_angry`), 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.beside_itself_angry`) ?? "", 1000, false );
|
||||||
} else {
|
} else {
|
||||||
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.angry`), 1000, false );
|
await showEncounterText(scene, getEncounterText(scene, `${namespace}.safari.angry`) ?? "", 1000, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
await doEndTurn(scene, 2);
|
await doEndTurn(scene, 2);
|
||||||
@ -239,7 +239,7 @@ async function summonSafariPokemon(scene: BattleScene) {
|
|||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
// Message pokemon remaining
|
// Message pokemon remaining
|
||||||
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
encounter.setDialogueToken("remainingCount", encounter.misc.safariPokemonRemaining);
|
||||||
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.remaining_count`), null, true);
|
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.remaining_count`) ?? "", null, true);
|
||||||
|
|
||||||
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
// Generate pokemon using safariPokemonRemaining so they are always the same pokemon no matter how many turns are taken
|
||||||
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
// Safari pokemon roll twice on shiny and HA chances, but are otherwise normal
|
||||||
@ -288,7 +288,7 @@ async function summonSafariPokemon(scene: BattleScene) {
|
|||||||
scene.unshiftPhase(new SummonPhase(scene, 0, false));
|
scene.unshiftPhase(new SummonPhase(scene, 0, false));
|
||||||
|
|
||||||
encounter.setDialogueToken("pokemonName", getPokemonNameWithAffix(pokemon));
|
encounter.setDialogueToken("pokemonName", getPokemonNameWithAffix(pokemon));
|
||||||
showEncounterText(scene, getEncounterText(scene, "battle:singleWildAppeared"), 1500, false)
|
showEncounterText(scene, getEncounterText(scene, "battle:singleWildAppeared") ?? "", 1500, false)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const ivScannerModifier = scene.findModifier(m => m instanceof IvScannerModifier);
|
const ivScannerModifier = scene.findModifier(m => m instanceof IvScannerModifier);
|
||||||
if (ivScannerModifier) {
|
if (ivScannerModifier) {
|
||||||
@ -494,7 +494,7 @@ async function doEndTurn(scene: BattleScene, cursorIndex: number) {
|
|||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.watching`), 0, null, 1000);
|
scene.queueMessage(getEncounterText(scene, `${namespace}.safari.watching`) ?? "", 0, null, 1000);
|
||||||
initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true });
|
initSubsequentOptionSelect(scene, { overrideOptions: safariZoneGameOptions, startingCursorIndex: cursorIndex, hideDescription: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,13 +95,13 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
// If pokemon meets primary pokemon reqs, it can be selected
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Choose Cheap Option
|
// Choose Cheap Option
|
||||||
@ -178,13 +178,13 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter =
|
|||||||
// If pokemon meets primary pokemon reqs, it can be selected
|
// If pokemon meets primary pokemon reqs, it can be selected
|
||||||
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
|
const meetsReqs = encounter.pokemonMeetsPrimaryRequirements(scene, pokemon);
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
// Choose Expensive Option
|
// Choose Expensive Option
|
||||||
|
@ -140,7 +140,7 @@ export const SlumberingSnorlaxEncounter: MysteryEncounter =
|
|||||||
const instance = scene.currentBattle.mysteryEncounter;
|
const instance = scene.currentBattle.mysteryEncounter;
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.LEFTOVERS], fillRemaining: false });
|
||||||
// Snorlax exp to Pokemon that did the stealing
|
// Snorlax exp to Pokemon that did the stealing
|
||||||
setEncounterExp(scene, instance.primaryPokemon.id, getPokemonSpecies(Species.SNORLAX).baseExp);
|
setEncounterExp(scene, instance.primaryPokemon!.id, getPokemonSpecies(Species.SNORLAX).baseExp);
|
||||||
leaveEncounterWithoutBattle(scene);
|
leaveEncounterWithoutBattle(scene);
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
@ -29,7 +29,7 @@ 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(10, 180)
|
||||||
.withSceneRequirement(new MoneyRequirement(null, 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([
|
||||||
{
|
{
|
||||||
@ -66,10 +66,10 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
// If no HA mon found or you roll 1%, give shiny Magikarp
|
// If no HA mon found or you roll 1%, give shiny Magikarp
|
||||||
species = getPokemonSpecies(Species.MAGIKARP);
|
species = getPokemonSpecies(Species.MAGIKARP);
|
||||||
const hiddenIndex = species.ability2 ? 2 : 1;
|
const hiddenIndex = species.ability2 ? 2 : 1;
|
||||||
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, true, null, null, null, null);
|
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, undefined, true);
|
||||||
} else {
|
} else {
|
||||||
const hiddenIndex = species.ability2 ? 2 : 1;
|
const hiddenIndex = species.ability2 ? 2 : 1;
|
||||||
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex, null, null, null, null, null, null);
|
pokemon = new PlayerPokemon(scene, species, 5, hiddenIndex, species.formIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
|
const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(pokemon);
|
||||||
@ -88,8 +88,8 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
// Always max price for shiny (flip HA back to normal), and add special messaging
|
// Always max price for shiny (flip HA back to normal), and add special messaging
|
||||||
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
priceMultiplier = MAX_POKEMON_PRICE_MULTIPLIER;
|
||||||
pokemon.abilityIndex = 0;
|
pokemon.abilityIndex = 0;
|
||||||
encounter.dialogue.encounterOptionsDialogue.description = `${namespace}.description_shiny`;
|
encounter.dialogue.encounterOptionsDialogue!.description = `${namespace}.description_shiny`;
|
||||||
encounter.options[0].dialogue.buttonTooltip = `${namespace}.option.1.tooltip_shiny`;
|
encounter.options[0].dialogue!.buttonTooltip = `${namespace}.option.1.tooltip_shiny`;
|
||||||
}
|
}
|
||||||
const price = scene.getWaveMoneyAmount(priceMultiplier);
|
const price = scene.getWaveMoneyAmount(priceMultiplier);
|
||||||
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
|
encounter.setDialogueToken("purchasePokemon", pokemon.getNameToRender());
|
||||||
@ -107,7 +107,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter =
|
|||||||
MysteryEncounterOptionBuilder
|
MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
.withSceneMoneyRequirement(null, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2
|
.withSceneMoneyRequirement(undefined, MAX_POKEMON_PRICE_MULTIPLIER) // Wave scaling money multiplier of 2
|
||||||
.withDialogue({
|
.withDialogue({
|
||||||
buttonLabel: `${namespace}.option.1.label`,
|
buttonLabel: `${namespace}.option.1.label`,
|
||||||
buttonTooltip: `${namespace}.option.1.tooltip`,
|
buttonTooltip: `${namespace}.option.1.tooltip`,
|
||||||
|
@ -127,7 +127,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
// -20 to all base stats of highest BST, +10 to all base stats of rest of party
|
// -20 to all base stats of highest BST, +10 to all base stats of rest of party
|
||||||
// Get highest BST mon
|
// Get highest BST mon
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
let highestBst: PlayerPokemon = null;
|
let highestBst: PlayerPokemon | null = null;
|
||||||
let statTotal = 0;
|
let statTotal = 0;
|
||||||
for (const pokemon of party) {
|
for (const pokemon of party) {
|
||||||
if (!highestBst) {
|
if (!highestBst) {
|
||||||
@ -157,7 +157,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
|||||||
}
|
}
|
||||||
|
|
||||||
encounter.setDialogueToken("highBstPokemon", highestBst.getNameToRender());
|
encounter.setDialogueToken("highBstPokemon", highestBst.getNameToRender());
|
||||||
await showEncounterText(scene, `${namespace}.option.1.selected_2`, null, true);
|
await showEncounterText(scene, `${namespace}.option.1.selected_2`, undefined, true);
|
||||||
|
|
||||||
setEncounterRewards(scene, { fillRemaining: true });
|
setEncounterRewards(scene, { fillRemaining: true });
|
||||||
leaveEncounterWithoutBattle(scene, true);
|
leaveEncounterWithoutBattle(scene, true);
|
||||||
|
@ -140,7 +140,7 @@ async function spawnNextTrainerOrEndEncounter(scene: BattleScene) {
|
|||||||
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
await transitionMysteryEncounterIntroVisuals(scene, false, false);
|
||||||
await showEncounterDialogue(scene, `${namespace}.victory`, `${namespace}.speaker`);
|
await showEncounterDialogue(scene, `${namespace}.victory`, `${namespace}.speaker`);
|
||||||
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE], fillRemaining: false });
|
setEncounterRewards(scene, { guaranteedModifierTypeFuncs: [modifierTypes.MYSTERY_ENCOUNTER_MACHO_BRACE], fillRemaining: false });
|
||||||
encounter.doContinueEncounter = null;
|
encounter.doContinueEncounter = undefined;
|
||||||
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.TRAINER_BATTLE);
|
leaveEncounterWithoutBattle(scene, false, MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
} else {
|
} else {
|
||||||
await initBattleWithEnemyConfig(scene, nextConfig);
|
await initBattleWithEnemyConfig(scene, nextConfig);
|
||||||
@ -151,17 +151,21 @@ function endTrainerBattleAndShowDialogue(scene: BattleScene): Promise<void> {
|
|||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
if (scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length === 0) {
|
if (scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length === 0) {
|
||||||
// Battle is over
|
// Battle is over
|
||||||
|
const trainer = scene.currentBattle.trainer;
|
||||||
|
if (trainer) {
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: scene.currentBattle.trainer,
|
targets: trainer,
|
||||||
x: "+=16",
|
x: "+=16",
|
||||||
y: "-=16",
|
y: "-=16",
|
||||||
alpha: 0,
|
alpha: 0,
|
||||||
ease: "Sine.easeInOut",
|
ease: "Sine.easeInOut",
|
||||||
duration: 750,
|
duration: 750,
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
scene.field.remove(scene.currentBattle.trainer, true);
|
scene.field.remove(trainer, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await spawnNextTrainerOrEndEncounter(scene);
|
await spawnNextTrainerOrEndEncounter(scene);
|
||||||
resolve(); // Wait for all dialogue/post battle stuff to complete before resolving
|
resolve(); // Wait for all dialogue/post battle stuff to complete before resolving
|
||||||
} else {
|
} else {
|
||||||
@ -186,6 +190,7 @@ function endTrainerBattleAndShowDialogue(scene: BattleScene): Promise<void> {
|
|||||||
// Unassign previous trainer from battle so it isn't destroyed before animation completes
|
// Unassign previous trainer from battle so it isn't destroyed before animation completes
|
||||||
scene.currentBattle.trainer = null;
|
scene.currentBattle.trainer = null;
|
||||||
await spawnNextTrainerOrEndEncounter(scene);
|
await spawnNextTrainerOrEndEncounter(scene);
|
||||||
|
if (trainer) {
|
||||||
scene.tweens.add({
|
scene.tweens.add({
|
||||||
targets: trainer,
|
targets: trainer,
|
||||||
x: "+=16",
|
x: "+=16",
|
||||||
@ -199,6 +204,7 @@ function endTrainerBattleAndShowDialogue(scene: BattleScene): Promise<void> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,10 @@ import { Stat } from "#app/data/pokemon-stat";
|
|||||||
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
import Pokemon, { PlayerPokemon } from "#app/field/pokemon";
|
||||||
import { pokemonInfo } from "#app/locales/en/pokemon-info";
|
import { pokemonInfo } from "#app/locales/en/pokemon-info";
|
||||||
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { PokemonHeldItemModifierType } from "#app/modifier/modifier-type";
|
|
||||||
import { AbilityAttr } from "#app/system/game-data";
|
import { AbilityAttr } from "#app/system/game-data";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
import { randSeedShuffle } from "#app/utils";
|
import { isNullOrUndefined, randSeedShuffle } from "#app/utils";
|
||||||
import { BattlerTagType } from "#enums/battler-tag-type";
|
import { BattlerTagType } from "#enums/battler-tag-type";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
@ -19,6 +18,7 @@ import { MysteryEncounterOptionBuilder } from "../mystery-encounter-option";
|
|||||||
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 { 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 HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||||
|
|
||||||
/** The i18n namespace for the encounter */
|
/** The i18n namespace for the encounter */
|
||||||
const namespace = "mysteryEncounter:trainingSession";
|
const namespace = "mysteryEncounter:trainingSession";
|
||||||
@ -77,13 +77,13 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
const meetsReqs = pokemon.isAllowedInBattle();
|
const meetsReqs = pokemon.isAllowedInBattle();
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
@ -125,7 +125,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
encounter.setDialogueToken("stat1", "-");
|
encounter.setDialogueToken("stat1", "-");
|
||||||
encounter.setDialogueToken("stat2", "-");
|
encounter.setDialogueToken("stat2", "-");
|
||||||
// Add the pokemon back to party with IV boost
|
// Add the pokemon back to party with IV boost
|
||||||
const ivIndexes = [];
|
const ivIndexes: any[] = [];
|
||||||
playerPokemon.ivs.forEach((iv, index) => {
|
playerPokemon.ivs.forEach((iv, index) => {
|
||||||
if (iv < 31) {
|
if (iv < 31) {
|
||||||
ivIndexes.push({ iv: iv, index: index });
|
ivIndexes.push({ iv: iv, index: index });
|
||||||
@ -147,12 +147,12 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
if (improvedCount === 0) {
|
if (improvedCount === 0) {
|
||||||
encounter.setDialogueToken(
|
encounter.setDialogueToken(
|
||||||
"stat1",
|
"stat1",
|
||||||
getIvName(ivToChange.index)
|
getIvName(ivToChange.index) ?? ""
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
encounter.setDialogueToken(
|
encounter.setDialogueToken(
|
||||||
"stat2",
|
"stat2",
|
||||||
getIvName(ivToChange.index)
|
getIvName(ivToChange.index) ?? ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,12 +185,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
queueEncounterMessage(scene, `${namespace}.option.1.finished`);
|
queueEncounterMessage(scene, `${namespace}.option.1.finished`);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase);
|
||||||
scene,
|
|
||||||
{ fillRemaining: true },
|
|
||||||
null,
|
|
||||||
onBeforeRewardsPhase
|
|
||||||
);
|
|
||||||
|
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
})
|
})
|
||||||
@ -237,13 +232,13 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
const meetsReqs = pokemon.isAllowedInBattle();
|
const meetsReqs = pokemon.isAllowedInBattle();
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
@ -278,12 +273,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
scene.updateModifiers(true);
|
scene.updateModifiers(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase);
|
||||||
scene,
|
|
||||||
{ fillRemaining: true },
|
|
||||||
null,
|
|
||||||
onBeforeRewardsPhase
|
|
||||||
);
|
|
||||||
|
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
})
|
})
|
||||||
@ -339,13 +329,13 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
const selectableFilter = (pokemon: Pokemon) => {
|
const selectableFilter = (pokemon: Pokemon) => {
|
||||||
const meetsReqs = pokemon.isAllowedInBattle();
|
const meetsReqs = pokemon.isAllowedInBattle();
|
||||||
if (!meetsReqs) {
|
if (!meetsReqs) {
|
||||||
return getEncounterText(scene, `${namespace}.invalid_selection`);
|
return getEncounterText(scene, `${namespace}.invalid_selection`) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return selectPokemonForOption(scene, onPokemonSelected, null, selectableFilter);
|
return selectPokemonForOption(scene, onPokemonSelected, undefined, selectableFilter);
|
||||||
})
|
})
|
||||||
.withOptionPhase(async (scene: BattleScene) => {
|
.withOptionPhase(async (scene: BattleScene) => {
|
||||||
const encounter = scene.currentBattle.mysteryEncounter;
|
const encounter = scene.currentBattle.mysteryEncounter;
|
||||||
@ -354,18 +344,10 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
// Spawn hard training session with chosen pokemon
|
// Spawn hard training session with chosen pokemon
|
||||||
// Every 30 waves, add +1 boss segment, capping at 6
|
// Every 30 waves, add +1 boss segment, capping at 6
|
||||||
// Also starts with +1 to all stats
|
// Also starts with +1 to all stats
|
||||||
const segments = Math.min(
|
const segments = Math.min(2 + Math.floor(scene.currentBattle.waveIndex / 30), 6);
|
||||||
2 + Math.floor(scene.currentBattle.waveIndex / 30),
|
|
||||||
6
|
|
||||||
);
|
|
||||||
const modifiers = new ModifiersHolder();
|
const modifiers = new ModifiersHolder();
|
||||||
const config = getEnemyConfig(
|
const config = getEnemyConfig(scene, playerPokemon, segments, modifiers);
|
||||||
scene,
|
config.pokemonConfigs![0].tags = [
|
||||||
playerPokemon,
|
|
||||||
segments,
|
|
||||||
modifiers
|
|
||||||
);
|
|
||||||
config.pokemonConfigs[0].tags = [
|
|
||||||
BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON,
|
BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON,
|
||||||
];
|
];
|
||||||
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
scene.removePokemonFromPlayerParty(playerPokemon, false);
|
||||||
@ -376,15 +358,10 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
const abilityIndex = encounter.misc.abilityIndex;
|
const abilityIndex = encounter.misc.abilityIndex;
|
||||||
if (!!playerPokemon.getFusionSpeciesForm()) {
|
if (!!playerPokemon.getFusionSpeciesForm()) {
|
||||||
playerPokemon.fusionAbilityIndex = abilityIndex;
|
playerPokemon.fusionAbilityIndex = abilityIndex;
|
||||||
if (
|
if (!isNullOrUndefined(playerPokemon.fusionSpecies?.speciesId) && speciesStarters.hasOwnProperty(playerPokemon.fusionSpecies!.speciesId)) {
|
||||||
speciesStarters.hasOwnProperty(
|
scene.gameData.starterData[playerPokemon.fusionSpecies!.speciesId]
|
||||||
playerPokemon.fusionSpecies.speciesId
|
.abilityAttr |=
|
||||||
)
|
abilityIndex !== 1 || playerPokemon.fusionSpecies!.ability2
|
||||||
) {
|
|
||||||
scene.gameData.starterData[
|
|
||||||
playerPokemon.fusionSpecies.speciesId
|
|
||||||
].abilityAttr |=
|
|
||||||
abilityIndex !== 1 || playerPokemon.fusionSpecies.ability2
|
|
||||||
? Math.pow(2, playerPokemon.fusionAbilityIndex)
|
? Math.pow(2, playerPokemon.fusionAbilityIndex)
|
||||||
: AbilityAttr.ABILITY_HIDDEN;
|
: AbilityAttr.ABILITY_HIDDEN;
|
||||||
}
|
}
|
||||||
@ -414,12 +391,7 @@ export const TrainingSessionEncounter: MysteryEncounter =
|
|||||||
scene.updateModifiers(true);
|
scene.updateModifiers(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
setEncounterRewards(
|
setEncounterRewards(scene, { fillRemaining: true }, undefined, onBeforeRewardsPhase);
|
||||||
scene,
|
|
||||||
{ fillRemaining: true },
|
|
||||||
null,
|
|
||||||
onBeforeRewardsPhase
|
|
||||||
);
|
|
||||||
|
|
||||||
return initBattleWithEnemyConfig(scene, config);
|
return initBattleWithEnemyConfig(scene, config);
|
||||||
})
|
})
|
||||||
@ -432,7 +404,11 @@ function getEnemyConfig(scene: BattleScene, playerPokemon: PlayerPokemon,segment
|
|||||||
|
|
||||||
// Passes modifiers by reference
|
// Passes modifiers by reference
|
||||||
modifiers.value = scene.findModifiers((m) => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === playerPokemon.id) as PokemonHeldItemModifier[];
|
modifiers.value = scene.findModifiers((m) => m instanceof PokemonHeldItemModifier && (m as PokemonHeldItemModifier).pokemonId === playerPokemon.id) as PokemonHeldItemModifier[];
|
||||||
const modifierTypes = modifiers.value.map((mod) => mod.type) as PokemonHeldItemModifierType[];
|
const modifierConfigs = modifiers.value.map((mod) => {
|
||||||
|
return {
|
||||||
|
modifierType: mod.type
|
||||||
|
};
|
||||||
|
}) as HeldModifierConfig[];
|
||||||
|
|
||||||
const data = new PokemonData(playerPokemon);
|
const data = new PokemonData(playerPokemon);
|
||||||
return {
|
return {
|
||||||
@ -444,7 +420,7 @@ function getEnemyConfig(scene: BattleScene, playerPokemon: PlayerPokemon,segment
|
|||||||
formIndex: playerPokemon.formIndex,
|
formIndex: playerPokemon.formIndex,
|
||||||
level: playerPokemon.level,
|
level: playerPokemon.level,
|
||||||
dataSource: data,
|
dataSource: data,
|
||||||
modifierConfigs: modifierTypes,
|
modifierConfigs: modifierConfigs,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -178,7 +178,7 @@ async function tryApplyDigRewardItems(scene: BattleScene) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + leftovers.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + leftovers.name }), undefined, true);
|
||||||
|
|
||||||
// First Shell bell
|
// First Shell bell
|
||||||
for (const pokemon of party) {
|
for (const pokemon of party) {
|
||||||
@ -205,7 +205,7 @@ async function tryApplyDigRewardItems(scene: BattleScene) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scene.playSound("item_fanfare");
|
scene.playSound("item_fanfare");
|
||||||
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + shellBell.name }), null, true);
|
await showEncounterText(scene, i18next.t("battle:rewardGain", { modifierName: "2 " + shellBell.name }), undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doGarbageDig(scene: BattleScene) {
|
async function doGarbageDig(scene: BattleScene) {
|
||||||
|
@ -8,7 +8,7 @@ import { leaveEncounterWithoutBattle, setEncounterRewards, } from "../utils/enco
|
|||||||
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 Pokemon, { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
import Pokemon, { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import { IntegerHolder, randSeedInt, randSeedShuffle } from "#app/utils";
|
import { IntegerHolder, isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils";
|
||||||
import PokemonSpecies, { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species";
|
import PokemonSpecies, { allSpecies, getPokemonSpecies } from "#app/data/pokemon-species";
|
||||||
import { HiddenAbilityRateBoosterModifier, PokemonBaseStatTotalModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
import { HiddenAbilityRateBoosterModifier, PokemonBaseStatTotalModifier, PokemonFormChangeItemModifier, PokemonHeldItemModifier } from "#app/modifier/modifier";
|
||||||
import { achvs } from "#app/system/achv";
|
import { achvs } from "#app/system/achv";
|
||||||
@ -362,7 +362,7 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
|||||||
}
|
}
|
||||||
newTypes.push(newType);
|
newTypes.push(newType);
|
||||||
if (!newPokemon.mysteryEncounterData) {
|
if (!newPokemon.mysteryEncounterData) {
|
||||||
newPokemon.mysteryEncounterData = new MysteryEncounterPokemonData(null, null, null, newTypes);
|
newPokemon.mysteryEncounterData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||||
} else {
|
} else {
|
||||||
newPokemon.mysteryEncounterData.types = newTypes;
|
newPokemon.mysteryEncounterData.types = newTypes;
|
||||||
}
|
}
|
||||||
@ -381,10 +381,12 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
|||||||
// Def or SpDef
|
// Def or SpDef
|
||||||
stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF);
|
stats.push(baseStats[Stat.DEF] < baseStats[Stat.SPDEF] ? Stat.DEF : Stat.SPDEF);
|
||||||
// const mod = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().newModifier(newPokemon, 20, stats);
|
// const mod = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().newModifier(newPokemon, 20, stats);
|
||||||
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().generateType(null, [20, stats]);
|
const modType = modifierTypes.MYSTERY_ENCOUNTER_OLD_GATEAU().generateType(scene.getParty(), [20, stats]);
|
||||||
const modifier = modType.newModifier(newPokemon);
|
const modifier = modType?.newModifier(newPokemon);
|
||||||
|
if (modifier) {
|
||||||
scene.addModifier(modifier);
|
scene.addModifier(modifier);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Enable passive if previous had it
|
// Enable passive if previous had it
|
||||||
newPokemon.passive = previousPokemon.passive;
|
newPokemon.passive = previousPokemon.passive;
|
||||||
@ -422,8 +424,8 @@ function getOriginalBst(scene: BattleScene, pokemon: Pokemon) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTransformedSpecies(originalBst: number, bstSearchRange: [number, number], hasPokemonBstHigherThan600: boolean, hasPokemonBstBetween570And600: boolean, alreadyUsedSpecies: PokemonSpecies[]): PokemonSpecies {
|
function getTransformedSpecies(originalBst: number, bstSearchRange: [number, number], hasPokemonBstHigherThan600: boolean, hasPokemonBstBetween570And600: boolean, alreadyUsedSpecies: PokemonSpecies[]): PokemonSpecies {
|
||||||
let newSpecies: PokemonSpecies;
|
let newSpecies: PokemonSpecies | undefined;
|
||||||
while (!newSpecies) {
|
while (isNullOrUndefined(newSpecies)) {
|
||||||
const bstCap = originalBst + bstSearchRange[1];
|
const bstCap = originalBst + bstSearchRange[1];
|
||||||
const bstMin = Math.max(originalBst + bstSearchRange[0], 0);
|
const bstMin = Math.max(originalBst + bstSearchRange[0], 0);
|
||||||
|
|
||||||
@ -442,7 +444,7 @@ function getTransformedSpecies(originalBst: number, bstSearchRange: [number, num
|
|||||||
if (validSpecies?.length > 20) {
|
if (validSpecies?.length > 20) {
|
||||||
validSpecies = randSeedShuffle(validSpecies);
|
validSpecies = randSeedShuffle(validSpecies);
|
||||||
newSpecies = validSpecies.pop();
|
newSpecies = validSpecies.pop();
|
||||||
while (alreadyUsedSpecies.includes(newSpecies)) {
|
while (isNullOrUndefined(newSpecies) || alreadyUsedSpecies.includes(newSpecies!)) {
|
||||||
newSpecies = validSpecies.pop();
|
newSpecies = validSpecies.pop();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -452,7 +454,7 @@ function getTransformedSpecies(originalBst: number, bstSearchRange: [number, num
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newSpecies;
|
return newSpecies!;
|
||||||
}
|
}
|
||||||
|
|
||||||
function doShowDreamBackground(scene: BattleScene) {
|
function doShowDreamBackground(scene: BattleScene) {
|
||||||
@ -503,7 +505,7 @@ function doHideDreamBackground(scene: BattleScene) {
|
|||||||
|
|
||||||
function doSideBySideTransformations(scene: BattleScene, transformations: PokemonTransformation[]) {
|
function doSideBySideTransformations(scene: BattleScene, transformations: PokemonTransformation[]) {
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
const allTransformationPromises = [];
|
const allTransformationPromises: Promise<void>[] = [];
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const delay = i * 4000;
|
const delay = i * 4000;
|
||||||
scene.time.delayedCall(delay, () => {
|
scene.time.delayedCall(delay, () => {
|
||||||
|
@ -8,16 +8,32 @@ import { EncounterPokemonRequirement, EncounterSceneRequirement, MoneyRequiremen
|
|||||||
import { CanLearnMoveRequirement, CanLearnMoveRequirementOptions } from "./requirements/can-learn-move-requirement";
|
import { CanLearnMoveRequirement, CanLearnMoveRequirementOptions } from "./requirements/can-learn-move-requirement";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
|
||||||
|
|
||||||
|
|
||||||
export type OptionPhaseCallback = (scene: BattleScene) => Promise<void | boolean>;
|
export type OptionPhaseCallback = (scene: BattleScene) => Promise<void | boolean>;
|
||||||
|
|
||||||
// export default interface MysteryEncounterOption {
|
/**
|
||||||
//
|
* Used by {@link MysteryEncounterOptionBuilder} class to define required/optional properties on the {@link MysteryEncounterOption} class when building.
|
||||||
// }
|
*
|
||||||
|
* Should ONLY contain properties that are necessary for {@link MysteryEncounterOption} construction.
|
||||||
|
* Post-construct and flag data properties are defined in the {@link MysteryEncounterOption} class itself.
|
||||||
|
*/
|
||||||
|
export interface IMysteryEncounterOption {
|
||||||
|
optionMode: MysteryEncounterOptionMode;
|
||||||
|
hasDexProgress: boolean;
|
||||||
|
requirements: EncounterSceneRequirement[];
|
||||||
|
primaryPokemonRequirements: EncounterPokemonRequirement[];
|
||||||
|
secondaryPokemonRequirements: EncounterPokemonRequirement[];
|
||||||
|
excludePrimaryFromSecondaryRequirements: boolean;
|
||||||
|
|
||||||
export default class MysteryEncounterOption {
|
dialogue?: OptionTextDisplay;
|
||||||
|
|
||||||
|
onPreOptionPhase?: OptionPhaseCallback;
|
||||||
|
onOptionPhase: OptionPhaseCallback;
|
||||||
|
onPostOptionPhase?: OptionPhaseCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class MysteryEncounterOption implements IMysteryEncounterOption {
|
||||||
optionMode: MysteryEncounterOptionMode;
|
optionMode: MysteryEncounterOptionMode;
|
||||||
hasDexProgress: boolean;
|
hasDexProgress: boolean;
|
||||||
requirements: EncounterSceneRequirement[];
|
requirements: EncounterSceneRequirement[];
|
||||||
@ -40,12 +56,14 @@ export default class MysteryEncounterOption {
|
|||||||
/** Executes after the encounter is over. Usually this will be for calculating dialogueTokens or performing data updates */
|
/** Executes after the encounter is over. Usually this will be for calculating dialogueTokens or performing data updates */
|
||||||
onPostOptionPhase?: OptionPhaseCallback;
|
onPostOptionPhase?: OptionPhaseCallback;
|
||||||
|
|
||||||
constructor(option: MysteryEncounterOption | null) {
|
constructor(option: IMysteryEncounterOption | null) {
|
||||||
|
if (!isNullOrUndefined(option)) {
|
||||||
Object.assign(this, option);
|
Object.assign(this, option);
|
||||||
this.hasDexProgress = !isNullOrUndefined(this.hasDexProgress) ? this.hasDexProgress : false;
|
}
|
||||||
this.requirements = this.requirements ? this.requirements : [];
|
this.hasDexProgress = this.hasDexProgress ?? false;
|
||||||
this.primaryPokemonRequirements = this.primaryPokemonRequirements ? this.primaryPokemonRequirements : [];
|
this.requirements = this.requirements ?? [];
|
||||||
this.secondaryPokemonRequirements = this.secondaryPokemonRequirements ? this.secondaryPokemonRequirements : [];
|
this.primaryPokemonRequirements = this.primaryPokemonRequirements ?? [];
|
||||||
|
this.secondaryPokemonRequirements = this.secondaryPokemonRequirements ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
hasRequirements() {
|
hasRequirements() {
|
||||||
@ -70,7 +88,8 @@ export default class MysteryEncounterOption {
|
|||||||
for (const req of this.primaryPokemonRequirements) {
|
for (const req of this.primaryPokemonRequirements) {
|
||||||
if (req.meetsRequirement(scene)) {
|
if (req.meetsRequirement(scene)) {
|
||||||
if (req instanceof EncounterPokemonRequirement) {
|
if (req instanceof EncounterPokemonRequirement) {
|
||||||
qualified = qualified.filter(pkmn => req.queryParty(scene.getParty()).includes(pkmn));
|
const queryParty = req.queryParty(scene.getParty());
|
||||||
|
qualified = qualified.filter(pkmn => queryParty.includes(pkmn));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.primaryPokemon = undefined;
|
this.primaryPokemon = undefined;
|
||||||
@ -125,8 +144,8 @@ export default class MysteryEncounterOption {
|
|||||||
for (const req of this.secondaryPokemonRequirements) {
|
for (const req of this.secondaryPokemonRequirements) {
|
||||||
if (req.meetsRequirement(scene)) {
|
if (req.meetsRequirement(scene)) {
|
||||||
if (req instanceof EncounterPokemonRequirement) {
|
if (req instanceof EncounterPokemonRequirement) {
|
||||||
qualified = qualified.filter(pkmn => req.queryParty(scene.getParty()).includes(pkmn));
|
const queryParty = req.queryParty(scene.getParty());
|
||||||
|
qualified = qualified.filter(pkmn => queryParty.includes(pkmn));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.secondaryPokemon = [];
|
this.secondaryPokemon = [];
|
||||||
@ -138,7 +157,7 @@ export default class MysteryEncounterOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MysteryEncounterOptionBuilder implements Partial<MysteryEncounterOption> {
|
export class MysteryEncounterOptionBuilder implements Partial<IMysteryEncounterOption> {
|
||||||
optionMode: MysteryEncounterOptionMode = MysteryEncounterOptionMode.DEFAULT;
|
optionMode: MysteryEncounterOptionMode = MysteryEncounterOptionMode.DEFAULT;
|
||||||
requirements: EncounterSceneRequirement[] = [];
|
requirements: EncounterSceneRequirement[] = [];
|
||||||
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
||||||
@ -146,26 +165,17 @@ export class MysteryEncounterOptionBuilder implements Partial<MysteryEncounterOp
|
|||||||
excludePrimaryFromSecondaryRequirements: boolean = false;
|
excludePrimaryFromSecondaryRequirements: boolean = false;
|
||||||
isDisabledOnRequirementsNotMet: boolean = true;
|
isDisabledOnRequirementsNotMet: boolean = true;
|
||||||
hasDexProgress: boolean = false;
|
hasDexProgress: boolean = false;
|
||||||
onPreOptionPhase?: OptionPhaseCallback;
|
dialogue?: OptionTextDisplay;
|
||||||
onOptionPhase: OptionPhaseCallback;
|
|
||||||
onPostOptionPhase?: OptionPhaseCallback;
|
|
||||||
dialogue: OptionTextDisplay;
|
|
||||||
|
|
||||||
hasRequirements = MysteryEncounter.prototype["hasRequirements"];
|
static newOptionWithMode(optionMode: MysteryEncounterOptionMode): MysteryEncounterOptionBuilder & Pick<IMysteryEncounterOption, "optionMode"> {
|
||||||
meetsRequirements = MysteryEncounter.prototype["meetsRequirements"];
|
|
||||||
pokemonMeetsPrimaryRequirements = MysteryEncounter.prototype["pokemonMeetsPrimaryRequirements"];
|
|
||||||
meetsPrimaryRequirementAndPrimaryPokemonSelected = MysteryEncounter.prototype["meetsPrimaryRequirementAndPrimaryPokemonSelected"];
|
|
||||||
meetsSupportingRequirementAndSupportingPokemonSelected = MysteryEncounter.prototype["meetsSupportingRequirementAndSupportingPokemonSelected"];
|
|
||||||
|
|
||||||
static newOptionWithMode(optionMode: MysteryEncounterOptionMode): MysteryEncounterOptionBuilder & Pick<MysteryEncounterOption, "optionMode"> {
|
|
||||||
return Object.assign(new MysteryEncounterOptionBuilder(), { optionMode });
|
return Object.assign(new MysteryEncounterOptionBuilder(), { optionMode });
|
||||||
}
|
}
|
||||||
|
|
||||||
withHasDexProgress(hasDexProgress: boolean): this & Required<Pick<MysteryEncounterOption, "hasDexProgress">> {
|
withHasDexProgress(hasDexProgress: boolean): this & Required<Pick<IMysteryEncounterOption, "hasDexProgress">> {
|
||||||
return Object.assign(this, { hasDexProgress: hasDexProgress });
|
return Object.assign(this, { hasDexProgress: hasDexProgress });
|
||||||
}
|
}
|
||||||
|
|
||||||
withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<MysteryEncounterOption, "requirements">> {
|
withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<IMysteryEncounterOption, "requirements">> {
|
||||||
if (requirement instanceof EncounterPokemonRequirement) {
|
if (requirement instanceof EncounterPokemonRequirement) {
|
||||||
Error("Incorrectly added pokemon requirement as scene requirement.");
|
Error("Incorrectly added pokemon requirement as scene requirement.");
|
||||||
}
|
}
|
||||||
@ -174,23 +184,23 @@ export class MysteryEncounterOptionBuilder implements Partial<MysteryEncounterOp
|
|||||||
return Object.assign(this, { requirements: this.requirements });
|
return Object.assign(this, { requirements: this.requirements });
|
||||||
}
|
}
|
||||||
|
|
||||||
withSceneMoneyRequirement(requiredMoney: number, scalingMultiplier?: number) {
|
withSceneMoneyRequirement(requiredMoney?: number, scalingMultiplier?: number) {
|
||||||
return this.withSceneRequirement(new MoneyRequirement(requiredMoney, scalingMultiplier));
|
return this.withSceneRequirement(new MoneyRequirement(requiredMoney, scalingMultiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
withPreOptionPhase(onPreOptionPhase: OptionPhaseCallback): this & Required<Pick<MysteryEncounterOption, "onPreOptionPhase">> {
|
withPreOptionPhase(onPreOptionPhase: OptionPhaseCallback): this & Required<Pick<IMysteryEncounterOption, "onPreOptionPhase">> {
|
||||||
return Object.assign(this, { onPreOptionPhase: onPreOptionPhase });
|
return Object.assign(this, { onPreOptionPhase: onPreOptionPhase });
|
||||||
}
|
}
|
||||||
|
|
||||||
withOptionPhase(onOptionPhase: OptionPhaseCallback): this & Required<Pick<MysteryEncounterOption, "onOptionPhase">> {
|
withOptionPhase(onOptionPhase: OptionPhaseCallback): this & Required<Pick<IMysteryEncounterOption, "onOptionPhase">> {
|
||||||
return Object.assign(this, { onOptionPhase: onOptionPhase });
|
return Object.assign(this, { onOptionPhase: onOptionPhase });
|
||||||
}
|
}
|
||||||
|
|
||||||
withPostOptionPhase(onPostOptionPhase: OptionPhaseCallback): this & Required<Pick<MysteryEncounterOption, "onPostOptionPhase">> {
|
withPostOptionPhase(onPostOptionPhase: OptionPhaseCallback): this & Required<Pick<IMysteryEncounterOption, "onPostOptionPhase">> {
|
||||||
return Object.assign(this, { onPostOptionPhase: onPostOptionPhase });
|
return Object.assign(this, { onPostOptionPhase: onPostOptionPhase });
|
||||||
}
|
}
|
||||||
|
|
||||||
withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<MysteryEncounterOption, "primaryPokemonRequirements">> {
|
withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<IMysteryEncounterOption, "primaryPokemonRequirements">> {
|
||||||
if (requirement instanceof EncounterSceneRequirement) {
|
if (requirement instanceof EncounterSceneRequirement) {
|
||||||
Error("Incorrectly added scene requirement as pokemon requirement.");
|
Error("Incorrectly added scene requirement as pokemon requirement.");
|
||||||
}
|
}
|
||||||
@ -223,7 +233,7 @@ export class MysteryEncounterOptionBuilder implements Partial<MysteryEncounterOp
|
|||||||
return this.withPrimaryPokemonRequirement(new CanLearnMoveRequirement(move, options));
|
return this.withPrimaryPokemonRequirement(new CanLearnMoveRequirement(move, options));
|
||||||
}
|
}
|
||||||
|
|
||||||
withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = true): this & Required<Pick<MysteryEncounterOption, "secondaryPokemonRequirements">> {
|
withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = true): this & Required<Pick<IMysteryEncounterOption, "secondaryPokemonRequirements">> {
|
||||||
if (requirement instanceof EncounterSceneRequirement) {
|
if (requirement instanceof EncounterSceneRequirement) {
|
||||||
Error("Incorrectly added scene requirement as pokemon requirement.");
|
Error("Incorrectly added scene requirement as pokemon requirement.");
|
||||||
}
|
}
|
||||||
@ -244,7 +254,7 @@ export class MysteryEncounterOptionBuilder implements Partial<MysteryEncounterOp
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
build(this: MysteryEncounterOption) {
|
build(this: IMysteryEncounterOption) {
|
||||||
return new MysteryEncounterOption(this);
|
return new MysteryEncounterOption(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,10 +275,10 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||||||
requiredMoney: number; // Static value
|
requiredMoney: number; // Static value
|
||||||
scalingMultiplier: number; // Calculates required money based off wave index
|
scalingMultiplier: number; // Calculates required money based off wave index
|
||||||
|
|
||||||
constructor(requiredMoney: number, scalingMultiplier?: number) {
|
constructor(requiredMoney?: number, scalingMultiplier?: number) {
|
||||||
super();
|
super();
|
||||||
this.requiredMoney = requiredMoney;
|
this.requiredMoney = requiredMoney ?? 0;
|
||||||
this.scalingMultiplier = scalingMultiplier ? scalingMultiplier : 0;
|
this.scalingMultiplier = scalingMultiplier ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -287,14 +287,14 @@ export class MoneyRequirement extends EncounterSceneRequirement {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this?.scalingMultiplier > 0) {
|
if (this.scalingMultiplier > 0) {
|
||||||
this.requiredMoney = scene.getWaveMoneyAmount(this.scalingMultiplier);
|
this.requiredMoney = scene.getWaveMoneyAmount(this.scalingMultiplier);
|
||||||
}
|
}
|
||||||
return !(this?.requiredMoney > 0 && this.requiredMoney > money);
|
return !(this.requiredMoney > 0 && this.requiredMoney > money);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,10 +367,10 @@ export class NatureRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
if (this.requiredNature.includes(pokemon.nature)) {
|
if (!isNullOrUndefined(pokemon?.nature) && this.requiredNature.includes(pokemon!.nature)) {
|
||||||
return ["nature", Nature[pokemon.nature]];
|
return ["nature", Nature[pokemon!.nature]];
|
||||||
}
|
}
|
||||||
return null;
|
return ["nature", ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,9 +537,9 @@ export class EvolutionTargetSpeciesRequirement extends EncounterPokemonRequireme
|
|||||||
getMatchingDialogueToken(str:string, pokemon: PlayerPokemon): [RegExp, string] {
|
getMatchingDialogueToken(str:string, pokemon: PlayerPokemon): [RegExp, string] {
|
||||||
const evos = this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution().speciesId === evolutionTargetSpecies);
|
const evos = this.requiredEvolutionTargetSpecies.filter((evolutionTargetSpecies) => pokemon.getEvolution().speciesId === evolutionTargetSpecies);
|
||||||
if (evos.length > 0) {
|
if (evos.length > 0) {
|
||||||
return ["Evolution", Species[evos[0]]];
|
return ["evolution", Species[evos[0]]];
|
||||||
}
|
}
|
||||||
return null;
|
return ["evolution", ""];
|
||||||
}
|
}
|
||||||
|
|
||||||
}*/
|
}*/
|
||||||
@ -622,7 +622,7 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
return !this.requiredStatusEffect.some((statusEffect) => {
|
return !this.requiredStatusEffect.some((statusEffect) => {
|
||||||
if (statusEffect === StatusEffect.NONE) {
|
if (statusEffect === StatusEffect.NONE) {
|
||||||
// StatusEffect.NONE also checks for null or undefined status
|
// StatusEffect.NONE also checks for null or undefined status
|
||||||
return isNullOrUndefined(pokemon.status) || isNullOrUndefined(pokemon.status.effect) || pokemon.status?.effect === statusEffect;
|
return isNullOrUndefined(pokemon.status) || isNullOrUndefined(pokemon.status!.effect) || pokemon.status?.effect === statusEffect;
|
||||||
} else {
|
} else {
|
||||||
return pokemon.status?.effect === statusEffect;
|
return pokemon.status?.effect === statusEffect;
|
||||||
}
|
}
|
||||||
@ -634,9 +634,9 @@ export class StatusEffectRequirement extends EncounterPokemonRequirement {
|
|||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
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;
|
||||||
}
|
}
|
||||||
return pokemon.status?.effect === a;
|
return pokemon!.status?.effect === a;
|
||||||
});
|
});
|
||||||
if (reqStatus.length > 0) {
|
if (reqStatus.length > 0) {
|
||||||
return ["status", StatusEffect[reqStatus[0]]];
|
return ["status", StatusEffect[reqStatus[0]]];
|
||||||
@ -698,7 +698,7 @@ export class CanFormChangeWithItemRequirement extends EncounterPokemonRequiremen
|
|||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
return ["formChangeItem", FormChangeItem[requiredItems[0]]];
|
||||||
}
|
}
|
||||||
return null;
|
return ["formChangeItem", ""];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -748,7 +748,7 @@ export class CanEvolveWithItemRequirement extends EncounterPokemonRequirement {
|
|||||||
if (requiredItems.length > 0) {
|
if (requiredItems.length > 0) {
|
||||||
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
return ["evolutionItem", EvolutionItem[requiredItems[0]]];
|
||||||
}
|
}
|
||||||
return null;
|
return ["evolutionItem", ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,18 +789,18 @@ export class HeldItemRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
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);
|
||||||
});
|
});
|
||||||
if (requiredItems.length > 0) {
|
if (requiredItems && requiredItems.length > 0) {
|
||||||
return ["heldItem", requiredItems[0].type.name];
|
return ["heldItem", requiredItems[0].type.name];
|
||||||
}
|
}
|
||||||
return null;
|
return ["heldItem", ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LevelRequirement extends EncounterPokemonRequirement {
|
export class LevelRequirement extends EncounterPokemonRequirement {
|
||||||
requiredLevelRange?: [number, number];
|
requiredLevelRange: [number, number];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
invertQuery: boolean;
|
invertQuery: boolean;
|
||||||
|
|
||||||
@ -809,12 +809,11 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery;
|
||||||
this.requiredLevelRange = requiredLevelRange;
|
this.requiredLevelRange = requiredLevelRange;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
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();
|
||||||
const pokemonInRange = this.queryParty(partyPokemon);
|
const pokemonInRange = this.queryParty(partyPokemon);
|
||||||
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
||||||
@ -834,12 +833,12 @@ export class LevelRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["level", pokemon.level.toString()];
|
return ["level", pokemon?.level.toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FriendshipRequirement extends EncounterPokemonRequirement {
|
export class FriendshipRequirement extends EncounterPokemonRequirement {
|
||||||
requiredFriendshipRange?: [number, number];
|
requiredFriendshipRange: [number, number];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
invertQuery: boolean;
|
invertQuery: boolean;
|
||||||
|
|
||||||
@ -852,7 +851,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
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();
|
||||||
const pokemonInRange = this.queryParty(partyPokemon);
|
const pokemonInRange = this.queryParty(partyPokemon);
|
||||||
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
||||||
@ -872,7 +871,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["friendship", pokemon.friendship.toString()];
|
return ["friendship", pokemon?.friendship.toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -882,7 +881,7 @@ export class FriendshipRequirement extends EncounterPokemonRequirement {
|
|||||||
* 1 -> 100% hp
|
* 1 -> 100% hp
|
||||||
*/
|
*/
|
||||||
export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
||||||
requiredHealthRange?: [number, number];
|
requiredHealthRange: [number, number];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
invertQuery: boolean;
|
invertQuery: boolean;
|
||||||
|
|
||||||
@ -895,7 +894,7 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required level range
|
// Party Pokemon inside required level 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);
|
||||||
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
||||||
@ -917,12 +916,15 @@ export class HealthRatioRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["healthRatio", Math.floor(pokemon.getHpRatio() * 100).toString() + "%"];
|
if (!isNullOrUndefined(pokemon?.getHpRatio())) {
|
||||||
|
return ["healthRatio", Math.floor(pokemon!.getHpRatio() * 100).toString() + "%"];
|
||||||
|
}
|
||||||
|
return ["healthRatio", ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WeightRequirement extends EncounterPokemonRequirement {
|
export class WeightRequirement extends EncounterPokemonRequirement {
|
||||||
requiredWeightRange?: [number, number];
|
requiredWeightRange: [number, number];
|
||||||
minNumberOfPokemon: number;
|
minNumberOfPokemon: number;
|
||||||
invertQuery: boolean;
|
invertQuery: boolean;
|
||||||
|
|
||||||
@ -935,7 +937,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
meetsRequirement(scene: BattleScene): boolean {
|
meetsRequirement(scene: BattleScene): boolean {
|
||||||
// Party Pokemon inside required friendship range
|
// Party Pokemon inside required friendship 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);
|
||||||
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
if (pokemonInRange.length < this.minNumberOfPokemon) {
|
||||||
@ -955,7 +957,7 @@ export class WeightRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["weight", pokemon.getWeight().toString()];
|
return ["weight", pokemon?.getWeight().toString() ?? ""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,14 +24,41 @@ export interface EncounterStartOfBattleEffect {
|
|||||||
followUp?: boolean;
|
followUp?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IMysteryEncounter {
|
/**
|
||||||
meetsRequirements(scene: BattleScene): boolean;
|
* Used by {@link MysteryEncounterBuilder} class to define required/optional properties on the {@link MysteryEncounter} class when building.
|
||||||
pokemonMeetsPrimaryRequirements(scene: BattleScene, pokemon: Pokemon): boolean;
|
*
|
||||||
initIntroVisuals(scene: BattleScene): void;
|
* Should ONLY contain properties that are necessary for {@link MysteryEncounter} construction.
|
||||||
populateDialogueTokensFromRequirements(scene: BattleScene): void;
|
* Post-construct and flag data properties are defined in the {@link MysteryEncounter} class itself.
|
||||||
setDialogueToken(key: string, value: string): void;
|
*/
|
||||||
getSeedOffset(): number;
|
export interface IMysteryEncounter {
|
||||||
updateSeedOffset(scene: BattleScene): void;
|
encounterType: MysteryEncounterType;
|
||||||
|
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
||||||
|
spriteConfigs: MysteryEncounterSpriteConfig[];
|
||||||
|
encounterTier: MysteryEncounterTier;
|
||||||
|
encounterAnimations?: EncounterAnim[];
|
||||||
|
hideBattleIntroMessage: boolean;
|
||||||
|
autoHideIntroVisuals: boolean;
|
||||||
|
enterIntroVisualsFromRight: boolean;
|
||||||
|
catchAllowed: boolean;
|
||||||
|
continuousEncounter: boolean;
|
||||||
|
maxAllowedEncounters: number;
|
||||||
|
|
||||||
|
onInit?: (scene: BattleScene) => boolean;
|
||||||
|
onVisualsStart?: (scene: BattleScene) => boolean;
|
||||||
|
doEncounterExp?: (scene: BattleScene) => boolean;
|
||||||
|
doEncounterRewards?: (scene: BattleScene) => boolean;
|
||||||
|
doContinueEncounter?: (scene: BattleScene) => Promise<void>;
|
||||||
|
|
||||||
|
requirements: EncounterSceneRequirement[];
|
||||||
|
primaryPokemonRequirements: EncounterPokemonRequirement[];
|
||||||
|
secondaryPokemonRequirements: EncounterPokemonRequirement[];
|
||||||
|
excludePrimaryFromSupportRequirements: boolean;
|
||||||
|
|
||||||
|
dialogue: MysteryEncounterDialogue;
|
||||||
|
enemyPartyConfigs: EnemyPartyConfig[];
|
||||||
|
|
||||||
|
dialogueTokens: Record<string, string>;
|
||||||
|
expMultiplier: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +174,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
* 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.)
|
||||||
* Example use: see MYSTERIOUS_CHEST
|
* Example use: see MYSTERIOUS_CHEST
|
||||||
*/
|
*/
|
||||||
dialogueTokens: Map<string, string>;
|
dialogueTokens: Record<string, string>;
|
||||||
/**
|
/**
|
||||||
* Should be set depending upon option selected as part of an encounter
|
* Should be set depending upon option selected as part of an encounter
|
||||||
* For example, if there is no battle as part of the encounter/selected option, should be set to NO_BATTLE
|
* For example, if there is no battle as part of the encounter/selected option, should be set to NO_BATTLE
|
||||||
@ -171,7 +198,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
/**
|
/**
|
||||||
* Will be set by option select handlers automatically, and can be used to refer to which option was chosen by later phases
|
* Will be set by option select handlers automatically, and can be used to refer to which option was chosen by later phases
|
||||||
*/
|
*/
|
||||||
startOfBattleEffects?: EncounterStartOfBattleEffect[];
|
startOfBattleEffects: EncounterStartOfBattleEffect[] = [];
|
||||||
/**
|
/**
|
||||||
* Can be set higher or lower based on the type of battle or exp gained for an option/encounter
|
* Can be set higher or lower based on the type of battle or exp gained for an option/encounter
|
||||||
* Defaults to 1
|
* Defaults to 1
|
||||||
@ -188,7 +215,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
*/
|
*/
|
||||||
private seedOffset?: any;
|
private seedOffset?: any;
|
||||||
|
|
||||||
constructor(encounter: MysteryEncounter | null) {
|
constructor(encounter: IMysteryEncounter | null) {
|
||||||
if (!isNullOrUndefined(encounter)) {
|
if (!isNullOrUndefined(encounter)) {
|
||||||
Object.assign(this, encounter);
|
Object.assign(this, encounter);
|
||||||
}
|
}
|
||||||
@ -207,9 +234,9 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
// Reset any dirty flags or encounter data
|
// Reset any dirty flags or encounter data
|
||||||
this.startOfBattleEffectsComplete = false;
|
this.startOfBattleEffectsComplete = false;
|
||||||
this.lockEncounterRewardTiers = true;
|
this.lockEncounterRewardTiers = true;
|
||||||
this.dialogueTokens = new Map<string, string>();
|
this.dialogueTokens = {};
|
||||||
this.enemyPartyConfigs = [];
|
this.enemyPartyConfigs = [];
|
||||||
this.startOfBattleEffects = [];
|
// this.startOfBattleEffects = [];
|
||||||
this.introVisuals = undefined;
|
this.introVisuals = undefined;
|
||||||
this.misc = null;
|
this.misc = null;
|
||||||
this.expMultiplier = 1;
|
this.expMultiplier = 1;
|
||||||
@ -361,7 +388,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
const opt = this.options[i];
|
const opt = this.options[i];
|
||||||
opt.meetsRequirements(scene);
|
opt.meetsRequirements(scene);
|
||||||
const j = i + 1;
|
const j = i + 1;
|
||||||
if (opt.requirements?.length > 0) {
|
if (opt.requirements.length > 0) {
|
||||||
for (const req of opt.requirements) {
|
for (const req of opt.requirements) {
|
||||||
const dialogueToken = req.getDialogueToken(scene);
|
const dialogueToken = req.getDialogueToken(scene);
|
||||||
if (dialogueToken?.length === 2) {
|
if (dialogueToken?.length === 2) {
|
||||||
@ -369,7 +396,7 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (opt.primaryPokemonRequirements?.length > 0 && opt.primaryPokemon && opt.primaryPokemon.length > 0) {
|
if (opt.primaryPokemonRequirements.length > 0 && opt.primaryPokemon) {
|
||||||
this.setDialogueToken("option" + j + "PrimaryName", opt.primaryPokemon.getNameToRender());
|
this.setDialogueToken("option" + j + "PrimaryName", opt.primaryPokemon.getNameToRender());
|
||||||
for (const req of opt.primaryPokemonRequirements) {
|
for (const req of opt.primaryPokemonRequirements) {
|
||||||
if (!req.invertQuery) {
|
if (!req.invertQuery) {
|
||||||
@ -424,26 +451,16 @@ export default class MysteryEncounter implements IMysteryEncounter {
|
|||||||
* Builder class for creating a MysteryEncounter
|
* Builder class for creating a MysteryEncounter
|
||||||
* must call `build()` at the end after specifying all params for the MysteryEncounter
|
* must call `build()` at the end after specifying all params for the MysteryEncounter
|
||||||
*/
|
*/
|
||||||
export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
export class MysteryEncounterBuilder implements Partial<IMysteryEncounter> {
|
||||||
encounterType: MysteryEncounterType;
|
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]];
|
||||||
encounterMode: MysteryEncounterMode;
|
|
||||||
options: [MysteryEncounterOption, MysteryEncounterOption, ...MysteryEncounterOption[]] = [new MysteryEncounterOption(null), new MysteryEncounterOption(null)];
|
|
||||||
spriteConfigs: MysteryEncounterSpriteConfig[];
|
|
||||||
enemyPartyConfigs: EnemyPartyConfig[] = [];
|
enemyPartyConfigs: EnemyPartyConfig[] = [];
|
||||||
|
|
||||||
dialogue: MysteryEncounterDialogue = {};
|
dialogue: MysteryEncounterDialogue = {};
|
||||||
encounterTier: MysteryEncounterTier;
|
|
||||||
encounterAnimations: EncounterAnim[];
|
|
||||||
requirements: EncounterSceneRequirement[] = [];
|
requirements: EncounterSceneRequirement[] = [];
|
||||||
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
primaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
||||||
secondaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
secondaryPokemonRequirements: EncounterPokemonRequirement[] = [];
|
||||||
excludePrimaryFromSupportRequirements: boolean;
|
excludePrimaryFromSupportRequirements: boolean = true;
|
||||||
dialogueTokens: Map<string, string> = new Map<string, string>();
|
dialogueTokens: Record<string, string> = {};
|
||||||
|
|
||||||
doEncounterExp?: (scene: BattleScene) => boolean;
|
|
||||||
doEncounterRewards?: (scene: BattleScene) => boolean;
|
|
||||||
onInit?: (scene: BattleScene) => boolean;
|
|
||||||
onVisualsStart?: (scene: BattleScene) => boolean;
|
|
||||||
|
|
||||||
hideBattleIntroMessage: boolean = false;
|
hideBattleIntroMessage: boolean = false;
|
||||||
autoHideIntroVisuals: boolean = true;
|
autoHideIntroVisuals: boolean = true;
|
||||||
@ -455,21 +472,6 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
maxAllowedEncounters: number = 3;
|
maxAllowedEncounters: number = 3;
|
||||||
expMultiplier: number = 1;
|
expMultiplier: number = 1;
|
||||||
|
|
||||||
/**
|
|
||||||
* Builder class has to re-declare the {@link MysteryEncounter} class functions so
|
|
||||||
* the compiler does not yell about user not defining a non-optional property
|
|
||||||
*/
|
|
||||||
|
|
||||||
meetsRequirements = MysteryEncounter.prototype["meetsRequirements"];
|
|
||||||
pokemonMeetsPrimaryRequirements = MysteryEncounter.prototype["pokemonMeetsPrimaryRequirements"];
|
|
||||||
initIntroVisuals = MysteryEncounter.prototype["initIntroVisuals"];
|
|
||||||
populateDialogueTokensFromRequirements = MysteryEncounter.prototype["populateDialogueTokensFromRequirements"];
|
|
||||||
setDialogueToken = MysteryEncounter.prototype["setDialogueToken"];
|
|
||||||
getSeedOffset = MysteryEncounter.prototype["getSeedOffset"];
|
|
||||||
updateSeedOffset = MysteryEncounter.prototype["updateSeedOffset"];
|
|
||||||
meetsPrimaryRequirementAndPrimaryPokemonSelected = MysteryEncounter.prototype["meetsPrimaryRequirementAndPrimaryPokemonSelected"];
|
|
||||||
meetsSecondaryRequirementAndSecondaryPokemonSelected = MysteryEncounter.prototype["meetsSecondaryRequirementAndSecondaryPokemonSelected"];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REQUIRED
|
* REQUIRED
|
||||||
*/
|
*/
|
||||||
@ -480,7 +482,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param encounterType
|
* @param encounterType
|
||||||
* @returns this
|
* @returns this
|
||||||
*/
|
*/
|
||||||
static withEncounterType(encounterType: MysteryEncounterType): MysteryEncounterBuilder & Pick<MysteryEncounter, "encounterType"> {
|
static withEncounterType(encounterType: MysteryEncounterType): MysteryEncounterBuilder & Pick<IMysteryEncounter, "encounterType"> {
|
||||||
return Object.assign(new MysteryEncounterBuilder(), { encounterType });
|
return Object.assign(new MysteryEncounterBuilder(), { encounterType });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,14 +494,13 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param option - MysteryEncounterOption to add, can use MysteryEncounterOptionBuilder to create instance
|
* @param option - MysteryEncounterOption to add, can use MysteryEncounterOptionBuilder to create instance
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withOption(option: MysteryEncounterOption): this & Pick<MysteryEncounter, "options"> {
|
withOption(option: MysteryEncounterOption): this & Pick<IMysteryEncounter, "options"> {
|
||||||
if (this.options[0] === null) {
|
if (!this.options) {
|
||||||
return Object.assign(this, { options: [option, this.options[0]] });
|
const options = [option];
|
||||||
} else if (this.options[1] === null) {
|
return Object.assign(this, { options });
|
||||||
return Object.assign(this, { options: [this.options[0], option] });
|
|
||||||
} else {
|
} else {
|
||||||
this.options.push(option);
|
this.options.push(option);
|
||||||
return Object.assign(this, { options: this.options });
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +515,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param callback - {@linkcode OptionPhaseCallback}
|
* @param callback - {@linkcode OptionPhaseCallback}
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick<MysteryEncounter, "options"> {
|
withSimpleOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick<IMysteryEncounter, "options"> {
|
||||||
return this.withOption(MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT).withDialogue(dialogue).withOptionPhase(callback).build());
|
return this.withOption(MysteryEncounterOptionBuilder.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT).withDialogue(dialogue).withOptionPhase(callback).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,7 +529,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param callback - {@linkcode OptionPhaseCallback}
|
* @param callback - {@linkcode OptionPhaseCallback}
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withSimpleDexProgressOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick<MysteryEncounter, "options"> {
|
withSimpleDexProgressOption(dialogue: OptionTextDisplay, callback: OptionPhaseCallback): this & Pick<IMysteryEncounter, "options"> {
|
||||||
return this.withOption(MysteryEncounterOptionBuilder
|
return this.withOption(MysteryEncounterOptionBuilder
|
||||||
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
.newOptionWithMode(MysteryEncounterOptionMode.DEFAULT)
|
||||||
.withHasDexProgress(true)
|
.withHasDexProgress(true)
|
||||||
@ -542,7 +543,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param spriteConfigs
|
* @param spriteConfigs
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<MysteryEncounter, "spriteConfigs"> {
|
withIntroSpriteConfigs(spriteConfigs: MysteryEncounterSpriteConfig[]): this & Pick<IMysteryEncounter, "spriteConfigs"> {
|
||||||
return Object.assign(this, { spriteConfigs: spriteConfigs });
|
return Object.assign(this, { spriteConfigs: spriteConfigs });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +572,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param encounterTier
|
* @param encounterTier
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withEncounterTier(encounterTier: MysteryEncounterTier): this & Pick<MysteryEncounter, "encounterTier"> {
|
withEncounterTier(encounterTier: MysteryEncounterTier): this & Pick<IMysteryEncounter, "encounterTier"> {
|
||||||
return Object.assign(this, { encounterTier: encounterTier });
|
return Object.assign(this, { encounterTier: encounterTier });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +583,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param encounterAnimations
|
* @param encounterAnimations
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withAnimations(...encounterAnimations: EncounterAnim[]): this & Required<Pick<MysteryEncounter, "encounterAnimations">> {
|
withAnimations(...encounterAnimations: EncounterAnim[]): this & Required<Pick<IMysteryEncounter, "encounterAnimations">> {
|
||||||
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [encounterAnimations];
|
const animations = Array.isArray(encounterAnimations) ? encounterAnimations : [encounterAnimations];
|
||||||
return Object.assign(this, { encounterAnimations: animations });
|
return Object.assign(this, { encounterAnimations: animations });
|
||||||
}
|
}
|
||||||
@ -593,7 +594,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* Default false
|
* Default false
|
||||||
* @param continuousEncounter
|
* @param continuousEncounter
|
||||||
*/
|
*/
|
||||||
withContinuousEncounter(continuousEncounter: boolean): this & Required<Pick<MysteryEncounter, "continuousEncounter">> {
|
withContinuousEncounter(continuousEncounter: boolean): this & Required<Pick<IMysteryEncounter, "continuousEncounter">> {
|
||||||
return Object.assign(this, { continuousEncounter: continuousEncounter });
|
return Object.assign(this, { continuousEncounter: continuousEncounter });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,7 +603,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param maxAllowedEncounters
|
* @param maxAllowedEncounters
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withMaxAllowedEncounters(maxAllowedEncounters: number): this & Required<Pick<MysteryEncounter, "maxAllowedEncounters">> {
|
withMaxAllowedEncounters(maxAllowedEncounters: number): this & Required<Pick<IMysteryEncounter, "maxAllowedEncounters">> {
|
||||||
return Object.assign(this, { maxAllowedEncounters: maxAllowedEncounters });
|
return Object.assign(this, { maxAllowedEncounters: maxAllowedEncounters });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,12 +614,12 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param requirement
|
* @param requirement
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<MysteryEncounter, "requirements">> {
|
withSceneRequirement(requirement: EncounterSceneRequirement): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||||
if (requirement instanceof EncounterPokemonRequirement) {
|
if (requirement instanceof EncounterPokemonRequirement) {
|
||||||
Error("Incorrectly added pokemon requirement as scene requirement.");
|
Error("Incorrectly added pokemon requirement as scene requirement.");
|
||||||
}
|
}
|
||||||
this.requirements.push(requirement);
|
this.requirements.push(requirement);
|
||||||
return Object.assign(this, { requirements: this.requirements });
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -628,7 +629,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param max optional max wave. If not given, defaults to min => exact wave
|
* @param max optional max wave. If not given, defaults to min => exact wave
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withSceneWaveRangeRequirement(min: number, max?: number): this & Required<Pick<MysteryEncounter, "requirements">> {
|
withSceneWaveRangeRequirement(min: number, max?: number): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||||
return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min]));
|
return this.withSceneRequirement(new WaveRangeRequirement([min, max ?? min]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,7 +641,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param excludeFainted - if true, only counts unfainted mons
|
* @param excludeFainted - if true, only counts unfainted mons
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withScenePartySizeRequirement(min: number, max?: number, excludeFainted: boolean = false): this & Required<Pick<MysteryEncounter, "requirements">> {
|
withScenePartySizeRequirement(min: number, max?: number, excludeFainted: boolean = false): this & Required<Pick<IMysteryEncounter, "requirements">> {
|
||||||
return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeFainted));
|
return this.withSceneRequirement(new PartySizeRequirement([min, max ?? min], excludeFainted));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,7 +651,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param requirement {@linkcode EncounterPokemonRequirement}
|
* @param requirement {@linkcode EncounterPokemonRequirement}
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
|
withPrimaryPokemonRequirement(requirement: EncounterPokemonRequirement): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
|
||||||
if (requirement instanceof EncounterSceneRequirement) {
|
if (requirement instanceof EncounterSceneRequirement) {
|
||||||
Error("Incorrectly added scene requirement as pokemon requirement.");
|
Error("Incorrectly added scene requirement as pokemon requirement.");
|
||||||
}
|
}
|
||||||
@ -667,7 +668,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param invertQuery if true will invert the query
|
* @param invertQuery if true will invert the query
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withPrimaryPokemonStatusEffectRequirement(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
|
withPrimaryPokemonStatusEffectRequirement(statusEffect: StatusEffect | StatusEffect[], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
|
||||||
return this.withPrimaryPokemonRequirement(new StatusEffectRequirement(statusEffect, minNumberOfPokemon, invertQuery));
|
return this.withPrimaryPokemonRequirement(new StatusEffectRequirement(statusEffect, minNumberOfPokemon, invertQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,14 +680,14 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param invertQuery if true will invert the query
|
* @param invertQuery if true will invert the query
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withPrimaryPokemonHealthRatioRequirement(requiredHealthRange: [number, number], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<MysteryEncounter, "primaryPokemonRequirements">> {
|
withPrimaryPokemonHealthRatioRequirement(requiredHealthRange: [number, number], minNumberOfPokemon: number = 1, invertQuery: boolean = false): this & Required<Pick<IMysteryEncounter, "primaryPokemonRequirements">> {
|
||||||
return this.withPrimaryPokemonRequirement(new HealthRatioRequirement(requiredHealthRange, minNumberOfPokemon, invertQuery));
|
return this.withPrimaryPokemonRequirement(new HealthRatioRequirement(requiredHealthRange, minNumberOfPokemon, invertQuery));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe add an optional parameter for excluding primary pokemon from the support cast?
|
// TODO: Maybe add an optional parameter for excluding primary pokemon from the support cast?
|
||||||
// ex. if your only grass type pokemon, a snivy, is chosen as primary, if the support pokemon requires a grass type, the event won't trigger because
|
// ex. if your only grass type pokemon, a snivy, is chosen as primary, if the support pokemon requires a grass type, the event won't trigger because
|
||||||
// it's already been
|
// it's already been
|
||||||
withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = false): this & Required<Pick<MysteryEncounter, "secondaryPokemonRequirements">> {
|
withSecondaryPokemonRequirement(requirement: EncounterPokemonRequirement, excludePrimaryFromSecondaryRequirements: boolean = false): this & Required<Pick<IMysteryEncounter, "secondaryPokemonRequirements">> {
|
||||||
if (requirement instanceof EncounterSceneRequirement) {
|
if (requirement instanceof EncounterSceneRequirement) {
|
||||||
Error("Incorrectly added scene requirement as pokemon requirement.");
|
Error("Incorrectly added scene requirement as pokemon requirement.");
|
||||||
}
|
}
|
||||||
@ -706,7 +707,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param doEncounterRewards - synchronous callback function to perform during rewards phase of the encounter
|
* @param doEncounterRewards - synchronous callback function to perform during rewards phase of the encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withRewards(doEncounterRewards: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "doEncounterRewards">> {
|
withRewards(doEncounterRewards: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterRewards">> {
|
||||||
return Object.assign(this, { doEncounterRewards: doEncounterRewards });
|
return Object.assign(this, { doEncounterRewards: doEncounterRewards });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,7 +721,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param doEncounterExp - synchronous callback function to perform during rewards phase of the encounter
|
* @param doEncounterExp - synchronous callback function to perform during rewards phase of the encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withExp(doEncounterExp: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "doEncounterExp">> {
|
withExp(doEncounterExp: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "doEncounterExp">> {
|
||||||
return Object.assign(this, { doEncounterExp: doEncounterExp });
|
return Object.assign(this, { doEncounterExp: doEncounterExp });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,8 +732,8 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param onInit - synchronous callback function to perform as soon as the encounter is selected for the next phase
|
* @param onInit - synchronous callback function to perform as soon as the encounter is selected for the next phase
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withOnInit(onInit: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "onInit">> {
|
withOnInit(onInit: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "onInit">> {
|
||||||
return Object.assign(this, { onInit: onInit });
|
return Object.assign(this, { onInit });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -741,7 +742,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param onVisualsStart - synchronous callback function to perform as soon as the enemy field finishes sliding in
|
* @param onVisualsStart - synchronous callback function to perform as soon as the enemy field finishes sliding in
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withOnVisualsStart(onVisualsStart: (scene: BattleScene) => boolean): this & Required<Pick<MysteryEncounter, "onVisualsStart">> {
|
withOnVisualsStart(onVisualsStart: (scene: BattleScene) => boolean): this & Required<Pick<IMysteryEncounter, "onVisualsStart">> {
|
||||||
return Object.assign(this, { onVisualsStart: onVisualsStart });
|
return Object.assign(this, { onVisualsStart: onVisualsStart });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +752,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param catchAllowed - if true, allows enemy pokemon to be caught during the encounter
|
* @param catchAllowed - if true, allows enemy pokemon to be caught during the encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withCatchAllowed(catchAllowed: boolean): this & Required<Pick<MysteryEncounter, "catchAllowed">> {
|
withCatchAllowed(catchAllowed: boolean): this & Required<Pick<IMysteryEncounter, "catchAllowed">> {
|
||||||
return Object.assign(this, { catchAllowed: catchAllowed });
|
return Object.assign(this, { catchAllowed: catchAllowed });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +760,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param hideBattleIntroMessage - if true, will not show the trainerAppeared/wildAppeared/bossAppeared message for an encounter
|
* @param hideBattleIntroMessage - if true, will not show the trainerAppeared/wildAppeared/bossAppeared message for an encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withHideWildIntroMessage(hideBattleIntroMessage: boolean): this & Required<Pick<MysteryEncounter, "hideBattleIntroMessage">> {
|
withHideWildIntroMessage(hideBattleIntroMessage: boolean): this & Required<Pick<IMysteryEncounter, "hideBattleIntroMessage">> {
|
||||||
return Object.assign(this, { hideBattleIntroMessage: hideBattleIntroMessage });
|
return Object.assign(this, { hideBattleIntroMessage: hideBattleIntroMessage });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,7 +768,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* @param autoHideIntroVisuals - if false, will not hide the intro visuals that are displayed at the beginning of encounter
|
* @param autoHideIntroVisuals - if false, will not hide the intro visuals that are displayed at the beginning of encounter
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withAutoHideIntroVisuals(autoHideIntroVisuals: boolean): this & Required<Pick<MysteryEncounter, "autoHideIntroVisuals">> {
|
withAutoHideIntroVisuals(autoHideIntroVisuals: boolean): this & Required<Pick<IMysteryEncounter, "autoHideIntroVisuals">> {
|
||||||
return Object.assign(this, { autoHideIntroVisuals: autoHideIntroVisuals });
|
return Object.assign(this, { autoHideIntroVisuals: autoHideIntroVisuals });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,7 +777,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
* Default false
|
* Default false
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
withEnterIntroVisualsFromRight(enterIntroVisualsFromRight: boolean): this & Required<Pick<MysteryEncounter, "enterIntroVisualsFromRight">> {
|
withEnterIntroVisualsFromRight(enterIntroVisualsFromRight: boolean): this & Required<Pick<IMysteryEncounter, "enterIntroVisualsFromRight">> {
|
||||||
return Object.assign(this, { enterIntroVisualsFromRight: enterIntroVisualsFromRight });
|
return Object.assign(this, { enterIntroVisualsFromRight: enterIntroVisualsFromRight });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +857,7 @@ export class MysteryEncounterBuilder implements Partial<MysteryEncounter> {
|
|||||||
*
|
*
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
build(this: MysteryEncounter): MysteryEncounter {
|
build(this: IMysteryEncounter): MysteryEncounter {
|
||||||
return new MysteryEncounter(this);
|
return new MysteryEncounter(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ export function initMysteryEncounters() {
|
|||||||
extremeBiomeEncounters.forEach(encounter => {
|
extremeBiomeEncounters.forEach(encounter => {
|
||||||
EXTREME_ENCOUNTER_BIOMES.forEach(biome => {
|
EXTREME_ENCOUNTER_BIOMES.forEach(biome => {
|
||||||
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
||||||
if (!encountersForBiome.includes(encounter)) {
|
if (encountersForBiome && !encountersForBiome.includes(encounter)) {
|
||||||
encountersForBiome.push(encounter);
|
encountersForBiome.push(encounter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -287,7 +287,7 @@ export function initMysteryEncounters() {
|
|||||||
nonExtremeBiomeEncounters.forEach(encounter => {
|
nonExtremeBiomeEncounters.forEach(encounter => {
|
||||||
NON_EXTREME_ENCOUNTER_BIOMES.forEach(biome => {
|
NON_EXTREME_ENCOUNTER_BIOMES.forEach(biome => {
|
||||||
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
||||||
if (!encountersForBiome.includes(encounter)) {
|
if (encountersForBiome && !encountersForBiome.includes(encounter)) {
|
||||||
encountersForBiome.push(encounter);
|
encountersForBiome.push(encounter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -296,7 +296,7 @@ export function initMysteryEncounters() {
|
|||||||
humanTransitableBiomeEncounters.forEach(encounter => {
|
humanTransitableBiomeEncounters.forEach(encounter => {
|
||||||
HUMAN_TRANSITABLE_BIOMES.forEach(biome => {
|
HUMAN_TRANSITABLE_BIOMES.forEach(biome => {
|
||||||
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
||||||
if (!encountersForBiome.includes(encounter)) {
|
if (encountersForBiome && !encountersForBiome.includes(encounter)) {
|
||||||
encountersForBiome.push(encounter);
|
encountersForBiome.push(encounter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -305,7 +305,7 @@ export function initMysteryEncounters() {
|
|||||||
civilizationBiomeEncounters.forEach(encounter => {
|
civilizationBiomeEncounters.forEach(encounter => {
|
||||||
CIVILIZATION_ENCOUNTER_BIOMES.forEach(biome => {
|
CIVILIZATION_ENCOUNTER_BIOMES.forEach(biome => {
|
||||||
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
const encountersForBiome = mysteryEncountersByBiome.get(biome);
|
||||||
if (!encountersForBiome.includes(encounter)) {
|
if (encountersForBiome && !encountersForBiome.includes(encounter)) {
|
||||||
encountersForBiome.push(encounter);
|
encountersForBiome.push(encounter);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { Moves } from "#app/enums/moves";
|
import { Moves } from "#app/enums/moves";
|
||||||
import { PlayerPokemon } from "#app/field/pokemon";
|
import { PlayerPokemon, PokemonMove } from "#app/field/pokemon";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
import { EncounterPokemonRequirement } from "../mystery-encounter-requirements";
|
import { EncounterPokemonRequirement } from "../mystery-encounter-requirements";
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
this.excludeEggMoves = excludeEggMoves ?? false;
|
this.excludeEggMoves = excludeEggMoves ?? false;
|
||||||
this.includeFainted = includeFainted ?? false;
|
this.includeFainted = includeFainted ?? false;
|
||||||
this.minNumberOfPokemon = minNumberOfPokemon ?? 1;
|
this.minNumberOfPokemon = minNumberOfPokemon ?? 1;
|
||||||
this.invertQuery = invertQuery;
|
this.invertQuery = invertQuery ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
override meetsRequirement(scene: BattleScene): boolean {
|
override meetsRequirement(scene: BattleScene): boolean {
|
||||||
@ -66,7 +66,7 @@ export class CanLearnMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(_scene: BattleScene, _pokemon?: PlayerPokemon): [string, string] {
|
||||||
return ["requiredMoves", this.requiredMoves.join(", ")];
|
return ["requiredMoves", this.requiredMoves.map(m => new PokemonMove(m).getName()).join(", ")];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
|
private getPokemonLevelMoves(pkm: PlayerPokemon): Moves[] {
|
||||||
|
@ -4,34 +4,37 @@ import { UiTheme } from "#enums/ui-theme";
|
|||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export function getEncounterText(scene: BattleScene, keyOrString: string, primaryStyle?: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string {
|
export function getEncounterText(scene: BattleScene, keyOrString?: string, primaryStyle?: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string | null {
|
||||||
if (isNullOrUndefined(keyOrString)) {
|
if (isNullOrUndefined(keyOrString)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let textString: string = getTextWithDialogueTokens(scene, keyOrString);
|
let textString: string | null = getTextWithDialogueTokens(scene, keyOrString);
|
||||||
|
|
||||||
// Can only color the text if a Primary Style is defined
|
// Can only color the text if a Primary Style is defined
|
||||||
// primaryStyle is applied to all text that does not have its own specified style
|
// primaryStyle is applied to all text that does not have its own specified style
|
||||||
if (primaryStyle) {
|
if (primaryStyle && textString) {
|
||||||
textString = getTextWithColors(textString, primaryStyle, uiTheme);
|
textString = getTextWithColors(textString, primaryStyle, uiTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
return textString;
|
return textString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTextWithDialogueTokens(scene: BattleScene, keyOrString: string): string {
|
function getTextWithDialogueTokens(scene: BattleScene, keyOrString?: string): string | null {
|
||||||
if (isNullOrUndefined(keyOrString)) {
|
if (isNullOrUndefined(keyOrString)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i18next.exists(keyOrString, scene.currentBattle?.mysteryEncounter?.dialogueTokens)) {
|
const tokens = scene.currentBattle?.mysteryEncounter?.dialogueTokens;
|
||||||
|
// @ts-ignore
|
||||||
|
if (i18next.exists(keyOrString, tokens)) {
|
||||||
const stringArray = [`${keyOrString}`] as any;
|
const stringArray = [`${keyOrString}`] as any;
|
||||||
stringArray.raw = [`${keyOrString}`];
|
stringArray.raw = [`${keyOrString}`];
|
||||||
return i18next.t(stringArray, scene.currentBattle?.mysteryEncounter?.dialogueTokens);
|
// @ts-ignore
|
||||||
|
return i18next.t(stringArray, tokens) as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyOrString;
|
return keyOrString ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,8 +43,8 @@ function getTextWithDialogueTokens(scene: BattleScene, keyOrString: string): str
|
|||||||
* @param contentKey
|
* @param contentKey
|
||||||
*/
|
*/
|
||||||
export function queueEncounterMessage(scene: BattleScene, contentKey: string): void {
|
export function queueEncounterMessage(scene: BattleScene, contentKey: string): void {
|
||||||
const text: string = getEncounterText(scene, contentKey);
|
const text: string | null = getEncounterText(scene, contentKey);
|
||||||
scene.queueMessage(text, null, true);
|
scene.queueMessage(text ?? "", null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,8 +56,8 @@ export function queueEncounterMessage(scene: BattleScene, contentKey: string): v
|
|||||||
*/
|
*/
|
||||||
export function showEncounterText(scene: BattleScene, contentKey: string, callbackDelay: number = 0, prompt: boolean = true): Promise<void> {
|
export function showEncounterText(scene: BattleScene, contentKey: string, callbackDelay: number = 0, prompt: boolean = true): Promise<void> {
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
const text: string = getEncounterText(scene, contentKey);
|
const text: string | null = getEncounterText(scene, contentKey);
|
||||||
scene.ui.showText(text, null, () => resolve(), callbackDelay, prompt);
|
scene.ui.showText(text ?? "", null, () => resolve(), callbackDelay, prompt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,8 +70,8 @@ export function showEncounterText(scene: BattleScene, contentKey: string, callba
|
|||||||
*/
|
*/
|
||||||
export function showEncounterDialogue(scene: BattleScene, textContentKey: string, speakerContentKey: string, callbackDelay: number = 0): Promise<void> {
|
export function showEncounterDialogue(scene: BattleScene, textContentKey: string, speakerContentKey: string, callbackDelay: number = 0): Promise<void> {
|
||||||
return new Promise<void>(resolve => {
|
return new Promise<void>(resolve => {
|
||||||
const text: string = getEncounterText(scene, textContentKey);
|
const text: string | null = getEncounterText(scene, textContentKey);
|
||||||
const speaker: string = getEncounterText(scene, speakerContentKey);
|
const speaker: string | null = getEncounterText(scene, speakerContentKey);
|
||||||
scene.ui.showDialogue(text, speaker, null, () => resolve(), callbackDelay);
|
scene.ui.showDialogue(text ?? "", speaker ?? "", null, () => resolve(), callbackDelay);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { BattlerIndex, BattleType } from "#app/battle";
|
import Battle, { BattlerIndex, BattleType } from "#app/battle";
|
||||||
import { biomeLinks, BiomePoolTier } from "#app/data/biomes";
|
import { biomeLinks, BiomePoolTier } from "#app/data/biomes";
|
||||||
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
import MysteryEncounterOption from "#app/data/mystery-encounters/mystery-encounter-option";
|
||||||
import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
import { WEIGHT_INCREMENT_ON_SPAWN_MISS } from "#app/data/mystery-encounters/mystery-encounters";
|
||||||
@ -10,7 +10,7 @@ import { BattleEndPhase, EggLapsePhase, ExpPhase, GameOverPhase, MovePhase, Sele
|
|||||||
import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
import { MysteryEncounterBattlePhase, MysteryEncounterBattleStartCleanupPhase, MysteryEncounterPhase, MysteryEncounterRewardsPhase } from "#app/phases/mystery-encounter-phases";
|
||||||
import PokemonData from "#app/system/pokemon-data";
|
import PokemonData from "#app/system/pokemon-data";
|
||||||
import { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
import { OptionSelectConfig, OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||||
import { PartyOption, PartyUiMode } from "#app/ui/party-ui-handler";
|
import { PartyOption, PartyUiMode, PokemonSelectFilter } from "#app/ui/party-ui-handler";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import * as Utils from "#app/utils";
|
import * as Utils from "#app/utils";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
@ -101,29 +101,30 @@ export interface EnemyPartyConfig {
|
|||||||
* @param partyConfig - Can pass various customizable attributes for the enemy party, see EnemyPartyConfig
|
* @param partyConfig - Can pass various customizable attributes for the enemy party, see EnemyPartyConfig
|
||||||
*/
|
*/
|
||||||
export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: EnemyPartyConfig): Promise<void> {
|
export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig: EnemyPartyConfig): Promise<void> {
|
||||||
const loaded = false;
|
const loaded: boolean = false;
|
||||||
const loadEnemyAssets = [];
|
const loadEnemyAssets: Promise<void>[] = [];
|
||||||
|
|
||||||
const battle = scene.currentBattle;
|
const battle: Battle = scene.currentBattle;
|
||||||
|
|
||||||
let doubleBattle = partyConfig?.doubleBattle;
|
let doubleBattle: boolean = partyConfig?.doubleBattle ?? false;
|
||||||
|
|
||||||
// Trainer
|
// Trainer
|
||||||
const trainerType = partyConfig?.trainerType;
|
const trainerType = partyConfig?.trainerType;
|
||||||
let trainerConfig = partyConfig?.trainerConfig;
|
const partyTrainerConfig = partyConfig?.trainerConfig;
|
||||||
if (trainerType || trainerConfig) {
|
let trainerConfig: TrainerConfig;
|
||||||
|
if (!isNullOrUndefined(trainerType) || partyTrainerConfig) {
|
||||||
scene.currentBattle.mysteryEncounter.encounterMode = MysteryEncounterMode.TRAINER_BATTLE;
|
scene.currentBattle.mysteryEncounter.encounterMode = MysteryEncounterMode.TRAINER_BATTLE;
|
||||||
if (scene.currentBattle.trainer) {
|
if (scene.currentBattle.trainer) {
|
||||||
scene.currentBattle.trainer.setVisible(false);
|
scene.currentBattle.trainer.setVisible(false);
|
||||||
scene.currentBattle.trainer.destroy();
|
scene.currentBattle.trainer.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
trainerConfig = partyConfig?.trainerConfig ? partyConfig?.trainerConfig : trainerConfigs[trainerType];
|
trainerConfig = partyConfig?.trainerConfig ? partyConfig?.trainerConfig : trainerConfigs[trainerType!];
|
||||||
|
|
||||||
const doubleTrainer = trainerConfig.doubleOnly || (trainerConfig.hasDouble && partyConfig.doubleBattle);
|
const doubleTrainer = trainerConfig.doubleOnly || (trainerConfig.hasDouble && !!partyConfig.doubleBattle);
|
||||||
doubleBattle = doubleTrainer;
|
doubleBattle = doubleTrainer;
|
||||||
const trainerFemale = isNullOrUndefined(partyConfig.female) ? !!(Utils.randSeedInt(2)) : partyConfig.female;
|
const trainerFemale = isNullOrUndefined(partyConfig.female) ? !!(Utils.randSeedInt(2)) : partyConfig.female;
|
||||||
const newTrainer = new Trainer(scene, trainerConfig.trainerType, doubleTrainer ? TrainerVariant.DOUBLE : trainerFemale ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT, null, null, null, trainerConfig);
|
const newTrainer = new Trainer(scene, trainerConfig.trainerType, doubleTrainer ? TrainerVariant.DOUBLE : trainerFemale ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT, undefined, undefined, undefined, trainerConfig);
|
||||||
newTrainer.x += 300;
|
newTrainer.x += 300;
|
||||||
newTrainer.setVisible(false);
|
newTrainer.setVisible(false);
|
||||||
scene.field.add(newTrainer);
|
scene.field.add(newTrainer);
|
||||||
@ -134,7 +135,8 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
} else {
|
} else {
|
||||||
// Wild
|
// Wild
|
||||||
scene.currentBattle.mysteryEncounter.encounterMode = MysteryEncounterMode.WILD_BATTLE;
|
scene.currentBattle.mysteryEncounter.encounterMode = MysteryEncounterMode.WILD_BATTLE;
|
||||||
battle.enemyLevels = new Array(partyConfig?.pokemonConfigs?.length > 0 ? partyConfig?.pokemonConfigs?.length : doubleBattle ? 2 : 1).fill(null).map(() => scene.currentBattle.getLevelForWave());
|
const numEnemies = partyConfig?.pokemonConfigs && partyConfig.pokemonConfigs.length > 0 ? partyConfig?.pokemonConfigs?.length : doubleBattle ? 2 : 1;
|
||||||
|
battle.enemyLevels = new Array(numEnemies).fill(null).map(() => scene.currentBattle.getLevelForWave());
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
scene.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy());
|
||||||
@ -146,7 +148,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
// This can be amplified or counteracted by setting levelAdditiveMultiplier in config
|
// This can be amplified or counteracted by setting levelAdditiveMultiplier in config
|
||||||
// levelAdditiveMultiplier value of 0.5 will halve the modifier scaling, 2 will double it, etc.
|
// levelAdditiveMultiplier value of 0.5 will halve the modifier scaling, 2 will double it, etc.
|
||||||
// Leaving null/undefined will disable level scaling
|
// Leaving null/undefined will disable level scaling
|
||||||
const mult = !isNullOrUndefined(partyConfig.levelAdditiveMultiplier) ? partyConfig.levelAdditiveMultiplier : 0;
|
const mult: number = !isNullOrUndefined(partyConfig.levelAdditiveMultiplier) ? partyConfig.levelAdditiveMultiplier! : 0;
|
||||||
const additive = Math.max(Math.round((scene.currentBattle.waveIndex / 10) * mult), 0);
|
const additive = Math.max(Math.round((scene.currentBattle.waveIndex / 10) * mult), 0);
|
||||||
battle.enemyLevels = battle.enemyLevels.map(level => level + additive);
|
battle.enemyLevels = battle.enemyLevels.map(level => level + additive);
|
||||||
|
|
||||||
@ -155,10 +157,10 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
let dataSource;
|
let dataSource;
|
||||||
let isBoss = false;
|
let isBoss = false;
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
if (trainerType || trainerConfig) {
|
if ((!isNullOrUndefined(trainerType) || trainerConfig) && battle.trainer) {
|
||||||
// Allows overriding a trainer's pokemon to use specific species/data
|
// Allows overriding a trainer's pokemon to use specific species/data
|
||||||
if (e < partyConfig?.pokemonConfigs?.length) {
|
if (partyConfig?.pokemonConfigs && e < partyConfig.pokemonConfigs.length) {
|
||||||
const config = partyConfig?.pokemonConfigs?.[e];
|
const config = partyConfig.pokemonConfigs[e];
|
||||||
level = config.level ? config.level : level;
|
level = config.level ? config.level : level;
|
||||||
dataSource = config.dataSource;
|
dataSource = config.dataSource;
|
||||||
enemySpecies = config.species;
|
enemySpecies = config.species;
|
||||||
@ -168,8 +170,8 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
battle.enemyParty[e] = battle.trainer.genPartyMember(e);
|
battle.enemyParty[e] = battle.trainer.genPartyMember(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (e < partyConfig?.pokemonConfigs?.length) {
|
if (partyConfig?.pokemonConfigs && e < partyConfig.pokemonConfigs.length) {
|
||||||
const config = partyConfig?.pokemonConfigs?.[e];
|
const config = partyConfig.pokemonConfigs[e];
|
||||||
level = config.level ? config.level : level;
|
level = config.level ? config.level : level;
|
||||||
dataSource = config.dataSource;
|
dataSource = config.dataSource;
|
||||||
enemySpecies = config.species;
|
enemySpecies = config.species;
|
||||||
@ -201,8 +203,8 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
scene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig));
|
scene.gameData.setPokemonSeen(enemyPokemon, true, !!(trainerType || trainerConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e < partyConfig?.pokemonConfigs?.length) {
|
if (partyConfig?.pokemonConfigs && e < partyConfig.pokemonConfigs.length) {
|
||||||
const config = partyConfig?.pokemonConfigs?.[e];
|
const config = partyConfig.pokemonConfigs[e];
|
||||||
|
|
||||||
// Generate new id, reset status and HP in case using data source
|
// Generate new id, reset status and HP in case using data source
|
||||||
if (config.dataSource) {
|
if (config.dataSource) {
|
||||||
@ -211,24 +213,24 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
|
|
||||||
// Set form
|
// Set form
|
||||||
if (!isNullOrUndefined(config.formIndex)) {
|
if (!isNullOrUndefined(config.formIndex)) {
|
||||||
enemyPokemon.formIndex = config.formIndex;
|
enemyPokemon.formIndex = config.formIndex!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set shiny
|
// Set shiny
|
||||||
if (!isNullOrUndefined(config.shiny)) {
|
if (!isNullOrUndefined(config.shiny)) {
|
||||||
enemyPokemon.shiny = config.shiny;
|
enemyPokemon.shiny = config.shiny!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set custom mystery encounter data fields (such as sprite scale, custom abilities, types, etc.)
|
// Set custom mystery encounter data fields (such as sprite scale, custom abilities, types, etc.)
|
||||||
if (!isNullOrUndefined(config.mysteryEncounterData)) {
|
if (!isNullOrUndefined(config.mysteryEncounterData)) {
|
||||||
enemyPokemon.mysteryEncounterData = config.mysteryEncounterData;
|
enemyPokemon.mysteryEncounterData = config.mysteryEncounterData!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Boss
|
// Set Boss
|
||||||
if (config.isBoss) {
|
if (config.isBoss) {
|
||||||
let segments = !isNullOrUndefined(config.bossSegments) ? config.bossSegments : scene.getEncounterBossSegments(scene.currentBattle.waveIndex, level, enemySpecies, true);
|
let segments = !isNullOrUndefined(config.bossSegments) ? config.bossSegments! : scene.getEncounterBossSegments(scene.currentBattle.waveIndex, level, enemySpecies, true);
|
||||||
if (!isNullOrUndefined(config.bossSegmentModifier)) {
|
if (!isNullOrUndefined(config.bossSegmentModifier)) {
|
||||||
segments += config.bossSegmentModifier;
|
segments += config.bossSegmentModifier!;
|
||||||
}
|
}
|
||||||
enemyPokemon.setBoss(true, segments);
|
enemyPokemon.setBoss(true, segments);
|
||||||
}
|
}
|
||||||
@ -253,7 +255,7 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
if (statusEffects) {
|
if (statusEffects) {
|
||||||
// Default to cureturn 3 for sleep
|
// Default to cureturn 3 for sleep
|
||||||
const status = Array.isArray(statusEffects) ? statusEffects[0] : statusEffects;
|
const status = Array.isArray(statusEffects) ? statusEffects[0] : statusEffects;
|
||||||
const cureTurn = Array.isArray(statusEffects) ? statusEffects[1] : statusEffects === StatusEffect.SLEEP ? 3 : null;
|
const cureTurn = Array.isArray(statusEffects) ? statusEffects[1] : statusEffects === StatusEffect.SLEEP ? 3 : undefined;
|
||||||
enemyPokemon.status = new Status(status, 0, cureTurn);
|
enemyPokemon.status = new Status(status, 0, cureTurn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,24 +266,24 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
|
|
||||||
// Set ability
|
// Set ability
|
||||||
if (!isNullOrUndefined(config.abilityIndex)) {
|
if (!isNullOrUndefined(config.abilityIndex)) {
|
||||||
enemyPokemon.abilityIndex = config.abilityIndex;
|
enemyPokemon.abilityIndex = config.abilityIndex!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set gender
|
// Set gender
|
||||||
if (!isNullOrUndefined(config.gender)) {
|
if (!isNullOrUndefined(config.gender)) {
|
||||||
enemyPokemon.gender = config.gender;
|
enemyPokemon.gender = config.gender!;
|
||||||
enemyPokemon.summonData.gender = config.gender;
|
enemyPokemon.summonData.gender = config.gender!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set moves
|
// Set moves
|
||||||
if (config?.moveSet?.length > 0) {
|
if (config?.moveSet && config.moveSet.length > 0) {
|
||||||
const moves = config.moveSet.map(m => new PokemonMove(m));
|
const moves = config.moveSet.map(m => new PokemonMove(m));
|
||||||
enemyPokemon.moveset = moves;
|
enemyPokemon.moveset = moves;
|
||||||
enemyPokemon.summonData.moveset = moves;
|
enemyPokemon.summonData.moveset = moves;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set tags
|
// Set tags
|
||||||
if (config.tags?.length > 0) {
|
if (config.tags && config.tags.length > 0) {
|
||||||
const tags = config.tags;
|
const tags = config.tags;
|
||||||
tags.forEach(tag => enemyPokemon.addTag(tag));
|
tags.forEach(tag => enemyPokemon.addTag(tag));
|
||||||
}
|
}
|
||||||
@ -319,9 +321,13 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
|||||||
});
|
});
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
regenerateModifierPoolThresholds(scene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
|
regenerateModifierPoolThresholds(scene.getEnemyField(), battle.battleType === BattleType.TRAINER ? ModifierPoolType.TRAINER : ModifierPoolType.WILD);
|
||||||
const customModifierTypes = partyConfig?.pokemonConfigs?.map(config => config?.modifierConfigs);
|
const customModifierTypes = partyConfig?.pokemonConfigs
|
||||||
|
?.filter(config => config?.modifierConfigs)
|
||||||
|
.map(config => config.modifierConfigs!);
|
||||||
|
if (customModifierTypes) {
|
||||||
scene.generateEnemyModifiers(customModifierTypes);
|
scene.generateEnemyModifiers(customModifierTypes);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -368,7 +374,7 @@ export function updatePlayerMoney(scene: BattleScene, changeValue: number, playS
|
|||||||
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
* @param pregenArgs - can specify BerryType for berries, TM for TMs, AttackBoostType for item, etc.
|
||||||
*/
|
*/
|
||||||
export function generateModifierType(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierType {
|
export function generateModifierType(scene: BattleScene, modifier: () => ModifierType, pregenArgs?: any[]): ModifierType {
|
||||||
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier);
|
const modifierId = Object.keys(modifierTypes).find(k => modifierTypes[k] === modifier)!;
|
||||||
let result: ModifierType = modifierTypes[modifierId]?.();
|
let result: ModifierType = modifierTypes[modifierId]?.();
|
||||||
|
|
||||||
// Populates item id and tier (order matters)
|
// Populates item id and tier (order matters)
|
||||||
@ -376,8 +382,8 @@ export function generateModifierType(scene: BattleScene, modifier: () => Modifie
|
|||||||
.withIdFromFunc(modifierTypes[modifierId])
|
.withIdFromFunc(modifierTypes[modifierId])
|
||||||
.withTierFromPool();
|
.withTierFromPool();
|
||||||
|
|
||||||
result = result instanceof ModifierTypeGenerator ? result.generateType(scene.getParty(), pregenArgs) : result;
|
const generatedResult = result instanceof ModifierTypeGenerator ? result.generateType(scene.getParty(), pregenArgs) : result;
|
||||||
return result;
|
return generatedResult ?? result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -399,7 +405,7 @@ export function generateModifierTypeOption(scene: BattleScene, modifier: () => M
|
|||||||
* @param onPokemonNotSelected - Any logic that needs to be performed if no Pokemon is chosen
|
* @param onPokemonNotSelected - Any logic that needs to be performed if no Pokemon is chosen
|
||||||
* @param selectablePokemonFilter
|
* @param selectablePokemonFilter
|
||||||
*/
|
*/
|
||||||
export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (pokemon: PlayerPokemon) => void | OptionSelectItem[], onPokemonNotSelected?: () => void, selectablePokemonFilter?: (pokemon: PlayerPokemon) => string): Promise<boolean> {
|
export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (pokemon: PlayerPokemon) => void | OptionSelectItem[], onPokemonNotSelected?: () => void, selectablePokemonFilter?: PokemonSelectFilter): Promise<boolean> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const modeToSetOnExit = scene.ui.getMode();
|
const modeToSetOnExit = scene.ui.getMode();
|
||||||
|
|
||||||
@ -451,7 +457,7 @@ export function selectPokemonForOption(scene: BattleScene, onPokemonSelected: (p
|
|||||||
scene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
|
scene.ui.setModeWithoutClear(Mode.OPTION_SELECT, config, null, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const textPromptKey = scene.currentBattle.mysteryEncounter.selectedOption.dialogue.secondOptionPrompt;
|
const textPromptKey = scene.currentBattle.mysteryEncounter?.selectedOption?.dialogue?.secondOptionPrompt;
|
||||||
if (!textPromptKey) {
|
if (!textPromptKey) {
|
||||||
displayOptions();
|
displayOptions();
|
||||||
} else {
|
} else {
|
||||||
@ -486,7 +492,7 @@ export function setEncounterRewards(scene: BattleScene, customShopRewards?: Cust
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (customShopRewards) {
|
if (customShopRewards) {
|
||||||
scene.unshiftPhase(new SelectModifierPhase(scene, 0, null, customShopRewards));
|
scene.unshiftPhase(new SelectModifierPhase(scene, 0, undefined, customShopRewards));
|
||||||
} else {
|
} else {
|
||||||
scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
scene.tryRemovePhase(p => p instanceof SelectModifierPhase);
|
||||||
}
|
}
|
||||||
@ -530,7 +536,7 @@ export function setEncounterExp(scene: BattleScene, participantId: integer | int
|
|||||||
const multipleParticipantExpBonusModifier = scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
|
const multipleParticipantExpBonusModifier = scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
|
||||||
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
||||||
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < scene.getMaxExpLevel());
|
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < scene.getMaxExpLevel());
|
||||||
const partyMemberExp = [];
|
const partyMemberExp: number[] = [];
|
||||||
// EXP value calculation is based off Pokemon.getExpValue
|
// EXP value calculation is based off Pokemon.getExpValue
|
||||||
let expValue = Math.floor(baseExpValue * (useWaveIndex ? scene.currentBattle.waveIndex : 1) / 5 + 1);
|
let expValue = Math.floor(baseExpValue * (useWaveIndex ? scene.currentBattle.waveIndex : 1) / 5 + 1);
|
||||||
|
|
||||||
@ -581,7 +587,7 @@ export function setEncounterExp(scene: BattleScene, participantId: integer | int
|
|||||||
|
|
||||||
const medianLevel = Math.floor(totalLevel / expPartyMembers.length);
|
const medianLevel = Math.floor(totalLevel / expPartyMembers.length);
|
||||||
|
|
||||||
const recipientExpPartyMemberIndexes = [];
|
const recipientExpPartyMemberIndexes: number[] = [];
|
||||||
expPartyMembers.forEach((expPartyMember, epm) => {
|
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||||
if (expPartyMember.level <= medianLevel) {
|
if (expPartyMember.level <= medianLevel) {
|
||||||
recipientExpPartyMemberIndexes.push(epm);
|
recipientExpPartyMemberIndexes.push(epm);
|
||||||
@ -720,7 +726,7 @@ export function transitionMysteryEncounterIntroVisuals(scene: BattleScene, hide:
|
|||||||
scene.field.remove(pokemon, true);
|
scene.field.remove(pokemon, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.currentBattle.mysteryEncounter.introVisuals = null;
|
scene.currentBattle.mysteryEncounter.introVisuals = undefined;
|
||||||
}
|
}
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}
|
}
|
||||||
@ -808,12 +814,14 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
})
|
})
|
||||||
.map(b => !Array.isArray(b) ? b : b[0]);
|
.map(b => !Array.isArray(b) ? b : b[0]);
|
||||||
}, i * 100);
|
}, i * 100);
|
||||||
|
if (biomes! && biomes.length > 0) {
|
||||||
const specialBiomes = biomes.filter(b => alwaysPickTheseBiomes.includes(b));
|
const specialBiomes = biomes.filter(b => alwaysPickTheseBiomes.includes(b));
|
||||||
if (specialBiomes.length > 0) {
|
if (specialBiomes.length > 0) {
|
||||||
currentBiome = specialBiomes[Utils.randSeedInt(specialBiomes.length)];
|
currentBiome = specialBiomes[Utils.randSeedInt(specialBiomes.length)];
|
||||||
} else {
|
} else {
|
||||||
currentBiome = biomes[Utils.randSeedInt(biomes.length)];
|
currentBiome = biomes[Utils.randSeedInt(biomes.length)];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (biomeLinks.hasOwnProperty(currentBiome)) {
|
} else if (biomeLinks.hasOwnProperty(currentBiome)) {
|
||||||
currentBiome = (biomeLinks[currentBiome] as Biome);
|
currentBiome = (biomeLinks[currentBiome] as Biome);
|
||||||
} else {
|
} else {
|
||||||
@ -840,7 +848,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
// Otherwise, roll encounter
|
// Otherwise, roll encounter
|
||||||
|
|
||||||
const roll = Utils.randSeedInt(256);
|
const roll = Utils.randSeedInt(256);
|
||||||
validMEfloorsByBiome.set(Biome[currentBiome], validMEfloorsByBiome.get(Biome[currentBiome]) + 1);
|
validMEfloorsByBiome.set(Biome[currentBiome], (validMEfloorsByBiome.get(Biome[currentBiome]) ?? 0) + 1);
|
||||||
|
|
||||||
// If total number of encounters is lower than expected for the run, slightly favor a new encounter
|
// If total number of encounters is lower than expected for the run, slightly favor a new encounter
|
||||||
// Do the reverse as well
|
// Do the reverse as well
|
||||||
@ -866,7 +874,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
const rareThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2]; // 64 - 32 - 16 - 10 = 6
|
const rareThreshold = totalWeight - tierWeights[0] - tierWeights[1] - tierWeights[2]; // 64 - 32 - 16 - 10 = 6
|
||||||
|
|
||||||
tierValue > commonThreshold ? ++numEncounters[0] : tierValue > uncommonThreshold ? ++numEncounters[1] : tierValue > rareThreshold ? ++numEncounters[2] : ++numEncounters[3];
|
tierValue > commonThreshold ? ++numEncounters[0] : tierValue > uncommonThreshold ? ++numEncounters[1] : tierValue > rareThreshold ? ++numEncounters[2] : ++numEncounters[3];
|
||||||
encountersByBiome.set(Biome[currentBiome], encountersByBiome.get(Biome[currentBiome]) + 1);
|
encountersByBiome.set(Biome[currentBiome], (encountersByBiome.get(Biome[currentBiome]) ?? 0) + 1);
|
||||||
} else {
|
} else {
|
||||||
encounterRate += WEIGHT_INCREMENT_ON_SPAWN_MISS;
|
encounterRate += WEIGHT_INCREMENT_ON_SPAWN_MISS;
|
||||||
}
|
}
|
||||||
@ -899,7 +907,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
|
|
||||||
const encountersPerRunPerBiome = encountersByBiomeRuns.reduce((a, b) => {
|
const encountersPerRunPerBiome = encountersByBiomeRuns.reduce((a, b) => {
|
||||||
for (const biome of a.keys()) {
|
for (const biome of a.keys()) {
|
||||||
a.set(biome, a.get(biome) + b.get(biome));
|
a.set(biome, a.get(biome)! + b.get(biome)!);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
});
|
});
|
||||||
@ -910,7 +918,7 @@ export function calculateMEAggregateStats(scene: BattleScene, baseSpawnWeight: n
|
|||||||
|
|
||||||
const validMEFloorsPerRunPerBiome = validFloorsByBiome.reduce((a, b) => {
|
const validMEFloorsPerRunPerBiome = validFloorsByBiome.reduce((a, b) => {
|
||||||
for (const biome of a.keys()) {
|
for (const biome of a.keys()) {
|
||||||
a.set(biome, a.get(biome) + b.get(biome));
|
a.set(biome, a.get(biome)! + b.get(biome)!);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
});
|
});
|
||||||
|
@ -52,13 +52,13 @@ export function getRandomPlayerPokemon(scene: BattleScene, isAllowedInBattle: bo
|
|||||||
|
|
||||||
if (doNotReturnLastAbleMon && unfaintedMons.length === 1) {
|
if (doNotReturnLastAbleMon && unfaintedMons.length === 1) {
|
||||||
chosenIndex = randSeedInt(faintedMons.length);
|
chosenIndex = randSeedInt(faintedMons.length);
|
||||||
chosenPokemon = faintedMons.at(chosenIndex);
|
chosenPokemon = faintedMons[chosenIndex];
|
||||||
} else if (isAllowedInBattle) {
|
} else if (isAllowedInBattle) {
|
||||||
chosenIndex = randSeedInt(unfaintedMons.length);
|
chosenIndex = randSeedInt(unfaintedMons.length);
|
||||||
chosenPokemon = unfaintedMons.at(chosenIndex);
|
chosenPokemon = unfaintedMons[chosenIndex];
|
||||||
} else {
|
} else {
|
||||||
chosenIndex = randSeedInt(party.length);
|
chosenIndex = randSeedInt(party.length);
|
||||||
chosenPokemon = party.at(chosenIndex);
|
chosenPokemon = party[chosenIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
return chosenPokemon;
|
return chosenPokemon;
|
||||||
@ -72,17 +72,17 @@ export function getRandomPlayerPokemon(scene: BattleScene, isAllowedInBattle: bo
|
|||||||
*/
|
*/
|
||||||
export function getHighestLevelPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
export function getHighestLevelPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
let pokemon: PlayerPokemon;
|
let pokemon: PlayerPokemon | null = null;
|
||||||
party.every(p => {
|
|
||||||
|
for (const p of party) {
|
||||||
if (unfainted && p.isFainted()) {
|
if (unfainted && p.isFainted()) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon = pokemon ? pokemon?.level < p?.level ? p : pokemon : p;
|
pokemon = pokemon ? pokemon?.level < p?.level ? p : pokemon : p;
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return pokemon;
|
return pokemon!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,17 +94,17 @@ export function getHighestLevelPlayerPokemon(scene: BattleScene, unfainted: bool
|
|||||||
*/
|
*/
|
||||||
export function getHighestStatPlayerPokemon(scene: BattleScene, stat: Stat, unfainted: boolean = false): PlayerPokemon {
|
export function getHighestStatPlayerPokemon(scene: BattleScene, stat: Stat, unfainted: boolean = false): PlayerPokemon {
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
let pokemon: PlayerPokemon;
|
let pokemon: PlayerPokemon | null = null;
|
||||||
party.every(p => {
|
|
||||||
|
for (const p of party) {
|
||||||
if (unfainted && p.isFainted()) {
|
if (unfainted && p.isFainted()) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon = pokemon ? pokemon.getStat(stat) < p?.getStat(stat) ? p : pokemon : p;
|
pokemon = pokemon ? pokemon.getStat(stat) < p?.getStat(stat) ? p : pokemon : p;
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return pokemon;
|
return pokemon!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,17 +115,17 @@ export function getHighestStatPlayerPokemon(scene: BattleScene, stat: Stat, unfa
|
|||||||
*/
|
*/
|
||||||
export function getLowestLevelPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
export function getLowestLevelPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
let pokemon: PlayerPokemon;
|
let pokemon: PlayerPokemon | null = null;
|
||||||
party.every(p => {
|
|
||||||
|
for (const p of party) {
|
||||||
if (unfainted && p.isFainted()) {
|
if (unfainted && p.isFainted()) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon = pokemon ? pokemon?.level > p?.level ? p : pokemon : p;
|
pokemon = pokemon ? pokemon?.level > p?.level ? p : pokemon : p;
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return pokemon;
|
return pokemon!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,17 +136,17 @@ export function getLowestLevelPlayerPokemon(scene: BattleScene, unfainted: boole
|
|||||||
*/
|
*/
|
||||||
export function getHighestStatTotalPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
export function getHighestStatTotalPlayerPokemon(scene: BattleScene, unfainted: boolean = false): PlayerPokemon {
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
let pokemon: PlayerPokemon;
|
let pokemon: PlayerPokemon | null = null;
|
||||||
party.every(p => {
|
|
||||||
|
for (const p of party) {
|
||||||
if (unfainted && p.isFainted()) {
|
if (unfainted && p.isFainted()) {
|
||||||
return true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pokemon = pokemon ? pokemon?.stats.reduce((a, b) => a + b) < p?.stats.reduce((a, b) => a + b) ? p : pokemon : p;
|
pokemon = pokemon ? pokemon?.stats.reduce((a, b) => a + b) < p?.stats.reduce((a, b) => a + b) ? p : pokemon : p;
|
||||||
return true;
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return pokemon;
|
return pokemon!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,8 +166,8 @@ export function getRandomSpeciesByStarterTier(starterTiers: number | [number, nu
|
|||||||
.filter(s => getPokemonSpecies(s[0]) && (!excludedSpecies || !excludedSpecies.includes(s[0])))
|
.filter(s => getPokemonSpecies(s[0]) && (!excludedSpecies || !excludedSpecies.includes(s[0])))
|
||||||
.map(s => [getPokemonSpecies(s[0]), s[1]]);
|
.map(s => [getPokemonSpecies(s[0]), s[1]]);
|
||||||
|
|
||||||
if (!isNullOrUndefined(types) && types.length > 0) {
|
if (types && types.length > 0) {
|
||||||
filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || types.includes(s[0].type2));
|
filteredSpecies = filteredSpecies.filter(s => types.includes(s[0].type1) || (!isNullOrUndefined(s[0].type2) && types.includes(s[0].type2!)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no filtered mons exist at specified starter tiers, will expand starter search range until there are
|
// If no filtered mons exist at specified starter tiers, will expand starter search range until there are
|
||||||
@ -260,10 +260,12 @@ export function applyHealToPokemon(scene: BattleScene, pokemon: PlayerPokemon, h
|
|||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
|
export async function modifyPlayerPokemonBST(pokemon: PlayerPokemon, value: number) {
|
||||||
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE().generateType(null, [value]);
|
const modType = modifierTypes.MYSTERY_ENCOUNTER_SHUCKLE_JUICE().generateType(pokemon.scene.getParty(), [value]);
|
||||||
const modifier = modType.newModifier(pokemon);
|
const modifier = modType?.newModifier(pokemon);
|
||||||
|
if (modifier) {
|
||||||
await pokemon.scene.addModifier(modifier, false, false, false, true);
|
await pokemon.scene.addModifier(modifier, false, false, false, true);
|
||||||
pokemon.calculateStats();
|
pokemon.calculateStats();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -479,7 +481,7 @@ function failCatch(scene: BattleScene, pokemon: EnemyPokemon, originalY: number,
|
|||||||
* @param showCatchObtainMessage
|
* @param showCatchObtainMessage
|
||||||
* @param isObtain
|
* @param isObtain
|
||||||
*/
|
*/
|
||||||
export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phaser.GameObjects.Sprite, pokeballType: PokeballType, showCatchObtainMessage: boolean = true, isObtain: boolean = false): Promise<void> {
|
export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, pokeball: Phaser.GameObjects.Sprite | null, pokeballType: PokeballType, showCatchObtainMessage: boolean = true, isObtain: boolean = false): Promise<void> {
|
||||||
scene.unshiftPhase(new VictoryPhase(scene, BattlerIndex.ENEMY, true));
|
scene.unshiftPhase(new VictoryPhase(scene, BattlerIndex.ENEMY, true));
|
||||||
|
|
||||||
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
const speciesForm = !pokemon.fusionSpecies ? pokemon.getSpeciesForm() : pokemon.getFusionSpeciesForm();
|
||||||
@ -508,7 +510,9 @@ export async function catchPokemon(scene: BattleScene, pokemon: EnemyPokemon, po
|
|||||||
const doPokemonCatchMenu = () => {
|
const doPokemonCatchMenu = () => {
|
||||||
const end = () => {
|
const end = () => {
|
||||||
scene.pokemonInfoContainer.hide();
|
scene.pokemonInfoContainer.hide();
|
||||||
|
if (pokeball) {
|
||||||
removePb(scene, pokeball);
|
removePb(scene, pokeball);
|
||||||
|
}
|
||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
const removePokemon = () => {
|
const removePokemon = () => {
|
||||||
|
@ -146,7 +146,7 @@ export class Arena {
|
|||||||
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
|
return this.randomSpecies(waveIndex, level, (attempt || 0) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, isBoss, this.scene.gameMode);
|
const newSpeciesId = ret.getWildSpeciesForLevel(level, true, !!isBoss, this.scene.gameMode);
|
||||||
if (newSpeciesId !== ret.speciesId) {
|
if (newSpeciesId !== ret.speciesId) {
|
||||||
console.log("Replaced", Species[ret.speciesId], "with", Species[newSpeciesId]);
|
console.log("Replaced", Species[ret.speciesId], "with", Species[newSpeciesId]);
|
||||||
ret = getPokemonSpecies(newSpeciesId);
|
ret = getPokemonSpecies(newSpeciesId);
|
||||||
|
@ -4,6 +4,7 @@ import MysteryEncounter from "../data/mystery-encounters/mystery-encounter";
|
|||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { isNullOrUndefined } from "#app/utils";
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
import { getSpriteKeysFromSpecies } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils";
|
||||||
|
import PlayAnimationConfig = Phaser.Types.Animations.PlayAnimationConfig;
|
||||||
|
|
||||||
type KnownFileRoot =
|
type KnownFileRoot =
|
||||||
| "arenas"
|
| "arenas"
|
||||||
@ -85,7 +86,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!isNullOrUndefined(result.species)) {
|
if (!isNullOrUndefined(result.species)) {
|
||||||
const keys = getSpriteKeysFromSpecies(result.species);
|
const keys = getSpriteKeysFromSpecies(result.species!);
|
||||||
result.spriteKey = keys.spriteKey;
|
result.spriteKey = keys.spriteKey;
|
||||||
result.fileRoot = keys.fileRoot;
|
result.fileRoot = keys.fileRoot;
|
||||||
result.isPokemon = true;
|
result.isPokemon = true;
|
||||||
@ -164,7 +165,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNaN(alpha)) {
|
if (!isNullOrUndefined(alpha)) {
|
||||||
sprite.setAlpha(alpha);
|
sprite.setAlpha(alpha);
|
||||||
tintSprite.setAlpha(alpha);
|
tintSprite.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
@ -290,7 +291,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
const tintSprites = this.getTintSprites();
|
const tintSprites = this.getTintSprites();
|
||||||
this.spriteConfigs.forEach((config, i) => {
|
this.spriteConfigs.forEach((config, i) => {
|
||||||
if (!config.disableAnimation) {
|
if (!config.disableAnimation) {
|
||||||
const trainerAnimConfig = {
|
const trainerAnimConfig: PlayAnimationConfig = {
|
||||||
key: config.spriteKey,
|
key: config.spriteKey,
|
||||||
repeat: config?.repeat ? -1 : 0,
|
repeat: config?.repeat ? -1 : 0,
|
||||||
startFrame: config?.startFrame ?? 0
|
startFrame: config?.startFrame ?? 0
|
||||||
@ -307,7 +308,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
*/
|
*/
|
||||||
getSpriteAtIndex(index: number): Phaser.GameObjects.Sprite[] {
|
getSpriteAtIndex(index: number): Phaser.GameObjects.Sprite[] {
|
||||||
if (!this.spriteConfigs) {
|
if (!this.spriteConfigs) {
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret: Phaser.GameObjects.Sprite[] = [];
|
const ret: Phaser.GameObjects.Sprite[] = [];
|
||||||
@ -319,7 +320,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
|
|
||||||
getSprites(): Phaser.GameObjects.Sprite[] {
|
getSprites(): Phaser.GameObjects.Sprite[] {
|
||||||
if (!this.spriteConfigs) {
|
if (!this.spriteConfigs) {
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret: Phaser.GameObjects.Sprite[] = [];
|
const ret: Phaser.GameObjects.Sprite[] = [];
|
||||||
@ -331,7 +332,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
|
|||||||
|
|
||||||
getTintSprites(): Phaser.GameObjects.Sprite[] {
|
getTintSprites(): Phaser.GameObjects.Sprite[] {
|
||||||
if (!this.spriteConfigs) {
|
if (!this.spriteConfigs) {
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret: Phaser.GameObjects.Sprite[] = [];
|
const ret: Phaser.GameObjects.Sprite[] = [];
|
||||||
|
@ -108,7 +108,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
public mysteryEncounterData: MysteryEncounterPokemonData;
|
public mysteryEncounterData: MysteryEncounterPokemonData;
|
||||||
|
|
||||||
/** Used by Mystery Encounters to execute pokemon-specific logic (such as stat boosts) at start of battle */
|
/** Used by Mystery Encounters to execute pokemon-specific logic (such as stat boosts) at start of battle */
|
||||||
public mysteryEncounterBattleEffects: (pokemon: Pokemon) => void = null;
|
public mysteryEncounterBattleEffects?: (pokemon: Pokemon) => void;
|
||||||
|
|
||||||
public fieldPosition: FieldPosition;
|
public fieldPosition: FieldPosition;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export const delibirdyDialogue = {
|
export const delibirdyDialogue = {
|
||||||
intro: "A pack of Delibird have appeared!",
|
intro: "A pack of Delibird have appeared!",
|
||||||
title: "Delibird-y",
|
title: "Delibir-dy",
|
||||||
description: "The Delibirds are looking at you expectantly, as if they want something. Perhaps giving them an item or some money would satisfy them?",
|
description: "The Delibirds are looking at you expectantly, as if they want something. Perhaps giving them an item or some money would satisfy them?",
|
||||||
query: "What will you give them?",
|
query: "What will you give them?",
|
||||||
invalid_selection: "Pokémon doesn't have that kind of item.",
|
invalid_selection: "Pokémon doesn't have that kind of item.",
|
||||||
|
@ -28,7 +28,6 @@ import { BerryType } from "#enums/berry-type";
|
|||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import { Species } from "#enums/species";
|
import { Species } from "#enums/species";
|
||||||
import { getPokemonNameWithAffix } from "#app/messages.js";
|
import { getPokemonNameWithAffix } from "#app/messages.js";
|
||||||
import { isNullOrUndefined } from "../utils";
|
|
||||||
|
|
||||||
const outputModifierData = false;
|
const outputModifierData = false;
|
||||||
const useMaxWeightForOutput = false;
|
const useMaxWeightForOutput = false;
|
||||||
@ -120,26 +119,6 @@ export class ModifierType {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates the tier field by performing a reverse lookup on the modifier pool specified by {@linkcode poolType} using the
|
|
||||||
* {@linkcode ModifierType}'s id.
|
|
||||||
* @param poolType the {@linkcode ModifierPoolType} to look into to derive the item's tier; defaults to {@linkcode ModifierPoolType.PLAYER}
|
|
||||||
*/
|
|
||||||
withTierFromPool(poolType: ModifierPoolType = ModifierPoolType.PLAYER): ModifierType {
|
|
||||||
for (const tier of Object.values(getModifierPoolForType(poolType))) {
|
|
||||||
for (const modifier of tier) {
|
|
||||||
if (this.id === modifier.modifierType.id) {
|
|
||||||
this.tier = modifier.modifierType.tier;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.tier) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
@ -2113,10 +2092,10 @@ function getModifierTypeOptionWithRetry(existingOptions: ModifierTypeOption[], r
|
|||||||
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
allowLuckUpgrades = allowLuckUpgrades ?? true;
|
||||||
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier, undefined, 0, allowLuckUpgrades);
|
let candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, tier, undefined, 0, allowLuckUpgrades);
|
||||||
let r = 0;
|
let r = 0;
|
||||||
while (existingOptions.length && ++r < retryCount && existingOptions.filter(o => o.type.name === candidate.type.name || o.type.group === candidate.type.group).length) {
|
while (existingOptions.length && ++r < retryCount && existingOptions.filter(o => o.type.name === candidate?.type.name || o.type.group === candidate?.type.group).length) {
|
||||||
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate.type.tier, candidate.upgradeCount, 0, allowLuckUpgrades);
|
candidate = getNewModifierTypeOption(party, ModifierPoolType.PLAYER, candidate?.type.tier ?? tier, candidate?.upgradeCount, 0, allowLuckUpgrades);
|
||||||
}
|
}
|
||||||
return candidate;
|
return candidate!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -826,7 +826,7 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
|
|||||||
args[1].forEach((v, i) => {
|
args[1].forEach((v, i) => {
|
||||||
const isHp = i === 0;
|
const isHp = i === 0;
|
||||||
let mult = 1;
|
let mult = 1;
|
||||||
if (this.stackCount === this.getMaxHeldItemCount(null)) {
|
if (this.stackCount === this.getMaxHeldItemCount()) {
|
||||||
mult = isHp ? 1.05 : 1.1;
|
mult = isHp ? 1.05 : 1.1;
|
||||||
}
|
}
|
||||||
const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult);
|
const newVal = Math.floor((v + this.stackCount * (isHp ? 1 : 2)) * mult);
|
||||||
@ -840,7 +840,7 @@ export class PokemonIncrementingStatModifier extends PokemonHeldItemModifier {
|
|||||||
return 1.2;
|
return 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
getMaxHeldItemCount(pokemon?: Pokemon): integer {
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import { allMoves, applyMoveAttrs, BypassSleepAttr, ChargeAttr, applyFilteredMov
|
|||||||
import { Mode } from "./ui/ui";
|
import { Mode } from "./ui/ui";
|
||||||
import { Command } from "./ui/command-ui-handler";
|
import { Command } from "./ui/command-ui-handler";
|
||||||
import { Stat } from "./data/pokemon-stat";
|
import { Stat } from "./data/pokemon-stat";
|
||||||
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier, TurnStatusEffectModifier, PokemonResetNegativeStatStageModifier } from "./modifier/modifier";
|
import { BerryModifier, ContactHeldItemTransferChanceModifier, EnemyAttackStatusEffectChanceModifier, EnemyPersistentModifier, EnemyStatusEffectHealChanceModifier, EnemyTurnHealModifier, ExpBalanceModifier, ExpBoosterModifier, ExpShareModifier, ExtraModifierModifier, FlinchChanceModifier, HealingBoosterModifier, HitHealModifier, LapsingPersistentModifier, MapModifier, Modifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier, PokemonHeldItemModifier, PokemonInstantReviveModifier, SwitchEffectTransferModifier, TurnHealModifier, TurnHeldItemTransferModifier, MoneyMultiplierModifier, MoneyInterestModifier, IvScannerModifier, LapsingPokemonHeldItemModifier, PokemonMultiHitModifier, overrideModifiers, overrideHeldItems, BypassSpeedChanceModifier, TurnStatusEffectModifier, PokemonResetNegativeStatStageModifier, PokemonIncrementingStatModifier } from "./modifier/modifier";
|
||||||
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
import PartyUiHandler, { PartyOption, PartyUiMode } from "./ui/party-ui-handler";
|
||||||
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
import { doPokeballBounceAnim, getPokeballAtlasKey, getPokeballCatchMultiplier, getPokeballTintColor, PokeballType } from "./data/pokeball";
|
||||||
import { CommonAnim, CommonBattleAnim, initEncounterAnims, initMoveAnim, loadEncounterAnimAssets, loadMoveAnimAssets, MoveAnim } from "./data/battle-anims";
|
import { CommonAnim, CommonBattleAnim, initEncounterAnims, initMoveAnim, loadEncounterAnimAssets, loadMoveAnimAssets, MoveAnim } from "./data/battle-anims";
|
||||||
@ -19,7 +19,7 @@ import { biomeLinks, getBiomeName } from "./data/biomes";
|
|||||||
import { ModifierTier } from "./modifier/modifier-tier";
|
import { ModifierTier } from "./modifier/modifier-tier";
|
||||||
import { CustomModifierSettings, FusePokemonModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, modifierTypes, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, regenerateModifierPoolThresholds, RememberMoveModifierType, TmModifierType } from "./modifier/modifier-type";
|
import { CustomModifierSettings, FusePokemonModifierType, getDailyRunStarterModifiers, getEnemyBuffModifierForWave, getModifierType, getPlayerModifierTypeOptions, getPlayerShopModifierTypeOptionsForWave, ModifierPoolType, ModifierType, ModifierTypeFunc, ModifierTypeOption, modifierTypes, PokemonModifierType, PokemonMoveModifierType, PokemonPpRestoreModifierType, PokemonPpUpModifierType, regenerateModifierPoolThresholds, RememberMoveModifierType, TmModifierType } from "./modifier/modifier-type";
|
||||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||||
import { BattlerTagLapseType, CenterOfAttentionTag, EncoreTag, ProtectedTag, SemiInvulnerableTag, TrappedTag } from "./data/battler-tags";
|
import { BattlerTagLapseType, CenterOfAttentionTag, EncoreTag, MysteryEncounterPostSummonTag, ProtectedTag, SemiInvulnerableTag, TrappedTag } from "./data/battler-tags";
|
||||||
import { getPokemonNameWithAffix } from "./messages";
|
import { getPokemonNameWithAffix } from "./messages";
|
||||||
import { Starter } from "./ui/starter-select-ui-handler";
|
import { Starter } from "./ui/starter-select-ui-handler";
|
||||||
import { Gender } from "./data/gender";
|
import { Gender } from "./data/gender";
|
||||||
@ -70,6 +70,7 @@ import { doTrainerExclamation, handleMysteryEncounterBattleStartEffects, handleM
|
|||||||
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
import ModifierSelectUiHandler, { SHOP_OPTIONS_ROW_LIMIT } from "#app/ui/modifier-select-ui-handler";
|
||||||
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
import { getEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils";
|
||||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||||
|
import { isNullOrUndefined } from "./utils";
|
||||||
|
|
||||||
const { t } = i18next;
|
const { t } = i18next;
|
||||||
|
|
||||||
@ -865,7 +866,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
|
|
||||||
// Add intro visuals for mystery encounter
|
// Add intro visuals for mystery encounter
|
||||||
mysteryEncounter.initIntroVisuals(this.scene);
|
mysteryEncounter.initIntroVisuals(this.scene);
|
||||||
this.scene.field.add(mysteryEncounter.introVisuals);
|
this.scene.field.add(mysteryEncounter.introVisuals!);
|
||||||
}
|
}
|
||||||
|
|
||||||
let totalBst = 0;
|
let totalBst = 0;
|
||||||
@ -930,7 +931,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
const newEncounter = this.scene.getMysteryEncounter(mysteryEncounter);
|
const newEncounter = this.scene.getMysteryEncounter(mysteryEncounter);
|
||||||
battle.mysteryEncounter = newEncounter;
|
battle.mysteryEncounter = newEncounter;
|
||||||
}
|
}
|
||||||
loadEnemyAssets.push(battle.mysteryEncounter.introVisuals.loadAssets().then(() => battle.mysteryEncounter.introVisuals.initSprite()));
|
loadEnemyAssets.push(battle.mysteryEncounter.introVisuals!.loadAssets().then(() => battle.mysteryEncounter.introVisuals!.initSprite()));
|
||||||
// Load Mystery Encounter Exclamation bubble and sfx
|
// Load Mystery Encounter Exclamation bubble and sfx
|
||||||
loadEnemyAssets.push(new Promise<void>(resolve => {
|
loadEnemyAssets.push(new Promise<void>(resolve => {
|
||||||
this.scene.loadSe("GEN8- Exclaim", "battle_anims", "GEN8- Exclaim.wav");
|
this.scene.loadSe("GEN8- Exclaim", "battle_anims", "GEN8- Exclaim.wav");
|
||||||
@ -1130,7 +1131,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) {
|
} else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) {
|
||||||
const introVisuals = this.scene.currentBattle.mysteryEncounter.introVisuals;
|
const introVisuals = this.scene.currentBattle.mysteryEncounter.introVisuals!;
|
||||||
introVisuals.playAnim();
|
introVisuals.playAnim();
|
||||||
|
|
||||||
if (this.scene.currentBattle.mysteryEncounter.onVisualsStart) {
|
if (this.scene.currentBattle.mysteryEncounter.onVisualsStart) {
|
||||||
@ -1148,13 +1149,16 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
|
|
||||||
if (showEncounterMessage) {
|
if (showEncounterMessage) {
|
||||||
const introDialogue = this.scene.currentBattle.mysteryEncounter.dialogue.intro;
|
const introDialogue = this.scene.currentBattle.mysteryEncounter.dialogue.intro;
|
||||||
|
if (!introDialogue) {
|
||||||
|
doShowEncounterOptions();
|
||||||
|
} else {
|
||||||
const FIRST_DIALOGUE_PROMPT_DELAY = 750;
|
const FIRST_DIALOGUE_PROMPT_DELAY = 750;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const showNextDialogue = () => {
|
const showNextDialogue = () => {
|
||||||
const nextAction = i === introDialogue.length - 1 ? doShowEncounterOptions : showNextDialogue;
|
const nextAction = i === introDialogue.length - 1 ? doShowEncounterOptions : showNextDialogue;
|
||||||
const dialogue = introDialogue[i];
|
const dialogue = introDialogue[i];
|
||||||
const title = getEncounterText(this.scene, dialogue.speaker);
|
const title = getEncounterText(this.scene, dialogue?.speaker);
|
||||||
const text = getEncounterText(this.scene, dialogue.text);
|
const text = getEncounterText(this.scene, dialogue.text)!;
|
||||||
i++;
|
i++;
|
||||||
if (title) {
|
if (title) {
|
||||||
this.scene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
this.scene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
||||||
@ -1166,6 +1170,7 @@ export class EncounterPhase extends BattlePhase {
|
|||||||
if (introDialogue.length > 0) {
|
if (introDialogue.length > 0) {
|
||||||
showNextDialogue();
|
showNextDialogue();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
doShowEncounterOptions();
|
doShowEncounterOptions();
|
||||||
}
|
}
|
||||||
@ -1330,7 +1335,7 @@ export class NextEncounterPhase extends EncounterPhase {
|
|||||||
}
|
}
|
||||||
if (lastEncounterVisuals) {
|
if (lastEncounterVisuals) {
|
||||||
this.scene.field.remove(lastEncounterVisuals, true);
|
this.scene.field.remove(lastEncounterVisuals, true);
|
||||||
this.scene.lastMysteryEncounter.introVisuals = null;
|
this.scene.lastMysteryEncounter.introVisuals = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.tryOverrideForBattleSpec()) {
|
if (!this.tryOverrideForBattleSpec()) {
|
||||||
@ -4378,7 +4383,7 @@ export class VictoryPhase extends PokemonPhase {
|
|||||||
if (participated) {
|
if (participated) {
|
||||||
partyMember.addFriendship(2);
|
partyMember.addFriendship(2);
|
||||||
const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier);
|
const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier);
|
||||||
if (!isNullOrUndefined(machoBraceModifier) && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this.scene)) {
|
if (machoBraceModifier && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this.scene)) {
|
||||||
machoBraceModifier.stackCount++;
|
machoBraceModifier.stackCount++;
|
||||||
this.scene.updateModifiers(true, true);
|
this.scene.updateModifiers(true, true);
|
||||||
partyMember.updateInfo();
|
partyMember.updateInfo();
|
||||||
@ -5857,7 +5862,7 @@ export class SelectModifierPhase extends BattlePhase {
|
|||||||
} else {
|
} else {
|
||||||
baseValue = 250;
|
baseValue = 250;
|
||||||
}
|
}
|
||||||
const multiplier = !isNullOrUndefined(this.customModifierSettings?.rerollMultiplier) ? this.customModifierSettings.rerollMultiplier : 1;
|
const multiplier = !isNullOrUndefined(this.customModifierSettings?.rerollMultiplier) ? this.customModifierSettings!.rerollMultiplier! : 1;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -72,7 +72,7 @@ export class MysteryEncounterPhase extends Phase {
|
|||||||
|
|
||||||
if (option.onPreOptionPhase) {
|
if (option.onPreOptionPhase) {
|
||||||
this.scene.executeWithSeedOffset(async () => {
|
this.scene.executeWithSeedOffset(async () => {
|
||||||
return await option.onPreOptionPhase(this.scene)
|
return await option.onPreOptionPhase!(this.scene)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (isNullOrUndefined(result) || result) {
|
if (isNullOrUndefined(result) || result) {
|
||||||
this.continueEncounter();
|
this.continueEncounter();
|
||||||
@ -93,7 +93,7 @@ export class MysteryEncounterPhase extends Phase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const optionSelectDialogue = this.scene.currentBattle?.mysteryEncounter?.selectedOption?.dialogue;
|
const optionSelectDialogue = this.scene.currentBattle?.mysteryEncounter?.selectedOption?.dialogue;
|
||||||
if (optionSelectDialogue?.selected?.length > 0) {
|
if (optionSelectDialogue?.selected && optionSelectDialogue.selected.length > 0) {
|
||||||
// Handle intermediate dialogue (between player selection event and the onOptionSelect logic)
|
// Handle intermediate dialogue (between player selection event and the onOptionSelect logic)
|
||||||
this.scene.ui.setMode(Mode.MESSAGE);
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
const selectedDialogue = optionSelectDialogue.selected;
|
const selectedDialogue = optionSelectDialogue.selected;
|
||||||
@ -101,17 +101,17 @@ export class MysteryEncounterPhase extends Phase {
|
|||||||
const showNextDialogue = () => {
|
const showNextDialogue = () => {
|
||||||
const nextAction = i === selectedDialogue.length - 1 ? endDialogueAndContinueEncounter : showNextDialogue;
|
const nextAction = i === selectedDialogue.length - 1 ? endDialogueAndContinueEncounter : showNextDialogue;
|
||||||
const dialogue = selectedDialogue[i];
|
const dialogue = selectedDialogue[i];
|
||||||
let title: string = null;
|
let title: string | null = null;
|
||||||
const text: string = getEncounterText(this.scene, dialogue.text);
|
const text: string | null = getEncounterText(this.scene, dialogue.text);
|
||||||
if (dialogue.speaker) {
|
if (dialogue.speaker) {
|
||||||
title = getEncounterText(this.scene, dialogue.speaker);
|
title = getEncounterText(this.scene, dialogue.speaker);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
if (title) {
|
if (title) {
|
||||||
this.scene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
this.scene.ui.showDialogue(text ?? "", title, null, nextAction, 0, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
||||||
} else {
|
} else {
|
||||||
this.scene.ui.showText(text, null, nextAction, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
|
this.scene.ui.showText(text ?? "", null, nextAction, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ export class MysteryEncounterOptionSelectedPhase extends Phase {
|
|||||||
|
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene);
|
super(scene);
|
||||||
this.onOptionSelect = this.scene.currentBattle.mysteryEncounter.selectedOption.onOptionPhase;
|
this.onOptionSelect = this.scene.currentBattle.mysteryEncounter.selectedOption!.onOptionPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
@ -223,10 +223,10 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
|
|
||||||
if (encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
if (encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||||
if (scene.currentBattle.double) {
|
if (scene.currentBattle.double) {
|
||||||
return i18next.t("battle:trainerAppearedDouble", { trainerName: scene.currentBattle.trainer.getName(TrainerSlot.NONE, true) });
|
return i18next.t("battle:trainerAppearedDouble", { trainerName: scene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return i18next.t("battle:trainerAppeared", { trainerName: scene.currentBattle.trainer.getName(TrainerSlot.NONE, true) });
|
return i18next.t("battle:trainerAppeared", { trainerName: scene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,22 +276,22 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const encounterMessages = scene.currentBattle.trainer.getEncounterMessages();
|
const encounterMessages = scene.currentBattle.trainer?.getEncounterMessages();
|
||||||
|
|
||||||
if (!encounterMessages?.length) {
|
if (!encounterMessages || !encounterMessages.length) {
|
||||||
doSummon();
|
doSummon();
|
||||||
} else {
|
} else {
|
||||||
const trainer = this.scene.currentBattle.trainer;
|
const trainer = this.scene.currentBattle.trainer;
|
||||||
let message: string;
|
let message: string;
|
||||||
scene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), this.scene.currentBattle.mysteryEncounter.getSeedOffset());
|
scene.executeWithSeedOffset(() => message = Utils.randSeedItem(encounterMessages), this.scene.currentBattle.mysteryEncounter.getSeedOffset());
|
||||||
|
message = message!; // tell TS compiler it's defined now
|
||||||
const showDialogueAndSummon = () => {
|
const showDialogueAndSummon = () => {
|
||||||
scene.ui.showDialogue(message, trainer.getName(TrainerSlot.NONE, true), null, () => {
|
scene.ui.showDialogue(message, trainer?.getName(TrainerSlot.NONE, true), null, () => {
|
||||||
scene.charSprite.hide().then(() => scene.hideFieldOverlay(250).then(() => doSummon()));
|
scene.charSprite.hide().then(() => scene.hideFieldOverlay(250).then(() => doSummon()));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (scene.currentBattle.trainer.config.hasCharSprite && !scene.ui.shouldSkipDialogue(message)) {
|
if (this.scene.currentBattle.trainer?.config.hasCharSprite && !this.scene.ui.shouldSkipDialogue(message)) {
|
||||||
scene.showFieldOverlay(500).then(() => scene.charSprite.showCharacter(trainer.getKey(), getCharVariantFromDialogue(encounterMessages[0])).then(() => showDialogueAndSummon()));
|
this.scene.showFieldOverlay(500).then(() => this.scene.charSprite.showCharacter(trainer?.getKey()!, getCharVariantFromDialogue(encounterMessages[0])).then(() => showDialogueAndSummon())); // TODO: is this bang correct?
|
||||||
} else {
|
} else {
|
||||||
showDialogueAndSummon();
|
showDialogueAndSummon();
|
||||||
}
|
}
|
||||||
@ -349,6 +349,9 @@ export class MysteryEncounterBattlePhase extends Phase {
|
|||||||
showEnemyTrainer(): void {
|
showEnemyTrainer(): void {
|
||||||
// Show enemy trainer
|
// Show enemy trainer
|
||||||
const trainer = this.scene.currentBattle.trainer;
|
const trainer = this.scene.currentBattle.trainer;
|
||||||
|
if (!trainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
trainer.alpha = 0;
|
trainer.alpha = 0;
|
||||||
trainer.x += 16;
|
trainer.x += 16;
|
||||||
trainer.y -= 16;
|
trainer.y -= 16;
|
||||||
@ -416,7 +419,7 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
this.scene.currentBattle.mysteryEncounter.doEncounterRewards(this.scene);
|
this.scene.currentBattle.mysteryEncounter.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, null, { fillRemaining: false, rerollMultiplier: 0 }));
|
this.scene.unshiftPhase(new SelectModifierPhase(this.scene, 0, undefined, { fillRemaining: false, rerollMultiplier: 0 }));
|
||||||
}
|
}
|
||||||
// Do not use ME's seedOffset for rewards, these should always be consistent with waveIndex (once per wave)
|
// Do not use ME's seedOffset for rewards, these should always be consistent with waveIndex (once per wave)
|
||||||
}, this.scene.currentBattle.waveIndex * 1000);
|
}, this.scene.currentBattle.waveIndex * 1000);
|
||||||
@ -436,11 +439,11 @@ export class MysteryEncounterRewardsPhase extends Phase {
|
|||||||
*/
|
*/
|
||||||
export class PostMysteryEncounterPhase extends Phase {
|
export class PostMysteryEncounterPhase extends Phase {
|
||||||
private readonly FIRST_DIALOGUE_PROMPT_DELAY = 750;
|
private readonly FIRST_DIALOGUE_PROMPT_DELAY = 750;
|
||||||
onPostOptionSelect: OptionPhaseCallback;
|
onPostOptionSelect?: OptionPhaseCallback;
|
||||||
|
|
||||||
constructor(scene: BattleScene) {
|
constructor(scene: BattleScene) {
|
||||||
super(scene);
|
super(scene);
|
||||||
this.onPostOptionSelect = this.scene.currentBattle.mysteryEncounter.selectedOption.onPostOptionPhase;
|
this.onPostOptionSelect = this.scene.currentBattle.mysteryEncounter.selectedOption?.onPostOptionPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
@ -448,7 +451,7 @@ export class PostMysteryEncounterPhase extends Phase {
|
|||||||
|
|
||||||
if (this.onPostOptionSelect) {
|
if (this.onPostOptionSelect) {
|
||||||
this.scene.executeWithSeedOffset(async () => {
|
this.scene.executeWithSeedOffset(async () => {
|
||||||
return await this.onPostOptionSelect(this.scene)
|
return await this.onPostOptionSelect!(this.scene)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
if (isNullOrUndefined(result) || result) {
|
if (isNullOrUndefined(result) || result) {
|
||||||
this.continueEncounter();
|
this.continueEncounter();
|
||||||
@ -467,13 +470,13 @@ export class PostMysteryEncounterPhase extends Phase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const outroDialogue = this.scene.currentBattle?.mysteryEncounter?.dialogue?.outro;
|
const outroDialogue = this.scene.currentBattle?.mysteryEncounter?.dialogue?.outro;
|
||||||
if (outroDialogue?.length > 0) {
|
if (outroDialogue && outroDialogue.length > 0) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
const showNextDialogue = () => {
|
const showNextDialogue = () => {
|
||||||
const nextAction = i === outroDialogue.length - 1 ? endPhase : showNextDialogue;
|
const nextAction = i === outroDialogue.length - 1 ? endPhase : showNextDialogue;
|
||||||
const dialogue = outroDialogue[i];
|
const dialogue = outroDialogue[i];
|
||||||
let title: string = null;
|
let title: string | null = null;
|
||||||
const text: string = getEncounterText(this.scene, dialogue.text);
|
const text: string | null = getEncounterText(this.scene, dialogue.text);
|
||||||
if (dialogue.speaker) {
|
if (dialogue.speaker) {
|
||||||
title = getEncounterText(this.scene, dialogue.speaker);
|
title = getEncounterText(this.scene, dialogue.speaker);
|
||||||
}
|
}
|
||||||
@ -481,9 +484,9 @@ export class PostMysteryEncounterPhase extends Phase {
|
|||||||
i++;
|
i++;
|
||||||
this.scene.ui.setMode(Mode.MESSAGE);
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
if (title) {
|
if (title) {
|
||||||
this.scene.ui.showDialogue(text, title, null, nextAction, 0, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
this.scene.ui.showDialogue(text ?? "", title, null, nextAction, 0, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0);
|
||||||
} else {
|
} else {
|
||||||
this.scene.ui.showText(text, null, nextAction, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
|
this.scene.ui.showText(text ?? "", null, nextAction, i === 1 ? this.FIRST_DIALOGUE_PROMPT_DELAY : 0, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import { expect, vi } from "vitest";
|
|||||||
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
import * as EncounterPhaseUtils from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import PartyUiHandler from "#app/ui/party-ui-handler";
|
import PartyUiHandler from "#app/ui/party-ui-handler";
|
||||||
import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler";
|
import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler";
|
||||||
|
import { isNullOrUndefined } from "#app/utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a MysteryEncounter to either the start of a battle, or to the MysteryEncounterRewardsPhase, depending on the option selected
|
* Runs a MysteryEncounter to either the start of a battle, or to the MysteryEncounterRewardsPhase, depending on the option selected
|
||||||
@ -18,7 +19,7 @@ import OptionSelectUiHandler from "#app/ui/settings/option-select-ui-handler";
|
|||||||
* @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 } = null, 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");
|
||||||
await runSelectMysteryEncounterOption(game, optionNo, secondaryOptionSelect);
|
await runSelectMysteryEncounterOption(game, optionNo, secondaryOptionSelect);
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ export async function runMysteryEncounterToEnd(game: GameManager, optionNo: numb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runSelectMysteryEncounterOption(game: GameManager, optionNo: number, secondaryOptionSelect: { pokemonNo: number, optionNo?: number } = null) {
|
export async function runSelectMysteryEncounterOption(game: GameManager, optionNo: number, secondaryOptionSelect?: { pokemonNo: number, optionNo?: number }) {
|
||||||
// Handle any eventual queued messages (e.g. weather phase, etc.)
|
// Handle any eventual queued messages (e.g. weather phase, etc.)
|
||||||
game.onNextPrompt("MessagePhase", Mode.MESSAGE, () => {
|
game.onNextPrompt("MessagePhase", Mode.MESSAGE, () => {
|
||||||
const uiHandler = game.scene.ui.getHandler<MessageUiHandler>();
|
const uiHandler = game.scene.ui.getHandler<MessageUiHandler>();
|
||||||
@ -107,8 +108,8 @@ export async function runSelectMysteryEncounterOption(game: GameManager, optionN
|
|||||||
|
|
||||||
uiHandler.processInput(Button.ACTION);
|
uiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
if (!isNaN(secondaryOptionSelect?.pokemonNo)) {
|
if (!isNullOrUndefined(secondaryOptionSelect?.pokemonNo)) {
|
||||||
await handleSecondaryOptionSelect(game, secondaryOptionSelect.pokemonNo, secondaryOptionSelect.optionNo);
|
await handleSecondaryOptionSelect(game, secondaryOptionSelect!.pokemonNo, secondaryOptionSelect!.optionNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,14 +129,14 @@ async function handleSecondaryOptionSelect(game: GameManager, pokemonNo: number,
|
|||||||
partyUiHandler.processInput(Button.ACTION);
|
partyUiHandler.processInput(Button.ACTION);
|
||||||
|
|
||||||
// If there is a second choice to make after selecting a Pokemon
|
// If there is a second choice to make after selecting a Pokemon
|
||||||
if (!isNaN(optionNo)) {
|
if (!isNullOrUndefined(optionNo)) {
|
||||||
// Wait for Summary menu to close and second options to spawn
|
// Wait for Summary menu to close and second options to spawn
|
||||||
const secondOptionUiHandler = game.scene.ui.handlers[Mode.OPTION_SELECT] as OptionSelectUiHandler;
|
const secondOptionUiHandler = game.scene.ui.handlers[Mode.OPTION_SELECT] as OptionSelectUiHandler;
|
||||||
vi.spyOn(secondOptionUiHandler, "show");
|
vi.spyOn(secondOptionUiHandler, "show");
|
||||||
await vi.waitFor(() => expect(secondOptionUiHandler.show).toHaveBeenCalled());
|
await vi.waitFor(() => expect(secondOptionUiHandler.show).toHaveBeenCalled());
|
||||||
|
|
||||||
// Navigate down to the correct option
|
// Navigate down to the correct option
|
||||||
for (let i = 1; i < optionNo; i++) {
|
for (let i = 1; i < optionNo!; i++) {
|
||||||
secondOptionUiHandler.processInput(Button.DOWN);
|
secondOptionUiHandler.processInput(Button.DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
||||||
@ -59,11 +59,11 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
expect(ATrainersTestEncounter.encounterTier).toBe(MysteryEncounterTier.ROGUE);
|
expect(ATrainersTestEncounter.encounterTier).toBe(MysteryEncounterTier.ROGUE);
|
||||||
expect(ATrainersTestEncounter.dialogue).toBeDefined();
|
expect(ATrainersTestEncounter.dialogue).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.dialogue.intro).toBeDefined();
|
expect(ATrainersTestEncounter.dialogue.intro).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.dialogue.intro[0].speaker).toBeDefined();
|
expect(ATrainersTestEncounter.dialogue.intro?.[0].speaker).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.dialogue.intro[0].text).toBeDefined();
|
expect(ATrainersTestEncounter.dialogue.intro?.[0].text).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(ATrainersTestEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(ATrainersTestEncounter.options.length).toBe(2);
|
expect(ATrainersTestEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,14 +92,14 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
expect(ATrainersTestEncounter.onInit).toBeDefined();
|
expect(ATrainersTestEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
ATrainersTestEncounter.populateDialogueTokensFromRequirements(scene);
|
ATrainersTestEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(ATrainersTestEncounter.dialogueTokens?.statTrainerName).toBeDefined();
|
expect(ATrainersTestEncounter.dialogueTokens?.statTrainerName).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.misc.trainerType).toBeDefined();
|
expect(ATrainersTestEncounter.misc.trainerType).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.misc.trainerNameKey).toBeDefined();
|
expect(ATrainersTestEncounter.misc.trainerNameKey).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.misc.trainerEggDescription).toBeDefined();
|
expect(ATrainersTestEncounter.misc.trainerEggDescription).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.dialogue.intro).toBeDefined();
|
expect(ATrainersTestEncounter.dialogue.intro).toBeDefined();
|
||||||
expect(ATrainersTestEncounter.options[1].dialogue.selected).toBeDefined();
|
expect(ATrainersTestEncounter.options[1].dialogue?.selected).toBeDefined();
|
||||||
expect(onInitResult).toBe(true);
|
expect(onInitResult).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,19 +108,19 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
const option = ATrainersTestEncounter.options[0];
|
const option = ATrainersTestEncounter.options[0];
|
||||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||||
expect(option.dialogue).toBeDefined();
|
expect(option.dialogue).toBeDefined();
|
||||||
expect(option.dialogue.buttonLabel).toStrictEqual(`${namespace}.option.1.label`);
|
expect(option.dialogue!.buttonLabel).toStrictEqual(`${namespace}.option.1.label`);
|
||||||
expect(option.dialogue.buttonTooltip).toStrictEqual(`${namespace}.option.1.tooltip`);
|
expect(option.dialogue!.buttonTooltip).toStrictEqual(`${namespace}.option.1.tooltip`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should start battle against the trainer", async () => {
|
it("Should start battle against the trainer", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.A_TRAINERS_TEST, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(["buck", "cheryl", "marley", "mira", "riley"].includes(scene.currentBattle.trainer.config.name.toLowerCase())).toBeTruthy();
|
expect(["buck", "cheryl", "marley", "mira", "riley"].includes(scene.currentBattle.trainer!.config.name.toLowerCase())).toBeTruthy();
|
||||||
expect(enemyField[0]).toBeDefined();
|
expect(enemyField[0]).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,10 +131,10 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
expect(eggsBefore).toBeDefined();
|
expect(eggsBefore).toBeDefined();
|
||||||
const eggsBeforeLength = eggsBefore.length;
|
const eggsBeforeLength = eggsBefore.length;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const eggsAfter = scene.gameData.eggs;
|
const eggsAfter = scene.gameData.eggs;
|
||||||
expect(eggsAfter).toBeDefined();
|
expect(eggsAfter).toBeDefined();
|
||||||
@ -151,7 +151,7 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
return {
|
return {
|
||||||
totalDuration: 1,
|
totalDuration: 1,
|
||||||
destroy: () => null
|
destroy: () => null
|
||||||
} as Phaser.Sound.NoAudioSound;
|
} as any;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,8 +159,8 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
const option = ATrainersTestEncounter.options[1];
|
const option = ATrainersTestEncounter.options[1];
|
||||||
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DEFAULT);
|
||||||
expect(option.dialogue).toBeDefined();
|
expect(option.dialogue).toBeDefined();
|
||||||
expect(option.dialogue.buttonLabel).toStrictEqual(`${namespace}.option.2.label`);
|
expect(option.dialogue?.buttonLabel).toStrictEqual(`${namespace}.option.2.label`);
|
||||||
expect(option.dialogue.buttonTooltip).toStrictEqual(`${namespace}.option.2.tooltip`);
|
expect(option.dialogue?.buttonTooltip).toStrictEqual(`${namespace}.option.2.tooltip`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should fully heal the party", async () => {
|
it("Should fully heal the party", async () => {
|
||||||
@ -182,7 +182,7 @@ describe("A Trainer's Test - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const eggsAfter = scene.gameData.eggs;
|
const eggsAfter = scene.gameData.eggs;
|
||||||
expect(eggsAfter).toBeDefined();
|
expect(eggsAfter).toBeDefined();
|
||||||
|
@ -35,7 +35,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -58,9 +58,9 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
expect(AbsoluteAvariceEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
expect(AbsoluteAvariceEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
||||||
expect(AbsoluteAvariceEncounter.dialogue).toBeDefined();
|
expect(AbsoluteAvariceEncounter.dialogue).toBeDefined();
|
||||||
expect(AbsoluteAvariceEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(AbsoluteAvariceEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(AbsoluteAvariceEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(AbsoluteAvariceEncounter.options.length).toBe(3);
|
expect(AbsoluteAvariceEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should spawn if player has enough berries", async () => {
|
it("should spawn if player has enough berries", async () => {
|
||||||
game.override.mysteryEncounterTier(MysteryEncounterTier.GREAT);
|
game.override.mysteryEncounterTier(MysteryEncounterTier.GREAT);
|
||||||
game.override.starterHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]);
|
game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]);
|
||||||
|
|
||||||
await game.runToMysteryEncounter();
|
await game.runToMysteryEncounter();
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should remove all player's berries at the start of the encounter", async () => {
|
it("should remove all player's berries at the start of the encounter", async () => {
|
||||||
game.override.starterHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]);
|
game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}]);
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
||||||
|
|
||||||
@ -134,13 +134,13 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT);
|
expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT);
|
||||||
const moveset = enemyField[0].moveset.map(m => m.moveId);
|
const moveset = enemyField[0].moveset.map(m => m?.moveId);
|
||||||
expect(moveset?.length).toBe(4);
|
expect(moveset?.length).toBe(4);
|
||||||
expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF]);
|
expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF]);
|
||||||
|
|
||||||
@ -151,10 +151,10 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should give reviver seed to each pokemon after battle", async () => {
|
it("should give reviver seed to each pokemon after battle", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
for (const partyPokemon of scene.getParty()) {
|
for (const partyPokemon of scene.getParty()) {
|
||||||
const pokemonId = partyPokemon.id;
|
const pokemonId = partyPokemon.id;
|
||||||
@ -162,7 +162,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
&& (m as PokemonHeldItemModifier).pokemonId === pokemonId, true) as PokemonHeldItemModifier[];
|
&& (m as PokemonHeldItemModifier).pokemonId === pokemonId, true) as PokemonHeldItemModifier[];
|
||||||
const revSeed = pokemonItems.find(i => i.type.name === "Reviver Seed");
|
const revSeed = pokemonItems.find(i => i.type.name === "Reviver Seed");
|
||||||
expect(revSeed).toBeDefined;
|
expect(revSeed).toBeDefined;
|
||||||
expect(revSeed.stackCount).toBe(1);
|
expect(revSeed?.stackCount).toBe(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -184,7 +184,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should return 3 (2/5ths floored) berries if 8 were stolen", async () => {
|
it("Should return 3 (2/5ths floored) berries if 8 were stolen", async () => {
|
||||||
game.override.starterHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 3, type: BerryType.APICOT}]);
|
game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 3, type: BerryType.APICOT}]);
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should return 2 (2/5ths floored) berries if 7 were stolen", async () => {
|
it("Should return 2 (2/5ths floored) berries if 7 were stolen", async () => {
|
||||||
game.override.starterHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 2, type: BerryType.APICOT}]);
|
game.override.startingHeldItems([{name: "BERRY", count: 2, type: BerryType.SITRUS}, {name: "BERRY", count: 3, type: BerryType.GANLON}, {name: "BERRY", count: 2, type: BerryType.APICOT}]);
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.ABSOLUTE_AVARICE, defaultParty);
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
||||||
const greedent = scene.getParty()[scene.getParty().length - 1];
|
const greedent = scene.getParty()[scene.getParty().length - 1];
|
||||||
expect(greedent.species.speciesId).toBe(Species.GREEDENT);
|
expect(greedent.species.speciesId).toBe(Species.GREEDENT);
|
||||||
const moveset = greedent.moveset.map(m => m.moveId);
|
const moveset = greedent.moveset.map(m => m?.moveId);
|
||||||
expect(moveset?.length).toBe(4);
|
expect(moveset?.length).toBe(4);
|
||||||
expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF]);
|
expect(moveset).toEqual([Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF]);
|
||||||
});
|
});
|
||||||
|
@ -38,7 +38,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
||||||
@ -65,9 +65,9 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
{ text: `${namespace}.intro` },
|
{ text: `${namespace}.intro` },
|
||||||
{ speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` }
|
{ speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` }
|
||||||
]);
|
]);
|
||||||
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(AnOfferYouCantRefuseEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(AnOfferYouCantRefuseEncounter.options.length).toBe(3);
|
expect(AnOfferYouCantRefuseEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
expect(AnOfferYouCantRefuseEncounter.onInit).toBeDefined();
|
expect(AnOfferYouCantRefuseEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
AnOfferYouCantRefuseEncounter.populateDialogueTokensFromRequirements(scene);
|
AnOfferYouCantRefuseEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.strongestPokemon).toBeDefined();
|
expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.strongestPokemon).toBeDefined();
|
||||||
expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.price).toBeDefined();
|
expect(AnOfferYouCantRefuseEncounter.dialogueTokens?.price).toBeDefined();
|
||||||
@ -153,7 +153,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
const itemModifier = scene.findModifier(m => m instanceof ShinyRateBoosterModifier) as ShinyRateBoosterModifier;
|
const itemModifier = scene.findModifier(m => m instanceof ShinyRateBoosterModifier) as ShinyRateBoosterModifier;
|
||||||
|
|
||||||
expect(itemModifier).toBeDefined();
|
expect(itemModifier).toBeDefined();
|
||||||
expect(itemModifier.stackCount).toBe(1);
|
expect(itemModifier?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should remove the Pokemon from the party", async () => {
|
it("Should remove the Pokemon from the party", async () => {
|
||||||
@ -199,7 +199,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
it("should award EXP to a pokemon with an ability in EXTORTION_ABILITIES", async () => {
|
it("should award EXP to a pokemon with an ability in EXTORTION_ABILITIES", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty);
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
const gyarados = party.find((pkm) => pkm.species.speciesId === Species.GYARADOS);
|
const gyarados = party.find((pkm) => pkm.species.speciesId === Species.GYARADOS)!;
|
||||||
const expBefore = gyarados.exp;
|
const expBefore = gyarados.exp;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
@ -210,7 +210,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
|
|||||||
it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => {
|
it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [Species.ABRA]);
|
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [Species.ABRA]);
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA);
|
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!;
|
||||||
abra.moveset = [new PokemonMove(Moves.BEAT_UP)];
|
abra.moveset = [new PokemonMove(Moves.BEAT_UP)];
|
||||||
const expBefore = abra.exp;
|
const expBefore = abra.exp;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -59,9 +59,9 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
expect(BerriesAboundEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
expect(BerriesAboundEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
||||||
expect(BerriesAboundEncounter.dialogue).toBeDefined();
|
expect(BerriesAboundEncounter.dialogue).toBeDefined();
|
||||||
expect(BerriesAboundEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(BerriesAboundEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(BerriesAboundEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(BerriesAboundEncounter.options.length).toBe(3);
|
expect(BerriesAboundEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -90,12 +90,12 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
expect(BerriesAboundEncounter.onInit).toBeDefined();
|
expect(BerriesAboundEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
BerriesAboundEncounter.populateDialogueTokensFromRequirements(scene);
|
BerriesAboundEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
const config = BerriesAboundEncounter.enemyPartyConfigs[0];
|
const config = BerriesAboundEncounter.enemyPartyConfigs[0];
|
||||||
expect(config).toBeDefined();
|
expect(config).toBeDefined();
|
||||||
expect(config.levelAdditiveMultiplier).toBe(1);
|
expect(config.levelAdditiveMultiplier).toBe(1);
|
||||||
expect(config.pokemonConfigs[0].isBoss).toBe(true);
|
expect(config.pokemonConfigs?.[0].isBoss).toBe(true);
|
||||||
expect(onInitResult).toBe(true);
|
expect(onInitResult).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -119,12 +119,12 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||||
|
|
||||||
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
||||||
const speciesToSpawn = config.pokemonConfigs[0].species.speciesId;
|
const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
||||||
});
|
});
|
||||||
@ -133,11 +133,12 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||||
|
|
||||||
const numBerries = game.scene.currentBattle.mysteryEncounter.misc.numBerries;
|
const numBerries = game.scene.currentBattle.mysteryEncounter.misc.numBerries;
|
||||||
|
scene.modifiers = [];
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const berriesAfter = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
const berriesAfter = scene.findModifiers(m => m instanceof BerryModifier) as BerryModifier[];
|
||||||
const berriesAfterCount = berriesAfter.reduce((a, b) => a + b.stackCount, 0);
|
const berriesAfterCount = berriesAfter.reduce((a, b) => a + b.stackCount, 0);
|
||||||
@ -147,10 +148,10 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should spawn a shop with 5 berries", async () => {
|
it("should spawn a shop with 5 berries", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -178,14 +179,14 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
|
||||||
|
|
||||||
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
||||||
const speciesToSpawn = config.pokemonConfigs[0].species.speciesId;
|
const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId;
|
||||||
// Setting enemy's level arbitrarily high to outspeed
|
// Setting enemy's level arbitrarily high to outspeed
|
||||||
config.pokemonConfigs[0].dataSource.level = 1000;
|
config.pokemonConfigs![0].dataSource!.level = 1000;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
||||||
|
|
||||||
@ -207,7 +208,7 @@ describe("Berries Abound - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -50,7 +50,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -78,9 +78,9 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}.intro_dialogue`,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(ClowningAroundEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(ClowningAroundEncounter.options.length).toBe(3);
|
expect(ClowningAroundEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,23 +111,23 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
expect(ClowningAroundEncounter.onInit).toBeDefined();
|
expect(ClowningAroundEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
ClowningAroundEncounter.populateDialogueTokensFromRequirements(scene);
|
ClowningAroundEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
const config = ClowningAroundEncounter.enemyPartyConfigs[0];
|
const config = ClowningAroundEncounter.enemyPartyConfigs[0];
|
||||||
|
|
||||||
expect(config.doubleBattle).toBe(true);
|
expect(config.doubleBattle).toBe(true);
|
||||||
expect(config.trainerConfig.trainerType).toBe(TrainerType.HARLEQUIN);
|
expect(config.trainerConfig?.trainerType).toBe(TrainerType.HARLEQUIN);
|
||||||
expect(config.pokemonConfigs[0]).toEqual({
|
expect(config.pokemonConfigs?.[0]).toEqual({
|
||||||
species: getPokemonSpecies(Species.MR_MIME),
|
species: getPokemonSpecies(Species.MR_MIME),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC]
|
moveSet: [Moves.TEETER_DANCE, Moves.ALLY_SWITCH, Moves.DAZZLING_GLEAM, Moves.PSYCHIC]
|
||||||
});
|
});
|
||||||
expect(config.pokemonConfigs[1]).toEqual({
|
expect(config.pokemonConfigs?.[1]).toEqual({
|
||||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||||
mysteryEncounterData: expect.anything(),
|
mysteryEncounterData: expect.anything(),
|
||||||
isBoss: true,
|
isBoss: true,
|
||||||
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
||||||
});
|
});
|
||||||
expect(config.pokemonConfigs[1].mysteryEncounterData.types.length).toBe(2);
|
expect(config.pokemonConfigs?.[1].mysteryEncounterData?.types.length).toBe(2);
|
||||||
expect([
|
expect([
|
||||||
Abilities.STURDY,
|
Abilities.STURDY,
|
||||||
Abilities.PICKUP,
|
Abilities.PICKUP,
|
||||||
@ -144,8 +144,8 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
Abilities.MAGICIAN,
|
Abilities.MAGICIAN,
|
||||||
Abilities.SHEER_FORCE,
|
Abilities.SHEER_FORCE,
|
||||||
Abilities.PRANKSTER
|
Abilities.PRANKSTER
|
||||||
]).toContain(config.pokemonConfigs[1].mysteryEncounterData.ability);
|
]).toContain(config.pokemonConfigs?.[1].mysteryEncounterData?.ability);
|
||||||
expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs[1].mysteryEncounterData.ability);
|
expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs?.[1].mysteryEncounterData?.ability);
|
||||||
await vi.waitFor(() => expect(moveInitSpy).toHaveBeenCalled());
|
await vi.waitFor(() => expect(moveInitSpy).toHaveBeenCalled());
|
||||||
await vi.waitFor(() => expect(moveLoadSpy).toHaveBeenCalled());
|
await vi.waitFor(() => expect(moveLoadSpy).toHaveBeenCalled());
|
||||||
expect(onInitResult).toBe(true);
|
expect(onInitResult).toBe(true);
|
||||||
@ -172,10 +172,10 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(2);
|
expect(enemyField.length).toBe(2);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.MR_MIME);
|
expect(enemyField[0].species.speciesId).toBe(Species.MR_MIME);
|
||||||
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.TEETER_DANCE), new PokemonMove(Moves.ALLY_SWITCH), new PokemonMove(Moves.DAZZLING_GLEAM), new PokemonMove(Moves.PSYCHIC)]);
|
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.TEETER_DANCE), new PokemonMove(Moves.ALLY_SWITCH), new PokemonMove(Moves.DAZZLING_GLEAM), new PokemonMove(Moves.PSYCHIC)]);
|
||||||
@ -191,10 +191,10 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should let the player gain the ability after battle completion", async () => {
|
it("should let the player gain the ability after battle completion", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
const abilityToTrain = scene.currentBattle.mysteryEncounter.misc.ability;
|
const abilityToTrain = scene.currentBattle.mysteryEncounter.misc.ability;
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
vi.spyOn(partyUiHandler, "show");
|
vi.spyOn(partyUiHandler, "show");
|
||||||
game.endPhase();
|
game.endPhase();
|
||||||
await game.phaseInterceptor.to(PostMysteryEncounterPhase);
|
await game.phaseInterceptor.to(PostMysteryEncounterPhase);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(PostMysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(PostMysteryEncounterPhase.name);
|
||||||
|
|
||||||
// Wait for Yes/No confirmation to appear
|
// Wait for Yes/No confirmation to appear
|
||||||
await vi.waitFor(() => expect(optionSelectUiHandler.show).toHaveBeenCalled());
|
await vi.waitFor(() => expect(optionSelectUiHandler.show).toHaveBeenCalled());
|
||||||
@ -224,7 +224,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(NewBattlePhase, false);
|
await game.phaseInterceptor.to(NewBattlePhase, false);
|
||||||
|
|
||||||
const leadPokemon = scene.getParty()[0];
|
const leadPokemon = scene.getParty()[0];
|
||||||
expect(leadPokemon.mysteryEncounterData.ability).toBe(abilityToTrain);
|
expect(leadPokemon.mysteryEncounterData?.ability).toBe(abilityToTrain);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -255,6 +255,9 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
it("should randomize held items of the Pokemon with the most items, and not the held items of other pokemon", async () => {
|
it("should randomize held items of the Pokemon with the most items, and not the held items of other pokemon", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
|
||||||
|
|
||||||
|
// Set some moves on party for attack type booster generation
|
||||||
|
scene.getParty()[0].moveset = [new PokemonMove(Moves.TACKLE), new PokemonMove(Moves.THIEF)];
|
||||||
|
|
||||||
// 2 Sitrus Berries on lead
|
// 2 Sitrus Berries on lead
|
||||||
scene.modifiers = [];
|
scene.modifiers = [];
|
||||||
let itemType = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType;
|
let itemType = generateModifierType(scene, modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType;
|
||||||
@ -294,8 +297,8 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
const secondItemsAfter = scene.getParty()[1].getHeldItems();
|
const secondItemsAfter = scene.getParty()[1].getHeldItems();
|
||||||
expect(secondItemsAfter.length).toBe(1);
|
expect(secondItemsAfter.length).toBe(1);
|
||||||
expect(secondItemsAfter[0].type.id).toBe("SOUL_DEW");
|
expect(secondItemsAfter[0].type.id).toBe("SOUL_DEW");
|
||||||
expect(secondItemsAfter[0].stackCount).toBe(5);
|
expect(secondItemsAfter[0]?.stackCount).toBe(5);
|
||||||
});
|
}, 2000000);
|
||||||
|
|
||||||
it("should leave encounter without battle", async () => {
|
it("should leave encounter without battle", async () => {
|
||||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||||
@ -342,9 +345,9 @@ describe("Clowning Around - Mystery Encounter", () => {
|
|||||||
scene.getParty()[2].moveset = [];
|
scene.getParty()[2].moveset = [];
|
||||||
await runMysteryEncounterToEnd(game, 3);
|
await runMysteryEncounterToEnd(game, 3);
|
||||||
|
|
||||||
const leadTypesAfter = scene.getParty()[0].mysteryEncounterData.types;
|
const leadTypesAfter = scene.getParty()[0].mysteryEncounterData?.types;
|
||||||
const secondaryTypesAfter = scene.getParty()[1].mysteryEncounterData.types;
|
const secondaryTypesAfter = scene.getParty()[1].mysteryEncounterData?.types;
|
||||||
const thirdTypesAfter = scene.getParty()[2].mysteryEncounterData.types;
|
const thirdTypesAfter = scene.getParty()[2].mysteryEncounterData?.types;
|
||||||
|
|
||||||
expect(leadTypesAfter.length).toBe(2);
|
expect(leadTypesAfter.length).toBe(2);
|
||||||
expect(leadTypesAfter).not.toBe([Type.ICE, Type.WATER]);
|
expect(leadTypesAfter).not.toBe([Type.ICE, Type.WATER]);
|
||||||
|
@ -37,7 +37,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -60,9 +60,9 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
expect(DancingLessonsEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
expect(DancingLessonsEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
||||||
expect(DancingLessonsEncounter.dialogue).toBeDefined();
|
expect(DancingLessonsEncounter.dialogue).toBeDefined();
|
||||||
expect(DancingLessonsEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(DancingLessonsEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(DancingLessonsEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(DancingLessonsEncounter.options.length).toBe(3);
|
expect(DancingLessonsEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -110,14 +110,14 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.ORICORIO);
|
expect(enemyField[0].species.speciesId).toBe(Species.ORICORIO);
|
||||||
expect(enemyField[0].summonData.battleStats).toEqual([1, 1, 1, 1, 1, 0, 0]);
|
expect(enemyField[0].summonData.battleStats).toEqual([1, 1, 1, 1, 1, 0, 0]);
|
||||||
const moveset = enemyField[0].moveset.map(m => m.moveId);
|
const moveset = enemyField[0].moveset.map(m => m?.moveId);
|
||||||
expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
||||||
|
|
||||||
const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]);
|
const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]);
|
||||||
@ -127,10 +127,10 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should have a Baton in the rewards after battle", async () => {
|
it("should have a Baton in the rewards after battle", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -205,7 +205,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
||||||
const oricorio = scene.getParty()[scene.getParty().length - 1];
|
const oricorio = scene.getParty()[scene.getParty().length - 1];
|
||||||
expect(oricorio.species.speciesId).toBe(Species.ORICORIO);
|
expect(oricorio.species.speciesId).toBe(Species.ORICORIO);
|
||||||
const moveset = oricorio.moveset.map(m => m.moveId);
|
const moveset = oricorio.moveset.map(m => m?.moveId);
|
||||||
expect(moveset?.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
expect(moveset?.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
||||||
expect(moveset?.some(m => m === Moves.DRAGON_DANCE)).toBeTruthy();
|
expect(moveset?.some(m => m === Moves.DRAGON_DANCE)).toBeTruthy();
|
||||||
});
|
});
|
||||||
@ -217,7 +217,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -226,7 +226,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
await runSelectMysteryEncounterOption(game, 3);
|
await runSelectMysteryEncounterOption(game, 3);
|
||||||
const partyCountAfter = scene.getParty().length;
|
const partyCountAfter = scene.getParty().length;
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
|
@ -37,7 +37,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -60,9 +60,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
expect(DelibirdyEncounter.dialogue).toBeDefined();
|
expect(DelibirdyEncounter.dialogue).toBeDefined();
|
||||||
expect(DelibirdyEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(DelibirdyEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(DelibirdyEncounter.dialogue.outro).toStrictEqual([{ text: `${namespace}.outro` }]);
|
expect(DelibirdyEncounter.dialogue.outro).toStrictEqual([{ text: `${namespace}.outro` }]);
|
||||||
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(DelibirdyEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(DelibirdyEncounter.options.length).toBe(3);
|
expect(DelibirdyEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
const itemModifier = scene.findModifier(m => m instanceof HiddenAbilityRateBoosterModifier) as HiddenAbilityRateBoosterModifier;
|
const itemModifier = scene.findModifier(m => m instanceof HiddenAbilityRateBoosterModifier) as HiddenAbilityRateBoosterModifier;
|
||||||
|
|
||||||
expect(itemModifier).toBeDefined();
|
expect(itemModifier).toBeDefined();
|
||||||
expect(itemModifier.stackCount).toBe(1);
|
expect(itemModifier?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => {
|
it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => {
|
||||||
@ -148,9 +148,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier);
|
const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier);
|
||||||
|
|
||||||
expect(abilityCharmAfter).toBeDefined();
|
expect(abilityCharmAfter).toBeDefined();
|
||||||
expect(abilityCharmAfter.stackCount).toBe(4);
|
expect(abilityCharmAfter?.stackCount).toBe(4);
|
||||||
expect(shellBellAfter).toBeDefined();
|
expect(shellBellAfter).toBeDefined();
|
||||||
expect(shellBellAfter.stackCount).toBe(1);
|
expect(shellBellAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be disabled if player does not have enough money", async () => {
|
it("should be disabled if player does not have enough money", async () => {
|
||||||
@ -159,7 +159,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -167,7 +167,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 1);
|
await runSelectMysteryEncounterOption(game, 1);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -217,9 +217,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
const sitrusAfter = scene.findModifier(m => m instanceof BerryModifier);
|
const sitrusAfter = scene.findModifier(m => m instanceof BerryModifier);
|
||||||
const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier);
|
const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier);
|
||||||
|
|
||||||
expect(sitrusAfter.stackCount).toBe(1);
|
expect(sitrusAfter?.stackCount).toBe(1);
|
||||||
expect(candyJarAfter).toBeDefined();
|
expect(candyJarAfter).toBeDefined();
|
||||||
expect(candyJarAfter.stackCount).toBe(1);
|
expect(candyJarAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should remove Reviver Seed and give the player a Healing Charm", async () => {
|
it("Should remove Reviver Seed and give the player a Healing Charm", async () => {
|
||||||
@ -240,7 +240,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
expect(reviverSeedAfter).toBeUndefined();
|
expect(reviverSeedAfter).toBeUndefined();
|
||||||
expect(healingCharmAfter).toBeDefined();
|
expect(healingCharmAfter).toBeDefined();
|
||||||
expect(healingCharmAfter.stackCount).toBe(1);
|
expect(healingCharmAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give the player a Shell Bell if they have max stacks of Candy Jars", async () => {
|
it("Should give the player a Shell Bell if they have max stacks of Candy Jars", async () => {
|
||||||
@ -265,11 +265,11 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier);
|
const candyJarAfter = scene.findModifier(m => m instanceof LevelIncrementBoosterModifier);
|
||||||
const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier);
|
const shellBellAfter = scene.findModifier(m => m instanceof HitHealModifier);
|
||||||
|
|
||||||
expect(sitrusAfter.stackCount).toBe(1);
|
expect(sitrusAfter?.stackCount).toBe(1);
|
||||||
expect(candyJarAfter).toBeDefined();
|
expect(candyJarAfter).toBeDefined();
|
||||||
expect(candyJarAfter.stackCount).toBe(99);
|
expect(candyJarAfter?.stackCount).toBe(99);
|
||||||
expect(shellBellAfter).toBeDefined();
|
expect(shellBellAfter).toBeDefined();
|
||||||
expect(shellBellAfter.stackCount).toBe(1);
|
expect(shellBellAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give the player a Shell Bell if they have max stacks of Healing Charms", async () => {
|
it("Should give the player a Shell Bell if they have max stacks of Healing Charms", async () => {
|
||||||
@ -296,9 +296,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
expect(reviverSeedAfter).toBeUndefined();
|
expect(reviverSeedAfter).toBeUndefined();
|
||||||
expect(healingCharmAfter).toBeDefined();
|
expect(healingCharmAfter).toBeDefined();
|
||||||
expect(healingCharmAfter.stackCount).toBe(5);
|
expect(healingCharmAfter?.stackCount).toBe(5);
|
||||||
expect(shellBellAfter).toBeDefined();
|
expect(shellBellAfter).toBeDefined();
|
||||||
expect(shellBellAfter.stackCount).toBe(1);
|
expect(shellBellAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be disabled if player does not have any proper items", async () => {
|
it("should be disabled if player does not have any proper items", async () => {
|
||||||
@ -314,7 +314,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -322,7 +322,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 2);
|
await runSelectMysteryEncounterOption(game, 2);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -379,9 +379,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
const soulDewAfter = scene.findModifier(m => m instanceof PokemonNatureWeightModifier);
|
const soulDewAfter = scene.findModifier(m => m instanceof PokemonNatureWeightModifier);
|
||||||
const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier);
|
const berryPouchAfter = scene.findModifier(m => m instanceof PreserveBerryModifier);
|
||||||
|
|
||||||
expect(soulDewAfter.stackCount).toBe(1);
|
expect(soulDewAfter?.stackCount).toBe(1);
|
||||||
expect(berryPouchAfter).toBeDefined();
|
expect(berryPouchAfter).toBeDefined();
|
||||||
expect(berryPouchAfter.stackCount).toBe(1);
|
expect(berryPouchAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should remove held item and give the player a Berry Pouch", async () => {
|
it("Should remove held item and give the player a Berry Pouch", async () => {
|
||||||
@ -402,7 +402,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
expect(soulDewAfter).toBeUndefined();
|
expect(soulDewAfter).toBeUndefined();
|
||||||
expect(berryPouchAfter).toBeDefined();
|
expect(berryPouchAfter).toBeDefined();
|
||||||
expect(berryPouchAfter.stackCount).toBe(1);
|
expect(berryPouchAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => {
|
it("Should give the player a Shell Bell if they have max stacks of Berry Pouches", async () => {
|
||||||
@ -429,9 +429,9 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
expect(soulDewAfter).toBeUndefined();
|
expect(soulDewAfter).toBeUndefined();
|
||||||
expect(berryPouchAfter).toBeDefined();
|
expect(berryPouchAfter).toBeDefined();
|
||||||
expect(berryPouchAfter.stackCount).toBe(3);
|
expect(berryPouchAfter?.stackCount).toBe(3);
|
||||||
expect(shellBellAfter).toBeDefined();
|
expect(shellBellAfter).toBeDefined();
|
||||||
expect(shellBellAfter.stackCount).toBe(1);
|
expect(shellBellAfter?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should be disabled if player does not have any proper items", async () => {
|
it("should be disabled if player does not have any proper items", async () => {
|
||||||
@ -447,7 +447,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -455,7 +455,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 3);
|
await runSelectMysteryEncounterOption(game, 3);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
|
@ -35,7 +35,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
||||||
@ -65,9 +65,9 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}.intro_dialogue`,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(DepartmentStoreSaleEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(DepartmentStoreSaleEncounter.options.length).toBe(4);
|
expect(DepartmentStoreSaleEncounter.options.length).toBe(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
it("should have shop with only TMs", async () => {
|
it("should have shop with only TMs", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1);
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -144,7 +144,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
it("should have shop with only Vitamins", async () => {
|
it("should have shop with only Vitamins", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -180,7 +180,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
it("should have shop with only X Items", async () => {
|
it("should have shop with only X Items", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 3);
|
await runMysteryEncounterToEnd(game, 3);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -216,7 +216,7 @@ describe("Department Store Sale - Mystery Encounter", () => {
|
|||||||
it("should have shop with only Pokeballs", async () => {
|
it("should have shop with only Pokeballs", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.DEPARTMENT_STORE_SALE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 4);
|
await runMysteryEncounterToEnd(game, 4);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -42,7 +42,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -65,9 +65,9 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
expect(FieryFalloutEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
expect(FieryFalloutEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
||||||
expect(FieryFalloutEncounter.dialogue).toBeDefined();
|
expect(FieryFalloutEncounter.dialogue).toBeDefined();
|
||||||
expect(FieryFalloutEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(FieryFalloutEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(FieryFalloutEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(FieryFalloutEncounter.options.length).toBe(3);
|
expect(FieryFalloutEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
expect(FieryFalloutEncounter.onInit).toBeDefined();
|
expect(FieryFalloutEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
FieryFalloutEncounter.populateDialogueTokensFromRequirements(scene);
|
FieryFalloutEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(FieryFalloutEncounter.enemyPartyConfigs).toEqual([
|
expect(FieryFalloutEncounter.enemyPartyConfigs).toEqual([
|
||||||
{
|
{
|
||||||
@ -152,10 +152,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(2);
|
expect(enemyField.length).toBe(2);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.VOLCARONA);
|
expect(enemyField[0].species.speciesId).toBe(Species.VOLCARONA);
|
||||||
expect(enemyField[1].species.speciesId).toBe(Species.VOLCARONA);
|
expect(enemyField[1].species.speciesId).toBe(Species.VOLCARONA);
|
||||||
@ -169,10 +169,10 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should give charcoal to lead pokemon", async () => {
|
it("should give charcoal to lead pokemon", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const leadPokemonId = scene.getParty()?.[0].id;
|
const leadPokemonId = scene.getParty()?.[0].id;
|
||||||
const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
@ -202,9 +202,9 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.FIERY_FALLOUT, defaultParty);
|
||||||
|
|
||||||
const party = scene.getParty();
|
const party = scene.getParty();
|
||||||
const lapras = party.find((pkm) => pkm.species.speciesId === Species.LAPRAS);
|
const lapras = party.find((pkm) => pkm.species.speciesId === Species.LAPRAS)!;
|
||||||
lapras.status = new Status(StatusEffect.POISON);
|
lapras.status = new Status(StatusEffect.POISON);
|
||||||
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA);
|
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!;
|
||||||
vi.spyOn(abra, "isAllowedInBattle").mockReturnValue(false);
|
vi.spyOn(abra, "isAllowedInBattle").mockReturnValue(false);
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
@ -251,7 +251,7 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
await runMysteryEncounterToEnd(game, 3);
|
await runMysteryEncounterToEnd(game, 3);
|
||||||
// await skipBattleRunMysteryEncounterRewardsPhase(game);
|
// await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const leadPokemonId = scene.getParty()?.[0].id;
|
const leadPokemonId = scene.getParty()?.[0].id;
|
||||||
const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
const leadPokemonItems = scene.findModifiers(m => m instanceof PokemonHeldItemModifier
|
||||||
@ -274,12 +274,12 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const continueEncounterSpy = vi.spyOn((encounterPhase as MysteryEncounterPhase), "continueEncounter");
|
const continueEncounterSpy = vi.spyOn((encounterPhase as MysteryEncounterPhase), "continueEncounter");
|
||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 3);
|
await runSelectMysteryEncounterOption(game, 3);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(continueEncounterSpy).not.toHaveBeenCalled();
|
expect(continueEncounterSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -38,7 +38,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -60,9 +60,9 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
expect(FightOrFlightEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
expect(FightOrFlightEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
||||||
expect(FightOrFlightEncounter.dialogue).toBeDefined();
|
expect(FightOrFlightEncounter.dialogue).toBeDefined();
|
||||||
expect(FightOrFlightEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(FightOrFlightEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(FightOrFlightEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(FightOrFlightEncounter.options.length).toBe(3);
|
expect(FightOrFlightEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -91,12 +91,12 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
expect(FightOrFlightEncounter.onInit).toBeDefined();
|
expect(FightOrFlightEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
FightOrFlightEncounter.populateDialogueTokensFromRequirements(scene);
|
FightOrFlightEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
const config = FightOrFlightEncounter.enemyPartyConfigs[0];
|
const config = FightOrFlightEncounter.enemyPartyConfigs[0];
|
||||||
expect(config).toBeDefined();
|
expect(config).toBeDefined();
|
||||||
expect(config.levelAdditiveMultiplier).toBe(1);
|
expect(config.levelAdditiveMultiplier).toBe(1);
|
||||||
expect(config.pokemonConfigs[0].isBoss).toBe(true);
|
expect(config.pokemonConfigs?.[0].isBoss).toBe(true);
|
||||||
expect(onInitResult).toBe(true);
|
expect(onInitResult).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,12 +120,12 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty);
|
||||||
|
|
||||||
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
const config = game.scene.currentBattle.mysteryEncounter.enemyPartyConfigs[0];
|
||||||
const speciesToSpawn = config.pokemonConfigs[0].species.speciesId;
|
const speciesToSpawn = config.pokemonConfigs?.[0].species.speciesId;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
|
||||||
});
|
});
|
||||||
@ -135,10 +135,10 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
|
|
||||||
const item = game.scene.currentBattle.mysteryEncounter.misc;
|
const item = game.scene.currentBattle.mysteryEncounter.misc;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -179,7 +179,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 2);
|
await runSelectMysteryEncounterOption(game, 2);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -196,7 +196,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -59,9 +59,9 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
expect(LostAtSeaEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
expect(LostAtSeaEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
||||||
expect(LostAtSeaEncounter.dialogue).toBeDefined();
|
expect(LostAtSeaEncounter.dialogue).toBeDefined();
|
||||||
expect(LostAtSeaEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(LostAtSeaEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(LostAtSeaEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(LostAtSeaEncounter.options.length).toBe(3);
|
expect(LostAtSeaEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
expect(LostAtSeaEncounter.onInit).toBeDefined();
|
expect(LostAtSeaEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
LostAtSeaEncounter.populateDialogueTokensFromRequirements(scene);
|
LostAtSeaEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(LostAtSeaEncounter.dialogueTokens?.damagePercentage).toBe("25");
|
expect(LostAtSeaEncounter.dialogueTokens?.damagePercentage).toBe("25");
|
||||||
expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe(Moves[Moves.SURF]);
|
expect(LostAtSeaEncounter.dialogueTokens?.option1RequiredMove).toBe(Moves[Moves.SURF]);
|
||||||
@ -129,12 +129,12 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
||||||
const party = game.scene.getParty();
|
const party = game.scene.getParty();
|
||||||
const blastoise = party.find((pkm) => pkm.species.speciesId === Species.PIDGEOT);
|
const blastoise = party.find((pkm) => pkm.species.speciesId === Species.BLASTOISE);
|
||||||
const expBefore = blastoise.exp;
|
const expBefore = blastoise!.exp;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
|
|
||||||
expect(blastoise.exp).toBe(expBefore + Math.floor(laprasSpecies.baseExp * defaultWave / 5 + 1));
|
expect(blastoise?.exp).toBe(expBefore + Math.floor(laprasSpecies.baseExp * defaultWave / 5 + 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should leave encounter without battle", async () => {
|
it("should leave encounter without battle", async () => {
|
||||||
@ -152,7 +152,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -160,7 +160,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 1);
|
await runSelectMysteryEncounterOption(game, 1);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -194,11 +194,11 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
||||||
const party = game.scene.getParty();
|
const party = game.scene.getParty();
|
||||||
const pidgeot = party.find((pkm) => pkm.species.speciesId === Species.PIDGEOT);
|
const pidgeot = party.find((pkm) => pkm.species.speciesId === Species.PIDGEOT);
|
||||||
const expBefore = pidgeot.exp;
|
const expBefore = pidgeot!.exp;
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
|
|
||||||
expect(pidgeot.exp).toBe(expBefore + Math.floor(laprasBaseExp * defaultWave / 5 + 1));
|
expect(pidgeot!.exp).toBe(expBefore + Math.floor(laprasBaseExp * defaultWave / 5 + 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should leave encounter without battle", async () => {
|
it("should leave encounter without battle", async () => {
|
||||||
@ -216,7 +216,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -224,7 +224,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 2);
|
await runSelectMysteryEncounterOption(game, 2);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -254,7 +254,7 @@ describe("Lost at Sea - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.LOST_AT_SEA, defaultParty);
|
||||||
|
|
||||||
const party = game.scene.getParty();
|
const party = game.scene.getParty();
|
||||||
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA);
|
const abra = party.find((pkm) => pkm.species.speciesId === Species.ABRA)!;
|
||||||
vi.spyOn(abra, "isAllowedInBattle").mockReturnValue(false);
|
vi.spyOn(abra, "isAllowedInBattle").mockReturnValue(false);
|
||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 3);
|
await runMysteryEncounterToEnd(game, 3);
|
||||||
|
@ -40,7 +40,7 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]],
|
[Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]],
|
||||||
@ -64,9 +64,9 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
expect(MysteriousChallengersEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
expect(MysteriousChallengersEncounter.encounterTier).toBe(MysteryEncounterTier.GREAT);
|
||||||
expect(MysteriousChallengersEncounter.dialogue).toBeDefined();
|
expect(MysteriousChallengersEncounter.dialogue).toBeDefined();
|
||||||
expect(MysteriousChallengersEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(MysteriousChallengersEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(MysteriousChallengersEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(MysteriousChallengersEncounter.options.length).toBe(3);
|
expect(MysteriousChallengersEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
expect(encounter.onInit).toBeDefined();
|
expect(encounter.onInit).toBeDefined();
|
||||||
|
|
||||||
encounter.populateDialogueTokensFromRequirements(scene);
|
encounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(encounter.enemyPartyConfigs).toBeDefined();
|
expect(encounter.enemyPartyConfigs).toBeDefined();
|
||||||
expect(encounter.enemyPartyConfigs.length).toBe(3);
|
expect(encounter.enemyPartyConfigs.length).toBe(3);
|
||||||
@ -125,11 +125,11 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
female: expect.any(Boolean),
|
female: expect.any(Boolean),
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
expect(encounter.enemyPartyConfigs[1].trainerConfig.partyTemplates[0]).toEqual(new TrainerPartyCompoundTemplate(
|
expect(encounter.enemyPartyConfigs[1].trainerConfig?.partyTemplates[0]).toEqual(new TrainerPartyCompoundTemplate(
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER, false, true),
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER, false, true),
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true)
|
new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE, false, true)
|
||||||
));
|
));
|
||||||
expect(encounter.enemyPartyConfigs[2].trainerConfig.partyTemplates[0]).toEqual(new TrainerPartyCompoundTemplate(
|
expect(encounter.enemyPartyConfigs[2].trainerConfig?.partyTemplates[0]).toEqual(new TrainerPartyCompoundTemplate(
|
||||||
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE),
|
||||||
new TrainerPartyTemplate(3, PartyMemberStrength.STRONG),
|
new TrainerPartyTemplate(3, PartyMemberStrength.STRONG),
|
||||||
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER))
|
new TrainerPartyTemplate(1, PartyMemberStrength.STRONGER))
|
||||||
@ -157,19 +157,19 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should start battle against the trainer", async () => {
|
it("should start battle against the trainer", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have normal trainer rewards after battle", async () => {
|
it("should have normal trainer rewards after battle", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -199,19 +199,19 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should start battle against the trainer", async () => {
|
it("should start battle against the trainer", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have hard trainer rewards after battle", async () => {
|
it("should have hard trainer rewards after battle", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -242,19 +242,19 @@ describe("Mysterious Challengers - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should start battle against the trainer", async () => {
|
it("should start battle against the trainer", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 3, null, true);
|
await runMysteryEncounterToEnd(game, 3, undefined, true);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should have brutal trainer rewards after battle", async () => {
|
it("should have brutal trainer rewards after battle", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 3, null, true);
|
await runMysteryEncounterToEnd(game, 3, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -36,7 +36,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
||||||
@ -66,9 +66,9 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}.intro_dialogue`,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(PartTimerEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(PartTimerEncounter.options.length).toBe(3);
|
expect(PartTimerEncounter.options.length).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
// Expect PP of mon's moves to have been reduced to 2
|
// Expect PP of mon's moves to have been reduced to 2
|
||||||
const moves = scene.getParty()[0].moveset;
|
const moves = scene.getParty()[0].moveset;
|
||||||
for (const move of moves) {
|
for (const move of moves) {
|
||||||
expect(move.getMovePp() - move.ppUsed).toBe(2);
|
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
// Expect PP of mon's moves to have been reduced to 2
|
// Expect PP of mon's moves to have been reduced to 2
|
||||||
const moves = scene.getParty()[1].moveset;
|
const moves = scene.getParty()[1].moveset;
|
||||||
for (const move of moves) {
|
for (const move of moves) {
|
||||||
expect(move.getMovePp() - move.ppUsed).toBe(2);
|
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
// Expect PP of mon's moves to have been reduced to 2
|
// Expect PP of mon's moves to have been reduced to 2
|
||||||
const moves = scene.getParty()[2].moveset;
|
const moves = scene.getParty()[2].moveset;
|
||||||
for (const move of moves) {
|
for (const move of moves) {
|
||||||
expect(move.getMovePp() - move.ppUsed).toBe(2);
|
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -212,7 +212,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
// Expect PP of mon's moves to have been reduced to 2
|
// Expect PP of mon's moves to have been reduced to 2
|
||||||
const moves = scene.getParty()[3].moveset;
|
const moves = scene.getParty()[3].moveset;
|
||||||
for (const move of moves) {
|
for (const move of moves) {
|
||||||
expect(move.getMovePp() - move.ppUsed).toBe(2);
|
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -260,7 +260,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 3);
|
await runSelectMysteryEncounterOption(game, 3);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
@ -279,7 +279,7 @@ describe("Part-Timer - Mystery Encounter", () => {
|
|||||||
// Expect PP of mon's moves to have been reduced to 2
|
// Expect PP of mon's moves to have been reduced to 2
|
||||||
const moves = scene.getParty()[0].moveset;
|
const moves = scene.getParty()[0].moveset;
|
||||||
for (const move of moves) {
|
for (const move of moves) {
|
||||||
expect(move.getMovePp() - move.ppUsed).toBe(2);
|
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
[Biome.VOLCANO, [MysteryEncounterType.MYSTERIOUS_CHALLENGERS]],
|
||||||
@ -62,9 +62,9 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
|||||||
{ text: `${namespace}.intro` },
|
{ text: `${namespace}.intro` },
|
||||||
{ speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` }
|
{ speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` }
|
||||||
]);
|
]);
|
||||||
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(ThePokemonSalesmanEncounter.options.length).toBe(2);
|
expect(ThePokemonSalesmanEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
|||||||
expect(ThePokemonSalesmanEncounter.onInit).toBeDefined();
|
expect(ThePokemonSalesmanEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
ThePokemonSalesmanEncounter.populateDialogueTokensFromRequirements(scene);
|
ThePokemonSalesmanEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(ThePokemonSalesmanEncounter.dialogueTokens?.purchasePokemon).toBeDefined();
|
expect(ThePokemonSalesmanEncounter.dialogueTokens?.purchasePokemon).toBeDefined();
|
||||||
expect(ThePokemonSalesmanEncounter.dialogueTokens?.price).toBeDefined();
|
expect(ThePokemonSalesmanEncounter.dialogueTokens?.price).toBeDefined();
|
||||||
@ -167,7 +167,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
|||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
|
|
||||||
const encounterPhase = scene.getCurrentPhase();
|
const encounterPhase = scene.getCurrentPhase();
|
||||||
expect(encounterPhase.constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(encounterPhase?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
const mysteryEncounterPhase = encounterPhase as MysteryEncounterPhase;
|
||||||
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
vi.spyOn(mysteryEncounterPhase, "continueEncounter");
|
||||||
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
vi.spyOn(mysteryEncounterPhase, "handleOptionSelect");
|
||||||
@ -175,7 +175,7 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runSelectMysteryEncounterOption(game, 1);
|
await runSelectMysteryEncounterOption(game, 1);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
expect(scene.ui.playError).not.toHaveBeenCalled(); // No error sfx, option is disabled
|
||||||
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.handleOptionSelect).not.toHaveBeenCalled();
|
||||||
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
expect(mysteryEncounterPhase.continueEncounter).not.toHaveBeenCalled();
|
||||||
|
@ -11,7 +11,6 @@ import { runMysteryEncounterToEnd, skipBattleRunMysteryEncounterRewardsPhase } f
|
|||||||
import { CommandPhase, MovePhase, SelectModifierPhase } from "#app/phases";
|
import { CommandPhase, MovePhase, SelectModifierPhase } from "#app/phases";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import * as Modifiers from "#app/modifier/modifier";
|
|
||||||
import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter";
|
import { TheStrongStuffEncounter } from "#app/data/mystery-encounters/encounters/the-strong-stuff-encounter";
|
||||||
import { Nature } from "#app/data/nature";
|
import { Nature } from "#app/data/nature";
|
||||||
import { BerryType } from "#enums/berry-type";
|
import { BerryType } from "#enums/berry-type";
|
||||||
@ -19,7 +18,7 @@ import { BattlerTagType } from "#enums/battler-tag-type";
|
|||||||
import { PokemonMove } from "#app/field/pokemon";
|
import { PokemonMove } from "#app/field/pokemon";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
|
||||||
import { PokemonBaseStatTotalModifier } from "#app/modifier/modifier";
|
import { BerryModifier, PokemonBaseStatTotalModifier } from "#app/modifier/modifier";
|
||||||
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode";
|
||||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
|
import { initSceneWithoutEncounterPhase } from "#test/utils/gameManagerUtils";
|
||||||
@ -45,7 +44,7 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -68,9 +67,9 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||||||
expect(TheStrongStuffEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
expect(TheStrongStuffEncounter.encounterTier).toBe(MysteryEncounterTier.COMMON);
|
||||||
expect(TheStrongStuffEncounter.dialogue).toBeDefined();
|
expect(TheStrongStuffEncounter.dialogue).toBeDefined();
|
||||||
expect(TheStrongStuffEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(TheStrongStuffEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(TheStrongStuffEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(TheStrongStuffEncounter.options.length).toBe(2);
|
expect(TheStrongStuffEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,7 +108,7 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||||||
expect(TheStrongStuffEncounter.onInit).toBeDefined();
|
expect(TheStrongStuffEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
TheStrongStuffEncounter.populateDialogueTokensFromRequirements(scene);
|
TheStrongStuffEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(TheStrongStuffEncounter.enemyPartyConfigs).toEqual([
|
expect(TheStrongStuffEncounter.enemyPartyConfigs).toEqual([
|
||||||
{
|
{
|
||||||
@ -198,19 +197,19 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.SHUCKLE);
|
expect(enemyField[0].species.speciesId).toBe(Species.SHUCKLE);
|
||||||
expect(enemyField[0].summonData.battleStats).toEqual([0, 2, 0, 2, 0, 0, 0]);
|
expect(enemyField[0].summonData.battleStats).toEqual([0, 2, 0, 2, 0, 0, 0]);
|
||||||
const shuckleItems = scene.getModifiers(Modifiers.BerryModifier, false);
|
const shuckleItems = enemyField[0].getHeldItems();
|
||||||
expect(shuckleItems.length).toBe(4);
|
expect(shuckleItems.length).toBe(4);
|
||||||
expect(shuckleItems.find(m => m.berryType === BerryType.SITRUS)?.stackCount).toBe(1);
|
expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.SITRUS)?.stackCount).toBe(1);
|
||||||
expect(shuckleItems.find(m => m.berryType === BerryType.GANLON)?.stackCount).toBe(1);
|
expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.GANLON)?.stackCount).toBe(1);
|
||||||
expect(shuckleItems.find(m => m.berryType === BerryType.APICOT)?.stackCount).toBe(1);
|
expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.APICOT)?.stackCount).toBe(1);
|
||||||
expect(shuckleItems.find(m => m.berryType === BerryType.LUM)?.stackCount).toBe(2);
|
expect(shuckleItems.find(m => m instanceof BerryModifier && m.berryType === BerryType.LUM)?.stackCount).toBe(2);
|
||||||
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.INFESTATION), new PokemonMove(Moves.SALT_CURE), new PokemonMove(Moves.GASTRO_ACID), new PokemonMove(Moves.HEAL_ORDER)]);
|
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.INFESTATION), new PokemonMove(Moves.SALT_CURE), new PokemonMove(Moves.GASTRO_ACID), new PokemonMove(Moves.HEAL_ORDER)]);
|
||||||
|
|
||||||
// Should have used moves pre-battle
|
// Should have used moves pre-battle
|
||||||
@ -222,10 +221,10 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should have Soul Dew in rewards", async () => {
|
it("should have Soul Dew in rewards", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.THE_STRONG_STUFF, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -43,7 +43,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
const biomeMap = new Map<Biome, MysteryEncounterType[]>([
|
||||||
[Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]],
|
[Biome.VOLCANO, [MysteryEncounterType.FIGHT_OR_FLIGHT]],
|
||||||
@ -73,9 +73,9 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}.intro_dialogue`,
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(TheWinstrateChallengeEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(TheWinstrateChallengeEncounter.options.length).toBe(2);
|
expect(TheWinstrateChallengeEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
expect(encounter.onInit).toBeDefined();
|
expect(encounter.onInit).toBeDefined();
|
||||||
|
|
||||||
encounter.populateDialogueTokensFromRequirements(scene);
|
encounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(encounter.enemyPartyConfigs).toBeDefined();
|
expect(encounter.enemyPartyConfigs).toBeDefined();
|
||||||
expect(encounter.enemyPartyConfigs.length).toBe(5);
|
expect(encounter.enemyPartyConfigs.length).toBe(5);
|
||||||
@ -273,42 +273,42 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should battle all 5 trainers for a Macho Brace reward", async () => {
|
it("should battle all 5 trainers for a Macho Brace reward", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1, null, true);
|
await runMysteryEncounterToEnd(game, 1, undefined, true);
|
||||||
|
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.trainer.config.trainerType).toBe(TrainerType.VICTOR);
|
expect(scene.currentBattle.trainer!.config.trainerType).toBe(TrainerType.VICTOR);
|
||||||
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(4);
|
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(4);
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
|
|
||||||
await skipBattleToNextBattle(game);
|
await skipBattleToNextBattle(game);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.trainer.config.trainerType).toBe(TrainerType.VICTORIA);
|
expect(scene.currentBattle.trainer!.config.trainerType).toBe(TrainerType.VICTORIA);
|
||||||
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(3);
|
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(3);
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
|
|
||||||
await skipBattleToNextBattle(game);
|
await skipBattleToNextBattle(game);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.trainer.config.trainerType).toBe(TrainerType.VIVI);
|
expect(scene.currentBattle.trainer!.config.trainerType).toBe(TrainerType.VIVI);
|
||||||
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(2);
|
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(2);
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
|
|
||||||
await skipBattleToNextBattle(game);
|
await skipBattleToNextBattle(game);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.trainer.config.trainerType).toBe(TrainerType.VICKY);
|
expect(scene.currentBattle.trainer!.config.trainerType).toBe(TrainerType.VICKY);
|
||||||
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(1);
|
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(1);
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
|
|
||||||
await skipBattleToNextBattle(game);
|
await skipBattleToNextBattle(game);
|
||||||
expect(scene.currentBattle.trainer).toBeDefined();
|
expect(scene.currentBattle.trainer).toBeDefined();
|
||||||
expect(scene.currentBattle.trainer.config.trainerType).toBe(TrainerType.VITO);
|
expect(scene.currentBattle.trainer!.config.trainerType).toBe(TrainerType.VITO);
|
||||||
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(0);
|
expect(scene.currentBattle.mysteryEncounter.enemyPartyConfigs.length).toBe(0);
|
||||||
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
expect(scene.currentBattle.mysteryEncounter.encounterMode).toBe(MysteryEncounterMode.TRAINER_BATTLE);
|
||||||
|
|
||||||
// Should have Macho Brace in the rewards
|
// Should have Macho Brace in the rewards
|
||||||
await skipBattleToNextBattle(game, true);
|
await skipBattleToNextBattle(game, true);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
@ -348,7 +348,7 @@ describe("The Winstrate Challenge - Mystery Encounter", () => {
|
|||||||
it("should have a Rarer Candy in the rewards", async () => {
|
it("should have a Rarer Candy in the rewards", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.THE_WINSTRATE_CHALLENGE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2);
|
await runMysteryEncounterToEnd(game, 2);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -41,7 +41,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
new Map<Biome, MysteryEncounterType[]>([
|
new Map<Biome, MysteryEncounterType[]>([
|
||||||
@ -63,9 +63,9 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
expect(TrashToTreasureEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA);
|
expect(TrashToTreasureEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA);
|
||||||
expect(TrashToTreasureEncounter.dialogue).toBeDefined();
|
expect(TrashToTreasureEncounter.dialogue).toBeDefined();
|
||||||
expect(TrashToTreasureEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
expect(TrashToTreasureEncounter.dialogue.intro).toStrictEqual([{ text: `${namespace}.intro` }]);
|
||||||
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(TrashToTreasureEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(TrashToTreasureEncounter.options.length).toBe(2);
|
expect(TrashToTreasureEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
expect(TrashToTreasureEncounter.onInit).toBeDefined();
|
expect(TrashToTreasureEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
TrashToTreasureEncounter.populateDialogueTokensFromRequirements(scene);
|
TrashToTreasureEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(TrashToTreasureEncounter.enemyPartyConfigs).toEqual([
|
expect(TrashToTreasureEncounter.enemyPartyConfigs).toEqual([
|
||||||
{
|
{
|
||||||
@ -138,19 +138,19 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1);
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
const leftovers = scene.findModifier(m => m instanceof TurnHealModifier) as TurnHealModifier;
|
||||||
expect(leftovers).toBeDefined();
|
expect(leftovers).toBeDefined();
|
||||||
expect(leftovers.stackCount).toBe(2);
|
expect(leftovers?.stackCount).toBe(2);
|
||||||
|
|
||||||
const shellBell = scene.findModifier(m => m instanceof HitHealModifier) as HitHealModifier;
|
const shellBell = scene.findModifier(m => m instanceof HitHealModifier) as HitHealModifier;
|
||||||
expect(shellBell).toBeDefined();
|
expect(shellBell).toBeDefined();
|
||||||
expect(shellBell.stackCount).toBe(2);
|
expect(shellBell?.stackCount).toBe(2);
|
||||||
|
|
||||||
const blackSludge = scene.findModifier(m => m instanceof RemoveHealShopModifier) as RemoveHealShopModifier;
|
const blackSludge = scene.findModifier(m => m instanceof RemoveHealShopModifier) as RemoveHealShopModifier;
|
||||||
expect(blackSludge).toBeDefined();
|
expect(blackSludge).toBeDefined();
|
||||||
expect(blackSludge.stackCount).toBe(1);
|
expect(blackSludge?.stackCount).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should leave encounter without battle", async () => {
|
it("should leave encounter without battle", async () => {
|
||||||
@ -183,10 +183,10 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
const phaseSpy = vi.spyOn(scene, "pushPhase");
|
||||||
|
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
|
|
||||||
const enemyField = scene.getEnemyField();
|
const enemyField = scene.getEnemyField();
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.GARBODOR);
|
expect(enemyField[0].species.speciesId).toBe(Species.GARBODOR);
|
||||||
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.PAYBACK), new PokemonMove(Moves.GUNK_SHOT), new PokemonMove(Moves.STOMPING_TANTRUM), new PokemonMove(Moves.DRAIN_PUNCH)]);
|
expect(enemyField[0].moveset).toEqual([new PokemonMove(Moves.PAYBACK), new PokemonMove(Moves.GUNK_SHOT), new PokemonMove(Moves.STOMPING_TANTRUM), new PokemonMove(Moves.DRAIN_PUNCH)]);
|
||||||
@ -200,10 +200,10 @@ describe("Trash to Treasure - Mystery Encounter", () => {
|
|||||||
|
|
||||||
it("should have 2 Rogue, 1 Ultra, 1 Great in rewards", async () => {
|
it("should have 2 Rogue, 1 Ultra, 1 Great in rewards", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.TRASH_TO_TREASURE, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 2, null, true);
|
await runMysteryEncounterToEnd(game, 2, undefined, true);
|
||||||
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
await skipBattleRunMysteryEncounterRewardsPhase(game);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -36,7 +36,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
game.override.mysteryEncounterChance(100);
|
game.override.mysteryEncounterChance(100);
|
||||||
game.override.startingWave(defaultWave);
|
game.override.startingWave(defaultWave);
|
||||||
game.override.startingBiome(defaultBiome);
|
game.override.startingBiome(defaultBiome);
|
||||||
game.override.disableTrainerWaves(true);
|
game.override.disableTrainerWaves();
|
||||||
vi.spyOn(EncounterTransformationSequence, "doPokemonTransformationSequence").mockImplementation(() => new Promise<void>(resolve => resolve()));
|
vi.spyOn(EncounterTransformationSequence, "doPokemonTransformationSequence").mockImplementation(() => new Promise<void>(resolve => resolve()));
|
||||||
|
|
||||||
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
|
||||||
@ -67,9 +67,9 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
text: `${namespace}.intro_dialogue`,
|
text: `${namespace}.intro_dialogue`,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.title).toBe(`${namespace}.title`);
|
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`);
|
||||||
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.description).toBe(`${namespace}.description`);
|
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`);
|
||||||
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue.query).toBe(`${namespace}.query`);
|
expect(WeirdDreamEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`);
|
||||||
expect(WeirdDreamEncounter.options.length).toBe(2);
|
expect(WeirdDreamEncounter.options.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
expect(WeirdDreamEncounter.onInit).toBeDefined();
|
expect(WeirdDreamEncounter.onInit).toBeDefined();
|
||||||
|
|
||||||
WeirdDreamEncounter.populateDialogueTokensFromRequirements(scene);
|
WeirdDreamEncounter.populateDialogueTokensFromRequirements(scene);
|
||||||
const onInitResult = onInit(scene);
|
const onInitResult = onInit!(scene);
|
||||||
|
|
||||||
expect(loadBgmSpy).toHaveBeenCalled();
|
expect(loadBgmSpy).toHaveBeenCalled();
|
||||||
expect(onInitResult).toBe(true);
|
expect(onInitResult).toBe(true);
|
||||||
@ -129,7 +129,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
|
|
||||||
await runMysteryEncounterToEnd(game, 1);
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
|
|
||||||
const pokemonAfter = scene.getParty();
|
const pokemonAfter = scene.getParty();
|
||||||
const bstsAfter = pokemonAfter.map(pokemon => pokemon.getSpeciesForm().getBaseStatTotal());
|
const bstsAfter = pokemonAfter.map(pokemon => pokemon.getSpeciesForm().getBaseStatTotal());
|
||||||
@ -138,7 +138,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
for (let i = 0; i < pokemonAfter.length; i++) {
|
for (let i = 0; i < pokemonAfter.length; i++) {
|
||||||
const newPokemon = pokemonAfter[i];
|
const newPokemon = pokemonAfter[i];
|
||||||
expect(newPokemon.getSpeciesForm().speciesId).not.toBe(pokemonPrior[i].getSpeciesForm().speciesId);
|
expect(newPokemon.getSpeciesForm().speciesId).not.toBe(pokemonPrior[i].getSpeciesForm().speciesId);
|
||||||
expect(newPokemon.mysteryEncounterData.types.length).toBe(2);
|
expect(newPokemon.mysteryEncounterData?.types.length).toBe(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const plus90To110 = bstDiff.filter(bst => bst > 80);
|
const plus90To110 = bstDiff.filter(bst => bst > 80);
|
||||||
@ -152,7 +152,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
|
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
|
||||||
await runMysteryEncounterToEnd(game, 1);
|
await runMysteryEncounterToEnd(game, 1);
|
||||||
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
await game.phaseInterceptor.to(SelectModifierPhase, false);
|
||||||
expect(scene.getCurrentPhase().constructor.name).toBe(SelectModifierPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(SelectModifierPhase.name);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
|
@ -230,7 +230,7 @@ describe("Mystery Encounter Utils", () => {
|
|||||||
|
|
||||||
it("gets species of specified types", () => {
|
it("gets species of specified types", () => {
|
||||||
// Only 9 tiers are: Koraidon, Miraidon, Arceus, Rayquaza, Kyogre, Groudon, Zacian
|
// Only 9 tiers are: Koraidon, Miraidon, Arceus, Rayquaza, Kyogre, Groudon, Zacian
|
||||||
const result = getRandomSpeciesByStarterTier(9, null, [Type.GROUND]);
|
const result = getRandomSpeciesByStarterTier(9, undefined, [Type.GROUND]);
|
||||||
const pokeSpecies = getPokemonSpecies(result);
|
const pokeSpecies = getPokemonSpecies(result);
|
||||||
expect(pokeSpecies.speciesId).toBe(Species.GROUDON);
|
expect(pokeSpecies.speciesId).toBe(Species.GROUDON);
|
||||||
});
|
});
|
||||||
|
@ -29,14 +29,14 @@ describe("Mystery Encounters", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
||||||
|
|
||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(game.scene.getCurrentPhase()!.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("", async () => {
|
it("", async () => {
|
||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
||||||
|
|
||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(game.scene.getCurrentPhase()!.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("spawns mysterious challengers encounter", async () => {
|
it("spawns mysterious challengers encounter", async () => {
|
||||||
|
@ -37,7 +37,7 @@ describe("Mystery Encounter Phases", () => {
|
|||||||
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
await game.runToMysteryEncounter(MysteryEncounterType.MYSTERIOUS_CHALLENGERS, [Species.CHARIZARD, Species.VOLCARONA]);
|
||||||
|
|
||||||
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
|
||||||
expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterPhase.name);
|
expect(game.scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterPhase.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Runs MysteryEncounterPhase", async() => {
|
it("Runs MysteryEncounterPhase", async() => {
|
||||||
@ -73,7 +73,7 @@ describe("Mystery Encounter Phases", () => {
|
|||||||
handler.processInput(Button.ACTION);
|
handler.processInput(Button.ACTION);
|
||||||
|
|
||||||
// Waitfor required so that option select messages and preOptionPhase logic are handled
|
// Waitfor required so that option select messages and preOptionPhase logic are handled
|
||||||
await vi.waitFor(() => expect(game.scene.getCurrentPhase().constructor.name).toBe(MysteryEncounterOptionSelectedPhase.name));
|
await vi.waitFor(() => expect(game.scene.getCurrentPhase()?.constructor.name).toBe(MysteryEncounterOptionSelectedPhase.name));
|
||||||
expect(game.scene.ui.getMode()).toBe(Mode.MESSAGE);
|
expect(game.scene.ui.getMode()).toBe(Mode.MESSAGE);
|
||||||
expect(dialogueSpy).toHaveBeenCalledTimes(1);
|
expect(dialogueSpy).toHaveBeenCalledTimes(1);
|
||||||
expect(messageSpy).toHaveBeenCalledTimes(2);
|
expect(messageSpy).toHaveBeenCalledTimes(2);
|
||||||
|
@ -28,12 +28,6 @@ describe("SelectModifierPhase", () => {
|
|||||||
game = new GameManager(phaserGame);
|
game = new GameManager(phaserGame);
|
||||||
scene = game.scene;
|
scene = game.scene;
|
||||||
|
|
||||||
vi.spyOn(scene, "resetSeed").mockImplementation(() => {
|
|
||||||
scene.waveSeed = "test";
|
|
||||||
Phaser.Math.RND.sow([scene.waveSeed]);
|
|
||||||
scene.rngCounter = 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]);
|
initSceneWithoutEncounterPhase(scene, [Species.ABRA, Species.VOLCARONA]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -49,7 +43,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
}, 20000);
|
});
|
||||||
|
|
||||||
it("should generate random modifiers", async () => {
|
it("should generate random modifiers", async () => {
|
||||||
const selectModifierPhase = new SelectModifierPhase(scene);
|
const selectModifierPhase = new SelectModifierPhase(scene);
|
||||||
@ -60,10 +54,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
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(3);
|
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("TEMP_STAT_BOOSTER");
|
});
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("POKEBALL");
|
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("BERRY");
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
it("should modify reroll cost", async () => {
|
it("should modify reroll cost", async () => {
|
||||||
const options = [
|
const options = [
|
||||||
@ -73,12 +64,12 @@ describe("SelectModifierPhase", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const selectModifierPhase1 = new SelectModifierPhase(scene);
|
const selectModifierPhase1 = new SelectModifierPhase(scene);
|
||||||
const selectModifierPhase2 = new SelectModifierPhase(scene, 0, null, { rerollMultiplier: 2 });
|
const selectModifierPhase2 = new SelectModifierPhase(scene, 0, undefined, { rerollMultiplier: 2 });
|
||||||
|
|
||||||
const cost1 = selectModifierPhase1.getRerollCost(options, false);
|
const cost1 = selectModifierPhase1.getRerollCost(options, false);
|
||||||
const cost2 = selectModifierPhase2.getRerollCost(options, false);
|
const cost2 = selectModifierPhase2.getRerollCost(options, false);
|
||||||
expect(cost2).toEqual(cost1 * 2);
|
expect(cost2).toEqual(cost1 * 2);
|
||||||
}, 5000);
|
});
|
||||||
|
|
||||||
it("should generate random modifiers from reroll", async () => {
|
it("should generate random modifiers from reroll", async () => {
|
||||||
let selectModifierPhase = new SelectModifierPhase(scene);
|
let selectModifierPhase = new SelectModifierPhase(scene);
|
||||||
@ -88,9 +79,6 @@ describe("SelectModifierPhase", () => {
|
|||||||
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(3);
|
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("TEMP_STAT_BOOSTER");
|
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("POKEBALL");
|
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("BERRY");
|
|
||||||
|
|
||||||
// Simulate selecting reroll
|
// Simulate selecting reroll
|
||||||
selectModifierPhase = new SelectModifierPhase(scene, 1, [ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON]);
|
selectModifierPhase = new SelectModifierPhase(scene, 1, [ModifierTier.COMMON, ModifierTier.COMMON, ModifierTier.COMMON]);
|
||||||
@ -100,10 +88,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
|
|
||||||
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
expect(scene.ui.getMode()).to.equal(Mode.MODIFIER_SELECT);
|
||||||
expect(modifierSelectHandler.options.length).toEqual(3);
|
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("TM_COMMON");
|
});
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("LURE");
|
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("PP_UP");
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
it("should generate random modifiers of same tier for reroll with reroll lock", async () => {
|
it("should generate random modifiers of same tier for reroll with reroll lock", async () => {
|
||||||
// Just use fully random seed for this test
|
// Just use fully random seed for this test
|
||||||
@ -137,13 +122,13 @@ describe("SelectModifierPhase", () => {
|
|||||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.tier - modifierSelectHandler.options[0].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[0]);
|
expect(modifierSelectHandler.options[0].modifierTypeOption.type.tier - modifierSelectHandler.options[0].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[0]);
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.tier - modifierSelectHandler.options[1].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[1]);
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.tier - modifierSelectHandler.options[1].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[1]);
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier - modifierSelectHandler.options[2].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[2]);
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier - modifierSelectHandler.options[2].modifierTypeOption.upgradeCount).toEqual(firstRollTiers[2]);
|
||||||
}, 5000);
|
});
|
||||||
|
|
||||||
it("should generate custom modifiers", async () => {
|
it("should generate custom modifiers", async () => {
|
||||||
const customModifiers: CustomModifierSettings = {
|
const customModifiers: CustomModifierSettings = {
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_ULTRA, modifierTypes.LEFTOVERS, modifierTypes.AMULET_COIN, modifierTypes.GOLDEN_PUNCH]
|
guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_ULTRA, modifierTypes.LEFTOVERS, modifierTypes.AMULET_COIN, modifierTypes.GOLDEN_PUNCH]
|
||||||
};
|
};
|
||||||
const selectModifierPhase = new SelectModifierPhase(scene, 0, null, customModifiers);
|
const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers);
|
||||||
scene.pushPhase(selectModifierPhase);
|
scene.pushPhase(selectModifierPhase);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
@ -156,7 +141,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("LEFTOVERS");
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.id).toEqual("LEFTOVERS");
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toEqual("AMULET_COIN");
|
expect(modifierSelectHandler.options[3].modifierTypeOption.type.id).toEqual("AMULET_COIN");
|
||||||
expect(modifierSelectHandler.options[4].modifierTypeOption.type.id).toEqual("GOLDEN_PUNCH");
|
expect(modifierSelectHandler.options[4].modifierTypeOption.type.id).toEqual("GOLDEN_PUNCH");
|
||||||
}, 5000);
|
});
|
||||||
|
|
||||||
it("should generate custom modifier tiers that can upgrade from luck", async () => {
|
it("should generate custom modifier tiers that can upgrade from luck", async () => {
|
||||||
const customModifiers: CustomModifierSettings = {
|
const customModifiers: CustomModifierSettings = {
|
||||||
@ -170,7 +155,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
}
|
}
|
||||||
scene.getParty().push(pokemon, pokemon, pokemon, pokemon, pokemon, pokemon);
|
scene.getParty().push(pokemon, pokemon, pokemon, pokemon, pokemon, pokemon);
|
||||||
|
|
||||||
const selectModifierPhase = new SelectModifierPhase(scene, 0, null, customModifiers);
|
const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers);
|
||||||
scene.pushPhase(selectModifierPhase);
|
scene.pushPhase(selectModifierPhase);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
@ -183,14 +168,14 @@ describe("SelectModifierPhase", () => {
|
|||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier - modifierSelectHandler.options[2].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ULTRA);
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier - modifierSelectHandler.options[2].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ULTRA);
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.tier - modifierSelectHandler.options[3].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ROGUE);
|
expect(modifierSelectHandler.options[3].modifierTypeOption.type.tier - modifierSelectHandler.options[3].modifierTypeOption.upgradeCount).toEqual(ModifierTier.ROGUE);
|
||||||
expect(modifierSelectHandler.options[4].modifierTypeOption.type.tier - modifierSelectHandler.options[4].modifierTypeOption.upgradeCount).toEqual(ModifierTier.MASTER);
|
expect(modifierSelectHandler.options[4].modifierTypeOption.type.tier - modifierSelectHandler.options[4].modifierTypeOption.upgradeCount).toEqual(ModifierTier.MASTER);
|
||||||
}, 5000);
|
});
|
||||||
|
|
||||||
it("should generate custom modifiers and modifier tiers together", async () => {
|
it("should generate custom modifiers and modifier tiers together", async () => {
|
||||||
const customModifiers: CustomModifierSettings = {
|
const customModifiers: CustomModifierSettings = {
|
||||||
guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_COMMON],
|
guaranteedModifierTypeFuncs: [modifierTypes.MEMORY_MUSHROOM, modifierTypes.TM_COMMON],
|
||||||
guaranteedModifierTiers: [ModifierTier.MASTER, ModifierTier.MASTER]
|
guaranteedModifierTiers: [ModifierTier.MASTER, ModifierTier.MASTER]
|
||||||
};
|
};
|
||||||
const selectModifierPhase = new SelectModifierPhase(scene, 0, null, customModifiers);
|
const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers);
|
||||||
scene.pushPhase(selectModifierPhase);
|
scene.pushPhase(selectModifierPhase);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
@ -202,7 +187,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("TM_COMMON");
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.id).toEqual("TM_COMMON");
|
||||||
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
expect(modifierSelectHandler.options[2].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
||||||
expect(modifierSelectHandler.options[3].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
expect(modifierSelectHandler.options[3].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
||||||
}, 5000);
|
});
|
||||||
|
|
||||||
it("should fill remaining modifiers if fillRemaining is true with custom modifiers", async () => {
|
it("should fill remaining modifiers if fillRemaining is true with custom modifiers", async () => {
|
||||||
const customModifiers: CustomModifierSettings = {
|
const customModifiers: CustomModifierSettings = {
|
||||||
@ -210,7 +195,7 @@ describe("SelectModifierPhase", () => {
|
|||||||
guaranteedModifierTiers: [ModifierTier.MASTER],
|
guaranteedModifierTiers: [ModifierTier.MASTER],
|
||||||
fillRemaining: true
|
fillRemaining: true
|
||||||
};
|
};
|
||||||
const selectModifierPhase = new SelectModifierPhase(scene, 0, null, customModifiers);
|
const selectModifierPhase = new SelectModifierPhase(scene, 0, undefined, customModifiers);
|
||||||
scene.pushPhase(selectModifierPhase);
|
scene.pushPhase(selectModifierPhase);
|
||||||
await game.phaseInterceptor.run(SelectModifierPhase);
|
await game.phaseInterceptor.run(SelectModifierPhase);
|
||||||
|
|
||||||
@ -220,5 +205,5 @@ describe("SelectModifierPhase", () => {
|
|||||||
expect(modifierSelectHandler.options.length).toEqual(3);
|
expect(modifierSelectHandler.options.length).toEqual(3);
|
||||||
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("MEMORY_MUSHROOM");
|
expect(modifierSelectHandler.options[0].modifierTypeOption.type.id).toEqual("MEMORY_MUSHROOM");
|
||||||
expect(modifierSelectHandler.options[1].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
expect(modifierSelectHandler.options[1].modifierTypeOption.type.tier).toEqual(ModifierTier.MASTER);
|
||||||
}, 5000);
|
});
|
||||||
});
|
});
|
||||||
|
@ -171,8 +171,8 @@ export default class GameManager {
|
|||||||
*/
|
*/
|
||||||
async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: Species[]) {
|
async runToMysteryEncounter(encounterType?: MysteryEncounterType, species?: Species[]) {
|
||||||
if (!isNullOrUndefined(encounterType)) {
|
if (!isNullOrUndefined(encounterType)) {
|
||||||
this.override.disableTrainerWaves(true);
|
this.override.disableTrainerWaves();
|
||||||
this.override.mysteryEncounter(encounterType);
|
this.override.mysteryEncounter(encounterType!);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.runToTitle();
|
await this.runToTitle();
|
||||||
|
@ -108,5 +108,5 @@ export function initSceneWithoutEncounterPhase(scene, species?: Species[]) {
|
|||||||
scene.getParty().push(starterPokemon);
|
scene.getParty().push(starterPokemon);
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.currentBattle = new Battle(getGameMode(GameModes.CLASSIC), 5, BattleType.WILD, null, false);
|
scene.currentBattle = new Battle(getGameMode(GameModes.CLASSIC), 5, BattleType.WILD, undefined, false);
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import * as GameMode from "#app/game-mode";
|
|||||||
import { GameModes, getGameMode } from "#app/game-mode";
|
import { GameModes, getGameMode } from "#app/game-mode";
|
||||||
import { ModifierOverride } from "#app/modifier/modifier-type.js";
|
import { ModifierOverride } from "#app/modifier/modifier-type.js";
|
||||||
import Overrides from "#app/overrides";
|
import Overrides from "#app/overrides";
|
||||||
import { vi } from "vitest";
|
import { MockInstance, vi } from "vitest";
|
||||||
import { GameManagerHelper } from "./gameManagerHelper";
|
import { GameManagerHelper } from "./gameManagerHelper";
|
||||||
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
|
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to handle overrides in tests
|
* Helper to handle overrides in tests
|
||||||
@ -281,6 +283,41 @@ export class OverridesHelper extends GameManagerHelper {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the encounter chance for a mystery encounter.
|
||||||
|
* @param percentage the encounter chance in %
|
||||||
|
* @returns spy instance
|
||||||
|
*/
|
||||||
|
mysteryEncounterChance(percentage: number) {
|
||||||
|
const maxRate: number = 256; // 100%
|
||||||
|
const rate = maxRate * (percentage / 100);
|
||||||
|
const spy = vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_RATE_OVERRIDE", "get").mockReturnValue(rate);
|
||||||
|
this.log(`Mystery encounter chance set to ${percentage}% (=${rate})!`);
|
||||||
|
return spy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the encounter chance for a mystery encounter.
|
||||||
|
* @returns spy instance
|
||||||
|
* @param tier
|
||||||
|
*/
|
||||||
|
mysteryEncounterTier(tier: MysteryEncounterTier): MockInstance {
|
||||||
|
const spy = vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_TIER_OVERRIDE", "get").mockReturnValue(tier);
|
||||||
|
this.log(`Mystery encounter tier set to ${tier}!`);
|
||||||
|
return spy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the encounter that spawns for the scene
|
||||||
|
* @param encounterType
|
||||||
|
* @returns spy instance
|
||||||
|
*/
|
||||||
|
mysteryEncounter(encounterType: MysteryEncounterType) {
|
||||||
|
const spy = vi.spyOn(Overrides, "MYSTERY_ENCOUNTER_OVERRIDE", "get").mockReturnValue(encounterType);
|
||||||
|
this.log(`Mystery encounter override set to ${encounterType}!`);
|
||||||
|
return spy;
|
||||||
|
}
|
||||||
|
|
||||||
private log(...params: any[]) {
|
private log(...params: any[]) {
|
||||||
console.log("Overrides:", ...params);
|
console.log("Overrides:", ...params);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export interface MockGameObject {
|
export interface MockGameObject {
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ export default class MockContainer implements MockGameObject {
|
|||||||
public frame;
|
public frame;
|
||||||
protected textureManager;
|
protected textureManager;
|
||||||
public list: MockGameObject[] = [];
|
public list: MockGameObject[] = [];
|
||||||
private name?: string;
|
name: string;
|
||||||
|
|
||||||
constructor(textureManager: MockTextureManager, x, y) {
|
constructor(textureManager: MockTextureManager, x, y) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
|
@ -3,6 +3,7 @@ import { MockGameObject } from "../mockGameObject";
|
|||||||
export default class MockGraphics implements MockGameObject {
|
export default class MockGraphics implements MockGameObject {
|
||||||
private scene;
|
private scene;
|
||||||
public list: MockGameObject[] = [];
|
public list: MockGameObject[] = [];
|
||||||
|
name: string;
|
||||||
constructor(textureManager, config) {
|
constructor(textureManager, config) {
|
||||||
this.scene = textureManager.scene;
|
this.scene = textureManager.scene;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ export default class MockRectangle implements MockGameObject {
|
|||||||
private fillColor;
|
private fillColor;
|
||||||
private scene;
|
private scene;
|
||||||
public list: MockGameObject[] = [];
|
public list: MockGameObject[] = [];
|
||||||
|
name: string;
|
||||||
|
|
||||||
constructor(textureManager, x, y, width, height, fillColor) {
|
constructor(textureManager, x, y, width, height, fillColor) {
|
||||||
this.fillColor = fillColor;
|
this.fillColor = fillColor;
|
||||||
|
@ -14,6 +14,7 @@ export default class MockSprite implements MockGameObject {
|
|||||||
public scene;
|
public scene;
|
||||||
public anims;
|
public anims;
|
||||||
public list: MockGameObject[] = [];
|
public list: MockGameObject[] = [];
|
||||||
|
name: string;
|
||||||
constructor(textureManager, x, y, texture) {
|
constructor(textureManager, x, y, texture) {
|
||||||
this.textureManager = textureManager;
|
this.textureManager = textureManager;
|
||||||
this.scene = textureManager.scene;
|
this.scene = textureManager.scene;
|
||||||
|
@ -11,7 +11,7 @@ export default class MockText implements MockGameObject {
|
|||||||
public list: MockGameObject[] = [];
|
public list: MockGameObject[] = [];
|
||||||
public style;
|
public style;
|
||||||
public text = "";
|
public text = "";
|
||||||
private name?: string;
|
name: string;
|
||||||
public color?: string;
|
public color?: string;
|
||||||
|
|
||||||
constructor(textureManager, x, y, content, styleOptions) {
|
constructor(textureManager, x, y, content, styleOptions) {
|
||||||
|
@ -12,6 +12,7 @@ export default class MockTexture implements MockGameObject {
|
|||||||
public source;
|
public source;
|
||||||
public frames: object;
|
public frames: object;
|
||||||
public firstFrame: string;
|
public firstFrame: string;
|
||||||
|
name: string;
|
||||||
|
|
||||||
constructor(manager, key: string, source) {
|
constructor(manager, key: string, source) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
@ -336,7 +336,7 @@ export default class PhaseInterceptor {
|
|||||||
const actionForNextPrompt = this.prompts[0];
|
const actionForNextPrompt = this.prompts[0];
|
||||||
const expireFn = actionForNextPrompt.expireFn && actionForNextPrompt.expireFn();
|
const expireFn = actionForNextPrompt.expireFn && actionForNextPrompt.expireFn();
|
||||||
const currentMode = this.scene.ui.getMode();
|
const currentMode = this.scene.ui.getMode();
|
||||||
const currentPhase = this.scene.getCurrentPhase().constructor.name;
|
const currentPhase = this.scene.getCurrentPhase()?.constructor.name;
|
||||||
const currentHandler = this.scene.ui.getHandler();
|
const currentHandler = this.scene.ui.getHandler();
|
||||||
if (expireFn) {
|
if (expireFn) {
|
||||||
this.prompts.shift();
|
this.prompts.shift();
|
||||||
|
@ -18,24 +18,24 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
|||||||
|
|
||||||
export default class MysteryEncounterUiHandler extends UiHandler {
|
export default class MysteryEncounterUiHandler extends UiHandler {
|
||||||
private cursorContainer: Phaser.GameObjects.Container;
|
private cursorContainer: Phaser.GameObjects.Container;
|
||||||
private cursorObj: Phaser.GameObjects.Image;
|
private cursorObj?: Phaser.GameObjects.Image;
|
||||||
|
|
||||||
private optionsContainer: Phaser.GameObjects.Container;
|
private optionsContainer: Phaser.GameObjects.Container;
|
||||||
|
|
||||||
private tooltipWindow: Phaser.GameObjects.NineSlice;
|
private tooltipWindow: Phaser.GameObjects.NineSlice;
|
||||||
private tooltipContainer: Phaser.GameObjects.Container;
|
private tooltipContainer: Phaser.GameObjects.Container;
|
||||||
private tooltipScrollTween: Phaser.Tweens.Tween;
|
private tooltipScrollTween?: Phaser.Tweens.Tween;
|
||||||
|
|
||||||
private descriptionWindow: Phaser.GameObjects.NineSlice;
|
private descriptionWindow: Phaser.GameObjects.NineSlice;
|
||||||
private descriptionContainer: Phaser.GameObjects.Container;
|
private descriptionContainer: Phaser.GameObjects.Container;
|
||||||
private descriptionScrollTween: Phaser.Tweens.Tween;
|
private descriptionScrollTween?: Phaser.Tweens.Tween;
|
||||||
private rarityBall: Phaser.GameObjects.Sprite;
|
private rarityBall: Phaser.GameObjects.Sprite;
|
||||||
|
|
||||||
private dexProgressWindow: Phaser.GameObjects.NineSlice;
|
private dexProgressWindow: Phaser.GameObjects.NineSlice;
|
||||||
private dexProgressContainer: Phaser.GameObjects.Container;
|
private dexProgressContainer: Phaser.GameObjects.Container;
|
||||||
private showDexProgress: boolean = false;
|
private showDexProgress: boolean = false;
|
||||||
|
|
||||||
private overrideSettings: OptionSelectSettings;
|
private overrideSettings?: OptionSelectSettings;
|
||||||
private encounterOptions: MysteryEncounterOption[] = [];
|
private encounterOptions: MysteryEncounterOption[] = [];
|
||||||
private optionsMeetsReqs: boolean[];
|
private optionsMeetsReqs: boolean[];
|
||||||
|
|
||||||
@ -330,9 +330,9 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
this.encounterOptions = this.overrideSettings?.overrideOptions ?? mysteryEncounter.options;
|
this.encounterOptions = this.overrideSettings?.overrideOptions ?? mysteryEncounter.options;
|
||||||
this.optionsMeetsReqs = [];
|
this.optionsMeetsReqs = [];
|
||||||
|
|
||||||
const titleText: string = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.title, TextStyle.TOOLTIP_TITLE);
|
const titleText: string | null = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue?.title, TextStyle.TOOLTIP_TITLE);
|
||||||
const descriptionText: string = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.description, TextStyle.TOOLTIP_CONTENT);
|
const descriptionText: string | null = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue?.description, TextStyle.TOOLTIP_CONTENT);
|
||||||
const queryText: string = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue.query, TextStyle.TOOLTIP_CONTENT);
|
const queryText: string | null = getEncounterText(this.scene, mysteryEncounter.dialogue.encounterOptionsDialogue?.query, TextStyle.TOOLTIP_CONTENT);
|
||||||
|
|
||||||
// Clear options container (except cursor)
|
// Clear options container (except cursor)
|
||||||
this.optionsContainer.removeAll(true);
|
this.optionsContainer.removeAll(true);
|
||||||
@ -355,9 +355,9 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.optionsMeetsReqs.push(option.meetsRequirements(this.scene));
|
this.optionsMeetsReqs.push(option.meetsRequirements(this.scene));
|
||||||
const optionDialogue = option.dialogue;
|
const optionDialogue = option.dialogue!;
|
||||||
const label = !this.optionsMeetsReqs[i] && optionDialogue.disabledButtonLabel ? optionDialogue.disabledButtonLabel : optionDialogue.buttonLabel;
|
const label = !this.optionsMeetsReqs[i] && optionDialogue.disabledButtonLabel ? optionDialogue.disabledButtonLabel : optionDialogue.buttonLabel;
|
||||||
let text: string;
|
let text: string | null;
|
||||||
if (option.hasRequirements() && this.optionsMeetsReqs[i] && (option.optionMode === MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL || option.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)) {
|
if (option.hasRequirements() && this.optionsMeetsReqs[i] && (option.optionMode === MysteryEncounterOptionMode.DEFAULT_OR_SPECIAL || option.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL)) {
|
||||||
// Options with special requirements that are met are automatically colored green
|
// Options with special requirements that are met are automatically colored green
|
||||||
text = getEncounterText(this.scene, label, TextStyle.SUMMARY_GREEN);
|
text = getEncounterText(this.scene, label, TextStyle.SUMMARY_GREEN);
|
||||||
@ -383,7 +383,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
this.optionsContainer.add(viewPartyText);
|
this.optionsContainer.add(viewPartyText);
|
||||||
|
|
||||||
// Description Window
|
// Description Window
|
||||||
const titleTextObject = addBBCodeTextObject(this.scene, 0, 0, titleText, TextStyle.TOOLTIP_TITLE, { wordWrap: { width: 750 }, align: "center", lineSpacing: -8 });
|
const titleTextObject = addBBCodeTextObject(this.scene, 0, 0, titleText ?? "", TextStyle.TOOLTIP_TITLE, { wordWrap: { width: 750 }, align: "center", lineSpacing: -8 });
|
||||||
this.descriptionContainer.add(titleTextObject);
|
this.descriptionContainer.add(titleTextObject);
|
||||||
titleTextObject.setPosition(72 - titleTextObject.displayWidth / 2, 5.5);
|
titleTextObject.setPosition(72 - titleTextObject.displayWidth / 2, 5.5);
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
const ballType = getPokeballAtlasKey(index);
|
const ballType = getPokeballAtlasKey(index);
|
||||||
this.rarityBall.setTexture("pb", ballType);
|
this.rarityBall.setTexture("pb", ballType);
|
||||||
|
|
||||||
const descriptionTextObject = addBBCodeTextObject(this.scene, 6, 25, descriptionText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
const descriptionTextObject = addBBCodeTextObject(this.scene, 6, 25, descriptionText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||||
|
|
||||||
// Sets up the mask that hides the description text to give an illusion of scrolling
|
// Sets up the mask that hides the description text to give an illusion of scrolling
|
||||||
const descriptionTextMaskRect = this.scene.make.graphics({});
|
const descriptionTextMaskRect = this.scene.make.graphics({});
|
||||||
@ -412,7 +412,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
|
|
||||||
if (this.descriptionScrollTween) {
|
if (this.descriptionScrollTween) {
|
||||||
this.descriptionScrollTween.remove();
|
this.descriptionScrollTween.remove();
|
||||||
this.descriptionScrollTween = null;
|
this.descriptionScrollTween = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animates the description text moving upwards
|
// Animates the description text moving upwards
|
||||||
@ -429,7 +429,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
|
|
||||||
this.descriptionContainer.add(descriptionTextObject);
|
this.descriptionContainer.add(descriptionTextObject);
|
||||||
|
|
||||||
const queryTextObject = addBBCodeTextObject(this.scene, 0, 0, queryText, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
const queryTextObject = addBBCodeTextObject(this.scene, 0, 0, queryText ?? "", TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 830 } });
|
||||||
this.descriptionContainer.add(queryTextObject);
|
this.descriptionContainer.add(queryTextObject);
|
||||||
queryTextObject.setPosition(75 - queryTextObject.displayWidth / 2, 90);
|
queryTextObject.setPosition(75 - queryTextObject.displayWidth / 2, 90);
|
||||||
|
|
||||||
@ -460,9 +460,9 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let text: string;
|
let text: string | null;
|
||||||
const cursorOption = this.encounterOptions[cursor];
|
const cursorOption = this.encounterOptions[cursor];
|
||||||
const optionDialogue = cursorOption.dialogue;
|
const optionDialogue = cursorOption.dialogue!;
|
||||||
if (!this.optionsMeetsReqs[cursor] && (cursorOption.optionMode === MysteryEncounterOptionMode.DISABLED_OR_DEFAULT || cursorOption.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) && optionDialogue.disabledButtonTooltip) {
|
if (!this.optionsMeetsReqs[cursor] && (cursorOption.optionMode === MysteryEncounterOptionMode.DISABLED_OR_DEFAULT || cursorOption.optionMode === MysteryEncounterOptionMode.DISABLED_OR_SPECIAL) && optionDialogue.disabledButtonTooltip) {
|
||||||
text = getEncounterText(this.scene, optionDialogue.disabledButtonTooltip, TextStyle.TOOLTIP_CONTENT);
|
text = getEncounterText(this.scene, optionDialogue.disabledButtonTooltip, TextStyle.TOOLTIP_CONTENT);
|
||||||
} else {
|
} else {
|
||||||
@ -470,9 +470,11 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto-color options green/blue for good/bad by looking for (+)/(-)
|
// Auto-color options green/blue for good/bad by looking for (+)/(-)
|
||||||
const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))][0];
|
if (text) {
|
||||||
|
const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))!][0];
|
||||||
text = text.replace(/(\(\+\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_GREEN) + "[/color][/shadow]" + primaryStyleString);
|
text = text.replace(/(\(\+\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_GREEN) + "[/color][/shadow]" + primaryStyleString);
|
||||||
text = text.replace(/(\(\-\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_BLUE) + "[/color][/shadow]" + primaryStyleString);
|
text = text.replace(/(\(\-\)[^\(\[]*)/gi, substring => "[/color][/shadow]" + getBBCodeFrag(substring, TextStyle.SUMMARY_BLUE) + "[/color][/shadow]" + primaryStyleString);
|
||||||
|
}
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
const tooltipTextObject = addBBCodeTextObject(this.scene, 6, 7, text, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 600 }, fontSize: "72px" });
|
const tooltipTextObject = addBBCodeTextObject(this.scene, 6, 7, text, TextStyle.TOOLTIP_CONTENT, { wordWrap: { width: 600 }, fontSize: "72px" });
|
||||||
@ -492,7 +494,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
|
|
||||||
if (this.tooltipScrollTween) {
|
if (this.tooltipScrollTween) {
|
||||||
this.tooltipScrollTween.remove();
|
this.tooltipScrollTween.remove();
|
||||||
this.tooltipScrollTween = null;
|
this.tooltipScrollTween = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animates the tooltip text moving upwards
|
// Animates the tooltip text moving upwards
|
||||||
@ -518,7 +520,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
|
|
||||||
clear(): void {
|
clear(): void {
|
||||||
super.clear();
|
super.clear();
|
||||||
this.overrideSettings = null;
|
this.overrideSettings = undefined;
|
||||||
this.optionsContainer.setVisible(false);
|
this.optionsContainer.setVisible(false);
|
||||||
this.optionsContainer.removeAll(true);
|
this.optionsContainer.removeAll(true);
|
||||||
this.dexProgressContainer.setVisible(false);
|
this.dexProgressContainer.setVisible(false);
|
||||||
@ -534,7 +536,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
|||||||
if (this.cursorObj) {
|
if (this.cursorObj) {
|
||||||
this.cursorObj.destroy();
|
this.cursorObj.destroy();
|
||||||
}
|
}
|
||||||
this.cursorObj = null;
|
this.cursorObj = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,7 +243,7 @@ export function getBBCodeFrag(content: string, textStyle: TextStyle, uiTheme: Ui
|
|||||||
export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string {
|
export function getTextWithColors(content: string, primaryStyle: TextStyle, uiTheme: UiTheme = UiTheme.DEFAULT): string {
|
||||||
// Apply primary styling before anything else
|
// Apply primary styling before anything else
|
||||||
let text = getBBCodeFrag(content, primaryStyle, uiTheme) + "[/color][/shadow]";
|
let text = getBBCodeFrag(content, primaryStyle, uiTheme) + "[/color][/shadow]";
|
||||||
const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))][0];
|
const primaryStyleString = [...text.match(new RegExp(/\[color=[^\[]*\]\[shadow=[^\[]*\]/i))!][0];
|
||||||
|
|
||||||
// Set custom colors
|
// Set custom colors
|
||||||
text = text.replace(/@\[([^{]*)\]{([^}]*)}/gi, (substring, textStyle: string, textToColor: string) => {
|
text = text.replace(/@\[([^{]*)\]{([^}]*)}/gi, (substring, textStyle: string, textToColor: string) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user