From 5af5992db4675fe7a269d88f470fc4017f9f6eae Mon Sep 17 00:00:00 2001 From: ImperialSympathizer Date: Thu, 22 Aug 2024 17:39:02 -0400 Subject: [PATCH] adds teleporting hijinks encounter --- .../images/mystery-encounters/berry_bush.json | 41 +++ .../images/mystery-encounters/berry_bush.png | Bin 0 -> 719 bytes .../mystery-encounters/starry_background.png | Bin 10232 -> 0 bytes .../images/mystery-encounters/teleporter.json | 41 +++ .../images/mystery-encounters/teleporter.png | Bin 0 -> 661 bytes .../encounters/berries-abound-encounter.ts | 132 ++------- .../encounters/fiery-fallout-encounter.ts | 4 +- .../encounters/fight-or-flight-encounter.ts | 6 +- .../teleporting-hijinks-encounter.ts | 258 ++++++++++++++++++ .../mystery-encounter-requirements.ts | 31 ++- .../mystery-encounters/mystery-encounters.ts | 5 +- src/enums/mystery-encounter-type.ts | 3 +- src/locales/en/mystery-encounter.ts | 4 +- .../teleporting-hijinks-dialogue.ts | 30 ++ src/overrides.ts | 4 +- 15 files changed, 445 insertions(+), 114 deletions(-) create mode 100644 public/images/mystery-encounters/berry_bush.json create mode 100644 public/images/mystery-encounters/berry_bush.png delete mode 100644 public/images/mystery-encounters/starry_background.png create mode 100644 public/images/mystery-encounters/teleporter.json create mode 100644 public/images/mystery-encounters/teleporter.png create mode 100644 src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts create mode 100644 src/locales/en/mystery-encounters/teleporting-hijinks-dialogue.ts diff --git a/public/images/mystery-encounters/berry_bush.json b/public/images/mystery-encounters/berry_bush.json new file mode 100644 index 00000000000..397538d8af2 --- /dev/null +++ b/public/images/mystery-encounters/berry_bush.json @@ -0,0 +1,41 @@ +{ + "textures": [ + { + "image": "berry_bush.png", + "format": "RGBA8888", + "size": { + "w": 49, + "h": 53 + }, + "scale": 1, + "frames": [ + { + "filename": "0001.png", + "rotated": false, + "trimmed": false, + "sourceSize": { + "w": 49, + "h": 53 + }, + "spriteSourceSize": { + "x": 0, + "y": 0, + "w": 49, + "h": 53 + }, + "frame": { + "x": 0, + "y": 0, + "w": 49, + "h": 53 + } + } + ] + } + ], + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "3.0", + "smartupdate": "$TexturePacker:SmartUpdate:d5f83625477b5f98b726343f4a3a396f:f4665258986e97345cfeee041b4b8bcf:e7781fcc447e6d12deb2af78c9493c7f$" + } +} diff --git a/public/images/mystery-encounters/berry_bush.png b/public/images/mystery-encounters/berry_bush.png new file mode 100644 index 0000000000000000000000000000000000000000..e9be20b4863b927e6c1a3d26973ba946305131af GIT binary patch literal 719 zcmV;=0x0!`lk zao4&{hPHHfJ;P=6>G)-bEX)5GT;s0&UgHim+XwYa`yUXqmpJ<7O9Vi4q+KB6Bp=tn z_Ig18;xY0;gy<@x?e%tN4TL#!-?OA>ySBCJ zhhBj|k$cwMD~dC$R7Z3LB5`zS=3HHKPx_7sozPUtr>c#vaVoCHBLKkDk&&uR5$U|N zR=%3ZypJ)`Ka2p^$|fVYyA9|1XeU!Ti4ap?jM(Wmorfph5UmoRZZ=zNmCo(bIuCAw zc(HsTP>8D%qrqYNiW^I5Xjagoku4(xlayP^5|MN@`UKcug2TZ7E?Y7N(_N z5IhlFqSvJe+fr)YfD<%zfcvUj3gd|YmlINvX41rtG8!0!@8+zpu7fyooz8&okxZpi zbafCt_6b;QkyUfKmr^fI!to(*St& zkwO659F{}g*#+>658=qn4Mz^>4?ggludSOQt~v}-^!vX6YOy}n7(ZFZP~c(EJ^N+- z{2Su&Fyt1oMu^)8nx%=0_wsVvyuV+{%>Vm;!asTdB>5@Q%7p*`002ovPDHLkV1mb3 BLs|d; literal 0 HcmV?d00001 diff --git a/public/images/mystery-encounters/starry_background.png b/public/images/mystery-encounters/starry_background.png deleted file mode 100644 index 759c624ddc1134067ecf7b29e94c9b1d9576219b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10232 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 literal 0 HcmV?d00001 diff --git a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts index 62ef5631736..7a464a5fd55 100644 --- a/src/data/mystery-encounters/encounters/berries-abound-encounter.ts +++ b/src/data/mystery-encounters/encounters/berries-abound-encounter.ts @@ -46,96 +46,7 @@ export const BerriesAboundEncounter: MysteryEncounter = .withSceneWaveRangeRequirement(10, 180) // waves 10 to 180 .withCatchAllowed(true) .withHideWildIntroMessage(true) - .withIntroSpriteConfigs([ - { - spriteKey: "lum_berry", - fileRoot: "items", - isItem: true, - x: 7, - y: -14, - disableAnimation: true - }, - { - spriteKey: "salac_berry", - fileRoot: "items", - isItem: true, - x: 2, - y: 4, - disableAnimation: true - }, - { - spriteKey: "lansat_berry", - fileRoot: "items", - isItem: true, - x: 32, - y: 5, - disableAnimation: true - }, - { - spriteKey: "liechi_berry", - fileRoot: "items", - isItem: true, - x: 6, - y: -5, - disableAnimation: true - }, - { - spriteKey: "sitrus_berry", - fileRoot: "items", - isItem: true, - x: 7, - y: 8, - disableAnimation: true - }, - { - spriteKey: "enigma_berry", - fileRoot: "items", - isItem: true, - x: 26, - y: -4, - disableAnimation: true - }, - { - spriteKey: "leppa_berry", - fileRoot: "items", - isItem: true, - x: 16, - y: -27, - disableAnimation: true - }, - { - spriteKey: "petaya_berry", - fileRoot: "items", - isItem: true, - x: 30, - y: -17, - disableAnimation: true - }, - { - spriteKey: "ganlon_berry", - fileRoot: "items", - isItem: true, - x: 16, - y: -11, - disableAnimation: true - }, - { - spriteKey: "apicot_berry", - fileRoot: "items", - isItem: true, - x: 14, - y: -2, - disableAnimation: true - }, - { - spriteKey: "starf_berry", - fileRoot: "items", - isItem: true, - x: 18, - y: 9, - disableAnimation: true - }, - ]) // Set in onInit() + .withIntroSpriteConfigs([]) // Set in onInit() .withIntroDialogue([ { text: `${namespace}.intro`, @@ -145,12 +56,14 @@ export const BerriesAboundEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter; // Calculate boss mon - 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); + const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0); + 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)); const config: EnemyPartyConfig = { levelAdditiveMultiplier: 1, pokemonConfigs: [{ + level: level, species: bossSpecies, dataSource: new PokemonData(bossPokemon), isBoss: true @@ -168,15 +81,26 @@ export const BerriesAboundEncounter: MysteryEncounter = encounter.misc = { numBerries }; const { spriteKey, fileRoot } = getSpriteKeysFromPokemon(bossPokemon); - encounter.spriteConfigs.push({ - spriteKey: spriteKey, - fileRoot: fileRoot, - hasShadow: true, - tint: 0.25, - x: -5, - repeat: true, - isPokemon: true - }); + encounter.spriteConfigs = [ + { + spriteKey: "berry_bush", + fileRoot: "mystery-encounters", + x: 25, + y: -6, + yShadow: -7, + disableAnimation: true, + hasShadow: true + }, + { + spriteKey: spriteKey, + fileRoot: fileRoot, + hasShadow: true, + tint: 0.25, + x: -5, + repeat: true, + isPokemon: true + } + ]; // Get fastest party pokemon for option 2 const fastestPokemon = getHighestStatPlayerPokemon(scene, Stat.SPD, true); @@ -238,7 +162,7 @@ export const BerriesAboundEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter; const fastestPokemon = encounter.misc.fastestPokemon; const enemySpeed = encounter.misc.enemySpeed; - const speedDiff = fastestPokemon.getStat(Stat.SPD) / enemySpeed; + const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1); const numBerries = encounter.misc.numBerries; const shopOptions: ModifierTypeOption[] = []; @@ -272,8 +196,8 @@ export const BerriesAboundEncounter: MysteryEncounter = await initBattleWithEnemyConfig(scene, config); return; } else { - // Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 1 - const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.1), numBerries), 1); + // Gains 1 berry for every 10% faster the player's pokemon is than the enemy, up to a max of numBerries, minimum of 2 + const numBerriesGrabbed = Math.max(Math.min(Math.round((speedDiff - 1)/0.08), numBerries), 2); encounter.setDialogueToken("numBerries", String(numBerriesGrabbed)); const doFasterBerryRewards = async () => { const berryText = numBerriesGrabbed + " " + i18next.t(`${namespace}.berries`); diff --git a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts index 1eea328927b..fe5cf320401 100644 --- a/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts +++ b/src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts @@ -1,5 +1,5 @@ import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; -import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { EnemyPartyConfig, initBattleWithEnemyConfig, loadCustomMovesForEncounter, leaveEncounterWithoutBattle, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, generateModifierType } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; import { AttackTypeBoosterModifierType, modifierTypes, } from "#app/modifier/modifier-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import BattleScene from "#app/battle-scene"; @@ -243,7 +243,7 @@ function giveLeadPokemonCharcoal(scene: BattleScene) { // Give first party pokemon Charcoal for free at end of battle const leadPokemon = scene.getParty()?.[0]; if (leadPokemon) { - const charcoal = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]).type as AttackTypeBoosterModifierType; + const charcoal = generateModifierType(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.FIRE]) as AttackTypeBoosterModifierType; applyModifierTypeToPlayerPokemon(scene, leadPokemon, charcoal); scene.currentBattle.mysteryEncounter.setDialogueToken("leadPokemon", leadPokemon.getNameToRender()); queueEncounterMessage(scene, `${namespace}.found_charcoal`); 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 616c81880df..a7aeefe2db5 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -49,11 +49,13 @@ export const FightOrFlightEncounter: MysteryEncounter = const encounter = scene.currentBattle.mysteryEncounter; // Calculate boss mon - 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); + const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0); + const bossSpecies = scene.arena.randomSpecies(scene.currentBattle.waveIndex, level, 0, getPartyLuckValue(scene.getParty()), true); + const bossPokemon = new EnemyPokemon(scene, bossSpecies, level, TrainerSlot.NONE, true); const config: EnemyPartyConfig = { levelAdditiveMultiplier: 1, pokemonConfigs: [{ + level: level, species: bossSpecies, dataSource: new PokemonData(bossPokemon), isBoss: true diff --git a/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts new file mode 100644 index 00000000000..c6c41445bd0 --- /dev/null +++ b/src/data/mystery-encounters/encounters/teleporting-hijinks-encounter.ts @@ -0,0 +1,258 @@ +import { EnemyPartyConfig, generateModifierTypeOption, initBattleWithEnemyConfig, setEncounterExp, setEncounterRewards, transitionMysteryEncounterIntroVisuals, updatePlayerMoney, } from "#app/data/mystery-encounters/utils/encounter-phase-utils"; +import { randSeedInt } from "#app/utils"; +import { MysteryEncounterType } from "#enums/mystery-encounter-type"; +import BattleScene from "#app/battle-scene"; +import MysteryEncounter, { MysteryEncounterBuilder } from "../mystery-encounter"; +import { MoneyRequirement, WaveModulusRequirement } from "../mystery-encounter-requirements"; +import Pokemon, { EnemyPokemon } from "#app/field/pokemon"; +import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; +import { queueEncounterMessage, showEncounterText } from "#app/data/mystery-encounters/utils/encounter-dialogue-utils"; +import PokemonData from "#app/system/pokemon-data"; +import { MysteryEncounterTier } from "#enums/mystery-encounter-tier"; +import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; +import { Biome } from "#enums/biome"; +import { getBiomeKey } from "#app/field/arena"; +import { Type } from "#app/data/type"; +import { getPartyLuckValue, modifierTypes } from "#app/modifier/modifier-type"; +import { TrainerSlot } from "#app/data/trainer-config"; +import { BattlerTagType } from "#enums/battler-tag-type"; +import { StatChangePhase } from "#app/phases/stat-change-phase"; +import { BattleStat } from "#app/data/battle-stat"; +import { getPokemonNameWithAffix } from "#app/messages"; + +/** the i18n namespace for this encounter */ +const namespace = "mysteryEncounter:teleportingHijinks"; + +const MONEY_COST_MULTIPLIER = 2.5; +const BIOME_CANDIDATES = [Biome.SPACE, Biome.FAIRY_CAVE, Biome.LABORATORY, Biome.ISLAND]; + +/** + * Teleporting Hijinks encounter. + * @see {@link https://github.com/AsdarDevelops/PokeRogue-Events/issues/119 | GitHub Issue #119} + * @see For biome requirements check {@linkcode mysteryEncountersByBiome} + */ +export const TeleportingHijinksEncounter: MysteryEncounter = + MysteryEncounterBuilder.withEncounterType(MysteryEncounterType.TELEPORTING_HIJINKS) + .withEncounterTier(MysteryEncounterTier.COMMON) + .withSceneWaveRangeRequirement(10, 180) + .withSceneRequirement(new WaveModulusRequirement([1, 2, 3], 10)) // Must be in first 3 waves after boss wave + .withSceneRequirement(new MoneyRequirement(undefined, MONEY_COST_MULTIPLIER)) // Must be able to pay teleport cost + .withAutoHideIntroVisuals(false) + .withCatchAllowed(true) + .withIntroSpriteConfigs([ + { + spriteKey: "teleporter", + fileRoot: "mystery-encounters", + hasShadow: true, + y: 4 + } + ]) + .withIntroDialogue([ + { + text: `${namespace}.intro`, + } + ]) + .withTitle(`${namespace}.title`) + .withDescription(`${namespace}.description`) + .withQuery(`${namespace}.query`) + .withOnInit((scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + const price = scene.getWaveMoneyAmount(MONEY_COST_MULTIPLIER); + encounter.setDialogueToken("price", price.toString()); + encounter.misc = { + price + }; + + return true; + }) + .withOption( + MysteryEncounterOptionBuilder + .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) + .withSceneMoneyRequirement(undefined, MONEY_COST_MULTIPLIER) // Must be able to pay teleport cost + .withDialogue({ + buttonLabel: `${namespace}.option.1.label`, + buttonTooltip: `${namespace}.option.1.tooltip`, + selected: [ + { + text: `${namespace}.option.1.selected`, + } + ], + }) + .withPreOptionPhase(async (scene: BattleScene) => { + // Update money + updatePlayerMoney(scene, -scene.currentBattle.mysteryEncounter.misc.price, true, false); + }) + .withOptionPhase(async (scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + + // Calculate new biome (cannot be current biome) + const filteredBiomes = BIOME_CANDIDATES.filter(b => scene.arena.biomeType !== b); + const newBiome = filteredBiomes[randSeedInt(filteredBiomes.length)]; + + // Show dialogue + await showEncounterText(scene, `${namespace}.transport`); + await Promise.all([animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene)]); + scene.playBgm(); + await showEncounterText(scene, `${namespace}.attacked`); + + // Init enemy + const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0); + 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)); + const config: EnemyPartyConfig = { + pokemonConfigs: [{ + level: level, + species: bossSpecies, + dataSource: new PokemonData(bossPokemon), + isBoss: true, + tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + mysteryEncounterBattleEffects: (pokemon: Pokemon) => { + queueEncounterMessage(pokemon.scene, `${namespace}.boss_enraged`); + pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); + } + }], + }; + + setEncounterRewards(scene, { fillRemaining: true }); + await initBattleWithEnemyConfig(scene, config); + }) + .build() + ) + .withOption( + MysteryEncounterOptionBuilder + .newOptionWithMode(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT) + .withPokemonTypeRequirement([Type.ELECTRIC, Type.STEEL], true, 1) // Must have Steel or Electric type + .withDialogue({ + buttonLabel: `${namespace}.option.2.label`, + buttonTooltip: `${namespace}.option.2.tooltip`, + selected: [ + { + text: `${namespace}.option.2.selected`, + } + ], + }) + .withOptionPhase(async (scene: BattleScene) => { + const encounter = scene.currentBattle.mysteryEncounter; + + // Calculate new biome (cannot be current biome) + const filteredBiomes = BIOME_CANDIDATES.filter(b => scene.arena.biomeType !== b); + const newBiome = filteredBiomes[randSeedInt(filteredBiomes.length)]; + + // Show dialogue + await showEncounterText(scene, `${namespace}.transport`); + await Promise.all([animateBiomeChange(scene, newBiome), transitionMysteryEncounterIntroVisuals(scene)]); + scene.playBgm(); + await showEncounterText(scene, `${namespace}.attacked`); + + // Init enemy + const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0); + 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)); + const config: EnemyPartyConfig = { + pokemonConfigs: [{ + level: level, + species: bossSpecies, + dataSource: new PokemonData(bossPokemon), + isBoss: true, + tags: [BattlerTagType.MYSTERY_ENCOUNTER_POST_SUMMON], + mysteryEncounterBattleEffects: (pokemon: Pokemon) => { + queueEncounterMessage(pokemon.scene, `${namespace}.boss_enraged`); + pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK, BattleStat.DEF, BattleStat.SPATK, BattleStat.SPDEF, BattleStat.SPD], 1)); + } + }], + }; + + setEncounterRewards(scene, { fillRemaining: true }); + setEncounterExp(scene, encounter.selectedOption!.primaryPokemon!.id, 100); + await initBattleWithEnemyConfig(scene, config); + }) + .build() + ) + .withSimpleOption( + { + buttonLabel: `${namespace}.option.3.label`, + buttonTooltip: `${namespace}.option.3.tooltip`, + selected: [ + { + text: `${namespace}.option.3.selected`, + }, + ], + }, + async (scene: BattleScene) => { + // Inspect the Machine + const encounter = scene.currentBattle.mysteryEncounter; + + // Init enemy + const level = (scene.currentBattle.enemyLevels?.[0] ?? scene.currentBattle.waveIndex) + Math.max(Math.round((scene.currentBattle.waveIndex / 10)), 0); + 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)); + const config: EnemyPartyConfig = { + pokemonConfigs: [{ + level: level, + species: bossSpecies, + dataSource: new PokemonData(bossPokemon), + isBoss: true, + }], + }; + + const magnet = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.STEEL]); + const metalCoat = generateModifierTypeOption(scene, modifierTypes.ATTACK_TYPE_BOOSTER, [Type.ELECTRIC]); + setEncounterRewards(scene, { guaranteedModifierTypeOptions: [magnet, metalCoat], fillRemaining: true }); + setEncounterExp(scene, encounter.selectedOption!.primaryPokemon!.id, 100); + transitionMysteryEncounterIntroVisuals(scene, true, true); + await initBattleWithEnemyConfig(scene, config); + } + ) + .build(); + +async function animateBiomeChange(scene: BattleScene, nextBiome: Biome) { + return new Promise(resolve => { + scene.tweens.add({ + targets: [scene.arenaEnemy, scene.lastEnemyTrainer], + x: "+=300", + duration: 2000, + onComplete: () => { + scene.newArena(nextBiome); + + const biomeKey = getBiomeKey(nextBiome); + const bgTexture = `${biomeKey}_bg`; + scene.arenaBgTransition.setTexture(bgTexture); + scene.arenaBgTransition.setAlpha(0); + scene.arenaBgTransition.setVisible(true); + scene.arenaPlayerTransition.setBiome(nextBiome); + scene.arenaPlayerTransition.setAlpha(0); + scene.arenaPlayerTransition.setVisible(true); + + scene.tweens.add({ + targets: [scene.arenaPlayer, scene.arenaBgTransition, scene.arenaPlayerTransition], + duration: 1000, + ease: "Sine.easeInOut", + alpha: (target: any) => target === scene.arenaPlayer ? 0 : 1, + onComplete: () => { + scene.arenaBg.setTexture(bgTexture); + scene.arenaPlayer.setBiome(nextBiome); + scene.arenaPlayer.setAlpha(1); + scene.arenaEnemy.setBiome(nextBiome); + scene.arenaEnemy.setAlpha(1); + scene.arenaNextEnemy.setBiome(nextBiome); + scene.arenaBgTransition.setVisible(false); + scene.arenaPlayerTransition.setVisible(false); + if (scene.lastEnemyTrainer) { + scene.lastEnemyTrainer.destroy(); + } + + resolve(); + + scene.tweens.add({ + targets: scene.arenaEnemy, + x: "-=300", + }); + } + }); + } + }); + }); +} diff --git a/src/data/mystery-encounters/mystery-encounter-requirements.ts b/src/data/mystery-encounters/mystery-encounter-requirements.ts index 4163ece8cd8..042f967a23d 100644 --- a/src/data/mystery-encounters/mystery-encounter-requirements.ts +++ b/src/data/mystery-encounters/mystery-encounter-requirements.ts @@ -153,7 +153,36 @@ export class WaveRangeRequirement extends EncounterSceneRequirement { } getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { - return ["waveCount", scene.currentBattle.waveIndex.toString()]; + return ["waveIndex", scene.currentBattle.waveIndex.toString()]; + } +} + +export class WaveModulusRequirement extends EncounterSceneRequirement { + waveModuli: number[]; + modulusValue: number; + + /** + * Used for specifying a modulus requirement on the wave index + * For example, can be used to require the wave index to end with 1, 2, or 3 + * @param waveModuli - number[], the allowed modulus results + * @param modulusValue - number, the modulus calculation value + * + * Example: + * new WaveModulusRequirement([1, 2, 3], 10) will check for 1st/2nd/3rd waves that are immediately after a multiple of 10 wave + * So waves 21, 32, 53 all return true. 58, 14, 99 return false. + */ + constructor(waveModuli: number[], modulusValue: number) { + super(); + this.waveModuli = waveModuli; + this.modulusValue = modulusValue; + } + + meetsRequirement(scene: BattleScene): boolean { + return this.waveModuli.includes(scene.currentBattle.waveIndex % this.modulusValue); + } + + getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] { + return ["waveIndex", scene.currentBattle.waveIndex.toString()]; } } diff --git a/src/data/mystery-encounters/mystery-encounters.ts b/src/data/mystery-encounters/mystery-encounters.ts index b9e15302fe4..79a3b6ed635 100644 --- a/src/data/mystery-encounters/mystery-encounters.ts +++ b/src/data/mystery-encounters/mystery-encounters.ts @@ -26,6 +26,7 @@ import { PartTimerEncounter } from "#app/data/mystery-encounters/encounters/part import { DancingLessonsEncounter } from "#app/data/mystery-encounters/encounters/dancing-lessons-encounter"; import { WeirdDreamEncounter } from "#app/data/mystery-encounters/encounters/weird-dream-encounter"; import { TheWinstrateChallengeEncounter } from "#app/data/mystery-encounters/encounters/the-winstrate-challenge-encounter"; +import { TeleportingHijinksEncounter } from "#app/data/mystery-encounters/encounters/teleporting-hijinks-encounter"; // Spawn chance: (BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT + WIGHT_INCREMENT_ON_SPAWN_MISS * ) / 256 export const BASE_MYSTERY_ENCOUNTER_SPAWN_WEIGHT = 1; @@ -169,7 +170,8 @@ const anyBiomeEncounters: MysteryEncounterType[] = [ MysteryEncounterType.TRASH_TO_TREASURE, MysteryEncounterType.BERRIES_ABOUND, MysteryEncounterType.CLOWNING_AROUND, - MysteryEncounterType.WEIRD_DREAM + MysteryEncounterType.WEIRD_DREAM, + MysteryEncounterType.TELEPORTING_HIJINKS ]; /** @@ -273,6 +275,7 @@ export function initMysteryEncounters() { allMysteryEncounters[MysteryEncounterType.DANCING_LESSONS] = DancingLessonsEncounter; allMysteryEncounters[MysteryEncounterType.WEIRD_DREAM] = WeirdDreamEncounter; allMysteryEncounters[MysteryEncounterType.THE_WINSTRATE_CHALLENGE] = TheWinstrateChallengeEncounter; + allMysteryEncounters[MysteryEncounterType.TELEPORTING_HIJINKS] = TeleportingHijinksEncounter; // Add extreme encounters to biome map extremeBiomeEncounters.forEach(encounter => { diff --git a/src/enums/mystery-encounter-type.ts b/src/enums/mystery-encounter-type.ts index f9871a1a3dd..b36a2c4ce41 100644 --- a/src/enums/mystery-encounter-type.ts +++ b/src/enums/mystery-encounter-type.ts @@ -23,5 +23,6 @@ export enum MysteryEncounterType { PART_TIMER, DANCING_LESSONS, WEIRD_DREAM, - THE_WINSTRATE_CHALLENGE + THE_WINSTRATE_CHALLENGE, + TELEPORTING_HIJINKS } diff --git a/src/locales/en/mystery-encounter.ts b/src/locales/en/mystery-encounter.ts index 2779900eeff..bb3bc043e75 100644 --- a/src/locales/en/mystery-encounter.ts +++ b/src/locales/en/mystery-encounter.ts @@ -23,6 +23,7 @@ import { partTimerDialogue } from "#app/locales/en/mystery-encounters/part-timer import { dancingLessonsDialogue } from "#app/locales/en/mystery-encounters/dancing-lessons-dialogue"; import { weirdDreamDialogue } from "#app/locales/en/mystery-encounters/weird-dream-dialogue"; import { theWinstrateChallengeDialogue } from "#app/locales/en/mystery-encounters/the-winstrate-challenge-dialogue"; +import { teleportingHijinksDialogue } from "#app/locales/en/mystery-encounters/teleporting-hijinks-dialogue"; /** * Injection patterns that can be used: @@ -73,5 +74,6 @@ export const mysteryEncounter = { partTimer: partTimerDialogue, dancingLessons: dancingLessonsDialogue, weirdDream: weirdDreamDialogue, - theWinstrateChallenge: theWinstrateChallengeDialogue + theWinstrateChallenge: theWinstrateChallengeDialogue, + teleportingHijinks: teleportingHijinksDialogue } as const; diff --git a/src/locales/en/mystery-encounters/teleporting-hijinks-dialogue.ts b/src/locales/en/mystery-encounters/teleporting-hijinks-dialogue.ts new file mode 100644 index 00000000000..5480b9fb720 --- /dev/null +++ b/src/locales/en/mystery-encounters/teleporting-hijinks-dialogue.ts @@ -0,0 +1,30 @@ +export const teleportingHijinksDialogue = { + intro: "It's a strange machine, whirring noisily...", + title: "Teleportating Hijinks", + description: "The machine has a sign on it that reads:\n \"To use, insert money then step into the capsule.\"\n\nPerhaps it can transport you somewhere...", + query: "What will you do?", + option: { + 1: { + label: "Put Money In", + tooltip: "(-) Pay {{price, money}}\n(?) Teleport to New Biome", + selected: "You insert some money, and the capsule opens.\nYou step inside...", + }, + 2: { + label: "A Pokémon Helps", + tooltip: "(-) {{option2PrimaryName}} Helps\n(+) {{option2PrimaryName}} gains EXP\n(?) Teleport to New Biome", + selected: `{{option2PrimaryName}} uses its typing and overloads the machine! + $The capsule opens, and you step inside...` + }, + 3: { + label: "Inspect the Machine", + tooltip: "(-) Pokémon Battle", + selected: `You are drawn in by the blinking lights\nand strange noises coming from the machine... + $You don't even notice as a wild\nPokémon sneaks up and ambushes you!`, + }, + }, + transport: `The machine shakes violently,\nmaking all sorts of strange noises! + $Just as soon as it had started, it quiets once more.`, + attacked: `You step out into a completely new area, startling a wild Pokémon! + $The wild Pokémon attacks!`, + boss_enraged: "The opposing {{enemyPokemon}} has become enraged!" +}; diff --git a/src/overrides.ts b/src/overrides.ts index 1ec9df4b442..7d091243938 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -131,9 +131,9 @@ class DefaultOverrides { // MYSTERY ENCOUNTER OVERRIDES // ------------------------- // 1 to 256, set to null to ignore - readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number | null = null; + readonly MYSTERY_ENCOUNTER_RATE_OVERRIDE: number | null = 256; readonly MYSTERY_ENCOUNTER_TIER_OVERRIDE: MysteryEncounterTier | null = null; - readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType | null = null; + readonly MYSTERY_ENCOUNTER_OVERRIDE: MysteryEncounterType | null = MysteryEncounterType.TELEPORTING_HIJINKS; // ------------------------- // MODIFIER / ITEM OVERRIDES