mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2024-12-01 03:06:19 +00:00
Clean up all the bangs caused by movesets allowing null
This commit is contained in:
parent
8fabcba235
commit
648506e036
@ -1167,6 +1167,7 @@ export default class BattleScene extends SceneBase {
|
|||||||
return Math.max(doubleChance.value, 1);
|
return Math.max(doubleChance.value, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: ...this never returns `null`, right?
|
||||||
newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounterType?: MysteryEncounterType): Battle | null {
|
newBattle(waveIndex?: integer, battleType?: BattleType, trainerData?: TrainerData, double?: boolean, mysteryEncounterType?: MysteryEncounterType): Battle | null {
|
||||||
const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave;
|
const _startingWave = Overrides.STARTING_WAVE_OVERRIDE || startingWave;
|
||||||
const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1);
|
const newWaveIndex = waveIndex || ((this.currentBattle?.waveIndex || (_startingWave - 1)) + 1);
|
||||||
|
@ -1300,17 +1300,17 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.EXEGGUTOR, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.TANGELA]: [
|
[Species.TANGELA]: [
|
||||||
new SpeciesEvolution(Species.TANGROWTH, 34, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.TANGROWTH, 34, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.LICKITUNG]: [
|
[Species.LICKITUNG]: [
|
||||||
new SpeciesEvolution(Species.LICKILICKY, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ROLLOUT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LICKILICKY, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.ROLLOUT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.STARYU]: [
|
[Species.STARYU]: [
|
||||||
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.STARMIE, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.EEVEE]: [
|
[Species.EEVEE]: [
|
||||||
new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.SYLVEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m?.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.SYLVEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => !!p.getMoveset().find(m => m.getMove().type === Type.FAIRY)), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ESPEON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.ESPEON, "partner", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAY), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.UMBREON, "", "", 1, null, new SpeciesFriendshipEvolutionCondition(120, p => p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT), SpeciesWildEvolutionDelay.LONG),
|
||||||
@ -1330,13 +1330,13 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.TOGEKISS, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.AIPOM]: [
|
[Species.AIPOM]: [
|
||||||
new SpeciesEvolution(Species.AMBIPOM, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DOUBLE_HIT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.AMBIPOM, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DOUBLE_HIT).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.SUNKERN]: [
|
[Species.SUNKERN]: [
|
||||||
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SUNFLORA, 1, EvolutionItem.SUN_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.YANMA]: [
|
[Species.YANMA]: [
|
||||||
new SpeciesEvolution(Species.YANMEGA, 33, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.YANMEGA, 33, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.MURKROW]: [
|
[Species.MURKROW]: [
|
||||||
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.HONCHKROW, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1345,17 +1345,17 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.MISMAGIUS, 1, EvolutionItem.DUSK_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.GIRAFARIG]: [
|
[Species.GIRAFARIG]: [
|
||||||
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.FARIGIRAF, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TWIN_BEAM).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.DUNSPARCE]: [
|
[Species.DUNSPARCE]: [
|
||||||
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
|
new SpeciesFormEvolution(Species.DUDUNSPARCE, "", "three-segment", 32, null, new SpeciesEvolutionCondition(p => {
|
||||||
let ret = false;
|
let ret = false;
|
||||||
if (p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0) {
|
if (p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0) {
|
||||||
p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
p.scene.executeWithSeedOffset(() => ret = !Utils.randSeedInt(4), p.id);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}), SpeciesWildEvolutionDelay.LONG),
|
}), SpeciesWildEvolutionDelay.LONG),
|
||||||
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.DUDUNSPARCE, 32, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.HYPER_DRILL).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.GLIGAR]: [
|
[Species.GLIGAR]: [
|
||||||
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.GLISCOR, 1, EvolutionItem.RAZOR_FANG, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT /* Razor fang at night*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1367,10 +1367,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
|
new SpeciesEvolution(Species.URSALUNA, 1, EvolutionItem.PEAT_BLOCK, null, SpeciesWildEvolutionDelay.VERY_LONG) //Ursaring does not evolve into Bloodmoon Ursaluna
|
||||||
],
|
],
|
||||||
[Species.PILOSWINE]: [
|
[Species.PILOSWINE]: [
|
||||||
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.MAMOSWINE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.ANCIENT_POWER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.STANTLER]: [
|
[Species.STANTLER]: [
|
||||||
new SpeciesEvolution(Species.WYRDEER, 25, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.PSYSHIELD_BASH).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.WYRDEER, 25, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.PSYSHIELD_BASH).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.LOMBRE]: [
|
[Species.LOMBRE]: [
|
||||||
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.LUDICOLO, 1, EvolutionItem.WATER_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1388,11 +1388,11 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ROSERADE, 1, EvolutionItem.SHINY_STONE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.BONSLY]: [
|
[Species.BONSLY]: [
|
||||||
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.SUDOWOODO, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.MIME_JR]: [
|
[Species.MIME_JR]: [
|
||||||
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM),
|
new SpeciesEvolution(Species.GALAR_MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT)), SpeciesWildEvolutionDelay.MEDIUM),
|
||||||
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM)
|
new SpeciesEvolution(Species.MR_MIME, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.MIMIC).length > 0 && (p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY)), SpeciesWildEvolutionDelay.MEDIUM)
|
||||||
],
|
],
|
||||||
[Species.PANSAGE]: [
|
[Species.PANSAGE]: [
|
||||||
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.SIMISAGE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1447,10 +1447,10 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)))
|
new SpeciesFormEvolution(Species.LYCANROC, "", "midnight", 25, null, new SpeciesEvolutionCondition(p => (p.scene.arena.getTimeOfDay() === TimeOfDay.DUSK || p.scene.arena.getTimeOfDay() === TimeOfDay.NIGHT) && (p.formIndex === 0)))
|
||||||
],
|
],
|
||||||
[Species.STEENEE]: [
|
[Species.STEENEE]: [
|
||||||
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.TSAREENA, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.STOMP).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.POIPOLE]: [
|
[Species.POIPOLE]: [
|
||||||
new SpeciesEvolution(Species.NAGANADEL, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_PULSE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.NAGANADEL, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_PULSE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.ALOLA_SANDSHREW]: [
|
[Species.ALOLA_SANDSHREW]: [
|
||||||
new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.ALOLA_SANDSLASH, 1, EvolutionItem.ICE_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
@ -1464,7 +1464,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.APPLETUN, 1, EvolutionItem.SWEET_APPLE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.CLOBBOPUS]: [
|
[Species.CLOBBOPUS]: [
|
||||||
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.TAUNT).length > 0)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/)
|
new SpeciesEvolution(Species.GRAPPLOCT, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.TAUNT).length > 0)/*Once Taunt is implemented, change evo level to 1 and delay to LONG*/)
|
||||||
],
|
],
|
||||||
[Species.SINISTEA]: [
|
[Species.SINISTEA]: [
|
||||||
new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
|
new SpeciesFormEvolution(Species.POLTEAGEIST, "phony", "phony", 1, EvolutionItem.CRACKED_POT, null, SpeciesWildEvolutionDelay.LONG),
|
||||||
@ -1498,7 +1498,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.HISUI_ELECTRODE, 1, EvolutionItem.LEAF_STONE, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.HISUI_QWILFISH]: [
|
[Species.HISUI_QWILFISH]: [
|
||||||
new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
new SpeciesEvolution(Species.OVERQWIL, 28, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.BARB_BARRAGE).length > 0), SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.HISUI_SNEASEL]: [
|
[Species.HISUI_SNEASEL]: [
|
||||||
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.SNEASLER, 1, EvolutionItem.RAZOR_CLAW, new SpeciesEvolutionCondition(p => p.scene.arena.getTimeOfDay() === TimeOfDay.DAWN || p.scene.arena.getTimeOfDay() === TimeOfDay.DAY /* Razor claw at day*/), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1521,7 +1521,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
|
new SpeciesFormEvolution(Species.SINISTCHA, "artisan", "masterpiece", 1, EvolutionItem.MASTERPIECE_TEACUP, null, SpeciesWildEvolutionDelay.LONG)
|
||||||
],
|
],
|
||||||
[Species.DIPPLIN]: [
|
[Species.DIPPLIN]: [
|
||||||
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.HYDRAPPLE, 1, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.DRAGON_CHEER).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.KADABRA]: [
|
[Species.KADABRA]: [
|
||||||
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ALAKAZAM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
@ -1537,7 +1537,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
],
|
],
|
||||||
[Species.ONIX]: [
|
[Species.ONIX]: [
|
||||||
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
new SpeciesEvolution(Species.STEELIX, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
||||||
p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0),
|
p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0),
|
||||||
SpeciesWildEvolutionDelay.VERY_LONG)
|
SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.RHYDON]: [
|
[Species.RHYDON]: [
|
||||||
@ -1548,7 +1548,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
],
|
],
|
||||||
[Species.SCYTHER]: [
|
[Species.SCYTHER]: [
|
||||||
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
new SpeciesEvolution(Species.SCIZOR, 1, EvolutionItem.LINKING_CORD, new SpeciesEvolutionCondition(
|
||||||
p => p.moveset.filter(m => m?.getMove().type === Type.STEEL).length > 0),
|
p => p.moveset.filter(m => m.getMove().type === Type.STEEL).length > 0),
|
||||||
SpeciesWildEvolutionDelay.VERY_LONG),
|
SpeciesWildEvolutionDelay.VERY_LONG),
|
||||||
new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.KLEAVOR, 1, EvolutionItem.BLACK_AUGURITE, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
@ -1602,7 +1602,7 @@ export const pokemonEvolutions: PokemonEvolutions = {
|
|||||||
new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ALOLA_GOLEM, 1, EvolutionItem.LINKING_CORD, null, SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.PRIMEAPE]: [
|
[Species.PRIMEAPE]: [
|
||||||
new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m?.moveId === Moves.RAGE_FIST).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.ANNIHILAPE, 35, null, new SpeciesEvolutionCondition(p => p.moveset.filter(m => m.moveId === Moves.RAGE_FIST).length > 0), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
],
|
],
|
||||||
[Species.GOLBAT]: [
|
[Species.GOLBAT]: [
|
||||||
new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG)
|
new SpeciesEvolution(Species.CROBAT, 1, null, new SpeciesFriendshipEvolutionCondition(120), SpeciesWildEvolutionDelay.VERY_LONG)
|
||||||
|
@ -965,11 +965,11 @@ export class EncoreTag extends MoveRestrictionBattlerTag {
|
|||||||
|
|
||||||
const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
|
const movePhase = pokemon.scene.findPhase(m => m instanceof MovePhase && m.pokemon === pokemon);
|
||||||
if (movePhase) {
|
if (movePhase) {
|
||||||
const movesetMove = pokemon.getMoveset().find(m => m!.moveId === this.moveId); // TODO: is this bang correct?
|
const movesetMove = pokemon.getMoveset().find(m => m.moveId === this.moveId);
|
||||||
if (movesetMove) {
|
if (movesetMove) {
|
||||||
const lastMove = pokemon.getLastXMoves(1)[0];
|
const lastMove = pokemon.getLastXMoves(1)[0];
|
||||||
pokemon.scene.tryReplacePhase((m => m instanceof MovePhase && m.pokemon === pokemon),
|
pokemon.scene.tryReplacePhase((m => m instanceof MovePhase && m.pokemon === pokemon),
|
||||||
new MovePhase(pokemon.scene, pokemon, lastMove.targets!, movesetMove)); // TODO: is this bang correct?
|
new MovePhase(pokemon.scene, pokemon, lastMove.targets ?? [], movesetMove));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -980,7 +980,7 @@ export class EncoreTag extends MoveRestrictionBattlerTag {
|
|||||||
*/
|
*/
|
||||||
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
if (lapseType === BattlerTagLapseType.CUSTOM) {
|
||||||
const encoredMove = pokemon.getMoveset().find(m => m?.moveId === this.moveId);
|
const encoredMove = pokemon.getMoveset().find(m => m.moveId === this.moveId);
|
||||||
if (encoredMove && encoredMove?.getPpRatio() > 0) {
|
if (encoredMove && encoredMove?.getPpRatio() > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2767,7 +2767,7 @@ export class ImprisonTag extends MoveRestrictionBattlerTag {
|
|||||||
public override isMoveRestricted(move: Moves, user: Pokemon): boolean {
|
public override isMoveRestricted(move: Moves, user: Pokemon): boolean {
|
||||||
const source = this.getSourcePokemon(user.scene);
|
const source = this.getSourcePokemon(user.scene);
|
||||||
if (source) {
|
if (source) {
|
||||||
const sourceMoveset = source.getMoveset().map(m => m!.moveId);
|
const sourceMoveset = source.getMoveset().map(m => m.moveId);
|
||||||
return sourceMoveset?.includes(move) && source.isActive(true);
|
return sourceMoveset?.includes(move) && source.isActive(true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2901,7 +2901,7 @@ export class GrudgeTag extends BattlerTag {
|
|||||||
if (lapseType === BattlerTagLapseType.CUSTOM && sourcePokemon) {
|
if (lapseType === BattlerTagLapseType.CUSTOM && sourcePokemon) {
|
||||||
if (sourcePokemon.isActive() && pokemon.isOpponent(sourcePokemon)) {
|
if (sourcePokemon.isActive() && pokemon.isOpponent(sourcePokemon)) {
|
||||||
const lastMove = pokemon.turnData.attacksReceived[0];
|
const lastMove = pokemon.turnData.attacksReceived[0];
|
||||||
const lastMoveData = sourcePokemon.getMoveset().find(m => m?.moveId === lastMove.move);
|
const lastMoveData = sourcePokemon.getMoveset().find(m => m.moveId === lastMove.move);
|
||||||
if (lastMoveData && lastMove.move !== Moves.STRUGGLE) {
|
if (lastMoveData && lastMove.move !== Moves.STRUGGLE) {
|
||||||
lastMoveData.ppUsed = lastMoveData.getMovePp();
|
lastMoveData.ppUsed = lastMoveData.getMovePp();
|
||||||
pokemon.scene.queueMessage(i18next.t("battlerTags:grudgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: lastMoveData.getName() }));
|
pokemon.scene.queueMessage(i18next.t("battlerTags:grudgeLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: lastMoveData.getName() }));
|
||||||
|
@ -56,7 +56,7 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
|
|||||||
return (pokemon: Pokemon) => {
|
return (pokemon: Pokemon) => {
|
||||||
const threshold = new Utils.NumberHolder(0.25);
|
const threshold = new Utils.NumberHolder(0.25);
|
||||||
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
|
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
|
||||||
return !!pokemon.getMoveset().find(m => !m?.getPpRatio());
|
return !!pokemon.getMoveset().find(m => !m.getPpRatio());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
|
|||||||
if (pokemon.battleData) {
|
if (pokemon.battleData) {
|
||||||
pokemon.battleData.berriesEaten.push(berryType);
|
pokemon.battleData.berriesEaten.push(berryType);
|
||||||
}
|
}
|
||||||
const ppRestoreMove = pokemon.getMoveset().find(m => !m?.getPpRatio()) ? pokemon.getMoveset().find(m => !m?.getPpRatio()) : pokemon.getMoveset().find(m => m!.getPpRatio() < 1); // TODO: is this bang correct?
|
const ppRestoreMove = pokemon.getMoveset().find(m => !m.getPpRatio()) ? pokemon.getMoveset().find(m => !m.getPpRatio()) : pokemon.getMoveset().find(m => m.getPpRatio() < 1);
|
||||||
if (ppRestoreMove !== undefined) {
|
if (ppRestoreMove !== undefined) {
|
||||||
ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0);
|
ppRestoreMove!.ppUsed = Math.max(ppRestoreMove!.ppUsed - 10, 0);
|
||||||
pokemon.scene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) }));
|
pokemon.scene.queueMessage(i18next.t("battle:ppHealBerry", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: ppRestoreMove!.getName(), berryName: getBerryName(berryType) }));
|
||||||
|
@ -437,7 +437,7 @@ export class SingleGenerationChallenge extends Challenge {
|
|||||||
|
|
||||||
applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean {
|
applyPokemonInBattle(pokemon: Pokemon, valid: Utils.BooleanHolder): boolean {
|
||||||
const baseGeneration = pokemon.species.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.species.speciesId).generation;
|
const baseGeneration = pokemon.species.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.species.speciesId).generation;
|
||||||
const fusionGeneration = pokemon.isFusion() ? pokemon.fusionSpecies?.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.fusionSpecies!.speciesId).generation : 0; // TODO: is the bang on fusionSpecies correct?
|
const fusionGeneration = pokemon.isFusion() ? pokemon.fusionSpecies?.speciesId === Species.VICTINI ? 5 : getPokemonSpecies(pokemon.fusionSpecies?.speciesId).generation : 0;
|
||||||
if (pokemon.isPlayer() && (baseGeneration !== this.value || (pokemon.isFusion() && fusionGeneration !== this.value))) {
|
if (pokemon.isPlayer() && (baseGeneration !== this.value || (pokemon.isFusion() && fusionGeneration !== this.value))) {
|
||||||
valid.value = false;
|
valid.value = false;
|
||||||
return true;
|
return true;
|
||||||
|
123
src/data/move.ts
123
src/data/move.ts
@ -1772,14 +1772,14 @@ export class HealAttr extends MoveEffectAttr {
|
|||||||
*/
|
*/
|
||||||
export class PartyStatusCureAttr extends MoveEffectAttr {
|
export class PartyStatusCureAttr extends MoveEffectAttr {
|
||||||
/** Message to display after using move */
|
/** Message to display after using move */
|
||||||
private message: string;
|
private message: string | null;
|
||||||
/** Skips mons with this ability, ie. Soundproof */
|
/** Skips mons with this ability, ie. Soundproof */
|
||||||
private abilityCondition: Abilities;
|
private abilityCondition: Abilities;
|
||||||
|
|
||||||
constructor(message: string | null, abilityCondition: Abilities) {
|
constructor(message: string | null, abilityCondition: Abilities) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.message = message!; // TODO: is this bang correct?
|
this.message = message;
|
||||||
this.abilityCondition = abilityCondition;
|
this.abilityCondition = abilityCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1977,10 +1977,10 @@ export class BoostHealAttr extends HealAttr {
|
|||||||
/** The lambda expression to check against when boosting the healing value */
|
/** The lambda expression to check against when boosting the healing value */
|
||||||
private condition?: MoveConditionFunc;
|
private condition?: MoveConditionFunc;
|
||||||
|
|
||||||
constructor(normalHealRatio?: number, boostedHealRatio?: number, showAnim?: boolean, selfTarget?: boolean, condition?: MoveConditionFunc) {
|
constructor(normalHealRatio: number = 0.5, boostedHealRatio: number = 2 / 3, showAnim?: boolean, selfTarget?: boolean, condition?: MoveConditionFunc) {
|
||||||
super(normalHealRatio, showAnim, selfTarget);
|
super(normalHealRatio, showAnim, selfTarget);
|
||||||
this.normalHealRatio = normalHealRatio!; // TODO: is this bang correct?
|
this.normalHealRatio = normalHealRatio;
|
||||||
this.boostedHealRatio = boostedHealRatio!; // TODO: is this bang correct?
|
this.boostedHealRatio = boostedHealRatio;
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3214,14 +3214,14 @@ export class SecretPowerAttr extends MoveEffectAttr {
|
|||||||
export class PostVictoryStatStageChangeAttr extends MoveAttr {
|
export class PostVictoryStatStageChangeAttr extends MoveAttr {
|
||||||
private stats: BattleStat[];
|
private stats: BattleStat[];
|
||||||
private stages: number;
|
private stages: number;
|
||||||
private condition: MoveConditionFunc | null;
|
private condition?: MoveConditionFunc;
|
||||||
private showMessage: boolean;
|
private showMessage: boolean;
|
||||||
|
|
||||||
constructor(stats: BattleStat[], stages: number, selfTarget?: boolean, condition?: MoveConditionFunc, showMessage: boolean = true, firstHitOnly: boolean = false) {
|
constructor(stats: BattleStat[], stages: number, selfTarget?: boolean, condition?: MoveConditionFunc, showMessage: boolean = true, firstHitOnly: boolean = false) {
|
||||||
super();
|
super();
|
||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
this.stages = stages;
|
this.stages = stages;
|
||||||
this.condition = condition!; // TODO: is this bang correct?
|
this.condition = condition;
|
||||||
this.showMessage = showMessage;
|
this.showMessage = showMessage;
|
||||||
}
|
}
|
||||||
applyPostVictory(user: Pokemon, target: Pokemon, move: Move): void {
|
applyPostVictory(user: Pokemon, target: Pokemon, move: Move): void {
|
||||||
@ -3513,7 +3513,7 @@ export class LessPPMorePowerAttr extends VariablePowerAttr {
|
|||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const ppMax = move.pp;
|
const ppMax = move.pp;
|
||||||
const ppUsed = user.moveset.find((m) => m?.moveId === move.id)?.ppUsed!; // TODO: is the bang correct?
|
const ppUsed = user.moveset.find((m) => m.moveId === move.id)?.ppUsed ?? 0;
|
||||||
|
|
||||||
let ppRemains = ppMax - ppUsed;
|
let ppRemains = ppMax - ppUsed;
|
||||||
/** Reduce to 0 to avoid negative numbers if user has 1PP before attack and target has Ability.PRESSURE */
|
/** Reduce to 0 to avoid negative numbers if user has 1PP before attack and target has Ability.PRESSURE */
|
||||||
@ -3639,7 +3639,13 @@ export abstract class ConsecutiveUsePowerMultiplierAttr extends MovePowerMultipl
|
|||||||
let count = 0;
|
let count = 0;
|
||||||
let turnMove: TurnMove | undefined;
|
let turnMove: TurnMove | undefined;
|
||||||
|
|
||||||
while (((turnMove = moveHistory.shift())?.move === move.id || (comboMoves.length && comboMoves.includes(turnMove?.move!))) && (!resetOnFail || turnMove?.result === MoveResult.SUCCESS)) { // TODO: is this bang correct?
|
while (
|
||||||
|
(
|
||||||
|
(turnMove = moveHistory.shift())?.move === move.id
|
||||||
|
|| (comboMoves.length && comboMoves.includes(turnMove?.move ?? Moves.NONE))
|
||||||
|
)
|
||||||
|
&& (!resetOnFail || turnMove?.result === MoveResult.SUCCESS)
|
||||||
|
) {
|
||||||
if (count < (limit - 1)) {
|
if (count < (limit - 1)) {
|
||||||
count++;
|
count++;
|
||||||
} else if (resetOnLimit) {
|
} else if (resetOnLimit) {
|
||||||
@ -5237,7 +5243,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTagTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer | void {
|
getTagTargetBenefitScore(): number {
|
||||||
switch (this.tagType) {
|
switch (this.tagType) {
|
||||||
case BattlerTagType.RECHARGING:
|
case BattlerTagType.RECHARGING:
|
||||||
case BattlerTagType.PERISH_SONG:
|
case BattlerTagType.PERISH_SONG:
|
||||||
@ -5281,6 +5287,9 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||||||
case BattlerTagType.CRIT_BOOST:
|
case BattlerTagType.CRIT_BOOST:
|
||||||
case BattlerTagType.ALWAYS_CRIT:
|
case BattlerTagType.ALWAYS_CRIT:
|
||||||
return 5;
|
return 5;
|
||||||
|
default:
|
||||||
|
console.warn(`BattlerTag ${BattlerTagType[this.tagType]} is missing a score!`);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5289,7 +5298,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
|||||||
if (moveChance < 0) {
|
if (moveChance < 0) {
|
||||||
moveChance = 100;
|
moveChance = 100;
|
||||||
}
|
}
|
||||||
return Math.floor(this.getTagTargetBenefitScore(user, target, move)! * (moveChance / 100)); // TODO: is the bang correct?
|
return Math.floor(this.getTagTargetBenefitScore() * (moveChance / 100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5519,7 +5528,7 @@ export class ProtectAttr extends AddBattlerTagAttr {
|
|||||||
|
|
||||||
while (moveHistory.length) {
|
while (moveHistory.length) {
|
||||||
turnMove = moveHistory.shift();
|
turnMove = moveHistory.shift();
|
||||||
if (!allMoves[turnMove?.move!].hasAttr(ProtectAttr) || turnMove?.result !== MoveResult.SUCCESS) { // TODO: is the bang correct?
|
if (!allMoves[turnMove?.move ?? Moves.NONE].hasAttr(ProtectAttr) || turnMove?.result !== MoveResult.SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
timesUsed++;
|
timesUsed++;
|
||||||
@ -6370,7 +6379,7 @@ export class FirstMoveTypeAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstMoveType = target.getMoveset()[0]?.getMove().type!; // TODO: is this bang correct?
|
const firstMoveType = target.getMoveset()[0].getMove().type;
|
||||||
user.summonData.types = [ firstMoveType ];
|
user.summonData.types = [ firstMoveType ];
|
||||||
user.scene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${Type[firstMoveType]}`) }));
|
user.scene.queueMessage(i18next.t("battle:transformedIntoType", { pokemonName: getPokemonNameWithAffix(user), type: i18next.t(`pokemonInfo:Type.${Type[firstMoveType]}`) }));
|
||||||
|
|
||||||
@ -6389,11 +6398,11 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
|
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const moveset = (!this.enemyMoveset ? user : target).getMoveset();
|
const moveset = (!this.enemyMoveset ? user : target).getMoveset();
|
||||||
const moves = moveset.filter(m => !m?.getMove().hasFlag(MoveFlags.IGNORE_VIRTUAL));
|
const moves = moveset.filter(m => !m.getMove().hasFlag(MoveFlags.IGNORE_VIRTUAL));
|
||||||
if (moves.length) {
|
if (moves.length) {
|
||||||
const move = moves[user.randSeedInt(moves.length)];
|
const move = moves[user.randSeedInt(moves.length)];
|
||||||
const moveIndex = moveset.findIndex(m => m?.moveId === move?.moveId);
|
const moveIndex = moveset.findIndex(m => m.moveId === move?.moveId);
|
||||||
const moveTargets = getMoveTargets(user, move?.moveId!); // TODO: is this bang correct?
|
const moveTargets = getMoveTargets(user, move.moveId);
|
||||||
if (!moveTargets.targets.length) {
|
if (!moveTargets.targets.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -6414,8 +6423,8 @@ export class RandomMovesetMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const targets = selectTargets;
|
const targets = selectTargets;
|
||||||
user.getMoveQueue().push({ move: move?.moveId!, targets: targets, ignorePP: true }); // TODO: is this bang correct?
|
user.getMoveQueue().push({ move: move.moveId, targets: targets, ignorePP: true });
|
||||||
user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex]!, true)); // There's a PR to re-do the move(s) that use this Attr, gonna put `!` for now
|
user.scene.unshiftPhase(new MovePhase(user.scene, user, targets, moveset[moveIndex], true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6657,19 +6666,19 @@ export class ReducePpMoveAttr extends MoveEffectAttr {
|
|||||||
*
|
*
|
||||||
* @param user {@linkcode Pokemon} that used the attack
|
* @param user {@linkcode Pokemon} that used the attack
|
||||||
* @param target {@linkcode Pokemon} targeted by the attack
|
* @param target {@linkcode Pokemon} targeted by the attack
|
||||||
* @param move {@linkcode Move} being used
|
* @param move N/A
|
||||||
* @param args N/A
|
* @param args N/A
|
||||||
* @returns {boolean} true
|
* @returns `true`
|
||||||
*/
|
*/
|
||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
// Null checks can be skipped due to condition function
|
// Null checks can be skipped due to condition function
|
||||||
const lastMove = target.getLastXMoves().find(() => true);
|
const lastMove = target.getLastXMoves()[0];
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove?.move);
|
const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move)!;
|
||||||
const lastPpUsed = movesetMove?.ppUsed!; // TODO: is the bang correct?
|
const lastPpUsed = movesetMove.ppUsed;
|
||||||
movesetMove!.ppUsed = Math.min((movesetMove?.ppUsed!) + this.reduction, movesetMove?.getMovePp()!); // TODO: is the bang correct?
|
movesetMove.ppUsed = Math.min((lastPpUsed) + this.reduction, movesetMove.getMovePp());
|
||||||
|
|
||||||
const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove?.getName(), reduction: (movesetMove?.ppUsed!) - lastPpUsed }); // TODO: is the bang correct?
|
const message = i18next.t("battle:ppReduced", { targetName: getPokemonNameWithAffix(target), moveName: movesetMove.getName(), reduction: (movesetMove.ppUsed) - lastPpUsed });
|
||||||
user.scene.eventTarget.dispatchEvent(new MoveUsedEvent(target?.id, movesetMove?.getMove()!, movesetMove?.ppUsed!)); // TODO: are these bangs correct?
|
user.scene.eventTarget.dispatchEvent(new MoveUsedEvent(target.id, movesetMove.getMove(), movesetMove.ppUsed));
|
||||||
user.scene.queueMessage(message);
|
user.scene.queueMessage(message);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -6677,9 +6686,9 @@ export class ReducePpMoveAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user, target, move) => {
|
return (user, target, move) => {
|
||||||
const lastMove = target.getLastXMoves().find(() => true);
|
const lastMove = target.getLastXMoves()[0];
|
||||||
if (lastMove) {
|
if (lastMove) {
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move);
|
const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move);
|
||||||
return !!movesetMove?.getPpRatio();
|
return !!movesetMove?.getPpRatio();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -6687,9 +6696,9 @@ export class ReducePpMoveAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): number {
|
||||||
const lastMove = target.getLastXMoves().find(() => true);
|
const lastMove = target.getLastXMoves()[0];
|
||||||
if (lastMove) {
|
if (lastMove) {
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move);
|
const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move);
|
||||||
if (movesetMove) {
|
if (movesetMove) {
|
||||||
const maxPp = movesetMove.getMovePp();
|
const maxPp = movesetMove.getMovePp();
|
||||||
const ppLeft = maxPp - movesetMove.ppUsed;
|
const ppLeft = maxPp - movesetMove.ppUsed;
|
||||||
@ -6726,7 +6735,7 @@ export class AttackReducePpMoveAttr extends ReducePpMoveAttr {
|
|||||||
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
|
||||||
const lastMove = target.getLastXMoves().find(() => true);
|
const lastMove = target.getLastXMoves().find(() => true);
|
||||||
if (lastMove) {
|
if (lastMove) {
|
||||||
const movesetMove = target.getMoveset().find(m => m?.moveId === lastMove.move);
|
const movesetMove = target.getMoveset().find(m => m.moveId === lastMove.move);
|
||||||
if (Boolean(movesetMove?.getPpRatio())) {
|
if (Boolean(movesetMove?.getPpRatio())) {
|
||||||
super.apply(user, target, move, args);
|
super.apply(user, target, move, args);
|
||||||
}
|
}
|
||||||
@ -6772,7 +6781,7 @@ export class MovesetCopyMoveAttr extends OverrideMoveEffectAttr {
|
|||||||
|
|
||||||
const copiedMove = allMoves[targetMoves[0].move];
|
const copiedMove = allMoves[targetMoves[0].move];
|
||||||
|
|
||||||
const thisMoveIndex = user.getMoveset().findIndex(m => m?.moveId === move.id);
|
const thisMoveIndex = user.getMoveset().findIndex(m => m.moveId === move.id);
|
||||||
|
|
||||||
if (thisMoveIndex === -1) {
|
if (thisMoveIndex === -1) {
|
||||||
return false;
|
return false;
|
||||||
@ -6824,7 +6833,7 @@ export class SketchAttr extends MoveEffectAttr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sketchedMove = allMoves[targetMove.move];
|
const sketchedMove = allMoves[targetMove.move];
|
||||||
const sketchIndex = user.getMoveset().findIndex(m => m?.moveId === move.id);
|
const sketchIndex = user.getMoveset().findIndex(m => m.moveId === move.id);
|
||||||
if (sketchIndex === -1) {
|
if (sketchIndex === -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -6863,7 +6872,7 @@ export class SketchAttr extends MoveEffectAttr {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.getMoveset().find(m => m?.moveId === targetMove.move)) {
|
if (user.getMoveset().find(m => m.moveId === targetMove.move)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7347,7 +7356,7 @@ export class LastResortAttr extends MoveAttr {
|
|||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user: Pokemon, target: Pokemon, move: Move) => {
|
return (user: Pokemon, target: Pokemon, move: Move) => {
|
||||||
const uniqueUsedMoveIds = new Set<Moves>();
|
const uniqueUsedMoveIds = new Set<Moves>();
|
||||||
const movesetMoveIds = user.getMoveset().map(m => m?.moveId);
|
const movesetMoveIds = user.getMoveset().map(m => m.moveId);
|
||||||
user.getMoveHistory().map(m => {
|
user.getMoveHistory().map(m => {
|
||||||
if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move)) {
|
if (m.move !== move.id && movesetMoveIds.find(mm => mm === m.move)) {
|
||||||
uniqueUsedMoveIds.add(m.move);
|
uniqueUsedMoveIds.add(m.move);
|
||||||
@ -8649,7 +8658,17 @@ export function initMoves() {
|
|||||||
.attr(FlinchAttr),
|
.attr(FlinchAttr),
|
||||||
new AttackMove(Moves.WEATHER_BALL, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 3)
|
new AttackMove(Moves.WEATHER_BALL, Type.NORMAL, MoveCategory.SPECIAL, 50, 100, 10, -1, 0, 3)
|
||||||
.attr(WeatherBallTypeAttr)
|
.attr(WeatherBallTypeAttr)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => [ WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN ].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 2 : 1) // TODO: is this bang correct?
|
.attr(MovePowerMultiplierAttr, (user, target, move) => {
|
||||||
|
const weather = user.scene.arena.weather;
|
||||||
|
if (!weather) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const weatherTypes = [ WeatherType.SUNNY, WeatherType.RAIN, WeatherType.SANDSTORM, WeatherType.HAIL, WeatherType.SNOW, WeatherType.FOG, WeatherType.HEAVY_RAIN, WeatherType.HARSH_SUN ];
|
||||||
|
if (weatherTypes.includes(weather.weatherType) && !weather.isEffectSuppressed(user.scene)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
.ballBombMove(),
|
.ballBombMove(),
|
||||||
new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3)
|
new StatusMove(Moves.AROMATHERAPY, Type.GRASS, -1, 5, -1, 0, 3)
|
||||||
.attr(PartyStatusCureAttr, i18next.t("moveTriggers:soothingAromaWaftedThroughArea"), Abilities.SAP_SIPPER)
|
.attr(PartyStatusCureAttr, i18next.t("moveTriggers:soothingAromaWaftedThroughArea"), Abilities.SAP_SIPPER)
|
||||||
@ -8879,7 +8898,13 @@ export function initMoves() {
|
|||||||
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
|
new StatusMove(Moves.WORRY_SEED, Type.GRASS, 100, 10, -1, 0, 4)
|
||||||
.attr(AbilityChangeAttr, Abilities.INSOMNIA),
|
.attr(AbilityChangeAttr, Abilities.INSOMNIA),
|
||||||
new AttackMove(Moves.SUCKER_PUNCH, Type.DARK, MoveCategory.PHYSICAL, 70, 100, 5, -1, 1, 4)
|
new AttackMove(Moves.SUCKER_PUNCH, Type.DARK, MoveCategory.PHYSICAL, 70, 100, 5, -1, 1, 4)
|
||||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct?
|
.condition((user, target, move) => {
|
||||||
|
const turnCommand = user.scene.currentBattle.turnCommands[target.getBattlerIndex()];
|
||||||
|
if (!turnCommand || !turnCommand.move) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (turnCommand.command === Command.FIGHT && !target.turnData.acted && allMoves[turnCommand.move.move].category !== MoveCategory.STATUS);
|
||||||
|
}),
|
||||||
new StatusMove(Moves.TOXIC_SPIKES, Type.POISON, -1, 20, -1, 0, 4)
|
new StatusMove(Moves.TOXIC_SPIKES, Type.POISON, -1, 20, -1, 0, 4)
|
||||||
.attr(AddArenaTrapTagAttr, ArenaTagType.TOXIC_SPIKES)
|
.attr(AddArenaTrapTagAttr, ArenaTagType.TOXIC_SPIKES)
|
||||||
.target(MoveTarget.ENEMY_SIDE),
|
.target(MoveTarget.ENEMY_SIDE),
|
||||||
@ -9788,8 +9813,12 @@ export function initMoves() {
|
|||||||
.ignoresSubstitute(),
|
.ignoresSubstitute(),
|
||||||
new AttackMove(Moves.SMART_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 70, -1, 10, -1, 0, 7),
|
new AttackMove(Moves.SMART_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 70, -1, 10, -1, 0, 7),
|
||||||
new StatusMove(Moves.PURIFY, Type.POISON, -1, 20, -1, 0, 7)
|
new StatusMove(Moves.PURIFY, Type.POISON, -1, 20, -1, 0, 7)
|
||||||
.condition(
|
.condition((user, target, move) => {
|
||||||
(user: Pokemon, target: Pokemon, move: Move) => isNonVolatileStatusEffect(target.status?.effect!)) // TODO: is this bang correct?
|
if (!target.status) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isNonVolatileStatusEffect(target.status.effect);
|
||||||
|
})
|
||||||
.attr(HealAttr, 0.5)
|
.attr(HealAttr, 0.5)
|
||||||
.attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects())
|
.attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects())
|
||||||
.triageMove(),
|
.triageMove(),
|
||||||
@ -10521,7 +10550,13 @@ export function initMoves() {
|
|||||||
.slicingMove(),
|
.slicingMove(),
|
||||||
new AttackMove(Moves.HYDRO_STEAM, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9)
|
new AttackMove(Moves.HYDRO_STEAM, Type.WATER, MoveCategory.SPECIAL, 80, 100, 15, -1, 0, 9)
|
||||||
.attr(IgnoreWeatherTypeDebuffAttr, WeatherType.SUNNY)
|
.attr(IgnoreWeatherTypeDebuffAttr, WeatherType.SUNNY)
|
||||||
.attr(MovePowerMultiplierAttr, (user, target, move) => [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(user.scene.arena.weather?.weatherType!) && !user.scene.arena.weather?.isEffectSuppressed(user.scene) ? 1.5 : 1), // TODO: is this bang correct?
|
.attr(MovePowerMultiplierAttr, (user, target, move) => {
|
||||||
|
const weather = user.scene.arena.weather;
|
||||||
|
if (!weather) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return [ WeatherType.SUNNY, WeatherType.HARSH_SUN ].includes(weather.weatherType) && !weather.isEffectSuppressed(user.scene) ? 1.5 : 1;
|
||||||
|
}),
|
||||||
new AttackMove(Moves.RUINATION, Type.DARK, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 9)
|
new AttackMove(Moves.RUINATION, Type.DARK, MoveCategory.SPECIAL, -1, 90, 10, -1, 0, 9)
|
||||||
.attr(TargetHalfHpDamageAttr),
|
.attr(TargetHalfHpDamageAttr),
|
||||||
new AttackMove(Moves.COLLISION_COURSE, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9)
|
new AttackMove(Moves.COLLISION_COURSE, Type.FIGHTING, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 9)
|
||||||
@ -10636,7 +10671,13 @@ export function initMoves() {
|
|||||||
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK)
|
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK)
|
||||||
.condition(failIfLastCondition),
|
.condition(failIfLastCondition),
|
||||||
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
|
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
|
||||||
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct?
|
.condition((user, target, move) => {
|
||||||
|
const turnCommand = user.scene.currentBattle.turnCommands[target.getBattlerIndex()];
|
||||||
|
if (!turnCommand || !turnCommand.move) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (turnCommand.command === Command.FIGHT && !target.turnData.acted && allMoves[turnCommand.move.move].category !== MoveCategory.STATUS);
|
||||||
|
}),
|
||||||
new AttackMove(Moves.MIGHTY_CLEAVE, Type.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, -1, 0, 9)
|
new AttackMove(Moves.MIGHTY_CLEAVE, Type.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, -1, 0, 9)
|
||||||
.slicingMove()
|
.slicingMove()
|
||||||
.ignoresProtect(),
|
.ignoresProtect(),
|
||||||
|
@ -264,7 +264,7 @@ export const GlobalTradeSystemEncounter: MysteryEncounter =
|
|||||||
if (eggMoves) {
|
if (eggMoves) {
|
||||||
// Cannot gen the rare egg move, only 1 of the first 3 common moves
|
// Cannot gen the rare egg move, only 1 of the first 3 common moves
|
||||||
const eggMove = eggMoves[randSeedInt(3)];
|
const eggMove = eggMoves[randSeedInt(3)];
|
||||||
if (!tradePokemon.moveset.some(m => m?.moveId === eggMove)) {
|
if (!tradePokemon.moveset.some(m => m.moveId === eggMove)) {
|
||||||
if (tradePokemon.moveset.length < 4) {
|
if (tradePokemon.moveset.length < 4) {
|
||||||
tradePokemon.moveset.push(new PokemonMove(eggMove));
|
tradePokemon.moveset.push(new PokemonMove(eggMove));
|
||||||
} else {
|
} else {
|
||||||
|
@ -694,7 +694,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla
|
|||||||
let randomEggMoveIndex = eggMoveIndices.pop();
|
let randomEggMoveIndex = eggMoveIndices.pop();
|
||||||
let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
let randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
||||||
let retries = 0;
|
let retries = 0;
|
||||||
while (retries < 3 && (!randomEggMove || newPokemon.moveset.some(m => m?.moveId === randomEggMove))) {
|
while (retries < 3 && (!randomEggMove || newPokemon.moveset.some(m => m.moveId === randomEggMove))) {
|
||||||
// If Pokemon already knows this move, roll for another egg move
|
// If Pokemon already knows this move, roll for another egg move
|
||||||
randomEggMoveIndex = eggMoveIndices.pop();
|
randomEggMoveIndex = eggMoveIndices.pop();
|
||||||
randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
randomEggMove = !isNullOrUndefined(randomEggMoveIndex) ? eggMoves[randomEggMoveIndex] : null;
|
||||||
@ -702,7 +702,7 @@ async function addEggMoveToNewPokemonMoveset(scene: BattleScene, newPokemon: Pla
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (randomEggMove) {
|
if (randomEggMove) {
|
||||||
if (!newPokemon.moveset.some(m => m?.moveId === randomEggMove)) {
|
if (!newPokemon.moveset.some(m => m.moveId === randomEggMove)) {
|
||||||
if (newPokemon.moveset.length < 4) {
|
if (newPokemon.moveset.length < 4) {
|
||||||
newPokemon.moveset.push(new PokemonMove(randomEggMove));
|
newPokemon.moveset.push(new PokemonMove(randomEggMove));
|
||||||
} else {
|
} else {
|
||||||
@ -731,7 +731,7 @@ function addFavoredMoveToNewPokemonMoveset(newPokemon: PlayerPokemon, newPokemon
|
|||||||
let favoredMove: PokemonMove | null = null;
|
let favoredMove: PokemonMove | null = null;
|
||||||
for (const move of newPokemonGeneratedMoveset) {
|
for (const move of newPokemonGeneratedMoveset) {
|
||||||
// Needs to match first type, second type will be replaced
|
// Needs to match first type, second type will be replaced
|
||||||
if (move?.getMove().type === newPokemon.getTypes()[0] && !newPokemon.moveset.some(m => m?.moveId === move?.moveId)) {
|
if (move?.getMove().type === newPokemon.getTypes()[0] && !newPokemon.moveset.some(m => m.moveId === move?.moveId)) {
|
||||||
favoredMove = move;
|
favoredMove = move;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -741,7 +741,7 @@ function addFavoredMoveToNewPokemonMoveset(newPokemon: PlayerPokemon, newPokemon
|
|||||||
if (!favoredMove) {
|
if (!favoredMove) {
|
||||||
for (const move of newPokemonGeneratedMoveset) {
|
for (const move of newPokemonGeneratedMoveset) {
|
||||||
// Needs to match first type, second type will be replaced
|
// Needs to match first type, second type will be replaced
|
||||||
if (!newPokemon.moveset.some(m => m?.moveId === move?.moveId)) {
|
if (!newPokemon.moveset.some(m => m.moveId === move?.moveId)) {
|
||||||
favoredMove = move;
|
favoredMove = move;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -603,15 +603,15 @@ export class CompatibleMoveRequirement extends EncounterPokemonRequirement {
|
|||||||
|
|
||||||
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
override queryParty(partyPokemon: PlayerPokemon[]): PlayerPokemon[] {
|
||||||
if (!this.invertQuery) {
|
if (!this.invertQuery) {
|
||||||
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove)).length > 0);
|
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(learnableMove)).length > 0);
|
||||||
} else {
|
} else {
|
||||||
// for an inverted query, we only want to get the pokemon that don't have ANY of the listed learnableMoves
|
// for an inverted query, we only want to get the pokemon that don't have ANY of the listed learnableMoves
|
||||||
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m?.moveId === tm)).includes(learnableMove)).length === 0);
|
return partyPokemon.filter((pokemon) => this.requiredMoves.filter((learnableMove) => pokemon.compatibleTms.filter(tm => !pokemon.moveset.find(m => m.moveId === tm)).includes(learnableMove)).length === 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
override getDialogueToken(scene: BattleScene, pokemon?: PlayerPokemon): [string, string] {
|
||||||
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m?.moveId === tm)).includes(reqMove));
|
const includedCompatMoves = this.requiredMoves.filter((reqMove) => pokemon?.compatibleTms.filter((tm) => !pokemon.moveset.find(m => m.moveId === tm)).includes(reqMove));
|
||||||
if (includedCompatMoves.length > 0) {
|
if (includedCompatMoves.length > 0) {
|
||||||
return [ "compatibleMove", Moves[includedCompatMoves[0]] ];
|
return [ "compatibleMove", Moves[includedCompatMoves[0]] ];
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
|
|||||||
}
|
}
|
||||||
|
|
||||||
canChange(pokemon: Pokemon): boolean {
|
canChange(pokemon: Pokemon): boolean {
|
||||||
return (!!pokemon.moveset.filter(m => m?.moveId === this.move).length) === this.known;
|
return (!!pokemon.moveset.filter(m => m.moveId === this.move).length) === this.known;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2784,23 +2784,3 @@ export function initSpecies() {
|
|||||||
new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), //Marked as Sub-Legend, for casing purposes
|
new PokemonSpecies(Species.BLOODMOON_URSALUNA, 9, true, false, false, "Peat Pokémon", Type.GROUND, Type.NORMAL, 2.7, 333, Abilities.MINDS_EYE, Abilities.NONE, Abilities.NONE, 555, 113, 70, 120, 135, 65, 52, 75, 50, 275, GrowthRate.MEDIUM_FAST, 50, false), //Marked as Sub-Legend, for casing purposes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove
|
|
||||||
{
|
|
||||||
//setTimeout(() => {
|
|
||||||
/*for (let tc of Object.keys(trainerConfigs)) {
|
|
||||||
console.log(TrainerType[tc], !trainerConfigs[tc].speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(trainerConfigs[tc].speciesFilter).map(s => {
|
|
||||||
while (pokemonPrevolutions.hasOwnProperty(s.speciesId))
|
|
||||||
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);
|
|
||||||
return s;
|
|
||||||
}))].map(s => s.name));
|
|
||||||
}
|
|
||||||
|
|
||||||
const speciesFilter = (species: PokemonSpecies) => !species.legendary && !species.pseudoLegendary && !species.mythical && species.baseTotal >= 540;
|
|
||||||
console.log(!speciesFilter ? 'all' : [...new Set(allSpecies.filter(s => s.generation <= 9).filter(speciesFilter).map(s => {
|
|
||||||
while (pokemonPrevolutions.hasOwnProperty(s.speciesId))
|
|
||||||
s = getPokemonSpecies(pokemonPrevolutions[s.speciesId]);
|
|
||||||
return s;
|
|
||||||
}))].map(s => s.name));*/
|
|
||||||
//}, 1000);
|
|
||||||
}
|
|
||||||
|
@ -418,7 +418,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
|
|
||||||
loadAssets(ignoreOverride: boolean = true): Promise<void> {
|
loadAssets(ignoreOverride: boolean = true): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const moveIds = this.getMoveset().map(m => m!.getMove().id); // TODO: is this bang correct?
|
const moveIds = this.getMoveset().map(m => m.getMove().id);
|
||||||
Promise.allSettled(moveIds.map(m => initMoveAnim(this.scene, m)))
|
Promise.allSettled(moveIds.map(m => initMoveAnim(this.scene, m)))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
loadMoveAnimAssets(this.scene, moveIds);
|
loadMoveAnimAssets(this.scene, moveIds);
|
||||||
@ -1231,7 +1231,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
|||||||
if (Array.isArray(this.usedTMs) && this.usedTMs.length > 0) {
|
if (Array.isArray(this.usedTMs) && this.usedTMs.length > 0) {
|
||||||
levelMoves = this.usedTMs.filter(m => !levelMoves.includes(m)).concat(levelMoves);
|
levelMoves = this.usedTMs.filter(m => !levelMoves.includes(m)).concat(levelMoves);
|
||||||
}
|
}
|
||||||
levelMoves = levelMoves.filter(lm => !this.moveset.some(m => m?.moveId === lm));
|
levelMoves = levelMoves.filter(lm => !this.moveset.some(m => m.moveId === lm));
|
||||||
return levelMoves;
|
return levelMoves;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4639,10 +4639,7 @@ export class PlayerPokemon extends Pokemon {
|
|||||||
copyMoveset(): PokemonMove[] {
|
copyMoveset(): PokemonMove[] {
|
||||||
const newMoveset : PokemonMove[] = [];
|
const newMoveset : PokemonMove[] = [];
|
||||||
this.moveset.forEach((move) => {
|
this.moveset.forEach((move) => {
|
||||||
// TODO: refactor `moveset` to not accept `null`s
|
|
||||||
if (move) {
|
|
||||||
newMoveset.push(new PokemonMove(move.moveId, 0, move.ppUp, move.virtual, move.maxPpOverride));
|
newMoveset.push(new PokemonMove(move.moveId, 0, move.ppUp, move.virtual, move.maxPpOverride));
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return newMoveset;
|
return newMoveset;
|
||||||
@ -4788,7 +4785,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
getNextMove(): QueuedMove {
|
getNextMove(): QueuedMove {
|
||||||
// If this Pokemon has a move already queued, return it.
|
// If this Pokemon has a move already queued, return it.
|
||||||
const queuedMove = this.getMoveQueue().length
|
const queuedMove = this.getMoveQueue().length
|
||||||
? this.getMoveset().find(m => m?.moveId === this.getMoveQueue()[0].move)
|
? this.getMoveset().find(m => m.moveId === this.getMoveQueue()[0].move)
|
||||||
: null;
|
: null;
|
||||||
if (queuedMove) {
|
if (queuedMove) {
|
||||||
if (queuedMove.isUsable(this, this.getMoveQueue()[0].ignorePP)) {
|
if (queuedMove.isUsable(this, this.getMoveQueue()[0].ignorePP)) {
|
||||||
@ -4800,24 +4797,24 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out any moves this Pokemon cannot use
|
// Filter out any moves this Pokemon cannot use
|
||||||
let movePool = this.getMoveset().filter(m => m?.isUsable(this));
|
let movePool = this.getMoveset().filter(m => m.isUsable(this));
|
||||||
// If no moves are left, use Struggle. Otherwise, continue with move selection
|
// If no moves are left, use Struggle. Otherwise, continue with move selection
|
||||||
if (movePool.length) {
|
if (movePool.length) {
|
||||||
// If there's only 1 move in the move pool, use it.
|
// If there's only 1 move in the move pool, use it.
|
||||||
if (movePool.length === 1) {
|
if (movePool.length === 1) {
|
||||||
return { move: movePool[0]!.moveId, targets: this.getNextTargets(movePool[0]!.moveId) }; // TODO: are the bangs correct?
|
return { move: movePool[0].moveId, targets: this.getNextTargets(movePool[0].moveId) };
|
||||||
}
|
}
|
||||||
// If a move is forced because of Encore, use it.
|
// If a move is forced because of Encore, use it.
|
||||||
const encoreTag = this.getTag(EncoreTag) as EncoreTag;
|
const encoreTag = this.getTag(EncoreTag) as EncoreTag;
|
||||||
if (encoreTag) {
|
if (encoreTag) {
|
||||||
const encoreMove = movePool.find(m => m?.moveId === encoreTag.moveId);
|
const encoreMove = movePool.find(m => m.moveId === encoreTag.moveId);
|
||||||
if (encoreMove) {
|
if (encoreMove) {
|
||||||
return { move: encoreMove.moveId, targets: this.getNextTargets(encoreMove.moveId) };
|
return { move: encoreMove.moveId, targets: this.getNextTargets(encoreMove.moveId) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (this.aiType) {
|
switch (this.aiType) {
|
||||||
case AiType.RANDOM: // No enemy should spawn with this AI type in-game
|
case AiType.RANDOM: // No enemy should spawn with this AI type in-game
|
||||||
const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)]!.moveId; // TODO: is the bang correct?
|
const moveId = movePool[this.scene.randBattleSeedInt(movePool.length)].moveId;
|
||||||
return { move: moveId, targets: this.getNextTargets(moveId) };
|
return { move: moveId, targets: this.getNextTargets(moveId) };
|
||||||
case AiType.SMART_RANDOM:
|
case AiType.SMART_RANDOM:
|
||||||
case AiType.SMART:
|
case AiType.SMART:
|
||||||
@ -4860,9 +4857,9 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
* For more information on how benefit scores are calculated, see `docs/enemy-ai.md`.
|
* For more information on how benefit scores are calculated, see `docs/enemy-ai.md`.
|
||||||
*/
|
*/
|
||||||
const moveScores = movePool.map(() => 0);
|
const moveScores = movePool.map(() => 0);
|
||||||
const moveTargets = Object.fromEntries(movePool.map(m => [ m!.moveId, this.getNextTargets(m!.moveId) ])); // TODO: are those bangs correct?
|
const moveTargets = Object.fromEntries(movePool.map(m => [ m.moveId, this.getNextTargets(m.moveId) ]));
|
||||||
for (const m in movePool) {
|
for (const m in movePool) {
|
||||||
const pokemonMove = movePool[m]!; // TODO: is the bang correct?
|
const pokemonMove = movePool[m];
|
||||||
const move = pokemonMove.getMove();
|
const move = pokemonMove.getMove();
|
||||||
|
|
||||||
let moveScore = moveScores[m];
|
let moveScore = moveScores[m];
|
||||||
@ -4943,7 +4940,7 @@ export class EnemyPokemon extends Pokemon {
|
|||||||
r++;
|
r++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(movePool.map(m => m!.getName()), moveScores, r, sortedMovePool.map(m => m!.getName())); // TODO: are those bangs correct?
|
console.log(movePool.map(m => m.getName()), moveScores, r, sortedMovePool.map(m => m.getName()));
|
||||||
return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] };
|
return { move: sortedMovePool[r]!.moveId, targets: moveTargets[sortedMovePool[r]!.moveId] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ export class PokemonAllMovePpRestoreModifierType extends PokemonModifierType {
|
|||||||
constructor(localeKey: string, iconImage: string, restorePoints: integer) {
|
constructor(localeKey: string, iconImage: string, restorePoints: integer) {
|
||||||
super(localeKey, iconImage, (_type, args) => new PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints),
|
super(localeKey, iconImage, (_type, args) => new PokemonAllMovePpRestoreModifier(this, (args[0] as PlayerPokemon).id, this.restorePoints),
|
||||||
(pokemon: PlayerPokemon) => {
|
(pokemon: PlayerPokemon) => {
|
||||||
if (!pokemon.getMoveset().filter(m => m?.ppUsed).length) {
|
if (!pokemon.getMoveset().filter(m => m.ppUsed).length) {
|
||||||
return PartyUiHandler.NoEffectMessage;
|
return PartyUiHandler.NoEffectMessage;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -810,7 +810,7 @@ export class TmModifierType extends PokemonModifierType {
|
|||||||
constructor(moveId: Moves) {
|
constructor(moveId: Moves) {
|
||||||
super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new TmModifier(this, (args[0] as PlayerPokemon).id),
|
super("", `tm_${Type[allMoves[moveId].type].toLowerCase()}`, (_type, args) => new TmModifier(this, (args[0] as PlayerPokemon).id),
|
||||||
(pokemon: PlayerPokemon) => {
|
(pokemon: PlayerPokemon) => {
|
||||||
if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.getMoveset().filter(m => m?.moveId === moveId).length) {
|
if (pokemon.compatibleTms.indexOf(moveId) === -1 || pokemon.getMoveset().filter(m => m.moveId === moveId).length) {
|
||||||
return PartyUiHandler.NoEffectMessage;
|
return PartyUiHandler.NoEffectMessage;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -926,7 +926,7 @@ class AttackTypeBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
return new AttackTypeBoosterModifierType(pregenArgs[0] as Type, 20);
|
return new AttackTypeBoosterModifierType(pregenArgs[0] as Type, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
const attackMoveTypes = party.map(p => p.getMoveset().map(m => m?.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
|
const attackMoveTypes = party.map(p => p.getMoveset().map(m => m.getMove()).filter(m => m instanceof AttackMove).map(m => m.type)).flat();
|
||||||
if (!attackMoveTypes.length) {
|
if (!attackMoveTypes.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1040,7 +1040,7 @@ class SpeciesStatBoosterModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
for (const p of party) {
|
for (const p of party) {
|
||||||
const speciesId = p.getSpeciesForm(true).speciesId;
|
const speciesId = p.getSpeciesForm(true).speciesId;
|
||||||
const fusionSpeciesId = p.isFusion() ? p.getFusionSpeciesForm(true).speciesId : null;
|
const fusionSpeciesId = p.isFusion() ? p.getFusionSpeciesForm(true).speciesId : null;
|
||||||
const hasFling = p.getMoveset(true).some(m => m?.moveId === Moves.FLING);
|
const hasFling = p.getMoveset(true).some(m => m.moveId === Moves.FLING);
|
||||||
|
|
||||||
for (const i in values) {
|
for (const i in values) {
|
||||||
const checkedSpecies = values[i].species;
|
const checkedSpecies = values[i].species;
|
||||||
@ -1093,7 +1093,7 @@ class TmModifierTypeGenerator extends ModifierTypeGenerator {
|
|||||||
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Moves)) {
|
if (pregenArgs && (pregenArgs.length === 1) && (pregenArgs[0] in Moves)) {
|
||||||
return new TmModifierType(pregenArgs[0] as Moves);
|
return new TmModifierType(pregenArgs[0] as Moves);
|
||||||
}
|
}
|
||||||
const partyMemberCompatibleTms = party.map(p => (p as PlayerPokemon).compatibleTms.filter(tm => !p.moveset.find(m => m?.moveId === tm)));
|
const partyMemberCompatibleTms = party.map(p => (p as PlayerPokemon).compatibleTms.filter(tm => !p.moveset.find(m => m.moveId === tm)));
|
||||||
const tierUniqueCompatibleTms = partyMemberCompatibleTms.flat().filter(tm => tmPoolTiers[tm] === tier).filter(tm => !allMoves[tm].name.endsWith(" (N)")).filter((tm, i, array) => array.indexOf(tm) === i);
|
const tierUniqueCompatibleTms = partyMemberCompatibleTms.flat().filter(tm => tmPoolTiers[tm] === tier).filter(tm => !allMoves[tm].name.endsWith(" (N)")).filter((tm, i, array) => array.indexOf(tm) === i);
|
||||||
if (!tierUniqueCompatibleTms.length) {
|
if (!tierUniqueCompatibleTms.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -1630,12 +1630,12 @@ const modifierPool: ModifierPool = {
|
|||||||
}, 3),
|
}, 3),
|
||||||
new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.ETHER, (party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
||||||
&& p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
&& p.getMoveset().filter(m => m.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
||||||
return thresholdPartyMemberCount * 3;
|
return thresholdPartyMemberCount * 3;
|
||||||
}, 9),
|
}, 9),
|
||||||
new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.MAX_ETHER, (party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
||||||
&& p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
&& p.getMoveset().filter(m => m.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
||||||
return thresholdPartyMemberCount;
|
return thresholdPartyMemberCount;
|
||||||
}, 3),
|
}, 3),
|
||||||
new WeightedModifierType(modifierTypes.LURE, lureWeightFunc(10, 2)),
|
new WeightedModifierType(modifierTypes.LURE, lureWeightFunc(10, 2)),
|
||||||
@ -1688,12 +1688,12 @@ const modifierPool: ModifierPool = {
|
|||||||
}, 3),
|
}, 3),
|
||||||
new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.ELIXIR, (party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
||||||
&& p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
&& p.getMoveset().filter(m => m.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
||||||
return thresholdPartyMemberCount * 3;
|
return thresholdPartyMemberCount * 3;
|
||||||
}, 9),
|
}, 9),
|
||||||
new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => {
|
new WeightedModifierType(modifierTypes.MAX_ELIXIR, (party: Pokemon[]) => {
|
||||||
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
const thresholdPartyMemberCount = Math.min(party.filter(p => p.hp && !p.getHeldItems().some(m => m instanceof BerryModifier && m.berryType === BerryType.LEPPA)
|
||||||
&& p.getMoveset().filter(m => m?.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
&& p.getMoveset().filter(m => m.ppUsed && (m.getMovePp() - m.ppUsed) <= 5 && m.ppUsed > Math.floor(m.getMovePp() / 2)).length).length, 3);
|
||||||
return thresholdPartyMemberCount;
|
return thresholdPartyMemberCount;
|
||||||
}, 3),
|
}, 3),
|
||||||
new WeightedModifierType(modifierTypes.DIRE_HIT, 4),
|
new WeightedModifierType(modifierTypes.DIRE_HIT, 4),
|
||||||
|
@ -76,8 +76,8 @@ export class CommandPhase extends FieldPhase {
|
|||||||
const moveQueue = playerPokemon.getMoveQueue();
|
const moveQueue = playerPokemon.getMoveQueue();
|
||||||
|
|
||||||
while (moveQueue.length && moveQueue[0]
|
while (moveQueue.length && moveQueue[0]
|
||||||
&& moveQueue[0].move && (!playerPokemon.getMoveset().find(m => m?.moveId === moveQueue[0].move)
|
&& moveQueue[0].move && (!playerPokemon.getMoveset().find(m => m.moveId === moveQueue[0].move)
|
||||||
|| !playerPokemon.getMoveset()[playerPokemon.getMoveset().findIndex(m => m?.moveId === moveQueue[0].move)]!.isUsable(playerPokemon, moveQueue[0].ignorePP))) { // TODO: is the bang correct?
|
|| !playerPokemon.getMoveset()[playerPokemon.getMoveset().findIndex(m => m.moveId === moveQueue[0].move)].isUsable(playerPokemon, moveQueue[0].ignorePP))) {
|
||||||
moveQueue.shift();
|
moveQueue.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +86,8 @@ export class CommandPhase extends FieldPhase {
|
|||||||
if (!queuedMove.move) {
|
if (!queuedMove.move) {
|
||||||
this.handleCommand(Command.FIGHT, -1, false);
|
this.handleCommand(Command.FIGHT, -1, false);
|
||||||
} else {
|
} else {
|
||||||
const moveIndex = playerPokemon.getMoveset().findIndex(m => m?.moveId === queuedMove.move);
|
const moveIndex = playerPokemon.getMoveset().findIndex(m => m.moveId === queuedMove.move);
|
||||||
if (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex]!.isUsable(playerPokemon, queuedMove.ignorePP)) { // TODO: is the bang correct?
|
if (moveIndex > -1 && playerPokemon.getMoveset()[moveIndex].isUsable(playerPokemon, queuedMove.ignorePP)) {
|
||||||
this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, { targets: queuedMove.targets, multiple: queuedMove.targets.length > 1 });
|
this.handleCommand(Command.FIGHT, moveIndex, queuedMove.ignorePP, { targets: queuedMove.targets, multiple: queuedMove.targets.length > 1 });
|
||||||
} else {
|
} else {
|
||||||
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
|
this.scene.ui.setMode(Mode.COMMAND, this.fieldIndex);
|
||||||
@ -112,8 +112,8 @@ export class CommandPhase extends FieldPhase {
|
|||||||
let useStruggle = false;
|
let useStruggle = false;
|
||||||
if (cursor === -1 ||
|
if (cursor === -1 ||
|
||||||
playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
|
playerPokemon.trySelectMove(cursor, args[0] as boolean) ||
|
||||||
(useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m?.isUsable(playerPokemon)).length)) {
|
(useStruggle = cursor > -1 && !playerPokemon.getMoveset().filter(m => m.isUsable(playerPokemon)).length)) {
|
||||||
const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor]!.moveId : Moves.NONE : Moves.STRUGGLE; // TODO: is the bang correct?
|
const moveId = !useStruggle ? cursor > -1 ? playerPokemon.getMoveset()[cursor].moveId : Moves.NONE : Moves.STRUGGLE;
|
||||||
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
const turnCommand: TurnCommand = { command: Command.FIGHT, cursor: cursor, move: { move: moveId, targets: [], ignorePP: args[0] }, args: args };
|
||||||
const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
|
const moveTargets: MoveTargetSet = args.length < 3 ? getMoveTargets(playerPokemon, moveId) : args[2];
|
||||||
if (!moveId) {
|
if (!moveId) {
|
||||||
@ -123,17 +123,17 @@ export class CommandPhase extends FieldPhase {
|
|||||||
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
|
if (moveTargets.targets.length > 1 && moveTargets.multiple) {
|
||||||
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
|
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
|
||||||
}
|
}
|
||||||
if (moveTargets.targets.length <= 1 || moveTargets.multiple) {
|
if (turnCommand.move && (moveTargets.targets.length <= 1 || moveTargets.multiple)) {
|
||||||
turnCommand.move!.targets = moveTargets.targets; //TODO: is the bang correct here?
|
turnCommand.move.targets = moveTargets.targets;
|
||||||
} else if (playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) {
|
} else if (turnCommand.move && playerPokemon.getTag(BattlerTagType.CHARGING) && playerPokemon.getMoveQueue().length >= 1) {
|
||||||
turnCommand.move!.targets = playerPokemon.getMoveQueue()[0].targets; //TODO: is the bang correct here?
|
turnCommand.move.targets = playerPokemon.getMoveQueue()[0].targets;
|
||||||
} else {
|
} else {
|
||||||
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
|
this.scene.unshiftPhase(new SelectTargetPhase(this.scene, this.fieldIndex));
|
||||||
}
|
}
|
||||||
this.scene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
|
this.scene.currentBattle.turnCommands[this.fieldIndex] = turnCommand;
|
||||||
success = true;
|
success = true;
|
||||||
} else if (cursor < playerPokemon.getMoveset().length) {
|
} else if (cursor < playerPokemon.getMoveset().length) {
|
||||||
const move = playerPokemon.getMoveset()[cursor]!; //TODO: is this bang correct?
|
const move = playerPokemon.getMoveset()[cursor];
|
||||||
this.scene.ui.setMode(Mode.MESSAGE);
|
this.scene.ui.setMode(Mode.MESSAGE);
|
||||||
|
|
||||||
// Decides between a Disabled, Not Implemented, or No PP translation message
|
// Decides between a Disabled, Not Implemented, or No PP translation message
|
||||||
|
@ -43,7 +43,7 @@ export class LearnMovePhase extends PlayerPartyMemberPokemonPhase {
|
|||||||
const currentMoveset = pokemon.getMoveset();
|
const currentMoveset = pokemon.getMoveset();
|
||||||
|
|
||||||
// The game first checks if the Pokemon already has the move and ends the phase if it does.
|
// The game first checks if the Pokemon already has the move and ends the phase if it does.
|
||||||
const hasMoveAlready = currentMoveset.some(m => m?.moveId === move.id) && this.moveId !== Moves.SKETCH;
|
const hasMoveAlready = currentMoveset.some(m => m.moveId === move.id) && this.moveId !== Moves.SKETCH;
|
||||||
if (hasMoveAlready) {
|
if (hasMoveAlready) {
|
||||||
return this.end();
|
return this.end();
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ export class PartyHealPhase extends BattlePhase {
|
|||||||
pokemon.hp = pokemon.getMaxHp();
|
pokemon.hp = pokemon.getMaxHp();
|
||||||
pokemon.resetStatus();
|
pokemon.resetStatus();
|
||||||
for (const move of pokemon.moveset) {
|
for (const move of pokemon.moveset) {
|
||||||
move!.ppUsed = 0; // TODO: is this bang correct?
|
move.ppUsed = 0;
|
||||||
}
|
}
|
||||||
pokemon.updateInfo(true);
|
pokemon.updateInfo(true);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ export class TurnStartPhase extends FieldPhase {
|
|||||||
if (!queuedMove) {
|
if (!queuedMove) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const move = pokemon.getMoveset().find(m => m?.moveId === queuedMove.move && m?.ppUsed < m?.getMovePp()) || new PokemonMove(queuedMove.move);
|
const move = pokemon.getMoveset().find(m => m.moveId === queuedMove.move && m.ppUsed < m.getMovePp()) || new PokemonMove(queuedMove.move);
|
||||||
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
if (move.getMove().hasAttr(MoveHeaderAttr)) {
|
||||||
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
this.scene.unshiftPhase(new MoveHeaderPhase(this.scene, pokemon, move));
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ describe("Moves - Grudge", () => {
|
|||||||
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
await game.setTurnOrder([ BattlerIndex.ENEMY, BattlerIndex.PLAYER ]);
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.EMBER);
|
const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.EMBER);
|
||||||
|
|
||||||
expect(playerMove?.getPpRatio()).toBe(0);
|
expect(playerMove?.getPpRatio()).toBe(0);
|
||||||
});
|
});
|
||||||
@ -60,7 +60,7 @@ describe("Moves - Grudge", () => {
|
|||||||
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
await game.setTurnOrder([ BattlerIndex.PLAYER, BattlerIndex.ENEMY ]);
|
||||||
await game.phaseInterceptor.to("BerryPhase");
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.EMBER);
|
const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.EMBER);
|
||||||
|
|
||||||
expect(playerMove?.getPpRatio()).toBe(0);
|
expect(playerMove?.getPpRatio()).toBe(0);
|
||||||
});
|
});
|
||||||
@ -84,7 +84,7 @@ describe("Moves - Grudge", () => {
|
|||||||
|
|
||||||
expect(enemyPokemon?.isFainted()).toBe(true);
|
expect(enemyPokemon?.isFainted()).toBe(true);
|
||||||
|
|
||||||
const playerMove = playerPokemon?.getMoveset().find(m => m?.moveId === Moves.FALSE_SWIPE);
|
const playerMove = playerPokemon?.getMoveset().find(m => m.moveId === Moves.FALSE_SWIPE);
|
||||||
expect(playerMove?.getPpRatio()).toBeGreaterThan(0);
|
expect(playerMove?.getPpRatio()).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -127,7 +127,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
expect(scene.getCurrentPhase()?.constructor.name).toBe(CommandPhase.name);
|
||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT);
|
expect(enemyField[0].species.speciesId).toBe(Species.GREEDENT);
|
||||||
const moveset = enemyField[0].moveset.map(m => m?.moveId);
|
const moveset = enemyField[0].moveset.map(m => m.moveId);
|
||||||
expect(moveset?.length).toBe(4);
|
expect(moveset?.length).toBe(4);
|
||||||
expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ]);
|
expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.CRUNCH ]);
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ describe("Absolute Avarice - Mystery Encounter", () => {
|
|||||||
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
||||||
const greedent = scene.getPlayerParty()[scene.getPlayerParty().length - 1];
|
const greedent = scene.getPlayerParty()[scene.getPlayerParty().length - 1];
|
||||||
expect(greedent.species.speciesId).toBe(Species.GREEDENT);
|
expect(greedent.species.speciesId).toBe(Species.GREEDENT);
|
||||||
const moveset = greedent.moveset.map(m => m?.moveId);
|
const moveset = greedent.moveset.map(m => m.moveId);
|
||||||
expect(moveset?.length).toBe(4);
|
expect(moveset?.length).toBe(4);
|
||||||
expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF ]);
|
expect(moveset).toEqual([ Moves.THRASH, Moves.BODY_PRESS, Moves.STUFF_CHEEKS, Moves.SLACK_OFF ]);
|
||||||
});
|
});
|
||||||
|
@ -108,7 +108,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
expect(enemyField.length).toBe(1);
|
expect(enemyField.length).toBe(1);
|
||||||
expect(enemyField[0].species.speciesId).toBe(Species.ORICORIO);
|
expect(enemyField[0].species.speciesId).toBe(Species.ORICORIO);
|
||||||
expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 0, 0, 0 ]);
|
expect(enemyField[0].summonData.statStages).toEqual([ 1, 1, 1, 1, 0, 0, 0 ]);
|
||||||
const moveset = enemyField[0].moveset.map(m => m?.moveId);
|
const moveset = enemyField[0].moveset.map(m => m.moveId);
|
||||||
expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
expect(moveset.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
||||||
|
|
||||||
const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]);
|
const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof MovePhase).map(p => p[0]);
|
||||||
@ -204,7 +204,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
|
|||||||
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
expect(partyCountBefore + 1).toBe(partyCountAfter);
|
||||||
const oricorio = scene.getPlayerParty()[scene.getPlayerParty().length - 1];
|
const oricorio = scene.getPlayerParty()[scene.getPlayerParty().length - 1];
|
||||||
expect(oricorio.species.speciesId).toBe(Species.ORICORIO);
|
expect(oricorio.species.speciesId).toBe(Species.ORICORIO);
|
||||||
const moveset = oricorio.moveset.map(m => m?.moveId);
|
const moveset = oricorio.moveset.map(m => m.moveId);
|
||||||
expect(moveset?.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
expect(moveset?.some(m => m === Moves.REVELATION_DANCE)).toBeTruthy();
|
||||||
expect(moveset?.some(m => m === Moves.DRAGON_DANCE)).toBeTruthy();
|
expect(moveset?.some(m => m === Moves.DRAGON_DANCE)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
@ -257,7 +257,7 @@ export default class GameManager {
|
|||||||
selectTarget(movePosition: integer, targetIndex?: BattlerIndex) {
|
selectTarget(movePosition: integer, targetIndex?: BattlerIndex) {
|
||||||
this.onNextPrompt("SelectTargetPhase", Mode.TARGET_SELECT, () => {
|
this.onNextPrompt("SelectTargetPhase", Mode.TARGET_SELECT, () => {
|
||||||
const handler = this.scene.ui.getHandler() as TargetSelectUiHandler;
|
const handler = this.scene.ui.getHandler() as TargetSelectUiHandler;
|
||||||
const move = (this.scene.getCurrentPhase() as SelectTargetPhase).getPokemon().getMoveset()[movePosition]!.getMove(); // TODO: is the bang correct?
|
const move = (this.scene.getCurrentPhase() as SelectTargetPhase).getPokemon().getMoveset()[movePosition].getMove();
|
||||||
if (!move.isMultiTarget()) {
|
if (!move.isMultiTarget()) {
|
||||||
handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY);
|
handler.setCursor(targetIndex !== undefined ? targetIndex : BattlerIndex.ENEMY);
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ export function waitUntil(truth) {
|
|||||||
export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) {
|
export function getMovePosition(scene: BattleScene, pokemonIndex: 0 | 1, move: Moves) {
|
||||||
const playerPokemon = scene.getPlayerField()[pokemonIndex];
|
const playerPokemon = scene.getPlayerField()[pokemonIndex];
|
||||||
const moveSet = playerPokemon.getMoveset();
|
const moveSet = playerPokemon.getMoveset();
|
||||||
const index = moveSet.findIndex((m) => m?.moveId === move && m?.ppUsed < m?.getMovePp());
|
const index = moveSet.findIndex((m) => m.moveId === move && m.ppUsed < m.getMovePp());
|
||||||
console.log(`Move position for ${Moves[move]} (=${move}):`, index);
|
console.log(`Move position for ${Moves[move]} (=${move}):`, index);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ export default class FightUiHandler extends UiHandler implements InfoToggle {
|
|||||||
const hasMove = cursor < moveset.length;
|
const hasMove = cursor < moveset.length;
|
||||||
|
|
||||||
if (hasMove) {
|
if (hasMove) {
|
||||||
const pokemonMove = moveset[cursor]!; // TODO: is the bang correct?
|
const pokemonMove = moveset[cursor];
|
||||||
const moveType = pokemon.getMoveType(pokemonMove.getMove());
|
const moveType = pokemon.getMoveType(pokemonMove.getMove());
|
||||||
const textureKey = Utils.getLocalizedSpriteKey("types");
|
const textureKey = Utils.getLocalizedSpriteKey("types");
|
||||||
this.typeIcon.setTexture(textureKey, Type[moveType].toLowerCase()).setScale(0.8);
|
this.typeIcon.setTexture(textureKey, Type[moveType].toLowerCase()).setScale(0.8);
|
||||||
|
@ -406,7 +406,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
filterResult = this.FilterChallengeLegal(pokemon);
|
filterResult = this.FilterChallengeLegal(pokemon);
|
||||||
}
|
}
|
||||||
if (filterResult === null && this.partyUiMode === PartyUiMode.MOVE_MODIFIER) {
|
if (filterResult === null && this.partyUiMode === PartyUiMode.MOVE_MODIFIER) {
|
||||||
filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]!); // TODO: is this bang correct?
|
filterResult = this.moveSelectFilter(pokemon.moveset[this.optionsCursor]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, getTransferrableItemsFromPokemon(this.scene.getPlayerParty()[this.transferCursor])[this.transferOptionCursor]);
|
filterResult = (this.selectFilter as PokemonModifierTransferSelectFilter)(pokemon, getTransferrableItemsFromPokemon(this.scene.getPlayerParty()[this.transferCursor])[this.transferOptionCursor]);
|
||||||
@ -966,7 +966,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
|||||||
case PartyOption.MOVE_2:
|
case PartyOption.MOVE_2:
|
||||||
case PartyOption.MOVE_3:
|
case PartyOption.MOVE_3:
|
||||||
case PartyOption.MOVE_4:
|
case PartyOption.MOVE_4:
|
||||||
const move = pokemon.moveset[option - PartyOption.MOVE_1]!; // TODO: is the bang correct?
|
const move = pokemon.moveset[option - PartyOption.MOVE_1];
|
||||||
if (this.showMovePp) {
|
if (this.showMovePp) {
|
||||||
const maxPP = move.getMovePp();
|
const maxPP = move.getMovePp();
|
||||||
const currPP = maxPP - move.ppUsed;
|
const currPP = maxPP - move.ppUsed;
|
||||||
@ -1339,7 +1339,7 @@ class PartySlot extends Phaser.GameObjects.Container {
|
|||||||
this.slotHpText.setVisible(false);
|
this.slotHpText.setVisible(false);
|
||||||
let slotTmText: string;
|
let slotTmText: string;
|
||||||
|
|
||||||
if (this.pokemon.getMoveset().filter(m => m?.moveId === tmMoveId).length > 0) {
|
if (this.pokemon.getMoveset().filter(m => m.moveId === tmMoveId).length > 0) {
|
||||||
slotTmText = i18next.t("partyUiHandler:learned");
|
slotTmText = i18next.t("partyUiHandler:learned");
|
||||||
} else if (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1) {
|
} else if (this.pokemon.compatibleTms.indexOf(tmMoveId) === -1) {
|
||||||
slotTmText = i18next.t("partyUiHandler:notAble");
|
slotTmText = i18next.t("partyUiHandler:notAble");
|
||||||
|
@ -1069,7 +1069,7 @@ export default class SummaryUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.moveCursor < 4 && this.pokemon && this.moveCursor < this.pokemon.moveset.length) {
|
if (this.moveCursor < 4 && this.pokemon && this.moveCursor < this.pokemon.moveset.length) {
|
||||||
return this.pokemon.moveset[this.moveCursor]!.getMove(); // TODO: is this bang correct?
|
return this.pokemon.moveset[this.moveCursor].getMove();
|
||||||
} else if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.moveCursor === 4) {
|
} else if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE && this.moveCursor === 4) {
|
||||||
return this.newMove;
|
return this.newMove;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user