Fixed remaining issues; removed direct assignment to Pokemon.moveset

This commit is contained in:
Bertie690 2025-08-01 11:15:43 -04:00
parent 034c56473c
commit bad73f0ce2
6 changed files with 32 additions and 36 deletions

View File

@ -6,7 +6,6 @@ import { MoveResult } from "#enums/move-result";
import { SpeciesId } from "#enums/species-id";
import { StatusEffect } from "#enums/status-effect";
import { RandomMoveAttr } from "#moves/move";
import { PokemonMove } from "#moves/pokemon-move";
import { GameManager } from "#test/test-utils/game-manager";
import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
@ -40,7 +39,7 @@ describe("Moves - Sketch", () => {
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
const playerPokemon = game.scene.getPlayerPokemon()!;
// can't use normal moveset override because we need to check moveset changes
playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH), new PokemonMove(MoveId.SKETCH)];
game.move.changeMoveset(playerPokemon, [MoveId.SKETCH, MoveId.SKETCH]);
game.move.select(MoveId.SKETCH);
await game.phaseInterceptor.to("TurnEndPhase");
@ -62,7 +61,7 @@ describe("Moves - Sketch", () => {
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
const playerPokemon = game.scene.getPlayerPokemon()!;
const enemyPokemon = game.scene.getEnemyPokemon()!;
playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH), new PokemonMove(MoveId.GROWL)];
game.move.changeMoveset(playerPokemon, [MoveId.SKETCH, MoveId.GROWL]);
game.move.select(MoveId.GROWL);
await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]);
@ -89,7 +88,7 @@ describe("Moves - Sketch", () => {
game.override.enemyMoveset([MoveId.METRONOME]);
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
const playerPokemon = game.scene.getPlayerPokemon()!;
playerPokemon.moveset = [new PokemonMove(MoveId.SKETCH)];
game.move.changeMoveset(playerPokemon, MoveId.SKETCH);
// Opponent uses Metronome -> False Swipe, then player uses Sketch, which should sketch Metronome
game.move.select(MoveId.SKETCH);

View File

@ -7,7 +7,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { SpeciesId } from "#enums/species-id";
import { ShinyRateBoosterModifier } from "#modifiers/modifier";
import { PokemonMove } from "#moves/pokemon-move";
import { AnOfferYouCantRefuseEncounter } from "#mystery-encounters/an-offer-you-cant-refuse-encounter";
import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils";
import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
@ -207,9 +206,8 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
it("should award EXP to a pokemon with a move in EXTORTION_MOVES", async () => {
game.override.ability(AbilityId.SYNCHRONIZE); // Not an extortion ability, so we can test extortion move
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, [SpeciesId.ABRA]);
const party = scene.getPlayerParty();
const abra = party.find(pkm => pkm.species.speciesId === SpeciesId.ABRA)!;
abra.moveset = [new PokemonMove(MoveId.BEAT_UP)];
const abra = game.field.getPlayerPokemon();
game.move.changeMoveset(abra, MoveId.BEAT_UP);
const expBefore = abra.exp;
await runMysteryEncounterToEnd(game, 2);

View File

@ -230,7 +230,7 @@ describe("Clowning Around - Mystery Encounter", () => {
// Stop next battle before it runs
await game.phaseInterceptor.to(NewBattlePhase, false);
const leadPokemon = field.getPlayerPokemon();
const leadPokemon = game.field.getPlayerPokemon();
expect(leadPokemon.customPokemonData?.ability).toBe(abilityToTrain);
});
});
@ -263,30 +263,30 @@ describe("Clowning Around - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
// Set some moves on party for attack type booster generation
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.TACKLE), new PokemonMove(MoveId.THIEF)];
game.move.changeMoveset(game.field.getPlayerPokemon(), [MoveId.TACKLE, MoveId.THIEF]);
// 2 Sitrus Berries on lead
scene.modifiers = [];
let itemType = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS]) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 2, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType);
// 2 Ganlon Berries on lead
itemType = generateModifierType(modifierTypes.BERRY, [BerryType.GANLON]) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 2, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType);
// 5 Golden Punch on lead (ultra)
itemType = generateModifierType(modifierTypes.GOLDEN_PUNCH) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 5, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType);
// 5 Lucky Egg on lead (ultra)
itemType = generateModifierType(modifierTypes.LUCKY_EGG) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 5, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType);
// 3 Soothe Bell on lead (great tier, but counted as ultra by this ME)
itemType = generateModifierType(modifierTypes.SOOTHE_BELL) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 3, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 3, itemType);
// 5 Soul Dew on lead (rogue)
itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 5, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 5, itemType);
// 2 Golden Egg on lead (rogue)
itemType = generateModifierType(modifierTypes.GOLDEN_EGG) as PokemonHeldItemModifierType;
await addItemToPokemon(scene, field.getPlayerPokemon(), 2, itemType);
await addItemToPokemon(scene, game.field.getPlayerPokemon(), 2, itemType);
// 5 Soul Dew on second party pokemon (these should not change)
itemType = generateModifierType(modifierTypes.SOUL_DEW) as PokemonHeldItemModifierType;
@ -294,7 +294,7 @@ describe("Clowning Around - Mystery Encounter", () => {
await runMysteryEncounterToEnd(game, 2);
const leadItemsAfter = field.getPlayerPokemon().getHeldItems();
const leadItemsAfter = game.field.getPlayerPokemon().getHeldItems();
const ultraCountAfter = leadItemsAfter
.filter(m => m.type.tier === ModifierTier.ULTRA)
.reduce((a, b) => a + b.stackCount, 0);
@ -348,14 +348,14 @@ describe("Clowning Around - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.CLOWNING_AROUND, defaultParty);
// Same type moves on lead
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.ICE_BEAM), new PokemonMove(MoveId.SURF)];
game.move.changeMoveset(game.field.getPlayerPokemon(), [MoveId.ICE_BEAM, MoveId.SURF]);
// Different type moves on second
scene.getPlayerParty()[1].moveset = [new PokemonMove(MoveId.GRASS_KNOT), new PokemonMove(MoveId.ELECTRO_BALL)];
game.move.changeMoveset(scene.getPlayerParty()[1], [MoveId.GRASS_KNOT, MoveId.ELECTRO_BALL]);
// No moves on third
scene.getPlayerParty()[2].moveset = [];
await runMysteryEncounterToEnd(game, 3);
const leadTypesAfter = field.getPlayerPokemon().getTypes();
const leadTypesAfter = game.field.getPlayerPokemon().getTypes();
const secondaryTypesAfter = scene.getPlayerParty()[1].getTypes();
const thirdTypesAfter = scene.getPlayerParty()[2].getTypes();

View File

@ -6,7 +6,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode";
import { PokemonMove } from "#moves/pokemon-move";
import { DancingLessonsEncounter } from "#mystery-encounters/dancing-lessons-encounter";
import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils";
import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
@ -100,7 +99,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
// Make party lead's level arbitrarily high to not get KOed by move
const partyLead = field.getPlayerPokemon();
const partyLead = game.field.getPlayerPokemon();
partyLead.level = 1000;
partyLead.calculateStats();
await runMysteryEncounterToEnd(game, 1, undefined, true);
@ -121,7 +120,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
it("should have a Baton in the rewards after battle", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
// Make party lead's level arbitrarily high to not get KOed by move
const partyLead = field.getPlayerPokemon();
const partyLead = game.field.getPlayerPokemon();
partyLead.level = 1000;
partyLead.calculateStats();
await runMysteryEncounterToEnd(game, 1, undefined, true);
@ -159,7 +158,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
const phaseSpy = vi.spyOn(scene.phaseManager, "unshiftPhase");
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
field.getPlayerPokemon().moveset = [];
game.field.getPlayerPokemon().moveset = [];
await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1 });
const movePhases = phaseSpy.mock.calls.filter(p => p[0] instanceof LearnMovePhase).map(p => p[0]);
@ -171,7 +170,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
field.getPlayerPokemon().moveset = [];
game.field.getPlayerPokemon().moveset = [];
await runMysteryEncounterToEnd(game, 2, { pokemonNo: 1 });
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
@ -199,7 +198,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
it("should add Oricorio to the party", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
const partyCountBefore = scene.getPlayerParty().length;
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.DRAGON_DANCE)];
game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.DRAGON_DANCE);
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
const partyCountAfter = scene.getPlayerParty().length;
@ -238,7 +237,7 @@ describe("Dancing Lessons - Mystery Encounter", () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(MysteryEncounterType.DANCING_LESSONS, defaultParty);
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.DRAGON_DANCE)];
game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.DRAGON_DANCE);
await runMysteryEncounterToEnd(game, 3, { pokemonNo: 1, optionNo: 1 });
expect(leaveEncounterWithoutBattleSpy).toBeCalled();

View File

@ -6,7 +6,6 @@ import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { SpeciesId } from "#enums/species-id";
import { UiMode } from "#enums/ui-mode";
import { PokemonMove } from "#moves/pokemon-move";
import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils";
import { FightOrFlightEncounter } from "#mystery-encounters/fight-or-flight-encounter";
import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
@ -178,7 +177,7 @@ describe("Fight or Flight - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.FIGHT_OR_FLIGHT, defaultParty);
// Mock moveset
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.KNOCK_OFF)];
game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.KNOCK_OFF);
const item = game.scene.currentBattle.mysteryEncounter!.misc;
await runMysteryEncounterToEnd(game, 2);

View File

@ -5,7 +5,6 @@ import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode
import { MysteryEncounterTier } from "#enums/mystery-encounter-tier";
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
import { SpeciesId } from "#enums/species-id";
import { PokemonMove } from "#moves/pokemon-move";
import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils";
import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
import { CIVILIZATION_ENCOUNTER_BIOMES } from "#mystery-encounters/mystery-encounters";
@ -110,7 +109,7 @@ describe("Part-Timer - Mystery Encounter", () => {
expect(EncounterPhaseUtils.updatePlayerMoney).toHaveBeenCalledWith(scene.getWaveMoneyAmount(1), true, false);
// Expect PP of mon's moves to have been reduced to 2
const moves = field.getPlayerPokemon().moveset;
const moves = game.field.getPlayerPokemon().moveset;
for (const move of moves) {
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
}
@ -233,7 +232,9 @@ describe("Part-Timer - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.PART_TIMER, defaultParty);
// Mock movesets
scene.getPlayerParty().forEach(p => (p.moveset = []));
scene.getPlayerParty().forEach(p => {
p.moveset = [];
});
await game.phaseInterceptor.to(MysteryEncounterPhase, false);
const encounterPhase = scene.phaseManager.getCurrentPhase();
@ -257,14 +258,14 @@ describe("Part-Timer - Mystery Encounter", () => {
await game.runToMysteryEncounter(MysteryEncounterType.PART_TIMER, defaultParty);
// Mock moveset
field.getPlayerPokemon().moveset = [new PokemonMove(MoveId.ATTRACT)];
game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.ATTRACT);
await runMysteryEncounterToEnd(game, 3);
expect(EncounterPhaseUtils.updatePlayerMoney).toHaveBeenCalledWith(scene.getWaveMoneyAmount(2.5), true, false);
// Expect PP of mon's moves to have been reduced to 2
const moves = field.getPlayerPokemon().moveset;
const moves = game.field.getPlayerPokemon().moveset;
for (const move of moves) {
expect((move?.getMovePp() ?? 0) - (move?.ppUsed ?? 0)).toBe(2);
expect(move.getMovePp() - move.ppUsed).toBe(2);
}
});