diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 6e07f8f4ae6..27f1597fd04 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -1911,6 +1911,13 @@ export default class BattleScene extends SceneBase { return false; } + fadeAndSwitchBgm(newBgmKey: string, destroy: boolean = false, delay: number = 2000) { + this.fadeOutBgm(delay, destroy); + this.time.delayedCall(delay, () => { + this.playBgm(newBgmKey); + }); + } + playSound(sound: string | AnySound, config?: object): AnySound { const key = typeof sound === "string" ? sound : sound.key; config = config ?? {}; diff --git a/src/data/move.ts b/src/data/move.ts index c090fb3915a..1b7108448bc 100644 --- a/src/data/move.ts +++ b/src/data/move.ts @@ -2416,8 +2416,14 @@ export class BypassSleepAttr extends MoveAttr { return false; } + /** + * Returns arbitrarily high score when Pokemon is asleep, otherwise shouldn't be used + * @param user + * @param target + * @param move + */ getUserBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer { - return user.status && user.status.effect === StatusEffect.SLEEP ? 100 : -10; + return user.status && user.status.effect === StatusEffect.SLEEP ? 200 : -10; } } diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index 3414f260311..d1497c54527 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -23,7 +23,7 @@ import { getPokemonNameWithAffix } from "#app/messages"; import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { TrainerSlot } from "#app/data/trainer-config"; -import { applyModifierTypeToPlayerPokemon, getEncounterPokemonLevelForWave, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { applyModifierTypeToPlayerPokemon, getEncounterPokemonLevelForWave, getHighestStatPlayerPokemon, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import PokemonData from "#app/system/pokemon-data"; import { BerryModifier } from "#app/modifier/modifier"; import i18next from "#app/plugins/i18n"; @@ -56,7 +56,7 @@ export const BerriesAboundEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; // Calculate boss mon - const level = getEncounterPokemonLevelForWave(scene, 1); + const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true); encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon)); diff --git a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts index b7ecc138590..bd308a5919b 100644 --- a/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts +++ b/src/data/mystery-encounters/encounters/dancing-lessons-encounter.ts @@ -19,7 +19,7 @@ import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter- import { DANCING_MOVES } from "#app/data/mystery-encounters/requirements/requirement-groups"; import { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler"; import { BattlerIndex } from "#app/battle"; -import { catchPokemon, getEncounterPokemonLevelForWave } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { catchPokemon, getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import { PokeballType } from "#enums/pokeball"; import { modifierTypes } from "#app/modifier/modifier-type"; import { LearnMovePhase } from "#app/phases/learn-move-phase"; @@ -107,7 +107,7 @@ export const DancingLessonsEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; const species = getPokemonSpecies(Species.ORICORIO); - const level = getEncounterPokemonLevelForWave(scene, 1); + const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const enemyPokemon = new EnemyPokemon(scene, species, level, TrainerSlot.NONE, false); if (!enemyPokemon.moveset.some(m => m && m.getMove().id === Moves.REVELATION_DANCE)) { if (enemyPokemon.moveset.length < 4) { diff --git a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts index 346d8599546..25959abe19e 100644 --- a/src/data/mystery-encounters/encounters/delibirdy-encounter.ts +++ b/src/data/mystery-encounters/encounters/delibirdy-encounter.ts @@ -33,6 +33,8 @@ const OPTION_3_DISALLOWED_MODIFIERS = [ "PokemonBaseStatTotalModifier" ]; +const DELIBIRDY_MONEY_PRICE_MULTIPLIER = 1.5; + /** * Delibird-y encounter. * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3804 | GitHub Issue #3804} @@ -42,7 +44,7 @@ export const DelibirdyEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.DELIBIRDY) .withEncounterTier(MysteryEncounterTier.GREAT) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) - .withSceneRequirement(new MoneyRequirement(0, 1.5)) // Must have enough money for it to spawn at the very least + .withSceneRequirement(new MoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER)) // Must have enough money for it to spawn at the very least .withPrimaryPokemonRequirement(new CombinationPokemonRequirement( // Must also have either option 2 or 3 available to spawn new HeldItemRequirement(OPTION_2_ALLOWED_MODIFIERS), new HeldItemRequirement(OPTION_3_DISALLOWED_MODIFIERS, 1, true) @@ -98,18 +100,13 @@ export const DelibirdyEncounter: MysteryEncounter = return true; }) .withOnVisualsStart((scene: BattleScene) => { - // Change the bgm - scene.fadeOutBgm(2000, false); - scene.time.delayedCall(2000, () => { - scene.playBgm("mystery_encounter_delibirdy"); - }); - + scene.fadeAndSwitchBgm("mystery_encounter_delibirdy"); return true; }) .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) - .withSceneMoneyRequirement(0, 1.5) // Must have money to spawn + .withSceneMoneyRequirement(0, DELIBIRDY_MONEY_PRICE_MULTIPLIER) // Must have money to spawn .withDialogue({ buttonLabel: `${namespace}.option.1.label`, buttonTooltip: `${namespace}.option.1.tooltip`, diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index 08953b241e0..aa11a07f218 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -22,7 +22,7 @@ import { MoveRequirement } from "#app/data/mystery-encounters/mystery-encounter- import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; import { TrainerSlot } from "#app/data/trainer-config"; -import { getEncounterPokemonLevelForWave, getSpriteKeysFromPokemon } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { getEncounterPokemonLevelForWave, getSpriteKeysFromPokemon, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; import PokemonData from "#app/system/pokemon-data"; import { BattlerTagType } from "#enums/battler-tag-type"; import { queueEncounterMessage } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; @@ -54,7 +54,7 @@ export const FightOrFlightEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; // Calculate boss mon - const level = getEncounterPokemonLevelForWave(scene, 1); + const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true); encounter.setDialogueToken("enemyPokemon", bossPokemon.getNameToRender()); diff --git a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts index 98c0edaf257..9ca7c7c2865 100644 --- a/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts +++ b/src/data/mystery-encounters/encounters/fun-and-games-encounter.ts @@ -84,12 +84,7 @@ export const FunAndGamesEncounter: MysteryEncounter = return true; }) .withOnVisualsStart((scene: BattleScene) => { - // Change the bgm - scene.fadeOutBgm(2000, false); - scene.time.delayedCall(2000, () => { - scene.playBgm("mystery_encounter_fun_and_games"); - }); - + scene.fadeAndSwitchBgm("mystery_encounter_fun_and_games"); return true; }) .withOption(MysteryEncounterOptionBuilder diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index 622b28ae983..45619997579 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -119,12 +119,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter = return true; }) .withOnVisualsStart((scene: BattleScene) => { - // Change the bgm - scene.fadeOutBgm(1500, false); - scene.time.delayedCall(1500, () => { - scene.playBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey); - }); - + scene.fadeAndSwitchBgm(scene.currentBattle.mysteryEncounter!.misc.bgmKey); return true; }) .withOption( diff --git a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts index 7b9b6f2bb46..933f184351a 100644 --- a/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts +++ b/src/data/mystery-encounters/encounters/shady-vitamin-dealer-encounter.ts @@ -19,6 +19,9 @@ import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; /** the i18n namespace for this encounter */ const namespace = "mysteryEncounter:shadyVitaminDealer"; +const VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER = 1.5; +const VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER = 3.5; + /** * Shady Vitamin Dealer encounter. * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3798 | GitHub Issue #3798} @@ -28,7 +31,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.SHADY_VITAMIN_DEALER) .withEncounterTier(MysteryEncounterTier.COMMON) .withSceneWaveRangeRequirement(...CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES) - .withSceneRequirement(new MoneyRequirement(0, 1.5)) // Must have the money for at least the cheap deal + .withSceneRequirement(new MoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER)) // Must have the money for at least the cheap deal .withPrimaryPokemonHealthRatioRequirement([0.5, 1]) // At least 1 Pokemon must have above half HP .withIntroSpriteConfigs([ { @@ -64,7 +67,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) - .withSceneMoneyRequirement(0, 1.5) + .withSceneMoneyRequirement(0, VITAMIN_DEALER_CHEAP_PRICE_MULTIPLIER) .withDialogue({ buttonLabel: `${namespace}.option.1.label`, buttonTooltip: `${namespace}.option.1.tooltip`, @@ -142,7 +145,7 @@ export const ShadyVitaminDealerEncounter: MysteryEncounter = .withOption( MysteryEncounterOptionBuilder .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) - .withSceneMoneyRequirement(0, 3.5) + .withSceneMoneyRequirement(0, VITAMIN_DEALER_EXPENSIVE_PRICE_MULTIPLIER) .withDialogue({ buttonLabel: `${namespace}.option.2.label`, buttonTooltip: `${namespace}.option.2.tooltip`, diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts index 4db9222b19d..10b0e5222b3 100644 --- a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -20,7 +20,7 @@ import { getPokemonNameWithAffix } from "#app/messages"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { Stat } from "#enums/stat"; import { CLASSIC_MODE_MYSTERY_ENCOUNTER_WAVES } from "#app/game-mode"; -import { getEncounterPokemonLevelForWave } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; +import { getEncounterPokemonLevelForWave, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER } from "#app/data/mystery-encounters/utils/encounter-pokemon-utils"; /** the i18n namespace for this encounter */ const namespace = "mysteryEncounter:teleportingHijinks"; @@ -131,7 +131,7 @@ export const TeleportingHijinksEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter!; // Init enemy - const level = getEncounterPokemonLevelForWave(scene, 1); + const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true); encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon)); @@ -167,7 +167,7 @@ async function doBiomeTransitionDialogueAndBattleInit(scene: BattleScene) { await showEncounterText(scene, `${namespace}.attacked`); // Init enemy - const level = getEncounterPokemonLevelForWave(scene, 1); + const level = getEncounterPokemonLevelForWave(scene, STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER); const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true); encounter.setDialogueToken("enemyPokemon", getPokemonNameWithAffix(bossPokemon)); diff --git a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts index 62f4eb2e830..c26c6aa3b7f 100644 --- a/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-pokemon-salesman-encounter.ts @@ -22,6 +22,9 @@ const namespace = "mysteryEncounter:pokemonSalesman"; const MAX_POKEMON_PRICE_MULTIPLIER = 4; +/** Odds of shiny magikarp will be 1/value */ +const SHINY_MAGIKARP_WEIGHT = 100; + /** * Pokemon Salesman encounter. * @see {@link https://github.com/pagefaultgames/pokerogue/issues/3799 | GitHub Issue #3799} @@ -64,7 +67,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = } let pokemon: PlayerPokemon; - if (randSeedInt(100) === 0 || isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) { + if (randSeedInt(SHINY_MAGIKARP_WEIGHT) === 0 || isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) { // If no HA mon found or you roll 1%, give shiny Magikarp species = getPokemonSpecies(Species.MAGIKARP); const hiddenIndex = species.ability2 ? 2 : 1; diff --git a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts index 4c1063284ad..ed8986d99bb 100644 --- a/src/data/mystery-encounters/encounters/weird-dream-encounter.ts +++ b/src/data/mystery-encounters/encounters/weird-dream-encounter.ts @@ -130,12 +130,7 @@ export const WeirdDreamEncounter: MysteryEncounter = return true; }) .withOnVisualsStart((scene: BattleScene) => { - // Change the bgm - scene.fadeOutBgm(3000, false); - scene.time.delayedCall(3000, () => { - scene.playBgm("mystery_encounter_weird_dream"); - }); - + scene.fadeAndSwitchBgm("mystery_encounter_weird_dream"); return true; }) .withOption( diff --git a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts index 1bc9def466b..c85dda5842d 100644 --- a/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts +++ b/src/data/mystery-encounters/utils/encounter-pokemon-utils.ts @@ -21,6 +21,9 @@ import { PermanentStat } from "#enums/stat"; import { VictoryPhase } from "#app/phases/victory-phase"; import { SummaryUiMode } from "#app/ui/summary-ui-handler"; +/** Will give +1 level every 10 waves */ +export const STANDARD_ENCOUNTER_BOOSTED_LEVEL_MODIFIER = 1; + /** * Gets the sprite key and file root for a given PokemonSpecies (accounts for gender, shiny, variants, forms, and experimental) * @param species @@ -736,8 +739,11 @@ export function getGoldenBugNetSpecies(): PokemonSpecies { /** * Generates a Pokemon level for a given wave, with an option to increase/decrease by a scaling modifier + * @param scene + * @param levelAdditiveModifier Default 0. will add +(1 level / 10 waves * levelAdditiveModifier) to the level calculation */ -export function getEncounterPokemonLevelForWave({currentBattle}: BattleScene, levelAdditiveModifier: number = 0) { +export function getEncounterPokemonLevelForWave(scene: BattleScene, levelAdditiveModifier: number = 0) { + const currentBattle = scene.currentBattle; // Default to use the first generated level from enemyLevels, or generate a new one if it DNE const baseLevel = currentBattle.enemyLevels && currentBattle.enemyLevels?.length > 0 ? currentBattle.enemyLevels[0] : currentBattle.getLevelForWave();