diff --git a/src/battle-scene.ts b/src/battle-scene.ts index b0b1fa7bf0f..8c91cae232a 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -95,7 +95,7 @@ import { ToggleDoublePositionPhase } from "./phases/toggle-double-position-phase 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 { allMysteryEncounters, ANTI_VARIANCE_WEIGHT_MODIFIER, AVERAGE_ENCOUNTERS_PER_RUN_TARGET, BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT, MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, mysteryEncountersByBiome, WEIGHT_INCREMENT_ON_SPAWN_MISS } from "./data/mystery-encounters/mystery-encounters"; 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"; @@ -411,7 +411,6 @@ export default class BattleScene extends SceneBase { this.fieldUI = fieldUI; - // @ts-ignore const transition = this.make.rexTransitionImagePack({ x: 0, y: 0, @@ -1171,10 +1170,10 @@ export default class BattleScene extends SceneBase { // Check for mystery encounter // Can only occur in place of a standard (non-boss) wild battle, waves 10-180 - const highestMysteryEncounterWave = 180; - const lowestMysteryEncounterWave = 10; + const highestMysteryEncounterWave = this.gameMode.maxMysteryEncounterWave; + const lowestMysteryEncounterWave = this.gameMode.minMysteryEncounterWave; if (this.gameMode.hasMysteryEncounters && newBattleType === BattleType.WILD && !this.gameMode.isBoss(newWaveIndex) && newWaveIndex < highestMysteryEncounterWave && newWaveIndex > lowestMysteryEncounterWave) { - const roll = Utils.randSeedInt(256); + const roll = Utils.randSeedInt(MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT); // 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.mysteryEncounterSaveData.encounterSpawnChance; @@ -1254,7 +1253,7 @@ export default class BattleScene extends SceneBase { const isEndlessFifthWave = this.gameMode.hasShortBiomes && (lastBattle.waveIndex % 5) === 0; const isWaveIndexMultipleOfFiftyMinusOne = (lastBattle.waveIndex % 50) === 49; const isNewBiome = isWaveIndexMultipleOfTen || isEndlessFifthWave || (isEndlessOrDaily && isWaveIndexMultipleOfFiftyMinusOne); - const resetArenaState = isNewBiome || this.currentBattle.battleType === BattleType.TRAINER || this.currentBattle.battleType === BattleType.MYSTERY_ENCOUNTER || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS; + const resetArenaState = isNewBiome || [BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(this.currentBattle.battleType) || this.currentBattle.battleSpec === BattleSpec.FINAL_BOSS; this.getEnemyParty().forEach(enemyPokemon => enemyPokemon.destroy()); this.trySpreadPokerus(); if (!isNewBiome && (newWaveIndex % 10) === 5) { diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index 639fc474b1c..d235ff86861 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -33,9 +33,14 @@ import { UncommonBreedEncounter } from "#app/data/mystery-encounters/encounters/ import { GlobalTradeSystemEncounter } from "#app/data/mystery-encounters/encounters/global-trade-system-encounter"; /** - * Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / 256 + * Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT */ export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 3; +/** + * The divisor for determining ME spawns, defines the "maximum" weight required for a spawn + * If spawn_weight === MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT, 100% chance to spawn a ME + */ +export const MYSTERY_ENCOUNTER_SPAWN_MAX_WEIGHT = 256; /** * When an ME spawn roll fails, WEIGHT_INCREMENT_ON_SPAWN_MISS is added to future rolls for ME spawn checks. * These values are cleared whenever the next ME spawns, and spawn weight returns to BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT diff --git a/src/game-mode.ts b/src/game-mode.ts index 9bd2ddac18e..3f15f084cba 100644 --- a/src/game-mode.ts +++ b/src/game-mode.ts @@ -9,6 +9,7 @@ import * as Utils from "./utils"; import { Biome } from "#enums/biome"; import { Species } from "#enums/species"; import { Challenges } from "./enums/challenges"; +import MAX_SAFE_INTEGER = Phaser.Math.MAX_SAFE_INTEGER; export enum GameModes { CLASSIC, @@ -30,6 +31,8 @@ interface GameModeConfig { isSplicedOnly?: boolean; isChallenge?: boolean; hasMysteryEncounters?: boolean; + minMysteryEncounterWave?: number; + maxMysteryEncounterWave?: number; } export class GameMode implements GameModeConfig { @@ -47,6 +50,8 @@ export class GameMode implements GameModeConfig { public challenges: Challenge[]; public battleConfig: FixedBattleConfigs; public hasMysteryEncounters: boolean; + public minMysteryEncounterWave: number; + public maxMysteryEncounterWave: number; constructor(modeId: GameModes, config: GameModeConfig, battleConfig?: FixedBattleConfigs) { this.modeId = modeId; @@ -56,6 +61,8 @@ export class GameMode implements GameModeConfig { this.challenges = allChallenges.map(c => copyChallenge(c)); } this.battleConfig = battleConfig || {}; + this.minMysteryEncounterWave = this.minMysteryEncounterWave ?? 0; + this.maxMysteryEncounterWave = this.maxMysteryEncounterWave ?? MAX_SAFE_INTEGER; } /** @@ -338,7 +345,7 @@ export class GameMode implements GameModeConfig { export function getGameMode(gameMode: GameModes): GameMode { switch (gameMode) { case GameModes.CLASSIC: - return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true }, classicFixedBattles); + return new GameMode(GameModes.CLASSIC, { isClassic: true, hasTrainers: true, hasMysteryEncounters: true, maxMysteryEncounterWave: 180, minMysteryEncounterWave: 10 }, classicFixedBattles); case GameModes.ENDLESS: return new GameMode(GameModes.ENDLESS, { isEndless: true, hasShortBiomes: true, hasRandomBosses: true }); case GameModes.SPLICED_ENDLESS: