mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-19 23:41:00 +00:00
ME data schema updates
This commit is contained in:
parent
70a703f152
commit
0db39f9a1d
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -30,7 +30,7 @@
|
||||
- [ ] The PR is self-contained and cannot be split into smaller PRs?
|
||||
- [ ] Have I provided a clear explanation of the changes?
|
||||
- [ ] Have I considered writing automated tests for the issue?
|
||||
- [ ] If I have text, did I add make it translatable and added a key in the English language?
|
||||
- [ ] If I have text, did I make it translatable and add a key in the English locale file(s)?
|
||||
- [ ] Have I tested the changes (manually)?
|
||||
- [ ] Are all unit tests still passing? (`npm run test`)
|
||||
- [ ] Are the changes visual?
|
||||
|
@ -4,7 +4,7 @@ import Pokemon, { PlayerPokemon, EnemyPokemon } from "./field/pokemon";
|
||||
import PokemonSpecies, { PokemonSpeciesFilter, allSpecies, getPokemonSpecies } from "./data/pokemon-species";
|
||||
import { Constructor, isNullOrUndefined } from "#app/utils";
|
||||
import * as Utils from "./utils";
|
||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, TurnHeldItemTransferModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems } from "./modifier/modifier";
|
||||
import { Modifier, ModifierBar, ConsumablePokemonModifier, ConsumableModifier, PokemonHpRestoreModifier, TurnHeldItemTransferModifier, HealingBoosterModifier, PersistentModifier, PokemonHeldItemModifier, ModifierPredicate, DoubleBattleChanceBoosterModifier, FusePokemonModifier, PokemonFormChangeItemModifier, TerastallizeModifier, overrideModifiers, overrideHeldItems, PokemonIncrementingStatModifier, ExpShareModifier, ExpBalanceModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier } from "./modifier/modifier";
|
||||
import { PokeballType } from "./data/pokeball";
|
||||
import { initCommonAnims, initMoveAnim, loadCommonAnimAssets, loadMoveAnimAssets, populateAnims } from "./data/battle-anims";
|
||||
import { Phase } from "./phase";
|
||||
@ -96,10 +96,13 @@ import { TurnInitPhase } from "./phases/turn-init-phase";
|
||||
import { ShopCursorTarget } from "./enums/shop-cursor-target";
|
||||
import MysteryEncounter from "./data/mystery-encounters/mystery-encounter";
|
||||
import { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters";
|
||||
import { MysteryEncounterData } from "#app/data/mystery-encounters/mystery-encounter-data";
|
||||
import { MysteryEncounterSaveData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
|
||||
import HeldModifierConfig from "#app/interfaces/held-modifier-config";
|
||||
import { ExpPhase } from "#app/phases/exp-phase";
|
||||
import { ShowPartyExpBarPhase } from "#app/phases/show-party-exp-bar-phase";
|
||||
import { MysteryEncounterMode } from "#enums/mystery-encounter-mode";
|
||||
|
||||
export const bypassLogin = import.meta.env.VITE_BYPASS_LOGIN === "1";
|
||||
|
||||
@ -253,7 +256,7 @@ export default class BattleScene extends SceneBase {
|
||||
public money: integer;
|
||||
public pokemonInfoContainer: PokemonInfoContainer;
|
||||
private party: PlayerPokemon[];
|
||||
public mysteryEncounterData: MysteryEncounterData = new MysteryEncounterData(null);
|
||||
public mysteryEncounterSaveData: MysteryEncounterSaveData = new MysteryEncounterSaveData(null);
|
||||
public lastMysteryEncounter?: MysteryEncounter;
|
||||
/** Combined Biome and Wave count text */
|
||||
private biomeWaveText: Phaser.GameObjects.Text;
|
||||
@ -1168,8 +1171,8 @@ export default class BattleScene extends SceneBase {
|
||||
const roll = Utils.randSeedInt(256);
|
||||
|
||||
// Base spawn weight is BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT/256, and increases by WEIGHT_INCREMENT_ON_SPAWN_MISS/256 for each missed attempt at spawning an encounter on a valid floor
|
||||
const sessionEncounterRate = this.mysteryEncounterData.encounterSpawnChance;
|
||||
const encounteredEvents = this.mysteryEncounterData.encounteredEvents;
|
||||
const sessionEncounterRate = this.mysteryEncounterSaveData.encounterSpawnChance;
|
||||
const encounteredEvents = this.mysteryEncounterSaveData.encounteredEvents;
|
||||
|
||||
// If total number of encounters is lower than expected for the run, slightly favor a new encounter spawn (reverse as well)
|
||||
// Reduces occurrence of runs with total encounters significantly different from AVERAGE_ENCOUNTERS_PER_RUN_TARGET
|
||||
@ -1185,9 +1188,9 @@ export default class BattleScene extends SceneBase {
|
||||
if (canSpawn && roll < successRate) {
|
||||
newBattleType = BattleType.MYSTERY_ENCOUNTER;
|
||||
// Reset base spawn weight
|
||||
this.mysteryEncounterData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT;
|
||||
this.mysteryEncounterSaveData.encounterSpawnChance = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT;
|
||||
} else {
|
||||
this.mysteryEncounterData.encounterSpawnChance = sessionEncounterRate + WEIGHT_INCREMENT_ON_SPAWN_MISS;
|
||||
this.mysteryEncounterSaveData.encounterSpawnChance = sessionEncounterRate + WEIGHT_INCREMENT_ON_SPAWN_MISS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2917,6 +2920,96 @@ export default class BattleScene extends SceneBase {
|
||||
this.shiftPhase();
|
||||
}
|
||||
|
||||
applyPartyExp(expValue: number): void {
|
||||
const participantIds = this.currentBattle.playerParticipantIds;
|
||||
const party = this.getParty();
|
||||
const expShareModifier = this.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier;
|
||||
const expBalanceModifier = this.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
|
||||
const multipleParticipantExpBonusModifier = this.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
|
||||
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
||||
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < this.getMaxExpLevel());
|
||||
const partyMemberExp: number[] = [];
|
||||
|
||||
if (participantIds.size) {
|
||||
if (this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.mysteryEncounter?.encounterMode === MysteryEncounterMode.TRAINER_BATTLE) {
|
||||
expValue = Math.floor(expValue * 1.5);
|
||||
} else if (this.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.currentBattle.mysteryEncounter) {
|
||||
expValue = Math.floor(expValue * this.currentBattle.mysteryEncounter.expMultiplier);
|
||||
}
|
||||
for (const partyMember of nonFaintedPartyMembers) {
|
||||
const pId = partyMember.id;
|
||||
const participated = participantIds.has(pId);
|
||||
if (participated) {
|
||||
partyMember.addFriendship(2);
|
||||
const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier);
|
||||
if (machoBraceModifier && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this)) {
|
||||
machoBraceModifier.stackCount++;
|
||||
this.updateModifiers(true, true);
|
||||
partyMember.updateInfo();
|
||||
}
|
||||
}
|
||||
if (!expPartyMembers.includes(partyMember)) {
|
||||
continue;
|
||||
}
|
||||
if (!participated && !expShareModifier) {
|
||||
partyMemberExp.push(0);
|
||||
continue;
|
||||
}
|
||||
let expMultiplier = 0;
|
||||
if (participated) {
|
||||
expMultiplier += (1 / participantIds.size);
|
||||
if (participantIds.size > 1 && multipleParticipantExpBonusModifier) {
|
||||
expMultiplier += multipleParticipantExpBonusModifier.getStackCount() * 0.2;
|
||||
}
|
||||
} else if (expShareModifier) {
|
||||
expMultiplier += (expShareModifier.getStackCount() * 0.2) / participantIds.size;
|
||||
}
|
||||
if (partyMember.pokerus) {
|
||||
expMultiplier *= 1.5;
|
||||
}
|
||||
if (Overrides.XP_MULTIPLIER_OVERRIDE !== null) {
|
||||
expMultiplier = Overrides.XP_MULTIPLIER_OVERRIDE;
|
||||
}
|
||||
const pokemonExp = new Utils.NumberHolder(expValue * expMultiplier);
|
||||
this.applyModifiers(PokemonExpBoosterModifier, true, partyMember, pokemonExp);
|
||||
partyMemberExp.push(Math.floor(pokemonExp.value));
|
||||
}
|
||||
|
||||
if (expBalanceModifier) {
|
||||
let totalLevel = 0;
|
||||
let totalExp = 0;
|
||||
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||
totalExp += partyMemberExp[epm];
|
||||
totalLevel += expPartyMember.level;
|
||||
});
|
||||
|
||||
const medianLevel = Math.floor(totalLevel / expPartyMembers.length);
|
||||
|
||||
const recipientExpPartyMemberIndexes: number[] = [];
|
||||
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||
if (expPartyMember.level <= medianLevel) {
|
||||
recipientExpPartyMemberIndexes.push(epm);
|
||||
}
|
||||
});
|
||||
|
||||
const splitExp = Math.floor(totalExp / recipientExpPartyMemberIndexes.length);
|
||||
|
||||
expPartyMembers.forEach((_partyMember, pm) => {
|
||||
partyMemberExp[pm] = Phaser.Math.Linear(partyMemberExp[pm], recipientExpPartyMemberIndexes.indexOf(pm) > -1 ? splitExp : 0, 0.2 * expBalanceModifier.getStackCount());
|
||||
});
|
||||
}
|
||||
|
||||
for (let pm = 0; pm < expPartyMembers.length; pm++) {
|
||||
const exp = partyMemberExp[pm];
|
||||
|
||||
if (exp) {
|
||||
const partyMemberIndex = party.indexOf(expPartyMembers[pm]);
|
||||
this.unshiftPhase(expPartyMembers[pm].isOnField() ? new ExpPhase(this, partyMemberIndex, exp) : new ShowPartyExpBarPhase(this, partyMemberIndex, exp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads or generates a mystery encounter
|
||||
* @param override - used to load session encounter when restarting game, etc.
|
||||
@ -2932,13 +3025,13 @@ export default class BattleScene extends SceneBase {
|
||||
}
|
||||
|
||||
// Check for queued encounters first
|
||||
if (!encounter && this.mysteryEncounterData?.nextEncounterQueue && this.mysteryEncounterData.nextEncounterQueue.length > 0) {
|
||||
if (!encounter && this.mysteryEncounterSaveData?.queuedEncounters && this.mysteryEncounterSaveData.queuedEncounters.length > 0) {
|
||||
let i = 0;
|
||||
while (i < this.mysteryEncounterData.nextEncounterQueue.length && !!encounter) {
|
||||
const candidate = this.mysteryEncounterData.nextEncounterQueue[i];
|
||||
const forcedChance = candidate[1];
|
||||
while (i < this.mysteryEncounterSaveData.queuedEncounters.length && !!encounter) {
|
||||
const candidate = this.mysteryEncounterSaveData.queuedEncounters[i];
|
||||
const forcedChance = candidate.spawnPercent;
|
||||
if (Utils.randSeedInt(100) < forcedChance) {
|
||||
encounter = allMysteryEncounters[candidate[0]];
|
||||
encounter = allMysteryEncounters[candidate.type];
|
||||
}
|
||||
|
||||
i++;
|
||||
@ -2955,7 +3048,7 @@ export default class BattleScene extends SceneBase {
|
||||
const tierWeights = [MysteryEncounterTier.COMMON, MysteryEncounterTier.GREAT, MysteryEncounterTier.ULTRA, MysteryEncounterTier.ROGUE];
|
||||
|
||||
// Adjust tier weights by previously encountered events to lower odds of only Common/Great in run
|
||||
this.mysteryEncounterData.encounteredEvents.forEach(seenEncounterData => {
|
||||
this.mysteryEncounterSaveData.encounteredEvents.forEach(seenEncounterData => {
|
||||
if (seenEncounterData.tier === MysteryEncounterTier.COMMON) {
|
||||
tierWeights[0] = tierWeights[0] - 6;
|
||||
} else if (seenEncounterData.tier === MysteryEncounterTier.GREAT) {
|
||||
@ -2976,7 +3069,7 @@ export default class BattleScene extends SceneBase {
|
||||
|
||||
let availableEncounters: MysteryEncounter[] = [];
|
||||
// New encounter should never be the same as the most recent encounter
|
||||
const previousEncounter = this.mysteryEncounterData.encounteredEvents.length > 0 ? this.mysteryEncounterData.encounteredEvents[this.mysteryEncounterData.encounteredEvents.length - 1].type : null;
|
||||
const previousEncounter = this.mysteryEncounterSaveData.encounteredEvents.length > 0 ? this.mysteryEncounterSaveData.encounteredEvents[this.mysteryEncounterSaveData.encounteredEvents.length - 1].type : null;
|
||||
const biomeMysteryEncounters = mysteryEncountersByBiome.get(this.arena.biomeType) ?? [];
|
||||
// If no valid encounters exist at tier, checks next tier down, continuing until there are some encounters available
|
||||
while (availableEncounters.length === 0 && tier !== null) {
|
||||
@ -2995,9 +3088,9 @@ export default class BattleScene extends SceneBase {
|
||||
if (previousEncounter !== null && encounterType === previousEncounter) { // Previous encounter was not this one
|
||||
return false;
|
||||
}
|
||||
if (this.mysteryEncounterData.encounteredEvents.length > 0 && // Encounter has not exceeded max allowed encounters
|
||||
if (this.mysteryEncounterSaveData.encounteredEvents.length > 0 && // Encounter has not exceeded max allowed encounters
|
||||
(encounterCandidate.maxAllowedEncounters && encounterCandidate.maxAllowedEncounters > 0)
|
||||
&& this.mysteryEncounterData.encounteredEvents.filter(e => e.type === encounterType).length >= encounterCandidate.maxAllowedEncounters) {
|
||||
&& this.mysteryEncounterSaveData.encounteredEvents.filter(e => e.type === encounterType).length >= encounterCandidate.maxAllowedEncounters) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -129,7 +129,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
|
||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||
mysteryEncounterData: new MysteryEncounterPokemonData(undefined, ability, undefined, [randSeedInt(18), randSeedInt(18)]),
|
||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData(undefined, ability, undefined, [randSeedInt(18), randSeedInt(18)]),
|
||||
isBoss: true,
|
||||
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
||||
},
|
||||
@ -344,10 +344,10 @@ export const ClowningAroundEncounter: MysteryEncounter =
|
||||
}
|
||||
}
|
||||
newTypes.push(secondType);
|
||||
if (!pokemon.mysteryEncounterData) {
|
||||
pokemon.mysteryEncounterData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||
if (!pokemon.mysteryEncounterPokemonData) {
|
||||
pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||
} else {
|
||||
pokemon.mysteryEncounterData.types = newTypes;
|
||||
pokemon.mysteryEncounterPokemonData.types = newTypes;
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -410,10 +410,10 @@ function displayYesNoOptions(scene: BattleScene, resolve) {
|
||||
function onYesAbilitySwap(scene: BattleScene, resolve) {
|
||||
const onPokemonSelected = (pokemon: PlayerPokemon) => {
|
||||
// Do ability swap
|
||||
if (!pokemon.mysteryEncounterData) {
|
||||
pokemon.mysteryEncounterData = new MysteryEncounterPokemonData(undefined, Abilities.AERILATE);
|
||||
if (!pokemon.mysteryEncounterPokemonData) {
|
||||
pokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(undefined, Abilities.AERILATE);
|
||||
}
|
||||
pokemon.mysteryEncounterData.ability = scene.currentBattle.mysteryEncounter!.misc.ability;
|
||||
pokemon.mysteryEncounterPokemonData.ability = scene.currentBattle.mysteryEncounter!.misc.ability;
|
||||
scene.currentBattle.mysteryEncounter!.setDialogueToken("chosenPokemon", pokemon.getNameToRender());
|
||||
scene.ui.setMode(Mode.MESSAGE).then(() => resolve(true));
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ export const TheStrongStuffEncounter: MysteryEncounter =
|
||||
species: getPokemonSpecies(Species.SHUCKLE),
|
||||
isBoss: true,
|
||||
bossSegments: 5,
|
||||
mysteryEncounterData: new MysteryEncounterPokemonData(1.25),
|
||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData(1.25),
|
||||
nature: Nature.BOLD,
|
||||
moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER],
|
||||
modifierConfigs: [
|
||||
|
@ -369,10 +369,10 @@ async function doNewTeamPostProcess(scene: BattleScene, transformations: Pokemon
|
||||
newType = randSeedInt(18) as Type;
|
||||
}
|
||||
newTypes.push(newType);
|
||||
if (!newPokemon.mysteryEncounterData) {
|
||||
newPokemon.mysteryEncounterData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||
if (!newPokemon.mysteryEncounterPokemonData) {
|
||||
newPokemon.mysteryEncounterPokemonData = new MysteryEncounterPokemonData(undefined, undefined, undefined, newTypes);
|
||||
} else {
|
||||
newPokemon.mysteryEncounterData.types = newTypes;
|
||||
newPokemon.mysteryEncounterPokemonData.types = newTypes;
|
||||
}
|
||||
|
||||
for (const item of transformation.heldItems) {
|
||||
|
@ -123,11 +123,11 @@ export class PreviousEncounterRequirement extends EncounterSceneRequirement {
|
||||
}
|
||||
|
||||
meetsRequirement(scene: BattleScene): boolean {
|
||||
return scene.mysteryEncounterData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
|
||||
return scene.mysteryEncounterSaveData.encounteredEvents.some(e => e.type === this.previousEncounterRequirement);
|
||||
}
|
||||
|
||||
getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||
return ["previousEncounter", scene.mysteryEncounterData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""];
|
||||
return ["previousEncounter", scene.mysteryEncounterSaveData.encounteredEvents.find(e => e.type === this.previousEncounterRequirement)?.[0].toString() ?? ""];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,20 +7,27 @@ export class SeenEncounterData {
|
||||
type: MysteryEncounterType;
|
||||
tier: MysteryEncounterTier;
|
||||
waveIndex: number;
|
||||
selectedOption: number;
|
||||
|
||||
constructor(type: MysteryEncounterType, tier: MysteryEncounterTier, waveIndex: number) {
|
||||
constructor(type: MysteryEncounterType, tier: MysteryEncounterTier, waveIndex: number, selectedOption?: number) {
|
||||
this.type = type;
|
||||
this.tier = tier;
|
||||
this.waveIndex = waveIndex;
|
||||
this.selectedOption = selectedOption ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
export class MysteryEncounterData {
|
||||
export interface QueuedEncounter {
|
||||
type: MysteryEncounterType;
|
||||
spawnPercent: number; // Out of 100
|
||||
}
|
||||
|
||||
export class MysteryEncounterSaveData {
|
||||
encounteredEvents: SeenEncounterData[] = [];
|
||||
encounterSpawnChance: number = BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT;
|
||||
nextEncounterQueue: [MysteryEncounterType, integer][] = [];
|
||||
queuedEncounters: QueuedEncounter[] = [];
|
||||
|
||||
constructor(data: MysteryEncounterData | null) {
|
||||
constructor(data: MysteryEncounterSaveData | null) {
|
||||
if (!isNullOrUndefined(data)) {
|
||||
Object.assign(this, data);
|
||||
}
|
@ -72,7 +72,7 @@ export interface EnemyPokemonConfig {
|
||||
isBoss: boolean;
|
||||
bossSegments?: number;
|
||||
bossSegmentModifier?: number; // Additive to the determined segment number
|
||||
mysteryEncounterData?: MysteryEncounterPokemonData;
|
||||
mysteryEncounterPokemonData?: MysteryEncounterPokemonData;
|
||||
formIndex?: number;
|
||||
abilityIndex?: number;
|
||||
level?: number;
|
||||
@ -229,8 +229,8 @@ export async function initBattleWithEnemyConfig(scene: BattleScene, partyConfig:
|
||||
}
|
||||
|
||||
// Set custom mystery encounter data fields (such as sprite scale, custom abilities, types, etc.)
|
||||
if (!isNullOrUndefined(config.mysteryEncounterData)) {
|
||||
enemyPokemon.mysteryEncounterData = config.mysteryEncounterData!;
|
||||
if (!isNullOrUndefined(config.mysteryEncounterPokemonData)) {
|
||||
enemyPokemon.mysteryEncounterPokemonData = config.mysteryEncounterPokemonData!;
|
||||
}
|
||||
|
||||
// Set Boss
|
||||
|
@ -112,7 +112,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
public battleData: PokemonBattleData;
|
||||
public battleSummonData: PokemonBattleSummonData;
|
||||
public turnData: PokemonTurnData;
|
||||
public mysteryEncounterData: MysteryEncounterPokemonData;
|
||||
public mysteryEncounterPokemonData: MysteryEncounterPokemonData;
|
||||
|
||||
/** Used by Mystery Encounters to execute pokemon-specific logic (such as stat boosts) at start of battle */
|
||||
public mysteryEncounterBattleEffects?: (pokemon: Pokemon) => void;
|
||||
@ -201,7 +201,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
this.fusionGender = dataSource.fusionGender;
|
||||
this.fusionLuck = dataSource.fusionLuck;
|
||||
this.usedTMs = dataSource.usedTMs ?? [];
|
||||
this.mysteryEncounterData = dataSource.mysteryEncounterData ?? new MysteryEncounterPokemonData();
|
||||
this.mysteryEncounterPokemonData = dataSource.mysteryEncounterPokemonData ?? new MysteryEncounterPokemonData();
|
||||
} else {
|
||||
this.id = Utils.randSeedInt(4294967296);
|
||||
this.ivs = ivs || Utils.getIvsFromId(this.id);
|
||||
@ -249,7 +249,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
this.luck = (this.shiny ? this.variant + 1 : 0) + (this.fusionShiny ? this.fusionVariant + 1 : 0);
|
||||
this.fusionLuck = this.luck;
|
||||
this.mysteryEncounterData = new MysteryEncounterPokemonData();
|
||||
this.mysteryEncounterPokemonData = new MysteryEncounterPokemonData();
|
||||
}
|
||||
|
||||
this.generateName();
|
||||
@ -577,8 +577,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
const formKey = this.getFormKey();
|
||||
if (formKey.indexOf(SpeciesFormKey.GIGANTAMAX) > -1 || formKey.indexOf(SpeciesFormKey.ETERNAMAX) > -1) {
|
||||
return 1.5;
|
||||
} else if (!isNullOrUndefined(this.mysteryEncounterData.spriteScale) && this.mysteryEncounterData.spriteScale !== 0) {
|
||||
return this.mysteryEncounterData.spriteScale!;
|
||||
} else if (!isNullOrUndefined(this.mysteryEncounterPokemonData.spriteScale) && this.mysteryEncounterPokemonData.spriteScale !== 0) {
|
||||
return this.mysteryEncounterPokemonData.spriteScale!;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1082,9 +1082,9 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
if (!types.length || !includeTeraType) {
|
||||
if (this.mysteryEncounterData.types && this.mysteryEncounterData.types.length > 0) {
|
||||
if (this.mysteryEncounterPokemonData.types && this.mysteryEncounterPokemonData.types.length > 0) {
|
||||
// "Permanent" override for a Pokemon's normal types, currently only used by Mystery Encounters
|
||||
this.mysteryEncounterData.types.forEach(t => types.push(t));
|
||||
this.mysteryEncounterPokemonData.types.forEach(t => types.push(t));
|
||||
} else if (!ignoreOverride && this.summonData?.types && this.summonData.types.length > 0) {
|
||||
this.summonData.types.forEach(t => types.push(t));
|
||||
} else {
|
||||
@ -1146,8 +1146,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (Overrides.OPP_ABILITY_OVERRIDE && !this.isPlayer()) {
|
||||
return allAbilities[Overrides.OPP_ABILITY_OVERRIDE];
|
||||
}
|
||||
if (this.mysteryEncounterData?.ability) {
|
||||
return allAbilities[this.mysteryEncounterData.ability];
|
||||
if (this.mysteryEncounterPokemonData?.ability) {
|
||||
return allAbilities[this.mysteryEncounterPokemonData.ability];
|
||||
}
|
||||
if (this.isFusion()) {
|
||||
return allAbilities[this.getFusionSpeciesForm(ignoreOverride).getAbility(this.fusionAbilityIndex)];
|
||||
@ -1173,8 +1173,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
if (Overrides.OPP_PASSIVE_ABILITY_OVERRIDE && !this.isPlayer()) {
|
||||
return allAbilities[Overrides.OPP_PASSIVE_ABILITY_OVERRIDE];
|
||||
}
|
||||
if (this.mysteryEncounterData?.passive) {
|
||||
return allAbilities[this.mysteryEncounterData.passive];
|
||||
if (this.mysteryEncounterPokemonData?.passive) {
|
||||
return allAbilities[this.mysteryEncounterPokemonData.passive];
|
||||
}
|
||||
|
||||
let starterSpeciesId = this.species.speciesId;
|
||||
|
@ -8,7 +8,7 @@
|
||||
"label": "Battle the Pokémon",
|
||||
"tooltip": "(-) Tricky Battle\n(+) Strong Catchable Foe",
|
||||
"selected": "You approach the\n{{enemyPokemon}} without fear.",
|
||||
"stat_boost": "The {{enemyPokemon}} heightened abilities boost its stats!"
|
||||
"stat_boost": "The {{enemyPokemon}}'s heightened abilities boost its stats!"
|
||||
},
|
||||
"2": {
|
||||
"label": "Give It Food",
|
||||
|
@ -239,7 +239,7 @@ export class GameOverPhase extends BattlePhase {
|
||||
timestamp: new Date().getTime(),
|
||||
challenges: this.scene.gameMode.challenges.map(c => new ChallengeData(c)),
|
||||
mysteryEncounter: this.scene.currentBattle.mysteryEncounter,
|
||||
mysteryEncounterData: this.scene.mysteryEncounterData
|
||||
mysteryEncounterSaveData: this.scene.mysteryEncounterSaveData
|
||||
} as SessionSaveData;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
|
||||
import { NewBattlePhase } from "#app/phases/new-battle-phase";
|
||||
import { GameOverPhase } from "#app/phases/game-over-phase";
|
||||
import { SwitchPhase } from "#app/phases/switch-phase";
|
||||
import { SeenEncounterData } from "#app/data/mystery-encounters/mystery-encounter-data";
|
||||
import { SeenEncounterData } from "#app/data/mystery-encounters/mystery-encounter-save-data";
|
||||
|
||||
/**
|
||||
* Will handle (in order):
|
||||
@ -63,7 +63,7 @@ export class MysteryEncounterPhase extends Phase {
|
||||
if (!this.optionSelectSettings) {
|
||||
// Sets flag that ME was encountered, only if this is not a followup option select phase
|
||||
// Can be used in later MEs to check for requirements to spawn, run history, etc.
|
||||
this.scene.mysteryEncounterData.encounteredEvents.push(new SeenEncounterData(encounter.encounterType, encounter.encounterTier, this.scene.currentBattle.waveIndex));
|
||||
this.scene.mysteryEncounterSaveData.encounteredEvents.push(new SeenEncounterData(encounter.encounterType, encounter.encounterTier, this.scene.currentBattle.waveIndex));
|
||||
}
|
||||
|
||||
// Initiates encounter dialogue window and option select
|
||||
@ -74,6 +74,15 @@ export class MysteryEncounterPhase extends Phase {
|
||||
// Set option selected flag
|
||||
this.scene.currentBattle.mysteryEncounter!.selectedOption = option;
|
||||
|
||||
if (!this.optionSelectSettings) {
|
||||
// Saves the selected option in the ME save data, only if this is not a followup option select phase
|
||||
// Can be used for analytics purposes to track what options are popular on certain encounters
|
||||
const encounterSaveData = this.scene.mysteryEncounterSaveData.encounteredEvents[this.scene.mysteryEncounterSaveData.encounteredEvents.length - 1];
|
||||
if (encounterSaveData.type === this.scene.currentBattle.mysteryEncounter?.encounterType) {
|
||||
encounterSaveData.selectedOption = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (!option.onOptionPhase) {
|
||||
return false;
|
||||
}
|
||||
|
20
src/phases/party-exp-phase.ts
Normal file
20
src/phases/party-exp-phase.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { Phase } from "#app/phase";
|
||||
|
||||
export class PartyExpPhase extends Phase {
|
||||
expValue: number;
|
||||
|
||||
constructor(scene: BattleScene, expValue: number) {
|
||||
super(scene);
|
||||
|
||||
this.expValue = expValue;
|
||||
}
|
||||
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
this.scene.applyPartyExp(this.expValue);
|
||||
|
||||
this.end();
|
||||
}
|
||||
}
|
@ -1,21 +1,15 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { BattlerIndex, BattleType } from "#app/battle.js";
|
||||
import { modifierTypes } from "#app/modifier/modifier-type.js";
|
||||
import { ExpShareModifier, ExpBalanceModifier, MultipleParticipantExpBonusModifier, PokemonExpBoosterModifier } from "#app/modifier/modifier.js";
|
||||
import * as Utils from "#app/utils.js";
|
||||
import Overrides from "#app/overrides";
|
||||
import { BattleEndPhase } from "./battle-end-phase";
|
||||
import { NewBattlePhase } from "./new-battle-phase";
|
||||
import { PokemonPhase } from "./pokemon-phase";
|
||||
import { AddEnemyBuffModifierPhase } from "./add-enemy-buff-modifier-phase";
|
||||
import { EggLapsePhase } from "./egg-lapse-phase";
|
||||
import { ExpPhase } from "./exp-phase";
|
||||
import { GameOverPhase } from "./game-over-phase";
|
||||
import { ModifierRewardPhase } from "./modifier-reward-phase";
|
||||
import { SelectModifierPhase } from "./select-modifier-phase";
|
||||
import { ShowPartyExpBarPhase } from "./show-party-exp-bar-phase";
|
||||
import { TrainerVictoryPhase } from "./trainer-victory-phase";
|
||||
import { PokemonIncrementingStatModifier } from "#app/modifier/modifier";
|
||||
import { handleMysteryEncounterVictory } from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||
|
||||
export class VictoryPhase extends PokemonPhase {
|
||||
@ -33,94 +27,8 @@ export class VictoryPhase extends PokemonPhase {
|
||||
|
||||
this.scene.gameData.gameStats.pokemonDefeated++;
|
||||
|
||||
const participantIds = this.scene.currentBattle.playerParticipantIds;
|
||||
const party = this.scene.getParty();
|
||||
const expShareModifier = this.scene.findModifier(m => m instanceof ExpShareModifier) as ExpShareModifier;
|
||||
const expBalanceModifier = this.scene.findModifier(m => m instanceof ExpBalanceModifier) as ExpBalanceModifier;
|
||||
const multipleParticipantExpBonusModifier = this.scene.findModifier(m => m instanceof MultipleParticipantExpBonusModifier) as MultipleParticipantExpBonusModifier;
|
||||
const nonFaintedPartyMembers = party.filter(p => p.hp);
|
||||
const expPartyMembers = nonFaintedPartyMembers.filter(p => p.level < this.scene.getMaxExpLevel());
|
||||
const partyMemberExp: number[] = [];
|
||||
|
||||
if (participantIds.size) {
|
||||
let expValue = this.getPokemon().getExpValue();
|
||||
if (this.scene.currentBattle.battleType === BattleType.TRAINER) {
|
||||
expValue = Math.floor(expValue * 1.5);
|
||||
} else if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER && this.scene.currentBattle.mysteryEncounter) {
|
||||
expValue = Math.floor(expValue * this.scene.currentBattle.mysteryEncounter.expMultiplier);
|
||||
}
|
||||
for (const partyMember of nonFaintedPartyMembers) {
|
||||
const pId = partyMember.id;
|
||||
const participated = participantIds.has(pId);
|
||||
if (participated) {
|
||||
partyMember.addFriendship(2);
|
||||
const machoBraceModifier = partyMember.getHeldItems().find(m => m instanceof PokemonIncrementingStatModifier);
|
||||
if (machoBraceModifier && machoBraceModifier.stackCount < machoBraceModifier.getMaxStackCount(this.scene)) {
|
||||
machoBraceModifier.stackCount++;
|
||||
this.scene.updateModifiers(true, true);
|
||||
partyMember.updateInfo();
|
||||
}
|
||||
}
|
||||
if (!expPartyMembers.includes(partyMember)) {
|
||||
continue;
|
||||
}
|
||||
if (!participated && !expShareModifier) {
|
||||
partyMemberExp.push(0);
|
||||
continue;
|
||||
}
|
||||
let expMultiplier = 0;
|
||||
if (participated) {
|
||||
expMultiplier += (1 / participantIds.size);
|
||||
if (participantIds.size > 1 && multipleParticipantExpBonusModifier) {
|
||||
expMultiplier += multipleParticipantExpBonusModifier.getStackCount() * 0.2;
|
||||
}
|
||||
} else if (expShareModifier) {
|
||||
expMultiplier += (expShareModifier.getStackCount() * 0.2) / participantIds.size;
|
||||
}
|
||||
if (partyMember.pokerus) {
|
||||
expMultiplier *= 1.5;
|
||||
}
|
||||
if (Overrides.XP_MULTIPLIER_OVERRIDE !== null) {
|
||||
expMultiplier = Overrides.XP_MULTIPLIER_OVERRIDE;
|
||||
}
|
||||
const pokemonExp = new Utils.NumberHolder(expValue * expMultiplier);
|
||||
this.scene.applyModifiers(PokemonExpBoosterModifier, true, partyMember, pokemonExp);
|
||||
partyMemberExp.push(Math.floor(pokemonExp.value));
|
||||
}
|
||||
|
||||
if (expBalanceModifier) {
|
||||
let totalLevel = 0;
|
||||
let totalExp = 0;
|
||||
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||
totalExp += partyMemberExp[epm];
|
||||
totalLevel += expPartyMember.level;
|
||||
});
|
||||
|
||||
const medianLevel = Math.floor(totalLevel / expPartyMembers.length);
|
||||
|
||||
const recipientExpPartyMemberIndexes: number[] = [];
|
||||
expPartyMembers.forEach((expPartyMember, epm) => {
|
||||
if (expPartyMember.level <= medianLevel) {
|
||||
recipientExpPartyMemberIndexes.push(epm);
|
||||
}
|
||||
});
|
||||
|
||||
const splitExp = Math.floor(totalExp / recipientExpPartyMemberIndexes.length);
|
||||
|
||||
expPartyMembers.forEach((_partyMember, pm) => {
|
||||
partyMemberExp[pm] = Phaser.Math.Linear(partyMemberExp[pm], recipientExpPartyMemberIndexes.indexOf(pm) > -1 ? splitExp : 0, 0.2 * expBalanceModifier.getStackCount());
|
||||
});
|
||||
}
|
||||
|
||||
for (let pm = 0; pm < expPartyMembers.length; pm++) {
|
||||
const exp = partyMemberExp[pm];
|
||||
|
||||
if (exp) {
|
||||
const partyMemberIndex = party.indexOf(expPartyMembers[pm]);
|
||||
this.scene.unshiftPhase(expPartyMembers[pm].isOnField() ? new ExpPhase(this.scene, partyMemberIndex, exp) : new ShowPartyExpBarPhase(this.scene, partyMemberIndex, exp));
|
||||
}
|
||||
}
|
||||
}
|
||||
const expValue = this.getPokemon().getExpValue();
|
||||
this.scene.applyPartyExp(expValue);
|
||||
|
||||
if (this.scene.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER) {
|
||||
handleMysteryEncounterVictory(this.scene, false, this.isExpOnly);
|
||||
|
@ -45,7 +45,7 @@ import { TerrainType } from "#app/data/terrain.js";
|
||||
import { OutdatedPhase } from "#app/phases/outdated-phase.js";
|
||||
import { ReloadSessionPhase } from "#app/phases/reload-session-phase.js";
|
||||
import { RUN_HISTORY_LIMIT } from "#app/ui/run-history-ui-handler";
|
||||
import { MysteryEncounterData } from "../data/mystery-encounters/mystery-encounter-data";
|
||||
import { MysteryEncounterSaveData } from "../data/mystery-encounters/mystery-encounter-save-data";
|
||||
import MysteryEncounter from "../data/mystery-encounters/mystery-encounter";
|
||||
|
||||
export const defaultStarterSpecies: Species[] = [
|
||||
@ -132,7 +132,7 @@ export interface SessionSaveData {
|
||||
timestamp: integer;
|
||||
challenges: ChallengeData[];
|
||||
mysteryEncounter: MysteryEncounter;
|
||||
mysteryEncounterData: MysteryEncounterData;
|
||||
mysteryEncounterSaveData: MysteryEncounterSaveData;
|
||||
}
|
||||
|
||||
interface Unlocks {
|
||||
@ -978,7 +978,7 @@ export class GameData {
|
||||
timestamp: new Date().getTime(),
|
||||
challenges: scene.gameMode.challenges.map(c => new ChallengeData(c)),
|
||||
mysteryEncounter: scene.currentBattle.mysteryEncounter,
|
||||
mysteryEncounterData: scene.mysteryEncounterData
|
||||
mysteryEncounterSaveData: scene.mysteryEncounterSaveData
|
||||
} as SessionSaveData;
|
||||
}
|
||||
|
||||
@ -1069,7 +1069,7 @@ export class GameData {
|
||||
scene.score = sessionData.score;
|
||||
scene.updateScoreText();
|
||||
|
||||
scene.mysteryEncounterData = sessionData?.mysteryEncounterData ? sessionData?.mysteryEncounterData : new MysteryEncounterData(null);
|
||||
scene.mysteryEncounterSaveData = sessionData?.mysteryEncounterSaveData ?? new MysteryEncounterSaveData(null);
|
||||
|
||||
scene.newArena(sessionData.arena.biome);
|
||||
|
||||
@ -1294,8 +1294,8 @@ export class GameData {
|
||||
return new MysteryEncounter(v);
|
||||
}
|
||||
|
||||
if (k === "mysteryEncounterData") {
|
||||
return new MysteryEncounterData(v);
|
||||
if (k === "mysteryEncounterSaveData") {
|
||||
return new MysteryEncounterSaveData(v);
|
||||
}
|
||||
|
||||
return v;
|
||||
|
@ -57,7 +57,7 @@ export default class PokemonData {
|
||||
public bossSegments?: integer;
|
||||
|
||||
public summonData: PokemonSummonData;
|
||||
public mysteryEncounterData: MysteryEncounterPokemonData;
|
||||
public mysteryEncounterPokemonData: MysteryEncounterPokemonData;
|
||||
|
||||
constructor(source: Pokemon | any, forHistory: boolean = false) {
|
||||
const sourcePokemon = source instanceof Pokemon ? source : null;
|
||||
@ -103,7 +103,7 @@ export default class PokemonData {
|
||||
this.fusionLuck = source.fusionLuck !== undefined ? source.fusionLuck : (source.fusionShiny ? source.fusionVariant + 1 : 0);
|
||||
this.usedTMs = source.usedTMs ?? [];
|
||||
|
||||
this.mysteryEncounterData = source.mysteryEncounterData ?? new MysteryEncounterPokemonData();
|
||||
this.mysteryEncounterPokemonData = source.mysteryEncounterPokemonData ?? new MysteryEncounterPokemonData();
|
||||
|
||||
if (!forHistory) {
|
||||
this.boss = (source instanceof EnemyPokemon && !!source.bossSegments) || (!this.player && !!source.boss);
|
||||
|
@ -126,11 +126,11 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
});
|
||||
expect(config.pokemonConfigs?.[1]).toEqual({
|
||||
species: getPokemonSpecies(Species.BLACEPHALON),
|
||||
mysteryEncounterData: expect.anything(),
|
||||
mysteryEncounterPokemonData: expect.anything(),
|
||||
isBoss: true,
|
||||
moveSet: [Moves.TRICK, Moves.HYPNOSIS, Moves.SHADOW_BALL, Moves.MIND_BLOWN]
|
||||
});
|
||||
expect(config.pokemonConfigs?.[1].mysteryEncounterData?.types.length).toBe(2);
|
||||
expect(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.types.length).toBe(2);
|
||||
expect([
|
||||
Abilities.STURDY,
|
||||
Abilities.PICKUP,
|
||||
@ -147,8 +147,8 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
Abilities.MAGICIAN,
|
||||
Abilities.SHEER_FORCE,
|
||||
Abilities.PRANKSTER
|
||||
]).toContain(config.pokemonConfigs?.[1].mysteryEncounterData?.ability);
|
||||
expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs?.[1].mysteryEncounterData?.ability);
|
||||
]).toContain(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.ability);
|
||||
expect(ClowningAroundEncounter.misc.ability).toBe(config.pokemonConfigs?.[1].mysteryEncounterPokemonData?.ability);
|
||||
await vi.waitFor(() => expect(moveInitSpy).toHaveBeenCalled());
|
||||
await vi.waitFor(() => expect(moveLoadSpy).toHaveBeenCalled());
|
||||
expect(onInitResult).toBe(true);
|
||||
@ -227,7 +227,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
await game.phaseInterceptor.to(NewBattlePhase, false);
|
||||
|
||||
const leadPokemon = scene.getParty()[0];
|
||||
expect(leadPokemon.mysteryEncounterData?.ability).toBe(abilityToTrain);
|
||||
expect(leadPokemon.mysteryEncounterPokemonData?.ability).toBe(abilityToTrain);
|
||||
});
|
||||
});
|
||||
|
||||
@ -348,9 +348,9 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
scene.getParty()[2].moveset = [];
|
||||
await runMysteryEncounterToEnd(game, 3);
|
||||
|
||||
const leadTypesAfter = scene.getParty()[0].mysteryEncounterData?.types;
|
||||
const secondaryTypesAfter = scene.getParty()[1].mysteryEncounterData?.types;
|
||||
const thirdTypesAfter = scene.getParty()[2].mysteryEncounterData?.types;
|
||||
const leadTypesAfter = scene.getParty()[0].mysteryEncounterPokemonData?.types;
|
||||
const secondaryTypesAfter = scene.getParty()[1].mysteryEncounterPokemonData?.types;
|
||||
const thirdTypesAfter = scene.getParty()[2].mysteryEncounterPokemonData?.types;
|
||||
|
||||
expect(leadTypesAfter.length).toBe(2);
|
||||
expect(leadTypesAfter[0]).toBe(Type.WATER);
|
||||
|
@ -121,7 +121,7 @@ describe("The Strong Stuff - Mystery Encounter", () => {
|
||||
species: getPokemonSpecies(Species.SHUCKLE),
|
||||
isBoss: true,
|
||||
bossSegments: 5,
|
||||
mysteryEncounterData: new MysteryEncounterPokemonData(1.25),
|
||||
mysteryEncounterPokemonData: new MysteryEncounterPokemonData(1.25),
|
||||
nature: Nature.BOLD,
|
||||
moveSet: [Moves.INFESTATION, Moves.SALT_CURE, Moves.GASTRO_ACID, Moves.HEAL_ORDER],
|
||||
modifierConfigs: expect.any(Array),
|
||||
|
@ -138,7 +138,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
||||
for (let i = 0; i < pokemonAfter.length; i++) {
|
||||
const newPokemon = pokemonAfter[i];
|
||||
expect(newPokemon.getSpeciesForm().speciesId).not.toBe(pokemonPrior[i].getSpeciesForm().speciesId);
|
||||
expect(newPokemon.mysteryEncounterData?.types.length).toBe(2);
|
||||
expect(newPokemon.mysteryEncounterPokemonData?.types.length).toBe(2);
|
||||
}
|
||||
|
||||
const plus90To110 = bstDiff.filter(bst => bst > 80);
|
||||
|
@ -49,9 +49,9 @@ describe("Mystery Encounter Phases", () => {
|
||||
});
|
||||
await game.phaseInterceptor.run(MysteryEncounterPhase);
|
||||
|
||||
expect(game.scene.mysteryEncounterData.encounteredEvents.length).toBeGreaterThan(0);
|
||||
expect(game.scene.mysteryEncounterData.encounteredEvents[0].type).toEqual(MysteryEncounterType.MYSTERIOUS_CHALLENGERS);
|
||||
expect(game.scene.mysteryEncounterData.encounteredEvents[0].tier).toEqual(MysteryEncounterTier.GREAT);
|
||||
expect(game.scene.mysteryEncounterSaveData.encounteredEvents.length).toBeGreaterThan(0);
|
||||
expect(game.scene.mysteryEncounterSaveData.encounteredEvents[0].type).toEqual(MysteryEncounterType.MYSTERIOUS_CHALLENGERS);
|
||||
expect(game.scene.mysteryEncounterSaveData.encounteredEvents[0].tier).toEqual(MysteryEncounterTier.GREAT);
|
||||
expect(game.scene.ui.getMode()).toBe(Mode.MYSTERY_ENCOUNTER);
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user