diff --git a/src/data/mystery-encounters/encounters/sky-battle-encounter.ts b/src/data/mystery-encounters/encounters/sky-battle-encounter.ts index 2d5dc798a47..630d4e022d3 100644 --- a/src/data/mystery-encounters/encounters/sky-battle-encounter.ts +++ b/src/data/mystery-encounters/encounters/sky-battle-encounter.ts @@ -25,7 +25,7 @@ import { PokemonType } from "#enums/pokemon-type"; import { AbilityId } from "#enums/ability-id"; import { MoveId } from "#enums/move-id"; import { SpeciesId } from "#enums/species-id"; -import { randSeedInt, randSeedShuffle } from "#app/utils/common"; +import { isNullOrUndefined, randSeedInt, randSeedShuffle } from "#app/utils/common"; import type { PlayerPokemon } from "#app/field/pokemon"; import { PokemonMove } from "#app/data/moves/pokemon-move"; import i18next from "i18next"; @@ -291,6 +291,883 @@ const POOL_SKY = [SpeciesId.SHAYMIN]; const POOL_BLACK = [SpeciesId.KYUREM]; const POOL_WHITE = [SpeciesId.KYUREM]; +// trainer pools +const WEAK_TIER = [ + SpeciesId.PIDGEY, + SpeciesId.SPEAROW, + SpeciesId.ZUBAT, + SpeciesId.MAGNEMITE, + SpeciesId.GASTLY, + SpeciesId.KOFFING, + SpeciesId.PORYGON, + SpeciesId.HOOTHOOT, + SpeciesId.LEDYBA, + SpeciesId.NATU, + SpeciesId.HOPPIP, + SpeciesId.SKIPLOOM, + SpeciesId.YANMA, + SpeciesId.MURKROW, + SpeciesId.MISDREAVUS, + SpeciesId.UNOWN, + SpeciesId.GLIGAR, + SpeciesId.DELIBIRD, + SpeciesId.TAILLOW, + SpeciesId.WINGULL, + SpeciesId.SHEDINJA, + SpeciesId.VOLBEAT, + SpeciesId.ILLUMISE, + SpeciesId.SWABLU, + SpeciesId.BALTOY, + SpeciesId.CASTFORM, + SpeciesId.DUSKULL, + SpeciesId.BELDUM, + SpeciesId.STARLY, + SpeciesId.COMBEE, + SpeciesId.DRIFLOON, + SpeciesId.CHINGLING, + SpeciesId.BRONZOR, + SpeciesId.CHATOT, + SpeciesId.MANTYKE, + SpeciesId.PIDOVE, + SpeciesId.WOOBAT, + SpeciesId.SOLOSIS, + SpeciesId.DUCKLETT, + SpeciesId.VANILLITE, + SpeciesId.EMOLGA, + SpeciesId.KLINK, + SpeciesId.TYNAMO, + SpeciesId.ELGYEM, + SpeciesId.RUFFLET, + SpeciesId.FLETCHLING, + SpeciesId.KLEFKI, + SpeciesId.NOIBAT, + SpeciesId.ROWLET, + SpeciesId.PIKIPEK, + SpeciesId.CUTIEFLY, + SpeciesId.COMFEY, + SpeciesId.MINIOR, + SpeciesId.COSMOG, + SpeciesId.POIPOLE, + SpeciesId.ROOKIDEE, + SpeciesId.SINISTEA, + SpeciesId.DREEPY, + SpeciesId.SQUAWKABILLY, + SpeciesId.WATTREL, + SpeciesId.VAROOM, + SpeciesId.GLIMMET, + SpeciesId.POLTCHAGEIST, +]; + +const MID_TIER = [ + { + species: SpeciesId.BUTTERFREE, + formIndex: 0, + }, + { + species: SpeciesId.BEEDRILL, + formIndex: 0, + }, + { + species: SpeciesId.PIDGEOTTO, + formIndex: 0, + }, + { + species: SpeciesId.PIDGEOT, + formIndex: 0, + }, + { + species: SpeciesId.FEAROW, + formIndex: 0, + }, + { + species: SpeciesId.GOLBAT, + formIndex: 0, + }, + { + species: SpeciesId.VENOMOTH, + formIndex: 0, + }, + { + species: SpeciesId.MAGNETON, + formIndex: 0, + }, + { + species: SpeciesId.HAUNTER, + formIndex: 0, + }, + { + species: SpeciesId.WEEZING, + formIndex: 0, + }, + { + species: SpeciesId.SCYTHER, + formIndex: 0, + }, + { + species: SpeciesId.NOCTOWL, + formIndex: 0, + }, + { + species: SpeciesId.LEDIAN, + formIndex: 0, + }, + { + species: SpeciesId.CROBAT, + formIndex: 0, + }, + { + species: SpeciesId.TOGETIC, + formIndex: 0, + }, + { + species: SpeciesId.XATU, + formIndex: 0, + }, + { + species: SpeciesId.JUMPLUFF, + formIndex: 0, + }, + { + species: SpeciesId.MANTINE, + formIndex: 0, + }, + { + species: SpeciesId.SKARMORY, + formIndex: 0, + }, + { + species: SpeciesId.PORYGON2, + formIndex: 0, + }, + { + species: SpeciesId.BEAUTIFLY, + formIndex: 0, + }, + { + species: SpeciesId.DUSTOX, + formIndex: 0, + }, + { + species: SpeciesId.SWELLOW, + formIndex: 0, + }, + { + species: SpeciesId.PELIPPER, + formIndex: 0, + }, + { + species: SpeciesId.MASQUERAIN, + formIndex: 0, + }, + { + species: SpeciesId.VIBRAVA, + formIndex: 0, + }, + { + species: SpeciesId.ALTARIA, + formIndex: 0, + }, + { + species: SpeciesId.LUNATONE, + formIndex: 0, + }, + { + species: SpeciesId.SOLROCK, + formIndex: 0, + }, + { + species: SpeciesId.CLAYDOL, + formIndex: 0, + }, + { + species: SpeciesId.TROPIUS, + formIndex: 0, + }, + { + species: SpeciesId.CHIMECHO, + formIndex: 0, + }, + { + species: SpeciesId.GLALIE, + formIndex: 0, + }, + { + species: SpeciesId.METANG, + formIndex: 0, + }, + { + species: SpeciesId.STARAVIA, + formIndex: 0, + }, + { + species: SpeciesId.STARAPTOR, + formIndex: 0, + }, + { + species: SpeciesId.MOTHIM, + formIndex: 0, + }, + { + species: SpeciesId.VESPIQUEN, + formIndex: 0, + }, + { + species: SpeciesId.DRIFBLIM, + formIndex: 0, + }, + { + species: SpeciesId.MISMAGIUS, + formIndex: 0, + }, + { + species: SpeciesId.HONCHKROW, + formIndex: 0, + }, + { + species: SpeciesId.BRONZONG, + formIndex: 0, + }, + { + species: SpeciesId.CARNIVINE, + formIndex: 0, + }, + { + species: SpeciesId.MAGNEZONE, + formIndex: 0, + }, + { + species: SpeciesId.TOGEKISS, + formIndex: 0, + }, + { + species: SpeciesId.YANMEGA, + formIndex: 0, + }, + { + species: SpeciesId.GLISCOR, + formIndex: 0, + }, + { + species: SpeciesId.PORYGON_Z, + formIndex: 0, + }, + { + species: SpeciesId.PROBOPASS, + formIndex: 0, + }, + { + species: SpeciesId.DUSKNOIR, + formIndex: 0, + }, + { + species: SpeciesId.FROSLASS, + formIndex: 0, + }, + { + species: SpeciesId.ROTOM, // allow all forms + formIndex: 0, // normal + }, + { + species: SpeciesId.ROTOM, + formIndex: 1, // heat + }, + { + species: SpeciesId.ROTOM, + formIndex: 2, // wash + }, + { + species: SpeciesId.ROTOM, + formIndex: 3, // frost + }, + { + species: SpeciesId.ROTOM, + formIndex: 4, // fan + }, + { + species: SpeciesId.ROTOM, + formIndex: 5, // mow + }, + { + species: SpeciesId.TRANQUILL, + formIndex: 0, + }, + { + species: SpeciesId.UNFEZANT, + formIndex: 0, + }, + { + species: SpeciesId.SWOOBAT, + formIndex: 0, + }, + { + species: SpeciesId.SIGILYPH, + formIndex: 0, + }, + { + species: SpeciesId.ARCHEOPS, + formIndex: 0, + }, + { + species: SpeciesId.DUOSION, + formIndex: 0, + }, + { + species: SpeciesId.REUNICLUS, + formIndex: 0, + }, + { + species: SpeciesId.SWANNA, + formIndex: 0, + }, + { + species: SpeciesId.VANILLISH, + formIndex: 0, + }, + { + species: SpeciesId.VANILLUXE, + formIndex: 0, + }, + { + species: SpeciesId.KLANG, + formIndex: 0, + }, + { + species: SpeciesId.KLINKLANG, + formIndex: 0, + }, + { + species: SpeciesId.EELEKTRIK, + formIndex: 0, + }, + { + species: SpeciesId.EELEKTROSS, + formIndex: 0, + }, + { + species: SpeciesId.BEHEEYEM, + formIndex: 0, + }, + { + species: SpeciesId.LAMPENT, + formIndex: 0, + }, + { + species: SpeciesId.CHANDELURE, + formIndex: 0, + }, + { + species: SpeciesId.CRYOGONAL, + formIndex: 0, + }, + { + species: SpeciesId.BRAVIARY, + formIndex: 0, + }, + { + species: SpeciesId.MANDIBUZZ, + formIndex: 0, + }, + { + species: SpeciesId.MELOETTA, + formIndex: 0, + }, // Aria + { + species: SpeciesId.FLETCHINDER, + formIndex: 0, + }, + { + species: SpeciesId.TALONFLAME, + formIndex: 0, + }, + { + species: SpeciesId.VIVILLON, + formIndex: 0, + }, + { + species: SpeciesId.HAWLUCHA, + formIndex: 0, + }, + { + species: SpeciesId.DARTRIX, + formIndex: 0, + }, + { + species: SpeciesId.TRUMBEAK, + formIndex: 0, + }, + { + species: SpeciesId.TOUCANNON, + formIndex: 0, + }, + { + species: SpeciesId.VIKAVOLT, + formIndex: 0, + }, + { + species: SpeciesId.ORICORIO, // ALL (Baile, Pompom, Pau, Sensu) + formIndex: 0, // Baile + }, + { + species: SpeciesId.ORICORIO, + formIndex: 1, // Pompom + }, + { + species: SpeciesId.ORICORIO, + formIndex: 2, // Pau + }, + { + species: SpeciesId.ORICORIO, + formIndex: 3, // Sensu + }, + { + species: SpeciesId.RIBOMBEE, + formIndex: 0, + }, + { + species: SpeciesId.COSMOEM, + formIndex: 0, + }, + { + species: SpeciesId.CORVISQUIRE, + formIndex: 0, + }, + { + species: SpeciesId.CORVIKNIGHT, + formIndex: 0, + }, + { + species: SpeciesId.ORBEETLE, + formIndex: 0, + }, + { + species: SpeciesId.FLAPPLE, + formIndex: 0, + }, + { + species: SpeciesId.CRAMORANT, + formIndex: 0, + }, + { + species: SpeciesId.POLTEAGEIST, + formIndex: 0, + }, + { + species: SpeciesId.FROSMOTH, + formIndex: 0, + }, + { + species: SpeciesId.DRAKLOAK, + formIndex: 0, + }, + { + species: SpeciesId.RABSCA, + formIndex: 0, + }, + { + species: SpeciesId.BOMBIRDIER, + formIndex: 0, + }, + { + species: SpeciesId.REVAVROOM, + formIndex: 0, + }, + { + species: SpeciesId.FLAMIGO, + formIndex: 0, + }, + { + species: SpeciesId.SINISTCHA, + formIndex: 0, + }, +]; + +const STRONG_TIER: { species: SpeciesId; formIndex?: number }[] = [ + { + species: SpeciesId.CHARIZARD, + formIndex: 0, + }, + { + species: SpeciesId.CHARIZARD, + formIndex: 1, + }, + { + species: SpeciesId.CHARIZARD, + formIndex: 2, + }, + { + species: SpeciesId.BUTTERFREE, + formIndex: 1, + }, + { + species: SpeciesId.PIDGEOT, + formIndex: 1, + }, + { + species: SpeciesId.ALAKAZAM, + formIndex: 1, + }, + { + species: SpeciesId.GENGAR, + formIndex: 0, + }, + { + species: SpeciesId.GYARADOS, + formIndex: 0, + }, + { + species: SpeciesId.GYARADOS, + formIndex: 1, + }, + { + species: SpeciesId.AERODACTYL, + formIndex: 0, + }, + { + species: SpeciesId.AERODACTYL, + formIndex: 1, + }, + { + species: SpeciesId.ARTICUNO, + }, + { + species: SpeciesId.ZAPDOS, + }, + { + species: SpeciesId.MOLTRES, + }, + { + species: SpeciesId.DRAGONITE, + }, + { + species: SpeciesId.MEWTWO, + formIndex: 0, + }, + { + species: SpeciesId.MEWTWO, + formIndex: 1, + }, + { + species: SpeciesId.MEWTWO, + formIndex: 2, + }, + { + species: SpeciesId.MEW, + }, + { + species: SpeciesId.LUGIA, + }, + { + species: SpeciesId.HO_OH, + }, + { + species: SpeciesId.CELEBI, + }, + { + species: SpeciesId.FLYGON, + }, + { + species: SpeciesId.ALTARIA, + formIndex: 1, + }, + { + species: SpeciesId.GLALIE, + formIndex: 1, + }, + { + species: SpeciesId.SALAMENCE, + formIndex: 0, + }, + { + species: SpeciesId.SALAMENCE, + formIndex: 1, + }, + { + species: SpeciesId.METAGROSS, + formIndex: 1, + }, + { + species: SpeciesId.LATIAS, + formIndex: 0, + }, + { + species: SpeciesId.LATIAS, + formIndex: 1, + }, + { + species: SpeciesId.LATIOS, + formIndex: 0, + }, + { + species: SpeciesId.LATIOS, + formIndex: 1, + }, + { + species: SpeciesId.RAYQUAZA, + formIndex: 0, + }, + { + species: SpeciesId.RAYQUAZA, + formIndex: 1, + }, + { + species: SpeciesId.JIRACHI, + }, + { + species: SpeciesId.DEOXYS, + formIndex: 0, + }, + { + species: SpeciesId.DEOXYS, + formIndex: 1, + }, + { + species: SpeciesId.DEOXYS, + formIndex: 2, + }, + { + species: SpeciesId.DEOXYS, + formIndex: 3, + }, + { + species: SpeciesId.UXIE, + }, + { + species: SpeciesId.MESPRIT, + }, + { + species: SpeciesId.AZELF, + }, + { + species: SpeciesId.DIALGA, + formIndex: 0, + }, + { + species: SpeciesId.DIALGA, + formIndex: 1, + }, + { + species: SpeciesId.PALKIA, + formIndex: 0, + }, + { + species: SpeciesId.PALKIA, + formIndex: 1, + }, + { + species: SpeciesId.GIRATINA, + formIndex: 0, + }, + { + species: SpeciesId.GIRATINA, + formIndex: 1, + }, + { + species: SpeciesId.CRESSELIA, + }, + { + species: SpeciesId.DARKRAI, + }, + { + species: SpeciesId.SHAYMIN, + formIndex: 1, + }, + { + species: SpeciesId.ARCEUS, + }, + { + species: SpeciesId.HYDREIGON, + }, + { + species: SpeciesId.VOLCARONA, + }, + { + species: SpeciesId.TORNADUS, + formIndex: 0, + }, + { + species: SpeciesId.TORNADUS, + formIndex: 1, + }, + { + species: SpeciesId.THUNDURUS, + formIndex: 0, + }, + { + species: SpeciesId.THUNDURUS, + formIndex: 1, + }, + { + species: SpeciesId.RESHIRAM, + }, + { + species: SpeciesId.ZEKROM, + }, + { + species: SpeciesId.KYUREM, + formIndex: 1, + }, + { + species: SpeciesId.KYUREM, + formIndex: 2, + }, + { + species: SpeciesId.LANDORUS, + formIndex: 0, + }, + { + species: SpeciesId.LANDORUS, + formIndex: 1, + }, + { + species: SpeciesId.NOIVERN, + }, + { + species: SpeciesId.YVELTAL, + }, + { + species: SpeciesId.HOOPA, + formIndex: 0, + }, + { + species: SpeciesId.HOOPA, + formIndex: 1, + }, + { + species: SpeciesId.TAPU_KOKO, + }, + { + species: SpeciesId.TAPU_LELE, + }, + { + species: SpeciesId.TAPU_BULU, + }, + { + species: SpeciesId.TAPU_FINI, + }, + { + species: SpeciesId.SOLGALEO, + }, + { + species: SpeciesId.LUNALA, + }, + { + species: SpeciesId.NIHILEGO, + }, + { + species: SpeciesId.BUZZWOLE, + }, + { + species: SpeciesId.CELESTEELA, + }, + { + species: SpeciesId.KARTANA, + }, + { + species: SpeciesId.NECROZMA, + formIndex: 0, + }, + { + species: SpeciesId.NECROZMA, + formIndex: 1, + }, + { + species: SpeciesId.NECROZMA, + formIndex: 2, + }, + { + species: SpeciesId.NECROZMA, + formIndex: 3, + }, + { + species: SpeciesId.NAGANADEL, + }, + { + species: SpeciesId.CORVIKNIGHT, + formIndex: 1, + }, + { + species: SpeciesId.ORBEETLE, + formIndex: 1, + }, + { + species: SpeciesId.DRAGAPULT, + }, + { + species: SpeciesId.ETERNATUS, + formIndex: 0, + }, + { + species: SpeciesId.ETERNATUS, + formIndex: 1, + }, + { + species: SpeciesId.REGIELEKI, + }, + { + species: SpeciesId.REGIDRAGO, + }, + { + species: SpeciesId.CALYREX, + formIndex: 0, + }, + { + species: SpeciesId.ENAMORUS, + formIndex: 0, + }, + { + species: SpeciesId.ENAMORUS, + formIndex: 1, + }, + { + species: SpeciesId.KILOWATTREL, + }, + { + species: SpeciesId.GLIMMORA, + }, + { + species: SpeciesId.SCREAM_TAIL, + }, + { + species: SpeciesId.FLUTTER_MANE, + }, + { + species: SpeciesId.IRON_JUGULIS, + }, + { + species: SpeciesId.IRON_MOTH, + }, + { + species: SpeciesId.CHI_YU, + }, + { + species: SpeciesId.ROARING_MOON, + }, + { + species: SpeciesId.MIRAIDON, + }, + { + species: SpeciesId.FEZANDIPITI, + }, + { + species: SpeciesId.PECHARUNT, + }, + { + species: SpeciesId.ALOLA_RAICHU, + }, + { + species: SpeciesId.GALAR_WEEZING, + }, + { + species: SpeciesId.GALAR_ARTICUNO, + }, + { + species: SpeciesId.GALAR_MOLTRES, + }, + { + species: SpeciesId.HISUI_BRAVIARY, + }, +]; + const PHYSICAL_TUTOR_MOVES = [ MoveId.FLY, MoveId.BRAVE_BIRD, @@ -305,11 +1182,11 @@ const SPECIAL_TUTOR_MOVES = [MoveId.AEROBLAST, MoveId.AIR_SLASH, MoveId.HURRICAN const SUPPORT_TUTOR_MOVES = [MoveId.FEATHER_DANCE, MoveId.ROOST, MoveId.PLUCK, MoveId.TAILWIND]; -// Not sure the best way to do this const INELIGIBLE_MOVES: MoveId[] = [ MoveId.BODY_SLAM, MoveId.BULLDOZE, MoveId.DIG, + MoveId.SAND_ATTACK, // extra move left here to test code with pidgey (with no need for overrides) MoveId.DIVE, MoveId.EARTH_POWER, MoveId.EARTHQUAKE, @@ -386,9 +1263,10 @@ const sky_battle_requirements = new AnyCombinationPokemonRequirement( ), ); +const WAVE_LEVEL_BREAKPOINTS = [80, 150]; + // Helpful variables -let originalUsedPP: number[] = []; -const disallowedPokemon: Map = new Map(); +let female = false; /** * Sky Battle encounter. @@ -417,8 +1295,8 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with const partySize: number = sky_battle_requirements.queryParty(globalScene.getPlayerParty()).length; // randomize trainer gender - const female = !!randSeedInt(2); - const config = getTrainerConfig(partySize, female); + female = !!randSeedInt(2); + const config = getTrainerConfig(partySize, globalScene.currentBattle.waveIndex); const spriteKey = config.getSpriteKey(female); encounter.enemyPartyConfigs.push({ trainerConfig: config, @@ -445,7 +1323,7 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with text: female ? `${namespace}:intro_dialogue_f` : `${namespace}:intro_dialogue`, }, ]; - const title = female ? `${namespace}:title_f` : `${namespace}:title`; + const title = `${namespace}:title`; const description = female ? `${namespace}:description_f` : `${namespace}:description`; const outro = [ { @@ -486,61 +1364,42 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with selected: [ { speaker: `${namespace}:speaker`, - text: `${namespace}:option.1.selected`, + text: female ? `${namespace}:option.1.selected_f` : `${namespace}:option.1.selected`, }, ], }, async () => { + // TODO: Update selected text based on female + // Select sky battle const encounter = globalScene.currentBattle.mysteryEncounter!; const config: EnemyPartyConfig = encounter.enemyPartyConfigs[0]; // Init the moves available for tutor const moveTutorOptions: PokemonMove[] = []; - moveTutorOptions.push(new PokemonMove(PHYSICAL_TUTOR_MOVES[randSeedInt(PHYSICAL_TUTOR_MOVES.length)])); - moveTutorOptions.push(new PokemonMove(SPECIAL_TUTOR_MOVES[randSeedInt(SPECIAL_TUTOR_MOVES.length)])); - moveTutorOptions.push(new PokemonMove(SUPPORT_TUTOR_MOVES[randSeedInt(SUPPORT_TUTOR_MOVES.length)])); + moveTutorOptions.push( + new PokemonMove(PHYSICAL_TUTOR_MOVES[randSeedInt(PHYSICAL_TUTOR_MOVES.length)]), + new PokemonMove(SPECIAL_TUTOR_MOVES[randSeedInt(SPECIAL_TUTOR_MOVES.length)]), + new PokemonMove(SUPPORT_TUTOR_MOVES[randSeedInt(SUPPORT_TUTOR_MOVES.length)]), + ); + encounter.misc = { moveTutorOptions, }; - //Remove disallowed pokemon - const allowedPokemon = sky_battle_requirements.queryParty(globalScene.getPlayerParty()); - globalScene.getPlayerParty().filter(pokemon => !allowedPokemon.includes(pokemon)); - globalScene.getPlayerParty().map((pokemon, index) => { - if (!allowedPokemon.includes(pokemon)) { - disallowedPokemon.set(index, pokemon); - } - }); - - disallowedPokemon.forEach(pokemon => globalScene.removePokemonFromPlayerParty(pokemon, false)); - - //Set illegal pokemon moves pp to 0 - originalUsedPP = []; - globalScene.getPlayerParty().forEach(pokemon => - pokemon.moveset - .filter(move => INELIGIBLE_MOVES.includes(move.getMove().id)) - .forEach(move => { - originalUsedPP.push(move.ppUsed); - move.ppUsed = move.getMovePp(); - }), - ); + //Ordering here is relevant + disableDisallowedPokemon(); + disableIllegalMoves(); // Assigns callback that teaches move before continuing to rewards encounter.onRewards = doFlyingTypeTutor; setEncounterRewards({ fillRemaining: true }); + encounter.spriteConfigs[0].hasShadow = false; //TODO: Is this [0] correct enough? await transitionMysteryEncounterIntroVisuals(true, true); await initBattleWithEnemyConfig(config); - //Set illegal enemy pokemon moves pp to 0 - globalScene.getEnemyParty().forEach(pokemon => - pokemon.moveset - .filter(move => INELIGIBLE_MOVES.includes(move.getMove().id)) - .forEach(move => { - move.ppUsed = move.getMovePp(); - }), - ); + disableEnemyIllegalMoves(); }, ) .withOption( @@ -563,7 +1422,7 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with encounter.selectedOption!.dialogue!.selected = [ { speaker: `${namespace}:speaker`, - text: `${namespace}:option.2.selected`, + text: female ? `${namespace}:option.2.selected_f` : `${namespace}:option.2.selected`, }, ]; }) @@ -580,7 +1439,7 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with buttonTooltip: `${namespace}:option.3.tooltip`, selected: [ { - text: `${namespace}:option.3.selected`, + text: female ? `${namespace}:option.3.selected_f` : `${namespace}:option.3.selected`, }, ], }, @@ -596,22 +1455,39 @@ export const SkyBattleEncounter: MysteryEncounter = MysteryEncounterBuilder.with ]) .build(); -function getTrainerConfig(party_size: number, female: boolean): TrainerConfig { +function getTrainerConfig(party_size: number, wave_index: number): TrainerConfig { // Sky trainer config const config = trainerConfigs[TrainerType.SKY_TRAINER].clone(); - const name = female ? "sky_trainer_f" : "sky_trainer_m"; - config.name = i18next.t("trainerNames:" + name); + config.name = i18next.t("trainerNames:sky_trainer"); - let pool0Copy = POOL_ALL_FORMS.slice(0); - pool0Copy = randSeedShuffle(pool0Copy); - let pool0Mon = pool0Copy.pop()!; + // choose pool according to wave + let trainer_pool: any; + if (wave_index < WAVE_LEVEL_BREAKPOINTS[0]) { + trainer_pool = WEAK_TIER.slice(0); + } else if (wave_index < WAVE_LEVEL_BREAKPOINTS[1]) { + trainer_pool = MID_TIER.slice(0); + } else { + trainer_pool = STRONG_TIER.slice(0); + } + + trainer_pool = randSeedShuffle(trainer_pool); config.setPartyTemplates(new TrainerPartyTemplate(party_size, PartyMemberStrength.STRONG)); // adds a non-repeating random pokemon for (let index = 0; index < party_size; index++) { - config.setPartyMemberFunc(index, getRandomPartyMemberFunc([pool0Mon], TrainerSlot.TRAINER, true)); - pool0Mon = pool0Copy.pop()!; + const rand_pokemon = trainer_pool.pop()!; + const rand_species = isNullOrUndefined(rand_pokemon.species) ? rand_pokemon : rand_pokemon.species; + config.setPartyMemberFunc( + index, + getRandomPartyMemberFunc([rand_species], TrainerSlot.TRAINER, true, p => { + if (!isNullOrUndefined(rand_pokemon.formIndex)) { + p.formIndex = rand_pokemon.formIndex; + p.generateAndPopulateMoveset(); + p.generateName(); + } + }), + ); } return config; @@ -621,7 +1497,11 @@ function doFlyingTypeTutor(): Promise { // biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO explain return new Promise(async resolve => { const moveOptions = globalScene.currentBattle.mysteryEncounter!.misc.moveTutorOptions; - const female = globalScene.currentBattle.mysteryEncounter!.enemyPartyConfigs[0].female; //TODO: Is this [0] correct enought? + + //Ordering here is relevant + reEnableIllegalMoves(); + reEnableDisallowedPokemon(); + await showEncounterDialogue( female ? `${namespace}:battle_won_f` : `${namespace}:battle_won`, `${namespace}:speaker`, @@ -677,22 +1557,52 @@ function doFlyingTypeTutor(): Promise { ); } - // Reset ineligible moves' pp - let idx = 0; - globalScene.getPlayerParty().forEach(pokemon => - pokemon.moveset - .filter(move => INELIGIBLE_MOVES.includes(move.getMove().id)) - .forEach(move => { - move.ppUsed = originalUsedPP[idx++]; - }), - ); - - //Return disallowed pokemons - disallowedPokemon.forEach((pokemon, index) => { - globalScene.getPlayerParty().splice(index, 0, pokemon); - }); - // Complete battle and go to rewards resolve(); }); } + +const disallowedPokemon: Map = new Map(); +function disableDisallowedPokemon(): void { + disallowedPokemon.clear(); + const allowedPokemon = sky_battle_requirements.queryParty(globalScene.getPlayerParty()); + globalScene.getPlayerParty().filter(pokemon => !allowedPokemon.includes(pokemon)); + globalScene.getPlayerParty().forEach((pokemon, index) => { + if (!allowedPokemon.includes(pokemon)) { + disallowedPokemon.set(index, pokemon); + } + }); + + disallowedPokemon.forEach(pokemon => globalScene.removePokemonFromPlayerParty(pokemon, false)); +} + +function reEnableDisallowedPokemon(): void { + disallowedPokemon.forEach((pokemon, index) => { + globalScene.getPlayerParty().splice(index, 0, pokemon); + }); +} + +let originalMovesets: PokemonMove[][] = []; +function disableIllegalMoves(): void { + originalMovesets = []; + globalScene.getPlayerParty().forEach(pokemon => { + originalMovesets.push(pokemon.moveset.slice(0)); + pokemon.moveset = pokemon.moveset.filter(move => !INELIGIBLE_MOVES.includes(move.getMove().id)); + }); +} + +function reEnableIllegalMoves(): void { + originalMovesets.forEach((moveset, idx) => { + globalScene.getPlayerParty()[idx].moveset = moveset; + }); +} + +function disableEnemyIllegalMoves(): void { + globalScene.getEnemyParty().forEach(pokemon => + pokemon.moveset + .filter(move => INELIGIBLE_MOVES.includes(move.getMove().id)) + .forEach(move => { + move.ppUsed = move.getMovePp(); + }), + ); +}