[Test] Tests now default to using "Set" battle style (#3728)

* Tests now default to using "Set" battle style

* Fix typo
This commit is contained in:
NightKev 2024-09-01 20:32:31 -07:00 committed by GitHub
parent 56b39032b9
commit 1fd662111e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 173 additions and 290 deletions

View File

@ -1,13 +1,11 @@
import { BattleStyle } from "#app/enums/battle-style";
import { CommandPhase } from "#app/phases/command-phase"; import { CommandPhase } from "#app/phases/command-phase";
import { MessagePhase } from "#app/phases/message-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
import i18next, { initI18n } from "#app/plugins/i18n"; import i18next, { initI18n } from "#app/plugins/i18n";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { SPLASH_ONLY } from "#test/utils/testUtils";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@ -28,19 +26,18 @@ describe("Ability Timing", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override.battleType("single");
game.override.enemySpecies(Species.PIDGEY); game.override
game.override.enemyAbility(Abilities.INTIMIDATE); .battleType("single")
game.override.enemyMoveset(SPLASH_ONLY); .enemySpecies(Species.MAGIKARP)
.enemyAbility(Abilities.INTIMIDATE)
game.override.ability(Abilities.BALL_FETCH); .ability(Abilities.BALL_FETCH);
game.override.moveset([Moves.SPLASH, Moves.ICE_BEAM]);
}); });
it("should trigger after switch check", async() => { it("should trigger after switch check", async () => {
initI18n(); initI18n();
i18next.changeLanguage("en"); i18next.changeLanguage("en");
game.settings.battleStyle = BattleStyle.SWITCH;
await game.classicMode.runToSummon([Species.EEVEE, Species.FEEBAS]); await game.classicMode.runToSummon([Species.EEVEE, Species.FEEBAS]);
game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
@ -48,7 +45,7 @@ describe("Ability Timing", () => {
game.endPhase(); game.endPhase();
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)); }, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
await game.phaseInterceptor.to(MessagePhase); await game.phaseInterceptor.to("MessagePhase");
const message = game.textInterceptor.getLatestMessage(); const message = game.textInterceptor.getLatestMessage();
expect(message).toContain("Attack fell"); expect(message).toContain("Attack fell");
}, 5000); }, 5000);

View File

@ -1,11 +1,5 @@
import { BattleStat } from "#app/data/battle-stat"; import { BattleStat } from "#app/data/battle-stat";
import { StatusEffect } from "#app/data/status-effect"; import { StatusEffect } from "#app/data/status-effect";
import { CommandPhase } from "#app/phases/command-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MoveEndPhase } from "#app/phases/move-end-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { Mode } from "#app/ui/ui";
import { toDmgValue } from "#app/utils"; import { toDmgValue } from "#app/utils";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
@ -33,13 +27,12 @@ describe("Abilities - Disguise", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override.battleType("single"); game.override
.battleType("single")
game.override.enemySpecies(Species.MIMIKYU); .enemySpecies(Species.MIMIKYU)
game.override.enemyMoveset(SPLASH_ONLY); .enemyMoveset(SPLASH_ONLY)
.starterSpecies(Species.REGIELEKI)
game.override.starterSpecies(Species.REGIELEKI); .moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
game.override.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
}, TIMEOUT); }, TIMEOUT);
it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => { it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => {
@ -53,7 +46,7 @@ describe("Abilities - Disguise", () => {
game.move.select(Moves.SHADOW_SNEAK); game.move.select(Moves.SHADOW_SNEAK);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
expect(mimikyu.hp).equals(maxHp - disguiseDamage); expect(mimikyu.hp).equals(maxHp - disguiseDamage);
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
@ -68,7 +61,7 @@ describe("Abilities - Disguise", () => {
game.move.select(Moves.VACUUM_WAVE); game.move.select(Moves.VACUUM_WAVE);
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to("MoveEndPhase");
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
}, TIMEOUT); }, TIMEOUT);
@ -87,12 +80,12 @@ describe("Abilities - Disguise", () => {
game.move.select(Moves.SURGING_STRIKES); game.move.select(Moves.SURGING_STRIKES);
// First hit // First hit
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to("MoveEffectPhase");
expect(mimikyu.hp).equals(maxHp - disguiseDamage); expect(mimikyu.hp).equals(maxHp - disguiseDamage);
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
// Second hit // Second hit
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to("MoveEffectPhase");
expect(mimikyu.hp).lessThan(maxHp - disguiseDamage); expect(mimikyu.hp).lessThan(maxHp - disguiseDamage);
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); }, TIMEOUT);
@ -105,7 +98,7 @@ describe("Abilities - Disguise", () => {
game.move.select(Moves.TOXIC_THREAD); game.move.select(Moves.TOXIC_THREAD);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
expect(mimikyu.status?.effect).toBe(StatusEffect.POISON); expect(mimikyu.status?.effect).toBe(StatusEffect.POISON);
@ -125,7 +118,7 @@ describe("Abilities - Disguise", () => {
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
expect(mimikyu.hp).equals(maxHp - disguiseDamage); expect(mimikyu.hp).equals(maxHp - disguiseDamage);
@ -133,7 +126,7 @@ describe("Abilities - Disguise", () => {
await game.toNextTurn(); await game.toNextTurn();
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to("TurnEndPhase");
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); }, TIMEOUT);
@ -194,15 +187,6 @@ describe("Abilities - Disguise", () => {
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.doKillOpponents(); await game.doKillOpponents();
game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => { // TODO: Make tests run in set mode instead of switch mode
game.setMode(Mode.MESSAGE);
game.endPhase();
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
game.onNextPrompt("CheckSwitchPhase", Mode.CONFIRM, () => {
game.setMode(Mode.MESSAGE);
game.endPhase();
}, () => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase));
await game.phaseInterceptor.to("PartyHealPhase"); await game.phaseInterceptor.to("PartyHealPhase");
expect(mimikyu1.formIndex).toBe(disguisedForm); expect(mimikyu1.formIndex).toBe(disguisedForm);

View File

@ -1,12 +1,8 @@
import { BattleStat } from "#app/data/battle-stat"; import { BattleStat } from "#app/data/battle-stat";
import { Status, StatusEffect } from "#app/data/status-effect"; import { Status, StatusEffect } from "#app/data/status-effect";
import { GameModes, getGameMode } from "#app/game-mode"; import { GameModes, getGameMode } from "#app/game-mode";
import { CommandPhase } from "#app/phases/command-phase";
import { DamagePhase } from "#app/phases/damage-phase";
import { EncounterPhase } from "#app/phases/encounter-phase"; import { EncounterPhase } from "#app/phases/encounter-phase";
import { EnemyCommandPhase } from "#app/phases/enemy-command-phase";
import { SelectStarterPhase } from "#app/phases/select-starter-phase"; import { SelectStarterPhase } from "#app/phases/select-starter-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
@ -33,36 +29,26 @@ describe("Abilities - Intimidate", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override.battleType("single"); game.override
game.override.enemySpecies(Species.RATTATA); .battleType("single")
game.override.enemyAbility(Abilities.INTIMIDATE); .enemySpecies(Species.MAGIKARP)
game.override.enemyPassiveAbility(Abilities.HYDRATION); .enemyAbility(Abilities.INTIMIDATE)
game.override.ability(Abilities.INTIMIDATE); .ability(Abilities.INTIMIDATE)
game.override.startingWave(3); .moveset([Moves.SPLASH, Moves.AERIAL_ACE])
game.override.enemyMoveset(SPLASH_ONLY); .enemyMoveset(SPLASH_ONLY);
}); });
it("single - wild with switch", async () => { it("single - wild with switch", async () => {
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
game.onNextPrompt(
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.MIGHTYENA);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.run(CommandPhase); await game.phaseInterceptor.to("CommandPhase");
await game.phaseInterceptor.to(CommandPhase);
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.POOCHYENA);
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(0); expect(battleStatsPokemon[BattleStat.ATK]).toBe(0);
@ -73,25 +59,16 @@ describe("Abilities - Intimidate", () => {
it("single - boss should only trigger once then switch", async () => { it("single - boss should only trigger once then switch", async () => {
game.override.startingWave(10); game.override.startingWave(10);
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
game.onNextPrompt(
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.run(CommandPhase); await game.phaseInterceptor.to("CommandPhase");
await game.phaseInterceptor.to(CommandPhase);
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.POOCHYENA);
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(0); expect(battleStatsPokemon[BattleStat.ATK]).toBe(0);
@ -102,25 +79,16 @@ describe("Abilities - Intimidate", () => {
it("single - trainer should only trigger once with switch", async () => { it("single - trainer should only trigger once with switch", async () => {
game.override.startingWave(5); game.override.startingWave(5);
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
game.onNextPrompt(
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.run(CommandPhase); await game.phaseInterceptor.to("CommandPhase");
await game.phaseInterceptor.to(CommandPhase);
expect(game.scene.getParty()[0].species.speciesId).toBe(Species.POOCHYENA);
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(0); expect(battleStatsPokemon[BattleStat.ATK]).toBe(0);
@ -130,21 +98,14 @@ describe("Abilities - Intimidate", () => {
}, 200000); }, 200000);
it("double - trainer should only trigger once per pokemon", async () => { it("double - trainer should only trigger once per pokemon", async () => {
game.override.battleType("double"); game.override
game.override.startingWave(5); .battleType("double")
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); .startingWave(5);
game.onNextPrompt( await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2);
const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats; const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats;
expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2);
@ -157,20 +118,11 @@ describe("Abilities - Intimidate", () => {
it("double - wild: should only trigger once per pokemon", async () => { it("double - wild: should only trigger once per pokemon", async () => {
game.override.battleType("double"); game.override.battleType("double");
game.override.startingWave(3); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]);
game.onNextPrompt(
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2);
const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats; const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats;
expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2);
@ -182,21 +134,14 @@ describe("Abilities - Intimidate", () => {
}, 20000); }, 20000);
it("double - boss: should only trigger once per pokemon", async () => { it("double - boss: should only trigger once per pokemon", async () => {
game.override.battleType("double"); game.override
game.override.startingWave(10); .battleType("double")
await game.classicMode.runToSummon([Species.MIGHTYENA, Species.POOCHYENA]); .startingWave(10);
game.onNextPrompt( await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
"CheckSwitchPhase",
Mode.CONFIRM,
() => {
game.setMode(Mode.MESSAGE);
game.endPhase();
},
() => game.isCurrentPhase(CommandPhase) || game.isCurrentPhase(TurnInitPhase)
);
await game.phaseInterceptor.to(CommandPhase, false);
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-2);
const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats; const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats;
expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2); expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-2);
@ -208,104 +153,101 @@ describe("Abilities - Intimidate", () => {
}, 20000); }, 20000);
it("single - wild next wave opp triger once, us: none", async () => { it("single - wild next wave opp triger once, us: none", async () => {
game.override.startingWave(2); await game.startBattle([Species.MIGHTYENA]);
game.override.moveset([Moves.AERIAL_ACE]);
await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.move.select(Moves.AERIAL_ACE); game.move.select(Moves.AERIAL_ACE);
await game.phaseInterceptor.runFrom(EnemyCommandPhase).to(DamagePhase); await game.phaseInterceptor.to("DamagePhase");
await game.killPokemon(game.scene.currentBattle.enemyParty[0]); await game.doKillOpponents();
expect(game.scene.currentBattle.enemyParty[0].isFainted()).toBe(true);
await game.toNextWave(); await game.toNextWave();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-2); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-2);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(0); expect(battleStatsOpponent[BattleStat.ATK]).toBe(0);
}, 20000); }, 20000);
it("single - wild next turn - no retrigger on next turn", async () => { it("single - wild next turn - no retrigger on next turn", async () => {
game.override.startingWave(2); await game.startBattle([Species.MIGHTYENA]);
game.override.moveset([Moves.SPLASH]);
await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.move.select(Moves.AERIAL_ACE); game.move.select(Moves.SPLASH);
console.log("===to new turn===");
await game.toNextTurn(); await game.toNextTurn();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
}, 20000); }, 20000);
it("single - trainer should only trigger once and each time he switch", async () => { it("single - trainer should only trigger once and each time he switch", async () => {
game.override.moveset([Moves.SPLASH]); game.override
game.override.enemyMoveset([Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH, Moves.VOLT_SWITCH]); .enemyMoveset(Array(4).fill(Moves.VOLT_SWITCH))
game.override.startingWave(5); .startingWave(5);
await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); await game.startBattle([Species.MIGHTYENA]);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.move.select(Moves.AERIAL_ACE); game.move.select(Moves.SPLASH);
console.log("===to new turn===");
await game.toNextTurn(); await game.toNextTurn();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-2); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-2);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(0); expect(battleStatsOpponent[BattleStat.ATK]).toBe(0);
game.move.select(Moves.AERIAL_ACE); game.move.select(Moves.SPLASH);
console.log("===to new turn===");
await game.toNextTurn(); await game.toNextTurn();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats; battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-3); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-3);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(0); expect(battleStatsOpponent[BattleStat.ATK]).toBe(0);
}, 200000); }, 200000);
it("single - trainer should only trigger once whatever turn we are", async () => { it("single - trainer should only trigger once whatever turn we are", async () => {
game.override.moveset([Moves.SPLASH]);
game.override.enemyMoveset(SPLASH_ONLY);
game.override.startingWave(5); game.override.startingWave(5);
await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]); await game.startBattle([Species.MIGHTYENA]);
let battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
const battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
let battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
game.move.select(Moves.AERIAL_ACE); game.move.select(Moves.SPLASH);
console.log("===to new turn===");
await game.toNextTurn(); await game.toNextTurn();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
game.move.select(Moves.AERIAL_ACE);
console.log("===to new turn===");
await game.toNextTurn();
battleStatsPokemon = game.scene.getParty()[0].summonData.battleStats;
expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1); expect(battleStatsPokemon[BattleStat.ATK]).toBe(-1);
battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
}, 20000); }, 20000);
it("double - wild vs only 1 on player side", async () => { it("double - wild vs only 1 on player side", async () => {
game.override.battleType("double"); game.override.battleType("double");
game.override.startingWave(3);
await game.classicMode.runToSummon([Species.MIGHTYENA]); await game.classicMode.runToSummon([Species.MIGHTYENA]);
await game.phaseInterceptor.to(CommandPhase, false); await game.phaseInterceptor.to("CommandPhase", false);
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats; const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats;
expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-1);
@ -315,7 +257,6 @@ describe("Abilities - Intimidate", () => {
it("double - wild vs only 1 alive on player side", async () => { it("double - wild vs only 1 alive on player side", async () => {
game.override.battleType("double"); game.override.battleType("double");
game.override.startingWave(3);
await game.runToTitle(); await game.runToTitle();
game.onNextPrompt("TitlePhase", Mode.TITLE, () => { game.onNextPrompt("TitlePhase", Mode.TITLE, () => {
@ -330,9 +271,11 @@ describe("Abilities - Intimidate", () => {
await game.phaseInterceptor.run(EncounterPhase); await game.phaseInterceptor.run(EncounterPhase);
await game.phaseInterceptor.to(CommandPhase, false); await game.phaseInterceptor.to("CommandPhase", false);
const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats; const battleStatsOpponent = game.scene.currentBattle.enemyParty[0].summonData.battleStats;
expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent[BattleStat.ATK]).toBe(-1);
const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats; const battleStatsOpponent2 = game.scene.currentBattle.enemyParty[1].summonData.battleStats;
expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-1); expect(battleStatsOpponent2[BattleStat.ATK]).toBe(-1);

View File

@ -2,9 +2,10 @@ import { pokemonEvolutions, SpeciesFormEvolution, SpeciesWildEvolutionDelay } fr
import { Abilities } from "#app/enums/abilities"; import { Abilities } from "#app/enums/abilities";
import { Moves } from "#app/enums/moves"; import { Moves } from "#app/enums/moves";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species";
import * as Utils from "#app/utils";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { SPLASH_ONLY } from "./utils/testUtils"; import { SPLASH_ONLY } from "./utils/testUtils";
describe("Evolution", () => { describe("Evolution", () => {
@ -148,4 +149,28 @@ describe("Evolution", () => {
expect(cyndaquil.hp).toBeGreaterThan(hpBefore); expect(cyndaquil.hp).toBeGreaterThan(hpBefore);
expect(cyndaquil.hp).toBeLessThan(cyndaquil.getMaxHp()); expect(cyndaquil.hp).toBeLessThan(cyndaquil.getMaxHp());
}, TIMEOUT); }, TIMEOUT);
it("should handle rng-based split evolution", async () => {
/* this test checks to make sure that tandemaus will
* evolve into a 3 family maushold 25% of the time
* and a 4 family maushold the other 75% of the time
* This is done by using the getEvolution method in pokemon.ts
* getEvolution will give back the form that the pokemon can evolve into
* It does this by checking the pokemon conditions in pokemon-forms.ts
* For tandemaus, the conditions are random due to a randSeedInt(4)
* If the value is 0, it's a 3 family maushold, whereas if the value is
* 1, 2 or 3, it's a 4 family maushold
*/
await game.startBattle([Species.TANDEMAUS]); // starts us off with a tandemaus
const playerPokemon = game.scene.getPlayerPokemon()!;
playerPokemon.level = 25; // tandemaus evolves at level 25
vi.spyOn(Utils, "randSeedInt").mockReturnValue(0); // setting the random generator to be 0 to force a three family maushold
const threeForm = playerPokemon.getEvolution()!;
expect(threeForm.evoFormKey).toBe("three"); // as per pokemon-forms, the evoFormKey for 3 family mausholds is "three"
for (let f = 1; f < 4; f++) {
vi.spyOn(Utils, "randSeedInt").mockReturnValue(f); // setting the random generator to 1, 2 and 3 to force 4 family mausholds
const fourForm = playerPokemon.getEvolution()!;
expect(fourForm.evoFormKey).toBe(null); // meanwhile, according to the pokemon-forms, the evoFormKey for a 4 family maushold is null
}
}, TIMEOUT);
}); });

View File

@ -1,48 +0,0 @@
import * as Utils from "#app/utils";
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("Evolution tests", () => {
let phaserGame: Phaser.Game;
let game: GameManager;
beforeAll(() => {
phaserGame = new Phaser.Game({
type: Phaser.HEADLESS,
});
});
afterEach(() => {
game.phaseInterceptor.restoreOg();
});
beforeEach(() => {
game = new GameManager(phaserGame);
});
it("tandemaus evolution form test", async () => {
/* this test checks to make sure that tandemaus will
* evolve into a 3 family maushold 25% of the time
* and a 4 family maushold the other 75% of the time
* This is done by using the getEvolution method in pokemon.ts
* getEvolution will give back the form that the pokemon can evolve into
* It does this by checking the pokemon conditions in pokemon-forms.ts
* For tandemaus, the conditions are random due to a randSeedInt(4)
* If the value is 0, it's a 3 family maushold, whereas if the value is
* 1, 2 or 3, it's a 4 family maushold
*/
await game.startBattle([Species.TANDEMAUS]); // starts us off with a tandemaus
const playerPokemon = game.scene.getPlayerPokemon()!;
playerPokemon.level = 25; // tandemaus evolves at level 25
vi.spyOn(Utils, "randSeedInt").mockReturnValue(0); // setting the random generator to be 0 to force a three family maushold
const threeForm = playerPokemon.getEvolution()!;
expect(threeForm.evoFormKey).toBe("three"); // as per pokemon-forms, the evoFormKey for 3 family mausholds is "three"
for (let f = 1; f < 4; f++) {
vi.spyOn(Utils, "randSeedInt").mockReturnValue(f); // setting the random generator to 1, 2 and 3 to force 4 family mausholds
const fourForm = playerPokemon.getEvolution()!;
expect(fourForm.evoFormKey).toBe(null); // meanwhile, according to the pokemon-forms, the evoFormKey for a 4 family maushold is null
}
}, 5000);
});

View File

@ -30,7 +30,7 @@ describe("Test misc", () => {
return response.json(); return response.json();
}).then(data => { }).then(data => {
spy(); // Call the spy function spy(); // Call the spy function
expect(data).toEqual({"username":"greenlamp", "lastSessionSlot":0}); expect(data).toEqual({ "username": "greenlamp", "lastSessionSlot": 0 });
}); });
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
@ -43,7 +43,7 @@ describe("Test misc", () => {
return response.json(); return response.json();
}).then(data => { }).then(data => {
spy(); // Call the spy function spy(); // Call the spy function
expect(data).toEqual({"username":"greenlamp", "lastSessionSlot":0}); expect(data).toEqual({ "username": "greenlamp", "lastSessionSlot": 0 });
}); });
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
@ -54,7 +54,7 @@ describe("Test misc", () => {
expect(response.ok).toBe(true); expect(response.ok).toBe(true);
expect(response.status).toBe(200); expect(response.status).toBe(200);
expect(data).toEqual({"username":"greenlamp", "lastSessionSlot":0}); expect(data).toEqual({ "username": "greenlamp", "lastSessionSlot": 0 });
}); });
it("test apifetch mock sync", async () => { it("test apifetch mock sync", async () => {

View File

@ -1,10 +1,10 @@
import { CommandPhase } from "#app/phases/command-phase";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { SPLASH_ONLY } from "../utils/testUtils";
describe("Moves - Spikes", () => { describe("Moves - Spikes", () => {
@ -23,93 +23,61 @@ describe("Moves - Spikes", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.scene.battleStyle = 1; game.override
game.override.battleType("single"); .battleType("single")
game.override.enemySpecies(Species.RATTATA); .enemySpecies(Species.MAGIKARP)
game.override.enemyAbility(Abilities.HYDRATION); .enemyAbility(Abilities.BALL_FETCH)
game.override.enemyPassiveAbility(Abilities.HYDRATION); .ability(Abilities.BALL_FETCH)
game.override.ability(Abilities.HYDRATION); .enemyMoveset(SPLASH_ONLY)
game.override.passiveAbility(Abilities.HYDRATION); .moveset([Moves.SPIKES, Moves.SPLASH, Moves.ROAR]);
game.override.startingWave(3);
game.override.enemyMoveset([Moves.SPLASH, Moves.SPLASH, Moves.SPLASH, Moves.SPLASH]);
game.override.moveset([Moves.SPIKES, Moves.SPLASH, Moves.ROAR]);
}); });
it("single - wild - stay on field - no damage", async () => { it("should not damage the team that set them", async () => {
await game.classicMode.runToSummon([ await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
Species.MIGHTYENA,
Species.POOCHYENA,
]);
await game.phaseInterceptor.to(CommandPhase, true);
const initialHp = game.scene.getParty()[0].hp;
expect(game.scene.getParty()[0].hp).toBe(initialHp);
game.move.select(Moves.SPIKES); game.move.select(Moves.SPIKES);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.getParty()[0].hp).toBe(initialHp);
}, 20000);
it("single - wild - take some damage", async () => {
// player set spikes on the field and switch back to back
// opponent do splash for 2 turns
// nobody should take damage
await game.classicMode.runToSummon([
Species.MIGHTYENA,
Species.POOCHYENA,
]);
await game.phaseInterceptor.to(CommandPhase, false);
const initialHp = game.scene.getParty()[0].hp;
game.doSwitchPokemon(1);
await game.phaseInterceptor.run(CommandPhase);
await game.phaseInterceptor.to(CommandPhase, false);
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.run(CommandPhase); await game.toNextTurn();
await game.phaseInterceptor.to(CommandPhase, false);
expect(game.scene.getParty()[0].hp).toBe(initialHp); game.doSwitchPokemon(1);
await game.toNextTurn();
const player = game.scene.getParty()[0];
expect(player.hp).toBe(player.getMaxHp());
}, 20000); }, 20000);
it("trainer - wild - force switch opponent - should take damage", async () => { it("should damage opposing pokemon that are forced to switch in", async () => {
game.override.startingWave(5); game.override.startingWave(5);
// player set spikes on the field and do splash for 3 turns await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
// opponent do splash for 4 turns
// nobody should take damage
await game.classicMode.runToSummon([
Species.MIGHTYENA,
Species.POOCHYENA,
]);
await game.phaseInterceptor.to(CommandPhase, true);
const initialHpOpponent = game.scene.currentBattle.enemyParty[1].hp;
game.move.select(Moves.SPIKES); game.move.select(Moves.SPIKES);
await game.toNextTurn(); await game.toNextTurn();
game.move.select(Moves.ROAR); game.move.select(Moves.ROAR);
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.currentBattle.enemyParty[0].hp).toBeLessThan(initialHpOpponent);
const enemy = game.scene.getEnemyParty()[0];
expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
}, 20000); }, 20000);
it("trainer - wild - force switch by himself opponent - should take damage", async () => { it("should damage opposing pokemon that choose to switch in", async () => {
game.override.startingWave(5); game.override.startingWave(5);
game.override.startingLevel(5000); await game.startBattle([Species.MIGHTYENA, Species.POOCHYENA]);
game.override.enemySpecies(0);
// turn 1: player set spikes, opponent do splash
// turn 2: player do splash, opponent switch pokemon
// opponent pokemon should trigger spikes and lose HP
await game.classicMode.runToSummon([
Species.MIGHTYENA,
Species.POOCHYENA,
]);
await game.phaseInterceptor.to(CommandPhase, true);
const initialHpOpponent = game.scene.currentBattle.enemyParty[1].hp;
game.move.select(Moves.SPIKES); game.move.select(Moves.SPIKES);
await game.toNextTurn(); await game.toNextTurn();
game.forceOpponentToSwitch();
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
game.forceOpponentToSwitch();
await game.toNextTurn(); await game.toNextTurn();
expect(game.scene.currentBattle.enemyParty[0].hp).toBeLessThan(initialHpOpponent);
const enemy = game.scene.getEnemyParty()[0];
expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
}, 20000); }, 20000);
}); });

View File

@ -139,7 +139,7 @@ export default class GameManager {
this.scene.hpBarSpeed = 3; this.scene.hpBarSpeed = 3;
this.scene.enableTutorials = false; this.scene.enableTutorials = false;
this.scene.gameData.gender = PlayerGender.MALE; // set initial player gender this.scene.gameData.gender = PlayerGender.MALE; // set initial player gender
this.scene.battleStyle = this.settings.battleStyle;
} }
/** /**

View File

@ -1,16 +1,30 @@
import { PlayerGender } from "#app/enums/player-gender"; import { PlayerGender } from "#app/enums/player-gender";
import { BattleStyle } from "#app/enums/battle-style";
import { GameManagerHelper } from "./gameManagerHelper"; import { GameManagerHelper } from "./gameManagerHelper";
/** /**
* Helper to handle settings for tests * Helper to handle settings for tests
*/ */
export class SettingsHelper extends GameManagerHelper { export class SettingsHelper extends GameManagerHelper {
private _battleStyle: BattleStyle = BattleStyle.SET;
get battleStyle(): BattleStyle {
return this._battleStyle;
}
/**
* Change the battle style to Switch or Set mode (tests default to {@linkcode BattleStyle.SET})
* @param mode {@linkcode BattleStyle.SWITCH} or {@linkcode BattleStyle.SET}
*/
set battleStyle(mode: BattleStyle.SWITCH | BattleStyle.SET) {
this._battleStyle = mode;
}
/** /**
* Disable/Enable type hints settings * Disable/Enable type hints settings
* @param enable true to enabled, false to disabled * @param enable true to enabled, false to disabled
*/ */
typeHints(enable: boolean) { typeHints(enable: boolean): void {
this.game.scene.typeHints = enable; this.game.scene.typeHints = enable;
this.log(`Type Hints ${enable? "enabled" : "disabled"}` ); this.log(`Type Hints ${enable? "enabled" : "disabled"}` );
} }