mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-09-23 23:13:42 +02:00
* Remove NCPQ * Implement PendingHealTag * Fix test * Code review * Use message directly instead of as key in tag * Update tag for serialization * Update test import * Update src/data/arena-tag.ts Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> * Remove isNullOrUndefined uses * Fix arena tag type(o) * Fix pendinghealtag * Fix hwish tests * Arena tag denesting --------- Co-authored-by: Bertie690 <136088738+Bertie690@users.noreply.github.com> Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com>
246 lines
8.3 KiB
TypeScript
246 lines
8.3 KiB
TypeScript
import { AbilityId } from "#enums/ability-id";
|
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
|
import { Challenges } from "#enums/challenges";
|
|
import { MoveId } from "#enums/move-id";
|
|
import { MoveResult } from "#enums/move-result";
|
|
import { PokemonType } from "#enums/pokemon-type";
|
|
import { SpeciesId } from "#enums/species-id";
|
|
import { StatusEffect } from "#enums/status-effect";
|
|
import { GameManager } from "#test/test-utils/game-manager";
|
|
import Phaser from "phaser";
|
|
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
|
|
describe("Moves - Lunar Dance and Healing Wish", () => {
|
|
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.battleStyle("double").enemyAbility(AbilityId.BALL_FETCH).enemyMoveset(MoveId.SPLASH);
|
|
});
|
|
|
|
describe.each([
|
|
{ moveName: "Healing Wish", moveId: MoveId.HEALING_WISH },
|
|
{ moveName: "Lunar Dance", moveId: MoveId.LUNAR_DANCE },
|
|
])("$moveName", ({ moveId }) => {
|
|
it("should sacrifice the user to restore the switched in Pokemon's HP", async () => {
|
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER, SpeciesId.SQUIRTLE]);
|
|
|
|
const [bulbasaur, charmander, squirtle] = game.scene.getPlayerParty();
|
|
squirtle.hp = 1;
|
|
|
|
game.move.use(MoveId.SPLASH, 0);
|
|
game.move.use(moveId, 1);
|
|
game.doSelectPartyPokemon(2);
|
|
|
|
await game.toNextTurn();
|
|
|
|
expect(bulbasaur.isFullHp()).toBe(true);
|
|
expect(charmander.isFainted()).toBe(true);
|
|
expect(squirtle.isFullHp()).toBe(true);
|
|
});
|
|
|
|
it("should sacrifice the user to cure the switched in Pokemon's status", async () => {
|
|
game.override.statusEffect(StatusEffect.BURN);
|
|
|
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER, SpeciesId.SQUIRTLE]);
|
|
const [bulbasaur, charmander, squirtle] = game.scene.getPlayerParty();
|
|
|
|
game.move.use(MoveId.SPLASH, 0);
|
|
game.move.use(moveId, 1);
|
|
game.doSelectPartyPokemon(2);
|
|
|
|
await game.toNextTurn();
|
|
|
|
expect(bulbasaur.status?.effect).toBe(StatusEffect.BURN);
|
|
expect(charmander.isFainted()).toBe(true);
|
|
expect(squirtle.status?.effect).toBeUndefined();
|
|
});
|
|
|
|
it("should fail if the user has no non-fainted allies in their party", async () => {
|
|
game.override.battleStyle("single");
|
|
|
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]);
|
|
const [bulbasaur, charmander] = game.scene.getPlayerParty();
|
|
|
|
game.move.use(MoveId.MEMENTO);
|
|
game.doSelectPartyPokemon(1);
|
|
|
|
await game.toNextTurn();
|
|
|
|
expect(bulbasaur.isFainted()).toBe(true);
|
|
expect(charmander.isActive(true)).toBe(true);
|
|
|
|
game.move.use(moveId);
|
|
|
|
await game.toEndOfTurn();
|
|
|
|
expect(charmander.isFullHp());
|
|
expect(charmander.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
|
});
|
|
|
|
it("should fail if the user has no challenge-eligible allies", async () => {
|
|
game.override.battleStyle("single");
|
|
// Mono normal challenge
|
|
game.challengeMode.addChallenge(Challenges.SINGLE_TYPE, PokemonType.NORMAL + 1, 0);
|
|
await game.challengeMode.startBattle([SpeciesId.RATICATE, SpeciesId.ODDISH]);
|
|
|
|
const raticate = game.field.getPlayerPokemon();
|
|
|
|
game.move.use(moveId);
|
|
await game.toNextTurn();
|
|
|
|
expect(raticate.isFullHp()).toBe(true);
|
|
expect(raticate.getLastXMoves()[0].result).toEqual(MoveResult.FAIL);
|
|
});
|
|
|
|
it("should store its effect if the switched-in Pokemon would be unaffected", async () => {
|
|
game.override.battleStyle("single");
|
|
|
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER, SpeciesId.SQUIRTLE]);
|
|
|
|
const [bulbasaur, charmander, squirtle] = game.scene.getPlayerParty();
|
|
squirtle.hp = 1;
|
|
|
|
game.move.use(moveId);
|
|
game.doSelectPartyPokemon(1);
|
|
|
|
await game.toNextTurn();
|
|
|
|
// Bulbasaur fainted and stored a healing effect
|
|
expect(bulbasaur.isFainted()).toBe(true);
|
|
expect(charmander.isFullHp()).toBe(true);
|
|
expect(game.phaseInterceptor.log).not.toContain("PokemonHealPhase");
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeDefined();
|
|
|
|
// Switch to damaged Squirtle. HW/LD's effect should activate
|
|
game.doSwitchPokemon(2);
|
|
|
|
await game.toEndOfTurn();
|
|
expect(squirtle.isFullHp()).toBe(true);
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeUndefined();
|
|
|
|
// Set Charmander's HP to 1, then switch back to Charmander.
|
|
// HW/LD shouldn't activate again
|
|
charmander.hp = 1;
|
|
game.doSwitchPokemon(2);
|
|
|
|
await game.toEndOfTurn();
|
|
expect(charmander.hp).toBe(1);
|
|
});
|
|
|
|
it("should only store one charge of the effect at a time", async () => {
|
|
game.override.battleStyle("single");
|
|
|
|
await game.classicMode.startBattle([
|
|
SpeciesId.BULBASAUR,
|
|
SpeciesId.CHARMANDER,
|
|
SpeciesId.SQUIRTLE,
|
|
SpeciesId.PIKACHU,
|
|
]);
|
|
|
|
const [bulbasaur, charmander, squirtle, pikachu] = game.scene.getPlayerParty();
|
|
[squirtle, pikachu].forEach(p => (p.hp = 1));
|
|
|
|
// Use HW/LD and send in Charmander. HW/LD's effect should be stored
|
|
game.move.use(moveId);
|
|
game.doSelectPartyPokemon(1);
|
|
|
|
await game.toNextTurn();
|
|
expect(bulbasaur.isFainted()).toBe(true);
|
|
expect(charmander.isFullHp()).toBe(true);
|
|
expect(charmander.isFullHp());
|
|
expect(game.phaseInterceptor.log).not.toContain("PokemonHealPhase");
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeDefined();
|
|
|
|
// Use HW/LD again, sending in Squirtle. HW/LD should activate and heal Squirtle
|
|
game.move.use(moveId);
|
|
game.doSelectPartyPokemon(2);
|
|
|
|
await game.toNextTurn();
|
|
expect(charmander.isFainted()).toBe(true);
|
|
expect(squirtle.isFullHp()).toBe(true);
|
|
expect(squirtle.isFullHp());
|
|
|
|
// Switch again to Pikachu. HW/LD's effect shouldn't be present
|
|
game.doSwitchPokemon(3);
|
|
|
|
expect(pikachu.isFullHp()).toBe(false);
|
|
});
|
|
});
|
|
|
|
it("Lunar Dance should sacrifice the user to restore the switched in Pokemon's PP", async () => {
|
|
game.override.battleStyle("single");
|
|
|
|
await game.classicMode.startBattle([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]);
|
|
|
|
const [bulbasaur, charmander] = game.scene.getPlayerParty();
|
|
|
|
game.move.use(MoveId.SPLASH);
|
|
await game.toNextTurn();
|
|
|
|
game.doSwitchPokemon(1);
|
|
await game.toNextTurn();
|
|
|
|
game.move.use(MoveId.LUNAR_DANCE);
|
|
game.doSelectPartyPokemon(1);
|
|
|
|
await game.toNextTurn();
|
|
expect(charmander.isFainted()).toBeTruthy();
|
|
bulbasaur.getMoveset().forEach(mv => expect(mv.ppUsed).toBe(0));
|
|
});
|
|
|
|
it("should stack with each other", async () => {
|
|
game.override.battleStyle("single");
|
|
|
|
await game.classicMode.startBattle([
|
|
SpeciesId.BULBASAUR,
|
|
SpeciesId.CHARMANDER,
|
|
SpeciesId.SQUIRTLE,
|
|
SpeciesId.PIKACHU,
|
|
]);
|
|
|
|
const [bulbasaur, charmander, squirtle, pikachu] = game.scene.getPlayerParty();
|
|
[squirtle, pikachu].forEach(p => {
|
|
p.hp = 1;
|
|
p.getMoveset().forEach(mv => (mv.ppUsed = 1));
|
|
});
|
|
|
|
game.move.use(MoveId.LUNAR_DANCE);
|
|
game.doSelectPartyPokemon(1);
|
|
|
|
await game.toNextTurn();
|
|
expect(bulbasaur.isFainted()).toBe(true);
|
|
expect(charmander.isFullHp()).toBe(true);
|
|
expect(game.phaseInterceptor.log).not.toContain("PokemonHealPhase");
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeDefined();
|
|
|
|
game.move.use(MoveId.HEALING_WISH);
|
|
game.doSelectPartyPokemon(2);
|
|
|
|
// Lunar Dance should apply first since it was used first, restoring Squirtle's HP and PP
|
|
await game.toNextTurn();
|
|
expect(squirtle.isFullHp()).toBe(true);
|
|
squirtle.getMoveset().forEach(mv => expect(mv.ppUsed).toBe(0));
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeDefined();
|
|
|
|
game.doSwitchPokemon(3);
|
|
|
|
// Healing Wish should apply on the next switch, restoring Pikachu's HP
|
|
await game.toEndOfTurn();
|
|
expect(pikachu.isFullHp()).toBe(true);
|
|
pikachu.getMoveset().forEach(mv => expect(mv.ppUsed).toBe(1));
|
|
expect(game.scene.arena.getTag(ArenaTagType.PENDING_HEAL)).toBeUndefined();
|
|
});
|
|
});
|