Hopefully fixed extraneous reset calls and call timing

This commit is contained in:
Bertie690 2025-05-17 21:45:15 -04:00
parent 5532432085
commit a42b7ed9f7
6 changed files with 231 additions and 148 deletions

View File

@ -86,7 +86,7 @@ export function ForceSwitch<TBase extends SubMoveOrAbAttr>(Base: TBase) {
/** /**
* Wrapper function to handle the actual "switching out" of Pokemon. * Wrapper function to handle the actual "switching out" of Pokemon.
* @param switchOutTarget - The {@linkcode Pokemon} (player or enemy) attempting to switch out. * @param switchOutTarget - The {@linkcode Pokemon} (player or enemy) to be switched switch out.
*/ */
protected doSwitch(switchOutTarget: Pokemon): void { protected doSwitch(switchOutTarget: Pokemon): void {
if (switchOutTarget instanceof PlayerPokemon) { if (switchOutTarget instanceof PlayerPokemon) {

View File

@ -7771,8 +7771,9 @@ const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target
const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseQueue.find(phase => phase instanceof MovePhase) !== undefined; const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => globalScene.phaseQueue.find(phase => phase instanceof MovePhase) !== undefined;
const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => { const failIfLastInPartyCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => {
const party: Pokemon[] = user.isPlayer() ? globalScene.getPlayerParty() : globalScene.getEnemyParty(); const player = user.isPlayer();
return party.some(pokemon => pokemon.isActive() && !pokemon.isOnField()); const otherPartyIndices = globalScene.getBackupPartyMemberIndices(player, !player ? (user as EnemyPokemon).trainerSlot : undefined)
return otherPartyIndices.length > 0;
}; };
const failIfGhostTypeCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => !target.isOfType(PokemonType.GHOST); const failIfGhostTypeCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => !target.isOfType(PokemonType.GHOST);

View File

@ -5034,6 +5034,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
for (const tag of source.summonData.tags) { for (const tag of source.summonData.tags) {
// Skip non-Baton Passable tags (or telekinesis for mega gengar; cf. https://bulbapedia.bulbagarden.net/wiki/Telekinesis_(move))
if ( if (
!tag.isBatonPassable || !tag.isBatonPassable ||
(tag.tagType === BattlerTagType.TELEKINESIS && (tag.tagType === BattlerTagType.TELEKINESIS &&
@ -6314,12 +6315,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param destroy - Whether to destroy this Pokemon once it leaves the field; default `false` * @param destroy - Whether to destroy this Pokemon once it leaves the field; default `false`
* @remarks * @remarks
* This **SHOULD NOT** be called when a `SummonPhase` or `SwitchSummonPhase` is already being added, * This **SHOULD NOT** be called when a `SummonPhase` or `SwitchSummonPhase` is already being added,
* which can lead to premature resetting of {@klinkcode turnData} and {@linkcode summonData}. * which can lead to premature resetting of {@linkcode turnData} and {@linkcode summonData}.
*/ */
leaveField(clearEffects = true, hideInfo = true, destroy = false) { leaveField(clearEffects = true, hideInfo = true, destroy = false) {
console.log(`leaveField called on Pokemon ${this.name}`) console.log(`leaveField called on Pokemon ${this.name}`)
this.resetSprite(); this.resetSprite();
this.resetTurnData();
globalScene globalScene
.getField(true) .getField(true)
.filter(p => p !== this) .filter(p => p !== this)
@ -6328,6 +6328,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (clearEffects) { if (clearEffects) {
this.destroySubstitute(); this.destroySubstitute();
this.resetSummonData(); this.resetSummonData();
this.resetTurnData();
} }
if (hideInfo) { if (hideInfo) {
this.hideInfo(); this.hideInfo();

View File

@ -61,8 +61,7 @@ export class FaintPhase extends PokemonPhase {
faintPokemon.getTag(BattlerTagType.GRUDGE)?.lapse(faintPokemon, BattlerTagLapseType.CUSTOM, this.source); faintPokemon.getTag(BattlerTagType.GRUDGE)?.lapse(faintPokemon, BattlerTagLapseType.CUSTOM, this.source);
} }
faintPokemon.resetSummonData(); // Check for reviver seed
if (!this.preventInstantRevive) { if (!this.preventInstantRevive) {
const instantReviveModifier = globalScene.applyModifier( const instantReviveModifier = globalScene.applyModifier(
PokemonInstantReviveModifier, PokemonInstantReviveModifier,
@ -71,6 +70,7 @@ export class FaintPhase extends PokemonPhase {
) as PokemonInstantReviveModifier; ) as PokemonInstantReviveModifier;
if (instantReviveModifier) { if (instantReviveModifier) {
faintPokemon.resetSummonData();
faintPokemon.loseHeldItem(instantReviveModifier); faintPokemon.loseHeldItem(instantReviveModifier);
globalScene.updateModifiers(this.player); globalScene.updateModifiers(this.player);
return this.end(); return this.end();
@ -179,11 +179,11 @@ export class FaintPhase extends PokemonPhase {
} else { } else {
globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex)); globalScene.unshiftPhase(new VictoryPhase(this.battlerIndex));
if ([BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(globalScene.currentBattle.battleType)) { if ([BattleType.TRAINER, BattleType.MYSTERY_ENCOUNTER].includes(globalScene.currentBattle.battleType)) {
const hasReservePartyMember = !!globalScene const reservePartyIndices = globalScene.getBackupPartyMemberIndices(
.getEnemyParty() false,
.filter(p => p.isActive() && !p.isOnField() && p.trainerSlot === (pokemon as EnemyPokemon).trainerSlot) (pokemon as EnemyPokemon).trainerSlot,
.length; );
if (hasReservePartyMember) { if (reservePartyIndices.length) {
globalScene.pushPhase(new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false)); globalScene.pushPhase(new SwitchSummonPhase(SwitchType.SWITCH, this.fieldIndex, -1, false, false));
} }
} }
@ -217,6 +217,7 @@ export class FaintPhase extends PokemonPhase {
globalScene.addFaintedEnemyScore(pokemon as EnemyPokemon); globalScene.addFaintedEnemyScore(pokemon as EnemyPokemon);
globalScene.currentBattle.addPostBattleLoot(pokemon as EnemyPokemon); globalScene.currentBattle.addPostBattleLoot(pokemon as EnemyPokemon);
} }
// TODO: Do we need to leave the field here & now as opposed to during `switchSummonPhase`?
pokemon.leaveField(); pokemon.leaveField();
this.end(); this.end();
}, },

View File

@ -111,7 +111,6 @@ export class SwitchSummonPhase extends SummonPhase {
scale: 0.5, scale: 0.5,
onComplete: () => { onComplete: () => {
globalScene.time.delayedCall(750, () => this.switchAndSummon()); globalScene.time.delayedCall(750, () => this.switchAndSummon());
lastPokemon.leaveField(this.switchType === SwitchType.SWITCH, false);
}, },
}); });
} }
@ -162,9 +161,12 @@ export class SwitchSummonPhase extends SummonPhase {
} }
} }
// Swap around the 2 pokemon's party positions and play an animation to send in the new pokemon.
party[this.slotIndex] = this.lastPokemon; party[this.slotIndex] = this.lastPokemon;
party[this.fieldIndex] = switchedInPokemon; party[this.fieldIndex] = switchedInPokemon;
const showTextAndSummon = () => { const showTextAndSummon = () => {
// TODO: Should this remove the info container?
this.lastPokemon.leaveField(![SwitchType.BATON_PASS, SwitchType.SHED_TAIL].includes(this.switchType), false);
globalScene.ui.showText( globalScene.ui.showText(
this.player this.player
? i18next.t("battle:playerGo", { ? i18next.t("battle:playerGo", {
@ -209,25 +211,30 @@ export class SwitchSummonPhase extends SummonPhase {
const pokemon = this.getPokemon(); const pokemon = this.getPokemon();
// If not switching at start of battle, reset turn counts and temp data on the newly sent in Pokemon
// Needed as we increment turn counters in `TurnEndPhase`.
if (this.switchType !== SwitchType.INITIAL_SWITCH) {
// No need to reset turn/summon data for initial switch
// (since both get initialized to an empty object on object creation)
this.lastPokemon.resetTurnData();
this.lastPokemon.resetSummonData();
pokemon.tempSummonData.turnCount--;
pokemon.tempSummonData.waveTurnCount--;
pokemon.turnData.switchedInThisTurn = true;
}
// Baton Pass over any eligible effects or substitutes before resetting the last pokemon's temporary data.
if (this.switchType === SwitchType.BATON_PASS) { if (this.switchType === SwitchType.BATON_PASS) {
pokemon.transferSummon(this.lastPokemon); pokemon.transferSummon(this.lastPokemon);
this.lastPokemon.resetTurnData();
this.lastPokemon.resetSummonData();
} else if (this.switchType === SwitchType.SHED_TAIL) { } else if (this.switchType === SwitchType.SHED_TAIL) {
const subTag = this.lastPokemon.getTag(SubstituteTag); const subTag = this.lastPokemon.getTag(SubstituteTag);
if (subTag) { if (subTag) {
pokemon.summonData.tags.push(subTag); pokemon.summonData.tags.push(subTag);
} }
} this.lastPokemon.resetTurnData();
this.lastPokemon.resetSummonData();
// If not switching at start of battle, reset turn counts and temp data.
// Needed as we increment turn counters in `TurnEndPhase`.
if (this.switchType !== SwitchType.INITIAL_SWITCH) {
pokemon.tempSummonData.turnCount--;
pokemon.tempSummonData.waveTurnCount--;
pokemon.turnData.switchedInThisTurn = true;
// No need to reset turn/summon data for initial switch
//(since both get initialized to an empty object on object creation)
pokemon.resetTurnData();
pokemon.resetSummonData();
} }
globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true); globalScene.triggerPokemonFormChange(pokemon, SpeciesFormChangeActiveTrigger, true);

View File

@ -1,21 +1,14 @@
import Trainer from "#app/field/trainer"; import { PokemonSummonData, PokemonTurnData } from "#app/field/pokemon";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { BattleType } from "#enums/battle-type"; import { BattleType } from "#enums/battle-type";
import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/testUtils/gameManager"; import GameManager from "#test/testUtils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove?: Moves }>([ describe("Manual Switching -", () => {
{ name: "Self Switch Attack Moves", selfMove: Moves.U_TURN },
{ name: "Target Switch Attack Moves", oppMove: Moves.DRAGON_TAIL },
{ name: "Self Switch Status Moves", selfMove: Moves.TELEPORT },
{ name: "Target Switch Status Moves", oppMove: Moves.WHIRLWIND },
{ name: "Self Switch Abilities", selfAbility: Abilities.EMERGENCY_EXIT },
])(
"Switch Outs - $name - ",
({ selfMove = Moves.SPLASH, selfAbility = Abilities.BALL_FETCH, oppMove = Moves.SPLASH }) => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -35,14 +28,13 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
.battleStyle("single") .battleStyle("single")
.disableCrits() .disableCrits()
.enemySpecies(Species.MAGIKARP) .enemySpecies(Species.MAGIKARP)
.enemyPassiveAbility(Abilities.NO_GUARD); .moveset(Moves.SPLASH)
}); .enemyMoveset(Moves.SPLASH)
.battleType(BattleType.TRAINER)
describe("Player -", () => { .enemyAbility(Abilities.BALL_FETCH);
beforeEach(() => {
game.override.moveset(oppMove).ability(selfAbility).enemyMoveset(selfMove).enemyAbility(Abilities.BALL_FETCH);
}); });
describe("Player", () => {
it("should only call leaveField once on the switched out pokemon", async () => { it("should only call leaveField once on the switched out pokemon", async () => {
await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]); await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]);
@ -50,9 +42,8 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const piloLeaveSpy = vi.spyOn(piloswine, "leaveField"); const piloLeaveSpy = vi.spyOn(piloswine, "leaveField");
const mamoLeaveSpy = vi.spyOn(mamoswine, "leaveField"); const mamoLeaveSpy = vi.spyOn(mamoswine, "leaveField");
game.move.select(selfMove); game.doSwitchPokemon(1);
game.doSelectPartyPokemon(1); await game.phaseInterceptor.to("TurnEndPhase");
await game.phaseInterceptor.to("BerryPhase", false);
expect(piloLeaveSpy).toHaveBeenCalledTimes(1); expect(piloLeaveSpy).toHaveBeenCalledTimes(1);
expect(mamoLeaveSpy).toHaveBeenCalledTimes(0); expect(mamoLeaveSpy).toHaveBeenCalledTimes(0);
@ -67,14 +58,13 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const mamoSummonSpy = vi.spyOn(mamoswine, "resetSummonData"); const mamoSummonSpy = vi.spyOn(mamoswine, "resetSummonData");
const mamoTurnSpy = vi.spyOn(mamoswine, "resetTurnData"); const mamoTurnSpy = vi.spyOn(mamoswine, "resetTurnData");
game.move.select(selfMove); game.doSwitchPokemon(1);
game.doSelectPartyPokemon(1); await game.phaseInterceptor.to("TurnEndPhase");
await game.phaseInterceptor.to("BerryPhase", false);
expect(piloSummonSpy).toHaveBeenCalledTimes(1); expect(piloSummonSpy).toHaveBeenCalledTimes(1);
expect(piloTurnSpy).toHaveBeenCalledTimes(1); expect(piloTurnSpy).toHaveBeenCalledTimes(1);
expect(mamoSummonSpy).toHaveBeenCalledTimes(1); expect(mamoSummonSpy).toHaveBeenCalledTimes(1);
expect(mamoTurnSpy).toHaveBeenCalledTimes(1); expect(mamoTurnSpy).toHaveBeenCalledTimes(2); // once from switching, once at turn start
}); });
it("should not reset battleData/waveData upon switching", async () => { it("should not reset battleData/waveData upon switching", async () => {
@ -86,8 +76,7 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const mamoWaveSpy = vi.spyOn(mamoswine, "resetWaveData"); const mamoWaveSpy = vi.spyOn(mamoswine, "resetWaveData");
const mamoBattleWaveSpy = vi.spyOn(mamoswine, "resetBattleAndWaveData"); const mamoBattleWaveSpy = vi.spyOn(mamoswine, "resetBattleAndWaveData");
game.move.select(selfMove); game.doSwitchPokemon(1);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(piloWaveSpy).toHaveBeenCalledTimes(0); expect(piloWaveSpy).toHaveBeenCalledTimes(0);
@ -97,22 +86,7 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
}); });
}); });
describe("Enemy - ", () => { describe("Enemy", () => {
beforeEach(() => {
game.override
.enemyMoveset(oppMove)
.enemyAbility(selfAbility)
.moveset(selfMove)
.ability(Abilities.BALL_FETCH)
.battleType(BattleType.TRAINER);
// prevent natural trainer switches
vi.spyOn(Trainer.prototype, "getPartyMemberMatchupScores").mockReturnValue([
[100, 1],
[100, 1],
]);
});
it("should only call leaveField once on the switched out pokemon", async () => { it("should only call leaveField once on the switched out pokemon", async () => {
await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]); await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]);
@ -120,8 +94,9 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const enemy1LeaveSpy = vi.spyOn(enemy1, "leaveField"); const enemy1LeaveSpy = vi.spyOn(enemy1, "leaveField");
const enemy2LeaveSpy = vi.spyOn(enemy2, "leaveField"); const enemy2LeaveSpy = vi.spyOn(enemy2, "leaveField");
game.move.select(selfMove); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to("BerryPhase", false); game.forceEnemyToSwitch();
await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy1LeaveSpy).toHaveBeenCalledTimes(1); expect(enemy1LeaveSpy).toHaveBeenCalledTimes(1);
expect(enemy2LeaveSpy).toHaveBeenCalledTimes(0); expect(enemy2LeaveSpy).toHaveBeenCalledTimes(0);
@ -136,13 +111,14 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const enemy2SummonSpy = vi.spyOn(enemy2, "resetSummonData"); const enemy2SummonSpy = vi.spyOn(enemy2, "resetSummonData");
const enemy2TurnSpy = vi.spyOn(enemy2, "resetTurnData"); const enemy2TurnSpy = vi.spyOn(enemy2, "resetTurnData");
game.move.select(selfMove); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to("BerryPhase", false); game.forceEnemyToSwitch();
await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy1SummonSpy).toHaveBeenCalledTimes(1); expect(enemy1SummonSpy).toHaveBeenCalledTimes(1);
expect(enemy1TurnSpy).toHaveBeenCalledTimes(1); expect(enemy1TurnSpy).toHaveBeenCalledTimes(1);
expect(enemy2SummonSpy).toHaveBeenCalledTimes(1); expect(enemy2SummonSpy).toHaveBeenCalledTimes(1);
expect(enemy2TurnSpy).toHaveBeenCalledTimes(1); expect(enemy2TurnSpy).toHaveBeenCalledTimes(2); // once from switching, once at turn start
}); });
it("should not reset battleData/waveData upon switching", async () => { it("should not reset battleData/waveData upon switching", async () => {
@ -154,7 +130,8 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
const enemy2WaveSpy = vi.spyOn(enemy2, "resetWaveData"); const enemy2WaveSpy = vi.spyOn(enemy2, "resetWaveData");
const enemy2BattleWaveSpy = vi.spyOn(enemy2, "resetBattleAndWaveData"); const enemy2BattleWaveSpy = vi.spyOn(enemy2, "resetBattleAndWaveData");
game.move.select(selfMove); game.move.select(Moves.SPLASH);
game.forceEnemyToSwitch();
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy1WaveSpy).toHaveBeenCalledTimes(0); expect(enemy1WaveSpy).toHaveBeenCalledTimes(0);
@ -163,5 +140,101 @@ describe.each<{ name: string; selfMove?: Moves; selfAbility?: Abilities; oppMove
expect(enemy2BattleWaveSpy).toHaveBeenCalledTimes(0); expect(enemy2BattleWaveSpy).toHaveBeenCalledTimes(0);
}); });
}); });
});
describe.each<{ name: string; playerMove?: Moves; playerAbility?: Abilities; enemyMove?: Moves }>([
{ name: "Self Switch Attack Moves", playerMove: Moves.U_TURN },
{ name: "Target Switch Attack Moves", enemyMove: Moves.DRAGON_TAIL },
{ name: "Self Switch Status Moves", playerMove: Moves.TELEPORT },
{ name: "Target Switch Status Moves", enemyMove: Moves.WHIRLWIND },
{ name: "Self Switch Abilities", playerAbility: Abilities.EMERGENCY_EXIT, enemyMove: Moves.BRAVE_BIRD },
/* { name: "Fainting", playerMove: Moves.EXPLOSION }, */ // TODO: This calls it twice...
])(
"Mid-Battle Switch Outs - $name - ",
({ playerMove = Moves.SPLASH, playerAbility = Abilities.BALL_FETCH, enemyMove = Moves.SPLASH }) => {
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(playerMove)
.ability(playerAbility)
.battleStyle("single")
.disableCrits()
.enemyLevel(100)
.battleType(BattleType.TRAINER)
.passiveAbility(Abilities.STURDY)
.enemySpecies(Species.MAGIKARP)
.enemyMoveset(enemyMove)
.enemyAbility(Abilities.BALL_FETCH)
.enemyPassiveAbility(Abilities.NO_GUARD);
});
it("should only call leaveField once on the switched out pokemon", async () => {
await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]);
const [piloswine, mamoswine] = game.scene.getPlayerParty();
const piloLeaveSpy = vi.spyOn(piloswine, "leaveField");
const mamoLeaveSpy = vi.spyOn(mamoswine, "leaveField");
game.move.select(playerMove);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase");
expect(piloLeaveSpy).toHaveBeenCalledTimes(1);
expect(mamoLeaveSpy).toHaveBeenCalledTimes(0);
});
it("should only reset summonData/turnData once per switch", async () => {
await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]);
const [piloswine, mamoswine] = game.scene.getPlayerParty();
piloswine.addTag(BattlerTagType.AQUA_RING, 999); // give piloswine a tag to ensure we know if summonData got reset
const piloSummonSpy = vi.spyOn(piloswine, "resetSummonData");
const piloTurnSpy = vi.spyOn(piloswine, "resetTurnData");
const mamoSummonSpy = vi.spyOn(mamoswine, "resetSummonData");
const mamoTurnSpy = vi.spyOn(mamoswine, "resetTurnData");
game.move.select(playerMove);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase");
expect(piloSummonSpy).toHaveBeenCalledTimes(1);
expect(piloTurnSpy).toHaveBeenCalledTimes(1);
expect(mamoSummonSpy).toHaveBeenCalledTimes(1);
expect(mamoTurnSpy).toHaveBeenCalledTimes(1);
expect(piloswine.summonData).toEqual(new PokemonSummonData());
expect(piloswine.turnData).toEqual(new PokemonTurnData());
});
it("should not reset battleData/waveData upon switching", async () => {
await game.classicMode.startBattle([Species.PILOSWINE, Species.MAMOSWINE]);
const [piloswine, mamoswine] = game.scene.getPlayerParty();
const piloWaveSpy = vi.spyOn(piloswine, "resetWaveData");
const piloBattleWaveSpy = vi.spyOn(piloswine, "resetBattleAndWaveData");
const mamoWaveSpy = vi.spyOn(mamoswine, "resetWaveData");
const mamoBattleWaveSpy = vi.spyOn(mamoswine, "resetBattleAndWaveData");
game.move.select(playerMove);
game.doSelectPartyPokemon(1);
await game.phaseInterceptor.to("TurnEndPhase");
expect(piloWaveSpy).toHaveBeenCalledTimes(0);
expect(piloBattleWaveSpy).toHaveBeenCalledTimes(0);
expect(mamoWaveSpy).toHaveBeenCalledTimes(0);
expect(mamoBattleWaveSpy).toHaveBeenCalledTimes(0);
});
}, },
); );