Merge branch 'beta' into instruct

This commit is contained in:
Bertie690 2024-11-15 14:08:44 -05:00 committed by GitHub
commit 0794a6b373
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 264 additions and 31 deletions

View File

@ -1424,10 +1424,19 @@ export default class BattleScene extends SceneBase {
case Species.PALDEA_TAUROS:
return Utils.randSeedInt(species.forms.length);
case Species.PIKACHU:
if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) {
return 0; // Ban Cosplay and Partner Pika from Trainers before wave 30
}
return Utils.randSeedInt(8);
case Species.EEVEE:
if (this.currentBattle?.battleType === BattleType.TRAINER && this.currentBattle?.waveIndex < 30) {
return 0; // No Partner Eevee for Wave 12 Preschoolers
}
return Utils.randSeedInt(2);
case Species.GRENINJA:
if (this.currentBattle?.battleType === BattleType.TRAINER) {
return 0; // Don't give trainers Battle Bond Greninja
}
return Utils.randSeedInt(2);
case Species.ZYGARDE:
return Utils.randSeedInt(4);

View File

@ -3302,11 +3302,23 @@ export const tmSpecies: TmSpecies = {
Species.FERALIGATR,
Species.SENTRET,
Species.FURRET,
Species.HOOTHOOT,
Species.NOCTOWL,
Species.LEDYBA,
Species.LEDIAN,
Species.SPINARAK,
Species.ARIADOS,
Species.CROBAT,
Species.CHINCHOU,
Species.LANTURN,
Species.PICHU,
Species.CLEFFA,
Species.IGGLYBUFF,
Species.TYROGUE,
Species.TOGEPI,
Species.TOGETIC,
Species.NATU,
Species.XATU,
Species.MAREEP,
Species.FLAAFFY,
Species.AMPHAROS,
@ -3328,6 +3340,7 @@ export const tmSpecies: TmSpecies = {
Species.UMBREON,
Species.MURKROW,
Species.SLOWKING,
Species.MISDREAVUS,
Species.GIRAFARIG,
Species.PINECO,
Species.FORRETRESS,
@ -3338,11 +3351,21 @@ export const tmSpecies: TmSpecies = {
Species.GRANBULL,
Species.QWILFISH,
Species.SCIZOR,
Species.SHUCKLE,
Species.HERACROSS,
Species.SNEASEL,
Species.TEDDIURSA,
Species.URSARING,
Species.SLUGMA,
Species.MAGCARGO,
Species.SWINUB,
Species.PILOSWINE,
Species.CORSOLA,
Species.REMORAID,
Species.OCTILLERY,
Species.DELIBIRD,
Species.MANTINE,
Species.SKARMORY,
Species.HOUNDOUR,
Species.HOUNDOOM,
Species.KINGDRA,
@ -3350,9 +3373,12 @@ export const tmSpecies: TmSpecies = {
Species.DONPHAN,
Species.PORYGON2,
Species.STANTLER,
Species.TYROGUE,
Species.HITMONTOP,
Species.SMOOCHUM,
Species.ELEKID,
Species.MAGBY,
Species.MILTANK,
Species.BLISSEY,
Species.RAIKOU,
Species.ENTEI,
@ -3362,6 +3388,9 @@ export const tmSpecies: TmSpecies = {
Species.TYRANITAR,
Species.LUGIA,
Species.HO_OH,
Species.CELEBI,
Species.TREECKO,
Species.GROVYLE,
Species.SCEPTILE,
Species.TORCHIC,
Species.COMBUSKEN,
@ -3371,41 +3400,116 @@ export const tmSpecies: TmSpecies = {
Species.SWAMPERT,
Species.POOCHYENA,
Species.MIGHTYENA,
Species.ZIGZAGOON,
Species.LINOONE,
Species.BEAUTIFLY,
Species.DUSTOX,
Species.LOTAD,
Species.LOMBRE,
Species.LUDICOLO,
Species.SEEDOT,
Species.NUZLEAF,
Species.SHIFTRY,
Species.TAILLOW,
Species.SWELLOW,
Species.WINGULL,
Species.PELIPPER,
Species.RALTS,
Species.KIRLIA,
Species.GARDEVOIR,
Species.SURSKIT,
Species.MASQUERAIN,
Species.SHROOMISH,
Species.BRELOOM,
Species.VIGOROTH,
Species.SLAKING,
Species.NINCADA,
Species.NINJASK,
Species.SHEDINJA,
Species.WHISMUR,
Species.LOUDRED,
Species.EXPLOUD,
Species.MAKUHITA,
Species.HARIYAMA,
Species.AZURILL,
Species.NOSEPASS,
Species.SKITTY,
Species.DELCATTY,
Species.SABLEYE,
Species.MAWILE,
Species.ARON,
Species.LAIRON,
Species.AGGRON,
Species.MEDITITE,
Species.MEDICHAM,
Species.ELECTRIKE,
Species.MANECTRIC,
Species.PLUSLE,
Species.MINUN,
Species.VOLBEAT,
Species.ILLUMISE,
Species.ROSELIA,
Species.GULPIN,
Species.SWALOT,
Species.CARVANHA,
Species.SHARPEDO,
Species.WAILMER,
Species.WAILORD,
Species.NUMEL,
Species.CAMERUPT,
Species.TORKOAL,
Species.SPOINK,
Species.GRUMPIG,
Species.SPINDA,
Species.TRAPINCH,
Species.VIBRAVA,
Species.FLYGON,
Species.CACNEA,
Species.CACTURNE,
Species.SWABLU,
Species.ALTARIA,
Species.ZANGOOSE,
Species.SEVIPER,
Species.LUNATONE,
Species.SOLROCK,
Species.BARBOACH,
Species.WHISCASH,
Species.CORPHISH,
Species.CRAWDAUNT,
Species.BALTOY,
Species.CLAYDOL,
Species.LILEEP,
Species.CRADILY,
Species.ANORITH,
Species.ARMALDO,
Species.FEEBAS,
Species.MILOTIC,
Species.CASTFORM,
Species.KECLEON,
Species.SHUPPET,
Species.BANETTE,
Species.DUSKULL,
Species.DUSCLOPS,
Species.TROPIUS,
Species.CHIMECHO,
Species.ABSOL,
Species.SNORUNT,
Species.GLALIE,
Species.SPHEAL,
Species.SEALEO,
Species.WALREIN,
Species.CLAMPERL,
Species.HUNTAIL,
Species.GOREBYSS,
Species.RELICANTH,
Species.LUVDISC,
Species.BAGON,
Species.SHELGON,
Species.SALAMENCE,
Species.METANG,
Species.METAGROSS,
Species.REGIROCK,
Species.REGICE,
Species.REGISTEEL,
Species.LATIAS,
Species.LATIOS,
@ -3413,6 +3517,7 @@ export const tmSpecies: TmSpecies = {
Species.GROUDON,
Species.RAYQUAZA,
Species.JIRACHI,
Species.DEOXYS,
Species.TURTWIG,
Species.GROTLE,
Species.TORTERRA,
@ -64246,12 +64351,16 @@ export const tmSpecies: TmSpecies = {
Species.BLOODMOON_URSALUNA,
],
[Moves.LIQUIDATION]: [
Species.SQUIRTLE,
Species.WARTORTLE,
Species.BLASTOISE,
Species.PSYDUCK,
Species.GOLDUCK,
Species.POLIWAG,
Species.POLIWHIRL,
Species.POLIWRATH,
Species.TENTACOOL,
Species.TENTACRUEL,
Species.SLOWPOKE,
Species.SLOWBRO,
Species.DEWGONG,
@ -64267,7 +64376,11 @@ export const tmSpecies: TmSpecies = {
Species.KABUTO,
Species.KABUTOPS,
Species.MEW,
Species.TOTODILE,
Species.CROCONAW,
Species.FERALIGATR,
Species.CHINCHOU,
Species.LANTURN,
Species.MARILL,
Species.AZUMARILL,
Species.POLITOED,
@ -64280,6 +64393,9 @@ export const tmSpecies: TmSpecies = {
Species.MANTINE,
Species.KINGDRA,
Species.SUICUNE,
Species.LUGIA,
Species.MUDKIP,
Species.MARSHTOMP,
Species.SWAMPERT,
Species.WINGULL,
Species.PELIPPER,
@ -64296,6 +64412,8 @@ export const tmSpecies: TmSpecies = {
Species.WALREIN,
Species.RELICANTH,
Species.LUVDISC,
Species.LATIAS,
Species.LATIOS,
Species.KYOGRE,
Species.PIPLUP,
Species.PRINPLUP,
@ -64407,11 +64525,13 @@ export const tmSpecies: TmSpecies = {
Species.ONIX,
Species.HYPNO,
Species.LICKITUNG,
Species.RHYHORN,
Species.RHYDON,
Species.LAPRAS,
Species.SNORLAX,
Species.DRAGONITE,
Species.MEW,
Species.MEGANIUM,
Species.SUDOWOODO,
Species.QUAGSIRE,
Species.FORRETRESS,
@ -64445,6 +64565,8 @@ export const tmSpecies: TmSpecies = {
Species.REGISTEEL,
Species.GROUDON,
Species.TORTERRA,
Species.RAMPARDOS,
Species.BASTIODON,
Species.BRONZONG,
Species.HIPPOPOTAS,
Species.HIPPOWDON,
@ -64459,6 +64581,7 @@ export const tmSpecies: TmSpecies = {
Species.HEATRAN,
Species.REGIGIGAS,
Species.ARCEUS,
Species.EMBOAR,
Species.ROGGENROLA,
Species.BOLDORE,
Species.GIGALITH,
@ -64471,6 +64594,7 @@ export const tmSpecies: TmSpecies = {
Species.CUBCHOO,
Species.BEARTIC,
Species.GOLURK,
Species.COBALION,
Species.RESHIRAM,
Species.ZEKROM,
Species.KYUREM,

View File

@ -2158,6 +2158,11 @@ export class CommandedTag extends BattlerTag {
pokemon.scene.triggerPokemonBattleAnim(pokemon, PokemonAnimType.COMMANDER_REMOVE);
}
}
override loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this._tatsugiriFormKey = source._tatsugiriFormKey;
}
}
/**

View File

@ -2589,12 +2589,11 @@ export class HealStatusEffectAttr extends MoveEffectAttr {
/**
* @param selfTarget - Whether this move targets the user
* @param ...effects - List of status effects to cure
* @param effects - status effect or list of status effects to cure
*/
constructor(selfTarget: boolean, ...effects: StatusEffect[]) {
constructor(selfTarget: boolean, effects: StatusEffect | StatusEffect[]) {
super(selfTarget, { lastHitOnly: true });
this.effects = effects;
this.effects = [ effects ].flat(1);
}
/**
@ -8702,7 +8701,7 @@ export function initMoves() {
.attr(AddArenaTagAttr, ArenaTagType.IMPRISON, 1, true, false)
.target(MoveTarget.ENEMY_SIDE),
new SelfStatusMove(Moves.REFRESH, Type.NORMAL, -1, 20, -1, 0, 3)
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN)
.attr(HealStatusEffectAttr, true, [ StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN ])
.condition((user, target, move) => !!user.status && (user.status.effect === StatusEffect.PARALYSIS || user.status.effect === StatusEffect.POISON || user.status.effect === StatusEffect.TOXIC || user.status.effect === StatusEffect.BURN)),
new SelfStatusMove(Moves.GRUDGE, Type.GHOST, -1, 5, -1, 0, 3)
.attr(AddBattlerTagAttr, BattlerTagType.GRUDGE, true, undefined, 1),
@ -9911,7 +9910,7 @@ export function initMoves() {
.condition(
(user: Pokemon, target: Pokemon, move: Move) => isNonVolatileStatusEffect(target.status?.effect!)) // TODO: is this bang correct?
.attr(HealAttr, 0.5)
.attr(HealStatusEffectAttr, false, ...getNonVolatileStatusEffects())
.attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects())
.triageMove(),
new AttackMove(Moves.REVELATION_DANCE, Type.NORMAL, MoveCategory.SPECIAL, 90, 100, 15, -1, 0, 7)
.danceMove()
@ -9996,11 +9995,9 @@ export function initMoves() {
.ignoresSubstitute()
.partial(), // Does not steal stats
new AttackMove(Moves.SUNSTEEL_STRIKE, Type.STEEL, MoveCategory.PHYSICAL, 100, 100, 5, -1, 0, 7)
.ignoresAbilities()
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
.ignoresAbilities(),
new AttackMove(Moves.MOONGEIST_BEAM, Type.GHOST, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
.ignoresAbilities()
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
.ignoresAbilities(),
new StatusMove(Moves.TEARFUL_LOOK, Type.NORMAL, -1, 20, -1, 0, 7)
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1),
new AttackMove(Moves.ZING_ZAP, Type.ELECTRIC, MoveCategory.PHYSICAL, 80, 100, 10, 30, 0, 7)
@ -10023,8 +10020,7 @@ export function initMoves() {
.punchingMove(),
new AttackMove(Moves.PHOTON_GEYSER, Type.PSYCHIC, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 7)
.attr(PhotonGeyserCategoryAttr)
.ignoresAbilities()
.edgeCase(), // Should not ignore abilities when called virtually (metronome)
.ignoresAbilities(),
/* Unused */
new AttackMove(Moves.LIGHT_THAT_BURNS_THE_SKY, Type.PSYCHIC, MoveCategory.SPECIAL, 200, -1, 1, -1, 0, 7)
.attr(PhotonGeyserCategoryAttr)
@ -10339,7 +10335,7 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.BURN),
new StatusMove(Moves.JUNGLE_HEALING, Type.GRASS, -1, 10, -1, 0, 8)
.attr(HealAttr, 0.25, true, false)
.attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects())
.target(MoveTarget.USER_AND_ALLIES),
new AttackMove(Moves.WICKED_BLOW, Type.DARK, MoveCategory.PHYSICAL, 75, 100, 5, -1, 0, 8)
.attr(CritOnlyAttr)
@ -10443,12 +10439,12 @@ export function initMoves() {
.target(MoveTarget.ALL_NEAR_ENEMIES),
new StatusMove(Moves.LUNAR_BLESSING, Type.PSYCHIC, -1, 5, -1, 0, 8)
.attr(HealAttr, 0.25, true, false)
.attr(HealStatusEffectAttr, false, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP)
.attr(HealStatusEffectAttr, false, getNonVolatileStatusEffects())
.target(MoveTarget.USER_AND_ALLIES)
.triageMove(),
new SelfStatusMove(Moves.TAKE_HEART, Type.PSYCHIC, -1, 10, -1, 0, 8)
.attr(StatStageChangeAttr, [ Stat.SPATK, Stat.SPDEF ], 1, true)
.attr(HealStatusEffectAttr, true, StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP),
.attr(HealStatusEffectAttr, true, [ StatusEffect.PARALYSIS, StatusEffect.POISON, StatusEffect.TOXIC, StatusEffect.BURN, StatusEffect.SLEEP ]),
/* Unused
new AttackMove(Moves.G_MAX_WILDFIRE, Type.FIRE, MoveCategory.PHYSICAL, 10, -1, 10, -1, 0, 8)
.target(MoveTarget.ALL_NEAR_ENEMIES)

View File

@ -505,11 +505,11 @@ export abstract class PokemonSpeciesForm {
scene.anims.create({
key: this.getSpriteKey(female, formIndex, shiny, variant),
frames: frameNames,
frameRate: 12,
frameRate: 10,
repeat: -1
});
} else {
scene.anims.get(spriteKey).frameRate = 12;
scene.anims.get(spriteKey).frameRate = 10;
}
let spritePath = this.getSpriteAtlasPath(female, formIndex, shiny, variant).replace("variant/", "").replace(/_[1-3]$/, "");
const useExpSprite = scene.experimentalSprites && scene.hasExpSprite(spriteKey);

View File

@ -1841,21 +1841,25 @@ export const trainerConfigs: TrainerConfigs = {
[TrainerType.RIVAL]: new TrainerConfig((t = TrainerType.RIVAL)).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL)
.setModifierRewardFuncs(() => modifierTypes.SUPER_EXP_CHARM, () => modifierTypes.EXP_SHARE)
.setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM, () => modifierTypes.ABILITY_CHARM)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.BULBASAUR, Species.CHARMANDER, Species.SQUIRTLE, Species.CHIKORITA, Species.CYNDAQUIL, Species.TOTODILE, Species.TREECKO, Species.TORCHIC, Species.MUDKIP, Species.TURTWIG, Species.CHIMCHAR, Species.PIPLUP, Species.SNIVY, Species.TEPIG, Species.OSHAWOTT, Species.CHESPIN, Species.FENNEKIN, Species.FROAKIE, Species.ROWLET, Species.LITTEN, Species.POPPLIO, Species.GROOKEY, Species.SCORBUNNY, Species.SOBBLE, Species.SPRIGATITO, Species.FUECOCO, Species.QUAXLY ], TrainerSlot.TRAINER, true,
(p => p.abilityIndex = 0)))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEY, Species.HOOTHOOT, Species.TAILLOW, Species.STARLY, Species.PIDOVE, Species.FLETCHLING, Species.PIKIPEK, Species.ROOKIDEE, Species.WATTREL ], TrainerSlot.TRAINER, true)),
[TrainerType.RIVAL_2]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_2)
.setModifierRewardFuncs(() => modifierTypes.EXP_SHARE)
.setEventModifierRewardFuncs(() => modifierTypes.SHINY_CHARM)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.IVYSAUR, Species.CHARMELEON, Species.WARTORTLE, Species.BAYLEEF, Species.QUILAVA, Species.CROCONAW, Species.GROVYLE, Species.COMBUSKEN, Species.MARSHTOMP, Species.GROTLE, Species.MONFERNO, Species.PRINPLUP, Species.SERVINE, Species.PIGNITE, Species.DEWOTT, Species.QUILLADIN, Species.BRAIXEN, Species.FROGADIER, Species.DARTRIX, Species.TORRACAT, Species.BRIONNE, Species.THWACKEY, Species.RABOOT, Species.DRIZZILE, Species.FLORAGATO, Species.CROCALOR, Species.QUAXWELL ], TrainerSlot.TRAINER, true,
(p => p.abilityIndex = 0)))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOTTO, Species.HOOTHOOT, Species.TAILLOW, Species.STARAVIA, Species.TRANQUILL, Species.FLETCHINDER, Species.TRUMBEAK, Species.CORVISQUIRE, Species.WATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450)),
[TrainerType.RIVAL_3]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setStaticParty().setMoneyMultiplier(1.5).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival").setMixedBattleBgm("battle_rival").setPartyTemplates(trainerPartyTemplates.RIVAL_3)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
(p => p.abilityIndex = 0)))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540),
[TrainerType.RIVAL_4]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(1.75).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_2").setMixedBattleBgm("battle_rival_2").setPartyTemplates(trainerPartyTemplates.RIVAL_4)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
(p => p.abilityIndex = 0)))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540)
@ -1865,7 +1869,10 @@ export const trainerConfigs: TrainerConfigs = {
}),
[TrainerType.RIVAL_5]: new TrainerConfig(++t).setName("Finn").setHasGenders("Ivy").setHasCharSprite().setTitle("Rival").setBoss().setStaticParty().setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.RIVAL).setBattleBgm("battle_rival_3").setMixedBattleBgm("battle_rival_3").setPartyTemplates(trainerPartyTemplates.RIVAL_5)
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
p => p.setBoss(true, 2)))
p => {
p.setBoss(true, 2);
p.abilityIndex = 0;
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true))
.setPartyMemberFunc(2, getSpeciesFilterRandomPartyMemberFunc((species: PokemonSpecies) => !pokemonEvolutions.hasOwnProperty(species.speciesId) && !pokemonPrevolutions.hasOwnProperty(species.speciesId) && species.baseTotal >= 450))
.setSpeciesFilter(species => species.baseTotal >= 540)
@ -1883,6 +1890,7 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyMemberFunc(0, getRandomPartyMemberFunc([ Species.VENUSAUR, Species.CHARIZARD, Species.BLASTOISE, Species.MEGANIUM, Species.TYPHLOSION, Species.FERALIGATR, Species.SCEPTILE, Species.BLAZIKEN, Species.SWAMPERT, Species.TORTERRA, Species.INFERNAPE, Species.EMPOLEON, Species.SERPERIOR, Species.EMBOAR, Species.SAMUROTT, Species.CHESNAUGHT, Species.DELPHOX, Species.GRENINJA, Species.DECIDUEYE, Species.INCINEROAR, Species.PRIMARINA, Species.RILLABOOM, Species.CINDERACE, Species.INTELEON, Species.MEOWSCARADA, Species.SKELEDIRGE, Species.QUAQUAVAL ], TrainerSlot.TRAINER, true,
p => {
p.setBoss(true, 3);
p.abilityIndex = 0;
p.generateAndPopulateMoveset();
}))
.setPartyMemberFunc(1, getRandomPartyMemberFunc([ Species.PIDGEOT, Species.NOCTOWL, Species.SWELLOW, Species.STARAPTOR, Species.UNFEZANT, Species.TALONFLAME, Species.TOUCANNON, Species.CORVIKNIGHT, Species.KILOWATTREL ], TrainerSlot.TRAINER, true,

View File

@ -212,7 +212,7 @@ export default class MysteryEncounterIntroVisuals extends Phaser.GameObjects.Con
this.scene.anims.create({
key: config.spriteKey,
frames: frameNames,
frameRate: 12,
frameRate: 10,
repeat: -1
});
}

View File

@ -427,7 +427,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.scene.anims.create({
key: this.getBattleSpriteKey(),
frames: battleFrameNames,
frameRate: 12,
frameRate: 10,
repeat: -1
});
}
@ -3612,7 +3612,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}
this.status = null;
if (lastStatus === StatusEffect.SLEEP) {
this.setFrameRate(12);
this.setFrameRate(10);
if (this.getTag(BattlerTagType.NIGHTMARE)) {
this.lapseTag(BattlerTagType.NIGHTMARE);
}

View File

@ -312,6 +312,10 @@ export class PokemonAnimPhase extends BattlePhase {
// Note: unlike the other Commander animation, this is played through the
// Dondozo instead of the Tatsugiri.
const tatsugiri = this.pokemon.getAlly();
if (isNullOrUndefined(tatsugiri)) {
console.warn("Aborting COMMANDER_REMOVE anim: Tatsugiri is undefined");
return this.end();
}
const tatsuSprite = this.scene.addPokemonSprite(
tatsugiri,

View File

@ -0,0 +1,59 @@
import { allMoves, RandomMoveAttr } from "#app/data/move";
import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe("Moves - Moongeist Beam", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
game.override
.moveset([ Moves.MOONGEIST_BEAM, Moves.METRONOME ])
.ability(Abilities.BALL_FETCH)
.startingLevel(200)
.battleType("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(Abilities.STURDY)
.enemyMoveset(Moves.SPLASH);
});
// Also covers Photon Geyser and Sunsteel Strike
it("should ignore enemy abilities", async () => {
await game.classicMode.startBattle([ Species.MILOTIC ]);
const enemy = game.scene.getEnemyPokemon()!;
game.move.select(Moves.MOONGEIST_BEAM);
await game.phaseInterceptor.to("BerryPhase");
expect(enemy.isFainted()).toBe(true);
});
// Also covers Photon Geyser and Sunsteel Strike
it("should not ignore enemy abilities when called by another move, such as metronome", async () => {
await game.classicMode.startBattle([ Species.MILOTIC ]);
vi.spyOn(allMoves[Moves.METRONOME].getAttrs(RandomMoveAttr)[0], "getMoveOverride").mockReturnValue(Moves.MOONGEIST_BEAM);
game.move.select(Moves.METRONOME);
await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.getEnemyPokemon()!.isFainted()).toBe(false);
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].move).toBe(Moves.MOONGEIST_BEAM);
});
});

View File

@ -13,9 +13,11 @@ import { SubstituteTag } from "#app/data/battler-tags";
export type TargetSelectCallback = (targets: BattlerIndex[]) => void;
export default class TargetSelectUiHandler extends UiHandler {
private fieldIndex: integer;
private fieldIndex: number;
private move: Moves;
private targetSelectCallback: TargetSelectCallback;
private cursor0: number; // associated with BattlerIndex.PLAYER
private cursor1: number; // associated with BattlerIndex.PLAYER_2
private isMultipleTargets: boolean = false;
private targets: BattlerIndex[];
@ -42,8 +44,9 @@ export default class TargetSelectUiHandler extends UiHandler {
this.fieldIndex = args[0] as integer;
this.move = args[1] as Moves;
this.targetSelectCallback = args[2] as TargetSelectCallback;
const user = this.scene.getPlayerField()[this.fieldIndex];
const moveTargets = getMoveTargets(this.scene.getPlayerField()[this.fieldIndex], this.move);
const moveTargets = getMoveTargets(user, this.move);
this.targets = moveTargets.targets;
this.isMultipleTargets = moveTargets.multiple ?? false;
@ -53,11 +56,29 @@ export default class TargetSelectUiHandler extends UiHandler {
this.enemyModifiers = this.scene.getModifierBar(true);
this.setCursor(this.targets.includes(this.cursor) ? this.cursor : this.targets[0]);
if (this.fieldIndex === BattlerIndex.PLAYER) {
this.resetCursor(this.cursor0, user);
} else if (this.fieldIndex === BattlerIndex.PLAYER_2) {
this.resetCursor(this.cursor1, user);
}
return true;
}
/**
* Determines what value to assign the main cursor based on the previous turn's target or the user's status
* @param cursorN the cursor associated with the user's field index
* @param user the Pokemon using the move
*/
resetCursor(cursorN: number, user: Pokemon): void {
if (!Utils.isNullOrUndefined(cursorN)) {
if ([ BattlerIndex.PLAYER, BattlerIndex.PLAYER_2 ].includes(cursorN) || user.battleSummonData.waveTurnCount === 1) {
// Reset cursor on the first turn of a fight or if an ally was targeted last turn
cursorN = -1;
}
}
this.setCursor(this.targets.includes(cursorN) ? cursorN : this.targets[0]);
}
processInput(button: Button): boolean {
const ui = this.getUi();
@ -67,6 +88,15 @@ export default class TargetSelectUiHandler extends UiHandler {
const targetIndexes: BattlerIndex[] = this.isMultipleTargets ? this.targets : [ this.cursor ];
this.targetSelectCallback(button === Button.ACTION ? targetIndexes : []);
success = true;
if (this.fieldIndex === BattlerIndex.PLAYER) {
if (Utils.isNullOrUndefined(this.cursor0) || this.cursor0 !== this.cursor) {
this.cursor0 = this.cursor;
}
} else if (this.fieldIndex === BattlerIndex.PLAYER_2) {
if (Utils.isNullOrUndefined(this.cursor1) || this.cursor1 !== this.cursor) {
this.cursor1 = this.cursor;
}
}
} else if (this.isMultipleTargets) {
success = false;
} else {
@ -152,7 +182,6 @@ export default class TargetSelectUiHandler extends UiHandler {
yoyo: true
}));
});
return ret;
}
@ -184,7 +213,6 @@ export default class TargetSelectUiHandler extends UiHandler {
}
clear() {
this.cursor = -1;
super.clear();
this.eraseCursor();
}