mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-20 22:39:31 +02:00
Compare commits
16 Commits
44a5e2f61e
...
6ec30e2451
Author | SHA1 | Date | |
---|---|---|---|
|
6ec30e2451 | ||
|
f42237d415 | ||
|
b44f0a4176 | ||
|
076ef81691 | ||
|
23271901cf | ||
|
1517e0512e | ||
|
ab968f1ac6 | ||
|
64be310b9a | ||
|
bf855d5acf | ||
|
bad73f0ce2 | ||
|
034c56473c | ||
|
3db1cb7486 | ||
|
a9a3b0760a | ||
|
c55f105d31 | ||
|
6013bc8c00 | ||
|
5d4e93b009 |
@ -90,9 +90,13 @@ If this feature requires new text, the text should be integrated into the code w
|
||||
- For any feature pulled from the mainline Pokémon games (e.g. a Move or Ability implementation), it's best practice to include a source link for any added text.
|
||||
[Poké Corpus](https://abcboy101.github.io/poke-corpus/) is a great resource for finding text from the mainline games; otherwise, a video/picture showing the text being displayed should suffice.
|
||||
- You should also [notify the current Head of Translation](#notifying-translation) to ensure a fast response.
|
||||
3. At this point, you may begin [testing locales integration in your main PR](#documenting-locales-changes).
|
||||
4. The Translation Team will approve the locale PR (after corrections, if necessary), then merge it into `pokerogue-locales`.
|
||||
5. The Dev Team will approve your main PR for your feature, then merge it into PokéRogue's beta environment.
|
||||
3. Your locales should use the following format:
|
||||
- File names should be in `kebab-case`. Example: `trainer-names.json`
|
||||
- Key names should be in `camelCase`. Example: `aceTrainer`
|
||||
- If you make use of i18next's inbuilt [context support](https://www.i18next.com/translation-function/context), you need to use `snake_case` for the context key. Example: `aceTrainer_male`
|
||||
4. At this point, you may begin [testing locales integration in your main PR](#documenting-locales-changes).
|
||||
5. The Translation Team will approve the locale PR (after corrections, if necessary), then merge it into `pokerogue-locales`.
|
||||
6. The Dev Team will approve your main PR for your feature, then merge it into PokéRogue's beta environment.
|
||||
|
||||
[^2]: For those wondering, the reason for choosing English specifically is due to it being the master language set in Pontoon (the program used by the Translation Team to perform locale updates).
|
||||
If a key is present in any language _except_ the master language, it won't appear anywhere else in the translation tool, rendering missing English keys quite a hassle.
|
||||
|
@ -104,6 +104,7 @@ import {
|
||||
getLuckString,
|
||||
getLuckTextTint,
|
||||
getPartyLuckValue,
|
||||
type ModifierType,
|
||||
PokemonHeldItemModifierType,
|
||||
} from "#modifiers/modifier-type";
|
||||
import { MysteryEncounter } from "#mystery-encounters/mystery-encounter";
|
||||
@ -1203,7 +1204,9 @@ export class BattleScene extends SceneBase {
|
||||
this.updateScoreText();
|
||||
this.scoreText.setVisible(false);
|
||||
|
||||
[this.luckLabelText, this.luckText].map(t => t.setVisible(false));
|
||||
[this.luckLabelText, this.luckText].forEach(t => {
|
||||
t.setVisible(false);
|
||||
});
|
||||
|
||||
this.newArena(Overrides.STARTING_BIOME_OVERRIDE || BiomeId.TOWN);
|
||||
|
||||
@ -1237,8 +1240,7 @@ export class BattleScene extends SceneBase {
|
||||
Object.values(mp)
|
||||
.flat()
|
||||
.map(mt => mt.modifierType)
|
||||
.filter(mt => "localize" in mt)
|
||||
.map(lpb => lpb as unknown as Localizable),
|
||||
.filter((mt): mt is ModifierType & Localizable => "localize" in mt && typeof mt.localize === "function"),
|
||||
),
|
||||
];
|
||||
for (const item of localizable) {
|
||||
@ -1513,8 +1515,8 @@ export class BattleScene extends SceneBase {
|
||||
return this.currentBattle;
|
||||
}
|
||||
|
||||
newArena(biome: BiomeId, playerFaints?: number): Arena {
|
||||
this.arena = new Arena(biome, BiomeId[biome].toLowerCase(), playerFaints);
|
||||
newArena(biome: BiomeId, playerFaints = 0): Arena {
|
||||
this.arena = new Arena(biome, playerFaints);
|
||||
this.eventTarget.dispatchEvent(new NewArenaEvent());
|
||||
|
||||
this.arenaBg.pipelineData = {
|
||||
@ -2711,7 +2713,9 @@ export class BattleScene extends SceneBase {
|
||||
}
|
||||
}
|
||||
|
||||
this.party.map(p => p.updateInfo(instant));
|
||||
this.party.forEach(p => {
|
||||
p.updateInfo(instant);
|
||||
});
|
||||
} else {
|
||||
const args = [this];
|
||||
if (modifier.shouldApply(...args)) {
|
||||
|
@ -74,6 +74,7 @@ import {
|
||||
randSeedItem,
|
||||
toDmgValue,
|
||||
} from "#utils/common";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class Ability implements Localizable {
|
||||
@ -109,13 +110,9 @@ export class Ability implements Localizable {
|
||||
}
|
||||
|
||||
localize(): void {
|
||||
const i18nKey = AbilityId[this.id]
|
||||
.split("_")
|
||||
.filter(f => f)
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("") as string;
|
||||
const i18nKey = toCamelCase(AbilityId[this.id]);
|
||||
|
||||
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`) as string}${this.nameAppend}` : "";
|
||||
this.name = this.id ? `${i18next.t(`ability:${i18nKey}.name`)}${this.nameAppend}` : "";
|
||||
this.description = this.id ? (i18next.t(`ability:${i18nKey}.description`) as string) : "";
|
||||
}
|
||||
|
||||
|
@ -1866,17 +1866,16 @@ interface PokemonPrevolutions {
|
||||
export const pokemonPrevolutions: PokemonPrevolutions = {};
|
||||
|
||||
export function initPokemonPrevolutions(): void {
|
||||
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ].map(sfk => sfk as string);
|
||||
const prevolutionKeys = Object.keys(pokemonEvolutions);
|
||||
prevolutionKeys.forEach(pk => {
|
||||
const evolutions = pokemonEvolutions[pk];
|
||||
// TODO: Why do we have empty strings in our array?
|
||||
const megaFormKeys = [ SpeciesFormKey.MEGA, "", SpeciesFormKey.MEGA_X, "", SpeciesFormKey.MEGA_Y ];
|
||||
for (const [pk, evolutions] of Object.entries(pokemonEvolutions)) {
|
||||
for (const ev of evolutions) {
|
||||
if (ev.evoFormKey && megaFormKeys.indexOf(ev.evoFormKey) > -1) {
|
||||
continue;
|
||||
}
|
||||
pokemonPrevolutions[ev.speciesId] = Number.parseInt(pk) as SpeciesId;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ import type { ChargingMove, MoveAttrMap, MoveAttrString, MoveClassMap, MoveKindS
|
||||
import type { TurnMove } from "#types/turn-move";
|
||||
import { BooleanHolder, type Constructor, isNullOrUndefined, NumberHolder, randSeedFloat, randSeedInt, randSeedItem, toDmgValue } from "#utils/common";
|
||||
import { getEnumValues } from "#utils/enums";
|
||||
import { toTitleCase } from "#utils/strings";
|
||||
import { toCamelCase, toTitleCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
import { applyChallenges } from "#utils/challenge-utils";
|
||||
|
||||
@ -162,10 +162,16 @@ export abstract class Move implements Localizable {
|
||||
}
|
||||
|
||||
localize(): void {
|
||||
const i18nKey = MoveId[this.id].split("_").filter(f => f).map((f, i) => i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()).join("") as unknown as string;
|
||||
const i18nKey = toCamelCase(MoveId[this.id])
|
||||
|
||||
this.name = this.id ? `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}` : "";
|
||||
this.effect = this.id ? `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}` : "";
|
||||
if (this.id === MoveId.NONE) {
|
||||
this.name = "";
|
||||
this.effect = ""
|
||||
return;
|
||||
}
|
||||
|
||||
this.name = `${i18next.t(`move:${i18nKey}.name`)}${this.nameAppend}`;
|
||||
this.effect = `${i18next.t(`move:${i18nKey}.effect`)}${this.nameAppend}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5926,8 +5932,8 @@ export class ProtectAttr extends AddBattlerTagAttr {
|
||||
for (const turnMove of user.getLastXMoves(-1).slice()) {
|
||||
if (
|
||||
// Quick & Wide guard increment the Protect counter without using it for fail chance
|
||||
!(allMoves[turnMove.move].hasAttr("ProtectAttr") ||
|
||||
[MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) ||
|
||||
!(allMoves[turnMove.move].hasAttr("ProtectAttr") ||
|
||||
[MoveId.QUICK_GUARD, MoveId.WIDE_GUARD].includes(turnMove.move)) ||
|
||||
turnMove.result !== MoveResult.SUCCESS
|
||||
) {
|
||||
break;
|
||||
|
@ -12,6 +12,7 @@ import { WeatherType } from "#enums/weather-type";
|
||||
import type { Pokemon } from "#field/pokemon";
|
||||
import type { PokemonFormChangeItemModifier } from "#modifiers/modifier";
|
||||
import { type Constructor, coerceArray } from "#utils/common";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
|
||||
export abstract class SpeciesFormChangeTrigger {
|
||||
@ -143,11 +144,7 @@ export class SpeciesFormChangeMoveLearnedTrigger extends SpeciesFormChangeTrigge
|
||||
super();
|
||||
this.move = move;
|
||||
this.known = known;
|
||||
const moveKey = MoveId[this.move]
|
||||
.split("_")
|
||||
.filter(f => f)
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("") as unknown as string;
|
||||
const moveKey = toCamelCase(MoveId[this.move]);
|
||||
this.description = known
|
||||
? i18next.t("pokemonEvolutions:Forms.moveLearned", {
|
||||
move: i18next.t(`move:${moveKey}.name`),
|
||||
|
@ -38,6 +38,7 @@ export enum UiMode {
|
||||
UNAVAILABLE,
|
||||
CHALLENGE_SELECT,
|
||||
RENAME_POKEMON,
|
||||
RENAME_RUN,
|
||||
RUN_HISTORY,
|
||||
RUN_INFO,
|
||||
TEST_DIALOGUE,
|
||||
|
@ -54,7 +54,7 @@ export class Arena {
|
||||
public bgm: string;
|
||||
public ignoreAbilities: boolean;
|
||||
public ignoringEffectSource: BattlerIndex | null;
|
||||
public playerTerasUsed: number;
|
||||
public playerTerasUsed = 0;
|
||||
/**
|
||||
* Saves the number of times a party pokemon faints during a arena encounter.
|
||||
* {@linkcode globalScene.currentBattle.enemyFaints} is the corresponding faint counter for the enemy (this resets every wave).
|
||||
@ -68,12 +68,11 @@ export class Arena {
|
||||
|
||||
public readonly eventTarget: EventTarget = new EventTarget();
|
||||
|
||||
constructor(biome: BiomeId, bgm: string, playerFaints = 0) {
|
||||
constructor(biome: BiomeId, playerFaints = 0) {
|
||||
this.biomeType = biome;
|
||||
this.bgm = bgm;
|
||||
this.bgm = BiomeId[biome].toLowerCase();
|
||||
this.trainerPool = biomeTrainerPools[biome];
|
||||
this.updatePoolsForTimeOfDay();
|
||||
this.playerTerasUsed = 0;
|
||||
this.playerFaints = playerFaints;
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,9 @@ export class LoadingScene extends SceneBase {
|
||||
);
|
||||
|
||||
if (!mobile) {
|
||||
loadingGraphics.map(g => g.setVisible(false));
|
||||
loadingGraphics.forEach(g => {
|
||||
g.setVisible(false);
|
||||
});
|
||||
}
|
||||
|
||||
const intro = this.add.video(0, 0);
|
||||
|
@ -121,8 +121,8 @@ export class ModifierBar extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
updateModifierOverflowVisibility(ignoreLimit: boolean) {
|
||||
const modifierIcons = this.getAll().reverse();
|
||||
for (const modifier of modifierIcons.map(m => m as Phaser.GameObjects.Container).slice(iconOverflowIndex)) {
|
||||
const modifierIcons = this.getAll().reverse() as Phaser.GameObjects.Container[];
|
||||
for (const modifier of modifierIcons.slice(iconOverflowIndex)) {
|
||||
modifier.setVisible(ignoreLimit);
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ export interface SessionSaveData {
|
||||
battleType: BattleType;
|
||||
trainer: TrainerData;
|
||||
gameVersion: string;
|
||||
runNameText: string;
|
||||
timestamp: number;
|
||||
challenges: ChallengeData[];
|
||||
mysteryEncounterType: MysteryEncounterType | -1; // Only defined when current wave is ME,
|
||||
@ -206,10 +207,12 @@ export interface StarterData {
|
||||
[key: number]: StarterDataEntry;
|
||||
}
|
||||
|
||||
export interface TutorialFlags {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
// TODO: Rework into a bitmask
|
||||
export type TutorialFlags = {
|
||||
[key in Tutorial]: boolean;
|
||||
};
|
||||
|
||||
// TODO: Rework into a bitmask
|
||||
export interface SeenDialogues {
|
||||
[key: string]: boolean;
|
||||
}
|
||||
@ -822,52 +825,51 @@ export class GameData {
|
||||
return true; // TODO: is `true` the correct return value?
|
||||
}
|
||||
|
||||
private loadGamepadSettings(): boolean {
|
||||
Object.values(SettingGamepad)
|
||||
.map(setting => setting as SettingGamepad)
|
||||
.forEach(setting => setSettingGamepad(setting, settingGamepadDefaults[setting]));
|
||||
private loadGamepadSettings(): void {
|
||||
Object.values(SettingGamepad).forEach(setting => {
|
||||
setSettingGamepad(setting, settingGamepadDefaults[setting]);
|
||||
});
|
||||
|
||||
if (!localStorage.hasOwnProperty("settingsGamepad")) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
const settingsGamepad = JSON.parse(localStorage.getItem("settingsGamepad")!); // TODO: is this bang correct?
|
||||
|
||||
for (const setting of Object.keys(settingsGamepad)) {
|
||||
setSettingGamepad(setting as SettingGamepad, settingsGamepad[setting]);
|
||||
}
|
||||
|
||||
return true; // TODO: is `true` the correct return value?
|
||||
}
|
||||
|
||||
public saveTutorialFlag(tutorial: Tutorial, flag: boolean): boolean {
|
||||
const key = getDataTypeKey(GameDataType.TUTORIALS);
|
||||
let tutorials: object = {};
|
||||
if (localStorage.hasOwnProperty(key)) {
|
||||
tutorials = JSON.parse(localStorage.getItem(key)!); // TODO: is this bang correct?
|
||||
/**
|
||||
* Save the specified tutorial as having the specified completion status.
|
||||
* @param tutorial - The {@linkcode Tutorial} whose completion status is being saved
|
||||
* @param status - The completion status to set
|
||||
*/
|
||||
public saveTutorialFlag(tutorial: Tutorial, status: boolean): void {
|
||||
// Grab the prior save data tutorial
|
||||
const saveDataKey = getDataTypeKey(GameDataType.TUTORIALS);
|
||||
const tutorials: TutorialFlags = localStorage.hasOwnProperty(saveDataKey)
|
||||
? JSON.parse(localStorage.getItem(saveDataKey)!)
|
||||
: {};
|
||||
|
||||
// TODO: We shouldn't be storing this like that
|
||||
for (const key of Object.values(Tutorial)) {
|
||||
if (key === tutorial) {
|
||||
tutorials[key] = status;
|
||||
} else {
|
||||
tutorials[key] ??= false;
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(Tutorial)
|
||||
.map(t => t as Tutorial)
|
||||
.forEach(t => {
|
||||
const key = Tutorial[t];
|
||||
if (key === tutorial) {
|
||||
tutorials[key] = flag;
|
||||
} else {
|
||||
tutorials[key] ??= false;
|
||||
}
|
||||
});
|
||||
|
||||
localStorage.setItem(key, JSON.stringify(tutorials));
|
||||
|
||||
return true;
|
||||
localStorage.setItem(saveDataKey, JSON.stringify(tutorials));
|
||||
}
|
||||
|
||||
public getTutorialFlags(): TutorialFlags {
|
||||
const key = getDataTypeKey(GameDataType.TUTORIALS);
|
||||
const ret: TutorialFlags = {};
|
||||
Object.values(Tutorial)
|
||||
.map(tutorial => tutorial as Tutorial)
|
||||
.forEach(tutorial => (ret[Tutorial[tutorial]] = false));
|
||||
const ret: TutorialFlags = Object.values(Tutorial).reduce((acc, tutorial) => {
|
||||
acc[Tutorial[tutorial]] = false;
|
||||
return acc;
|
||||
}, {} as TutorialFlags);
|
||||
|
||||
if (!localStorage.hasOwnProperty(key)) {
|
||||
return ret;
|
||||
@ -979,6 +981,54 @@ export class GameData {
|
||||
});
|
||||
}
|
||||
|
||||
async renameSession(slotId: number, newName: string): Promise<boolean> {
|
||||
return new Promise(async resolve => {
|
||||
if (slotId < 0) {
|
||||
return resolve(false);
|
||||
}
|
||||
const sessionData: SessionSaveData | null = await this.getSession(slotId);
|
||||
|
||||
if (!sessionData) {
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
if (newName === "") {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
sessionData.runNameText = newName;
|
||||
const updatedDataStr = JSON.stringify(sessionData);
|
||||
const encrypted = encrypt(updatedDataStr, bypassLogin);
|
||||
const secretId = this.secretId;
|
||||
const trainerId = this.trainerId;
|
||||
|
||||
if (bypassLogin) {
|
||||
localStorage.setItem(
|
||||
`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`,
|
||||
encrypt(updatedDataStr, bypassLogin),
|
||||
);
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
pokerogueApi.savedata.session
|
||||
.update({ slot: slotId, trainerId, secretId, clientSessionId }, encrypted)
|
||||
.then(error => {
|
||||
if (error) {
|
||||
console.error("Failed to update session name:", error);
|
||||
resolve(false);
|
||||
} else {
|
||||
localStorage.setItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`, encrypted);
|
||||
updateUserInfo().then(success => {
|
||||
if (success !== null && !success) {
|
||||
return resolve(false);
|
||||
}
|
||||
});
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadSession(slotId: number, sessionData?: SessionSaveData): Promise<boolean> {
|
||||
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: TODO: fix this
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
54
src/ui/rename-run-ui-handler.ts
Normal file
54
src/ui/rename-run-ui-handler.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import i18next from "i18next";
|
||||
import type { InputFieldConfig } from "./form-modal-ui-handler";
|
||||
import { FormModalUiHandler } from "./form-modal-ui-handler";
|
||||
import type { ModalConfig } from "./modal-ui-handler";
|
||||
|
||||
export class RenameRunFormUiHandler extends FormModalUiHandler {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return i18next.t("menu:renamerun");
|
||||
}
|
||||
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 160;
|
||||
}
|
||||
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return [i18next.t("menu:rename"), i18next.t("menu:cancel")];
|
||||
}
|
||||
|
||||
getReadableErrorMessage(error: string): string {
|
||||
const colonIndex = error?.indexOf(":");
|
||||
if (colonIndex > 0) {
|
||||
error = error.slice(0, colonIndex);
|
||||
}
|
||||
|
||||
return super.getReadableErrorMessage(error);
|
||||
}
|
||||
|
||||
override getInputFieldConfigs(): InputFieldConfig[] {
|
||||
return [{ label: i18next.t("menu:runName") }];
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (!super.show(args)) {
|
||||
return false;
|
||||
}
|
||||
if (this.inputs?.length) {
|
||||
this.inputs.forEach(input => {
|
||||
input.text = "";
|
||||
});
|
||||
}
|
||||
const config = args[0] as ModalConfig;
|
||||
this.submitAction = _ => {
|
||||
this.sanitizeInputs();
|
||||
const sanitizedName = btoa(encodeURIComponent(this.inputs[0].text));
|
||||
config.buttonActions[0](sanitizedName);
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import { addBBCodeTextObject, addTextObject, getTextColor } from "#ui/text";
|
||||
import { UiHandler } from "#ui/ui-handler";
|
||||
import { addWindow } from "#ui/ui-theme";
|
||||
import { formatFancyLargeNumber, formatLargeNumber, formatMoney, getPlayTimeString } from "#utils/common";
|
||||
import { toCamelCase } from "#utils/strings";
|
||||
import i18next from "i18next";
|
||||
import RoundRectangle from "phaser3-rex-plugins/plugins/roundrectangle";
|
||||
|
||||
@ -207,6 +208,10 @@ export class RunInfoUiHandler extends UiHandler {
|
||||
headerText.setOrigin(0, 0);
|
||||
headerText.setPositionRelative(headerBg, 8, 4);
|
||||
this.runContainer.add(headerText);
|
||||
const runName = addTextObject(0, 0, this.runInfo.runNameText, TextStyle.WINDOW);
|
||||
runName.setOrigin(0, 0);
|
||||
runName.setPositionRelative(headerBg, 60, 4);
|
||||
this.runContainer.add(runName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -702,10 +707,7 @@ export class RunInfoUiHandler extends UiHandler {
|
||||
rules.push(i18next.t("challenges:inverseBattle.shortName"));
|
||||
break;
|
||||
default: {
|
||||
const localizationKey = Challenges[this.runInfo.challenges[i].id]
|
||||
.split("_")
|
||||
.map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase()))
|
||||
.join("");
|
||||
const localizationKey = toCamelCase(Challenges[this.runInfo.challenges[i].id]);
|
||||
rules.push(i18next.t(`challenges:${localizationKey}.name`));
|
||||
break;
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { GameMode } from "#app/game-mode";
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import { Button } from "#enums/buttons";
|
||||
import { GameModes } from "#enums/game-modes";
|
||||
import { TextStyle } from "#enums/text-style";
|
||||
import { UiMode } from "#enums/ui-mode";
|
||||
// biome-ignore lint/performance/noNamespaceImport: See `src/system/game-data.ts`
|
||||
import * as Modifier from "#modifiers/modifier";
|
||||
import type { SessionSaveData } from "#system/game-data";
|
||||
import type { PokemonData } from "#system/pokemon-data";
|
||||
import type { OptionSelectConfig } from "#ui/abstract-option-select-ui-handler";
|
||||
import { MessageUiHandler } from "#ui/message-ui-handler";
|
||||
import { RunDisplayMode } from "#ui/run-info-ui-handler";
|
||||
import { addTextObject } from "#ui/text";
|
||||
@ -15,7 +17,7 @@ import { fixedInt, formatLargeNumber, getPlayTimeString, isNullOrUndefined } fro
|
||||
import i18next from "i18next";
|
||||
|
||||
const SESSION_SLOTS_COUNT = 5;
|
||||
const SLOTS_ON_SCREEN = 3;
|
||||
const SLOTS_ON_SCREEN = 2;
|
||||
|
||||
export enum SaveSlotUiMode {
|
||||
LOAD,
|
||||
@ -33,6 +35,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
private uiMode: SaveSlotUiMode;
|
||||
private saveSlotSelectCallback: SaveSlotSelectCallback | null;
|
||||
protected manageDataConfig: OptionSelectConfig;
|
||||
|
||||
private scrollCursor = 0;
|
||||
|
||||
@ -101,6 +104,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
const ui = this.getUi();
|
||||
const manageDataOptions: any[] = [];
|
||||
|
||||
let success = false;
|
||||
let error = false;
|
||||
@ -109,14 +113,115 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
if (button === Button.ACTION) {
|
||||
const cursor = this.cursor + this.scrollCursor;
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !this.sessionSlots[cursor].hasData) {
|
||||
const sessionSlot = this.sessionSlots[cursor];
|
||||
if (this.uiMode === SaveSlotUiMode.LOAD && !sessionSlot.hasData) {
|
||||
error = true;
|
||||
} else {
|
||||
switch (this.uiMode) {
|
||||
case SaveSlotUiMode.LOAD:
|
||||
this.saveSlotSelectCallback = null;
|
||||
originalCallback?.(cursor);
|
||||
if (!sessionSlot.malformed) {
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("menu:loadGame"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
originalCallback?.(cursor);
|
||||
return true;
|
||||
},
|
||||
keepOpen: false,
|
||||
});
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("saveSlotSelectUiHandler:renameRun"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
ui.setOverlayMode(
|
||||
UiMode.RENAME_RUN,
|
||||
{
|
||||
buttonActions: [
|
||||
(sanitizedName: string) => {
|
||||
const name = decodeURIComponent(atob(sanitizedName));
|
||||
globalScene.gameData.renameSession(cursor, name).then(response => {
|
||||
if (response[0] === false) {
|
||||
globalScene.reset(true);
|
||||
} else {
|
||||
this.clearSessionSlots();
|
||||
this.cursorObj = null;
|
||||
this.populateSessionSlots();
|
||||
this.setScrollCursor(0);
|
||||
this.setCursor(0);
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
ui.revertMode();
|
||||
},
|
||||
],
|
||||
},
|
||||
"",
|
||||
);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.manageDataConfig = {
|
||||
xOffset: 0,
|
||||
yOffset: 48,
|
||||
options: manageDataOptions,
|
||||
maxOptions: 4,
|
||||
};
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("saveSlotSelectUiHandler:deleteRun"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
ui.showText(i18next.t("saveSlotSelectUiHandler:deleteData"), null, () => {
|
||||
ui.setOverlayMode(
|
||||
UiMode.CONFIRM,
|
||||
() => {
|
||||
globalScene.gameData.tryClearSession(cursor).then(response => {
|
||||
if (response[0] === false) {
|
||||
globalScene.reset(true);
|
||||
} else {
|
||||
this.clearSessionSlots();
|
||||
this.cursorObj = null;
|
||||
this.populateSessionSlots();
|
||||
this.setScrollCursor(0);
|
||||
this.setCursor(0);
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
}
|
||||
});
|
||||
},
|
||||
() => {
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
},
|
||||
false,
|
||||
0,
|
||||
19,
|
||||
import.meta.env.DEV ? 300 : 2000,
|
||||
);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keepOpen: false,
|
||||
});
|
||||
|
||||
manageDataOptions.push({
|
||||
label: i18next.t("menuUiHandler:cancel"),
|
||||
handler: () => {
|
||||
globalScene.ui.revertMode();
|
||||
return true;
|
||||
},
|
||||
keepOpen: true,
|
||||
});
|
||||
|
||||
ui.setOverlayMode(UiMode.MENU_OPTION_SELECT, this.manageDataConfig);
|
||||
break;
|
||||
|
||||
case SaveSlotUiMode.SAVE: {
|
||||
const saveAndCallback = () => {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
@ -161,6 +266,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
} else {
|
||||
this.saveSlotSelectCallback = null;
|
||||
ui.showText("", 0);
|
||||
originalCallback?.(-1);
|
||||
success = true;
|
||||
}
|
||||
@ -267,33 +373,34 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
this.cursorObj = globalScene.add.container(0, 0);
|
||||
const cursorBox = globalScene.add.nineslice(
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
"select_cursor_highlight_thick",
|
||||
undefined,
|
||||
296,
|
||||
44,
|
||||
294,
|
||||
this.sessionSlots[prevSlotIndex ?? 0]?.saveData?.runNameText ? 50 : 60,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
);
|
||||
const rightArrow = globalScene.add.image(0, 0, "cursor");
|
||||
rightArrow.setPosition(160, 0);
|
||||
rightArrow.setPosition(160, 15);
|
||||
rightArrow.setName("rightArrow");
|
||||
this.cursorObj.add([cursorBox, rightArrow]);
|
||||
this.sessionSlotsContainer.add(this.cursorObj);
|
||||
}
|
||||
const cursorPosition = cursor + this.scrollCursor;
|
||||
const cursorIncrement = cursorPosition * 56;
|
||||
const cursorIncrement = cursorPosition * 76;
|
||||
if (this.sessionSlots[cursorPosition] && this.cursorObj) {
|
||||
const hasData = this.sessionSlots[cursorPosition].hasData;
|
||||
const session = this.sessionSlots[cursorPosition];
|
||||
const hasData = session.hasData && !session.malformed;
|
||||
// If the session slot lacks session data, it does not move from its default, central position.
|
||||
// Only session slots with session data will move leftwards and have a visible arrow.
|
||||
if (!hasData) {
|
||||
this.cursorObj.setPosition(151, 26 + cursorIncrement);
|
||||
this.cursorObj.setPosition(151, 20 + cursorIncrement);
|
||||
this.sessionSlots[cursorPosition].setPosition(0, cursorIncrement);
|
||||
} else {
|
||||
this.cursorObj.setPosition(145, 26 + cursorIncrement);
|
||||
this.cursorObj.setPosition(145, 20 + cursorIncrement);
|
||||
this.sessionSlots[cursorPosition].setPosition(-6, cursorIncrement);
|
||||
}
|
||||
this.setArrowVisibility(hasData);
|
||||
@ -311,7 +418,8 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
revertSessionSlot(slotIndex: number): void {
|
||||
const sessionSlot = this.sessionSlots[slotIndex];
|
||||
if (sessionSlot) {
|
||||
sessionSlot.setPosition(0, slotIndex * 56);
|
||||
const valueHeight = 76;
|
||||
sessionSlot.setPosition(0, slotIndex * valueHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +448,7 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
this.setCursor(this.cursor, prevSlotIndex);
|
||||
globalScene.tweens.add({
|
||||
targets: this.sessionSlotsContainer,
|
||||
y: this.sessionSlotsContainerInitialY - 56 * scrollCursor,
|
||||
y: this.sessionSlotsContainerInitialY - 76 * scrollCursor,
|
||||
duration: fixedInt(325),
|
||||
ease: "Sine.easeInOut",
|
||||
});
|
||||
@ -374,12 +482,14 @@ export class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
class SessionSlot extends Phaser.GameObjects.Container {
|
||||
public slotId: number;
|
||||
public hasData: boolean;
|
||||
/** Indicates the save slot ran into an error while being loaded */
|
||||
public malformed: boolean;
|
||||
private slotWindow: Phaser.GameObjects.NineSlice;
|
||||
private loadingLabel: Phaser.GameObjects.Text;
|
||||
|
||||
public saveData: SessionSaveData;
|
||||
|
||||
constructor(slotId: number) {
|
||||
super(globalScene, 0, slotId * 56);
|
||||
super(globalScene, 0, slotId * 76);
|
||||
|
||||
this.slotId = slotId;
|
||||
|
||||
@ -387,32 +497,89 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
setup() {
|
||||
const slotWindow = addWindow(0, 0, 304, 52);
|
||||
this.add(slotWindow);
|
||||
this.slotWindow = addWindow(0, 0, 304, 70);
|
||||
this.add(this.slotWindow);
|
||||
|
||||
this.loadingLabel = addTextObject(152, 26, i18next.t("saveSlotSelectUiHandler:loading"), TextStyle.WINDOW);
|
||||
this.loadingLabel = addTextObject(152, 33, i18next.t("saveSlotSelectUiHandler:loading"), TextStyle.WINDOW);
|
||||
this.loadingLabel.setOrigin(0.5, 0.5);
|
||||
this.add(this.loadingLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a name for sessions that don't have a name yet.
|
||||
* @param data - The {@linkcode SessionSaveData} being checked
|
||||
* @returns The default name for the given data.
|
||||
*/
|
||||
decideFallback(data: SessionSaveData): string {
|
||||
let fallbackName = `${GameMode.getModeName(data.gameMode)}`;
|
||||
switch (data.gameMode) {
|
||||
case GameModes.CLASSIC:
|
||||
fallbackName += ` (${globalScene.gameData.gameStats.classicSessionsPlayed + 1})`;
|
||||
break;
|
||||
case GameModes.ENDLESS:
|
||||
case GameModes.SPLICED_ENDLESS:
|
||||
fallbackName += ` (${globalScene.gameData.gameStats.endlessSessionsPlayed + 1})`;
|
||||
break;
|
||||
case GameModes.DAILY: {
|
||||
const runDay = new Date(data.timestamp).toLocaleDateString();
|
||||
fallbackName += ` (${runDay})`;
|
||||
break;
|
||||
}
|
||||
case GameModes.CHALLENGE: {
|
||||
const activeChallenges = data.challenges.filter(c => c.value !== 0);
|
||||
if (activeChallenges.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
fallbackName = "";
|
||||
for (const challenge of activeChallenges.slice(0, 3)) {
|
||||
if (fallbackName !== "") {
|
||||
fallbackName += ", ";
|
||||
}
|
||||
fallbackName += challenge.toChallenge().getName();
|
||||
}
|
||||
|
||||
if (activeChallenges.length > 3) {
|
||||
fallbackName += ", ...";
|
||||
} else if (fallbackName === "") {
|
||||
// Something went wrong when retrieving the names of the active challenges,
|
||||
// so fall back to just naming the run "Challenge"
|
||||
fallbackName = `${GameMode.getModeName(data.gameMode)}`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fallbackName;
|
||||
}
|
||||
|
||||
async setupWithData(data: SessionSaveData) {
|
||||
const hasName = data?.runNameText;
|
||||
this.remove(this.loadingLabel, true);
|
||||
if (hasName) {
|
||||
const nameLabel = addTextObject(8, 5, data.runNameText, TextStyle.WINDOW);
|
||||
this.add(nameLabel);
|
||||
} else {
|
||||
const fallbackName = this.decideFallback(data);
|
||||
await globalScene.gameData.renameSession(this.slotId, fallbackName);
|
||||
const nameLabel = addTextObject(8, 5, fallbackName, TextStyle.WINDOW);
|
||||
this.add(nameLabel);
|
||||
}
|
||||
|
||||
const gameModeLabel = addTextObject(
|
||||
8,
|
||||
5,
|
||||
19,
|
||||
`${GameMode.getModeName(data.gameMode) || i18next.t("gameMode:unknown")} - ${i18next.t("saveSlotSelectUiHandler:wave")} ${data.waveIndex}`,
|
||||
TextStyle.WINDOW,
|
||||
);
|
||||
this.add(gameModeLabel);
|
||||
|
||||
const timestampLabel = addTextObject(8, 19, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
|
||||
const timestampLabel = addTextObject(8, 33, new Date(data.timestamp).toLocaleString(), TextStyle.WINDOW);
|
||||
this.add(timestampLabel);
|
||||
|
||||
const playTimeLabel = addTextObject(8, 33, getPlayTimeString(data.playTime), TextStyle.WINDOW);
|
||||
const playTimeLabel = addTextObject(8, 47, getPlayTimeString(data.playTime), TextStyle.WINDOW);
|
||||
this.add(playTimeLabel);
|
||||
|
||||
const pokemonIconsContainer = globalScene.add.container(144, 4);
|
||||
const pokemonIconsContainer = globalScene.add.container(144, 16);
|
||||
data.party.forEach((p: PokemonData, i: number) => {
|
||||
const iconContainer = globalScene.add.container(26 * i, 0);
|
||||
iconContainer.setScale(0.75);
|
||||
@ -427,13 +594,9 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
TextStyle.PARTY,
|
||||
{ fontSize: "54px", color: "#f8f8f8" },
|
||||
);
|
||||
text.setShadow(0, 0, undefined);
|
||||
text.setStroke("#424242", 14);
|
||||
text.setOrigin(1, 0);
|
||||
|
||||
iconContainer.add(icon);
|
||||
iconContainer.add(text);
|
||||
text.setShadow(0, 0, undefined).setStroke("#424242", 14).setOrigin(1, 0);
|
||||
|
||||
iconContainer.add([icon, text]);
|
||||
pokemonIconsContainer.add(iconContainer);
|
||||
|
||||
pokemon.destroy();
|
||||
@ -441,7 +604,7 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
|
||||
this.add(pokemonIconsContainer);
|
||||
|
||||
const modifierIconsContainer = globalScene.add.container(148, 30);
|
||||
const modifierIconsContainer = globalScene.add.container(148, 38);
|
||||
modifierIconsContainer.setScale(0.5);
|
||||
let visibleModifierIndex = 0;
|
||||
for (const m of data.modifiers) {
|
||||
@ -464,22 +627,33 @@ class SessionSlot extends Phaser.GameObjects.Container {
|
||||
|
||||
load(): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
globalScene.gameData.getSession(this.slotId).then(async sessionData => {
|
||||
// Ignore the results if the view was exited
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
if (!sessionData) {
|
||||
this.hasData = false;
|
||||
this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty"));
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
this.hasData = true;
|
||||
this.saveData = sessionData;
|
||||
await this.setupWithData(sessionData);
|
||||
resolve(true);
|
||||
});
|
||||
globalScene.gameData
|
||||
.getSession(this.slotId)
|
||||
.then(async sessionData => {
|
||||
// Ignore the results if the view was exited
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
this.hasData = !!sessionData;
|
||||
if (!sessionData) {
|
||||
this.loadingLabel.setText(i18next.t("saveSlotSelectUiHandler:empty"));
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
this.saveData = sessionData;
|
||||
this.setupWithData(sessionData);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(e => {
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
console.warn(`Failed to load session slot #${this.slotId}:`, e);
|
||||
this.loadingLabel.setText(i18next.t("menu:failedToLoadSession"));
|
||||
this.hasData = true;
|
||||
this.malformed = true;
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ export class TestDialogueUiHandler extends FormModalUiHandler {
|
||||
// we check for null or undefined here as per above - the typeof is still an object but the value is null so we need to exit out of this and pass the null key
|
||||
|
||||
// Return in the format expected by i18next
|
||||
return middleKey ? `${topKey}:${middleKey.map(m => m).join(".")}.${t}` : `${topKey}:${t}`;
|
||||
return middleKey ? `${topKey}:${middleKey.join(".")}.${t}` : `${topKey}:${t}`;
|
||||
}
|
||||
})
|
||||
.filter(t => t);
|
||||
|
@ -60,6 +60,7 @@ import { addWindow } from "#ui/ui-theme";
|
||||
import { UnavailableModalUiHandler } from "#ui/unavailable-modal-ui-handler";
|
||||
import { executeIf } from "#utils/common";
|
||||
import i18next from "i18next";
|
||||
import { RenameRunFormUiHandler } from "./rename-run-ui-handler";
|
||||
|
||||
const transitionModes = [
|
||||
UiMode.SAVE_SLOT,
|
||||
@ -98,6 +99,7 @@ const noTransitionModes = [
|
||||
UiMode.SESSION_RELOAD,
|
||||
UiMode.UNAVAILABLE,
|
||||
UiMode.RENAME_POKEMON,
|
||||
UiMode.RENAME_RUN,
|
||||
UiMode.TEST_DIALOGUE,
|
||||
UiMode.AUTO_COMPLETE,
|
||||
UiMode.ADMIN,
|
||||
@ -168,6 +170,7 @@ export class UI extends Phaser.GameObjects.Container {
|
||||
new UnavailableModalUiHandler(),
|
||||
new GameChallengesUiHandler(),
|
||||
new RenameFormUiHandler(),
|
||||
new RenameRunFormUiHandler(),
|
||||
new RunHistoryUiHandler(),
|
||||
new RunInfoUiHandler(),
|
||||
new TestDialogueUiHandler(UiMode.TEST_DIALOGUE),
|
||||
|
@ -134,7 +134,7 @@ describe("Abilities - Disguise", () => {
|
||||
});
|
||||
await game.classicMode.startBattle([SpeciesId.FURRET, SpeciesId.MIMIKYU]);
|
||||
|
||||
const mimikyu = game.scene.getPlayerParty()[1]!;
|
||||
const mimikyu = game.scene.getPlayerParty()[1];
|
||||
expect(mimikyu.formIndex).toBe(bustedForm);
|
||||
|
||||
game.move.select(MoveId.SPLASH);
|
||||
|
@ -121,8 +121,8 @@ describe("Abilities - Sheer Force", () => {
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.PIDGEOT]);
|
||||
|
||||
const pidgeot = game.scene.getPlayerParty()[0];
|
||||
const onix = game.scene.getEnemyParty()[0];
|
||||
const pidgeot = game.field.getPlayerPokemon();
|
||||
const onix = game.field.getEnemyPokemon();
|
||||
|
||||
pidgeot.stats[Stat.DEF] = 10000;
|
||||
onix.stats[Stat.DEF] = 10000;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import type { EnemyPokemon } from "#field/pokemon";
|
||||
import { DamageAnimPhase } from "#phases/damage-anim-phase";
|
||||
import { MoveEndPhase } from "#phases/move-end-phase";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
@ -38,13 +37,13 @@ describe("Abilities - Sturdy", () => {
|
||||
await game.classicMode.startBattle();
|
||||
game.move.select(MoveId.CLOSE_COMBAT);
|
||||
await game.phaseInterceptor.to(MoveEndPhase);
|
||||
expect(game.scene.getEnemyParty()[0].hp).toBe(1);
|
||||
expect(game.field.getEnemyPokemon().hp).toBe(1);
|
||||
});
|
||||
|
||||
test("Sturdy doesn't activate when user is not at full HP", async () => {
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0];
|
||||
const enemyPokemon = game.field.getEnemyPokemon();
|
||||
enemyPokemon.hp = enemyPokemon.getMaxHp() - 1;
|
||||
|
||||
game.move.select(MoveId.CLOSE_COMBAT);
|
||||
@ -59,19 +58,7 @@ describe("Abilities - Sturdy", () => {
|
||||
game.move.select(MoveId.FISSURE);
|
||||
await game.phaseInterceptor.to(MoveEndPhase);
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0];
|
||||
const enemyPokemon = game.field.getEnemyPokemon();
|
||||
expect(enemyPokemon.isFullHp()).toBe(true);
|
||||
});
|
||||
|
||||
test("Sturdy is ignored by pokemon with `AbilityId.MOLD_BREAKER`", async () => {
|
||||
game.override.ability(AbilityId.MOLD_BREAKER);
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
game.move.select(MoveId.CLOSE_COMBAT);
|
||||
await game.phaseInterceptor.to(DamageAnimPhase);
|
||||
|
||||
const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0];
|
||||
expect(enemyPokemon.hp).toBe(0);
|
||||
expect(enemyPokemon.isFainted()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -336,7 +336,7 @@ describe("Abilities - Wimp Out", () => {
|
||||
game.move.select(MoveId.SPLASH);
|
||||
await game.phaseInterceptor.to("TurnEndPhase");
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].getHpRatio()).toEqual(0.51);
|
||||
expect(game.field.getPlayerPokemon().getHpRatio()).toEqual(0.51);
|
||||
expect(game.phaseInterceptor.log).not.toContain("SwitchSummonPhase");
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.WIMPOD);
|
||||
});
|
||||
@ -344,8 +344,7 @@ describe("Abilities - Wimp Out", () => {
|
||||
it("Wimp Out activating should not cancel a double battle", async () => {
|
||||
game.override.battleStyle("double").enemyAbility(AbilityId.WIMP_OUT).enemyMoveset([MoveId.SPLASH]).enemyLevel(1);
|
||||
await game.classicMode.startBattle([SpeciesId.WIMPOD, SpeciesId.TYRUNT]);
|
||||
const enemyLeadPokemon = game.scene.getEnemyParty()[0];
|
||||
const enemySecPokemon = game.scene.getEnemyParty()[1];
|
||||
const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty();
|
||||
|
||||
game.move.select(MoveId.FALSE_SWIPE, 0, BattlerIndex.ENEMY);
|
||||
game.move.select(MoveId.SPLASH, 1);
|
||||
|
@ -40,8 +40,7 @@ describe("Abilities - ZERO TO HERO", () => {
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.FEEBAS, SpeciesId.PALAFIN, SpeciesId.PALAFIN]);
|
||||
|
||||
const palafin1 = game.scene.getPlayerParty()[1];
|
||||
const palafin2 = game.scene.getPlayerParty()[2];
|
||||
const [, palafin1, palafin2] = game.scene.getPlayerParty();
|
||||
expect(palafin1.formIndex).toBe(heroForm);
|
||||
expect(palafin2.formIndex).toBe(heroForm);
|
||||
palafin2.hp = 0;
|
||||
|
@ -64,11 +64,9 @@ describe("Boss Pokemon / Shields", () => {
|
||||
|
||||
it("should reduce the number of shields if we are in a double battle", async () => {
|
||||
game.override.battleStyle("double").startingWave(150); // Floor 150 > 2 shields / 3 health segments
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.MEWTWO]);
|
||||
|
||||
const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!;
|
||||
const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!;
|
||||
const [boss1, boss2] = game.scene.getEnemyParty();
|
||||
expect(boss1.isBoss()).toBe(true);
|
||||
expect(boss1.bossSegments).toBe(2);
|
||||
expect(boss2.isBoss()).toBe(true);
|
||||
@ -112,7 +110,7 @@ describe("Boss Pokemon / Shields", () => {
|
||||
// In this test we want to break through 3 shields at once
|
||||
const brokenShields = 3;
|
||||
|
||||
const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!;
|
||||
const boss1 = game.field.getEnemyPokemon();
|
||||
const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments;
|
||||
const requiredDamageBoss1 = boss1SegmentHp * (1 + Math.pow(2, brokenShields));
|
||||
expect(boss1.isBoss()).toBe(true);
|
||||
@ -124,7 +122,7 @@ describe("Boss Pokemon / Shields", () => {
|
||||
expect(boss1.bossSegmentIndex).toBe(1);
|
||||
expect(boss1.hp).toBe(boss1.getMaxHp() - toDmgValue(boss1SegmentHp * 3));
|
||||
|
||||
const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!;
|
||||
const boss2 = game.scene.getEnemyParty()[1];
|
||||
const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments;
|
||||
const requiredDamageBoss2 = boss2SegmentHp * (1 + Math.pow(2, brokenShields));
|
||||
|
||||
@ -144,7 +142,7 @@ describe("Boss Pokemon / Shields", () => {
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.MEWTWO]);
|
||||
|
||||
const boss1: EnemyPokemon = game.scene.getEnemyParty()[0]!;
|
||||
const boss1 = game.field.getEnemyPokemon();
|
||||
const boss1SegmentHp = boss1.getMaxHp() / boss1.bossSegments;
|
||||
const singleShieldDamage = Math.ceil(boss1SegmentHp);
|
||||
expect(boss1.isBoss()).toBe(true);
|
||||
@ -167,7 +165,7 @@ describe("Boss Pokemon / Shields", () => {
|
||||
expect(getTotalStatStageBoosts(boss1)).toBe(totalStatStages);
|
||||
}
|
||||
|
||||
const boss2: EnemyPokemon = game.scene.getEnemyParty()[1]!;
|
||||
const boss2 = game.scene.getEnemyParty()[1];
|
||||
const boss2SegmentHp = boss2.getMaxHp() / boss2.bossSegments;
|
||||
const requiredDamage = boss2SegmentHp * (1 + Math.pow(2, shieldsToBreak - 1));
|
||||
|
||||
|
@ -34,8 +34,7 @@ describe("Evolution", () => {
|
||||
it("should keep hidden ability after evolving", async () => {
|
||||
await game.classicMode.runToSummon([SpeciesId.EEVEE, SpeciesId.TRAPINCH]);
|
||||
|
||||
const eevee = game.scene.getPlayerParty()[0];
|
||||
const trapinch = game.scene.getPlayerParty()[1];
|
||||
const [eevee, trapinch] = game.scene.getPlayerParty();
|
||||
eevee.abilityIndex = 2;
|
||||
trapinch.abilityIndex = 2;
|
||||
|
||||
@ -49,8 +48,7 @@ describe("Evolution", () => {
|
||||
it("should keep same ability slot after evolving", async () => {
|
||||
await game.classicMode.runToSummon([SpeciesId.BULBASAUR, SpeciesId.CHARMANDER]);
|
||||
|
||||
const bulbasaur = game.scene.getPlayerParty()[0];
|
||||
const charmander = game.scene.getPlayerParty()[1];
|
||||
const [bulbasaur, charmander] = game.scene.getPlayerParty();
|
||||
bulbasaur.abilityIndex = 0;
|
||||
charmander.abilityIndex = 1;
|
||||
|
||||
@ -80,8 +78,7 @@ describe("Evolution", () => {
|
||||
nincada.gender = 1;
|
||||
|
||||
await nincada.evolve(pokemonEvolutions[SpeciesId.NINCADA][0], nincada.getSpeciesForm());
|
||||
const ninjask = game.scene.getPlayerParty()[0];
|
||||
const shedinja = game.scene.getPlayerParty()[1];
|
||||
const [ninjask, shedinja] = game.scene.getPlayerParty();
|
||||
expect(ninjask.abilityIndex).toBe(2);
|
||||
expect(shedinja.abilityIndex).toBe(1);
|
||||
expect(ninjask.gender).toBe(1);
|
||||
|
@ -85,17 +85,14 @@ describe("Spec - Pokemon", () => {
|
||||
});
|
||||
|
||||
describe("Get correct fusion type", () => {
|
||||
let scene: BattleScene;
|
||||
|
||||
beforeEach(async () => {
|
||||
game.override.enemySpecies(SpeciesId.ZUBAT).starterSpecies(SpeciesId.ABRA).enableStarterFusion();
|
||||
scene = game.scene;
|
||||
});
|
||||
|
||||
it("Fusing two mons with a single type", async () => {
|
||||
game.override.starterFusionSpecies(SpeciesId.CHARMANDER);
|
||||
await game.classicMode.startBattle();
|
||||
const pokemon = scene.getPlayerParty()[0];
|
||||
const pokemon = game.field.getPlayerPokemon();
|
||||
|
||||
let types = pokemon.getTypes();
|
||||
expect(types[0]).toBe(PokemonType.PSYCHIC);
|
||||
@ -136,7 +133,7 @@ describe("Spec - Pokemon", () => {
|
||||
it("Fusing two mons with same single type", async () => {
|
||||
game.override.starterFusionSpecies(SpeciesId.DROWZEE);
|
||||
await game.classicMode.startBattle();
|
||||
const pokemon = scene.getPlayerParty()[0];
|
||||
const pokemon = game.field.getPlayerPokemon();
|
||||
|
||||
const types = pokemon.getTypes();
|
||||
expect(types[0]).toBe(PokemonType.PSYCHIC);
|
||||
@ -146,7 +143,7 @@ describe("Spec - Pokemon", () => {
|
||||
it("Fusing mons with one and two types", async () => {
|
||||
game.override.starterSpecies(SpeciesId.CHARMANDER).starterFusionSpecies(SpeciesId.HOUNDOUR);
|
||||
await game.classicMode.startBattle();
|
||||
const pokemon = scene.getPlayerParty()[0];
|
||||
const pokemon = game.field.getPlayerPokemon();
|
||||
|
||||
const types = pokemon.getTypes();
|
||||
expect(types[0]).toBe(PokemonType.FIRE);
|
||||
@ -156,7 +153,7 @@ describe("Spec - Pokemon", () => {
|
||||
it("Fusing mons with two and one types", async () => {
|
||||
game.override.starterSpecies(SpeciesId.NUMEL).starterFusionSpecies(SpeciesId.CHARMANDER);
|
||||
await game.classicMode.startBattle();
|
||||
const pokemon = scene.getPlayerParty()[0];
|
||||
const pokemon = game.field.getPlayerPokemon();
|
||||
|
||||
const types = pokemon.getTypes();
|
||||
expect(types[0]).toBe(PokemonType.FIRE);
|
||||
@ -166,7 +163,7 @@ describe("Spec - Pokemon", () => {
|
||||
it("Fusing two mons with two types", async () => {
|
||||
game.override.starterSpecies(SpeciesId.NATU).starterFusionSpecies(SpeciesId.HOUNDOUR);
|
||||
await game.classicMode.startBattle();
|
||||
const pokemon = scene.getPlayerParty()[0];
|
||||
const pokemon = game.field.getPlayerPokemon();
|
||||
|
||||
let types = pokemon.getTypes();
|
||||
expect(types[0]).toBe(PokemonType.PSYCHIC);
|
||||
|
@ -33,7 +33,7 @@ describe("Items - Light Ball", () => {
|
||||
const consoleSpy = vi.spyOn(console, "log");
|
||||
await game.classicMode.startBattle([SpeciesId.PIKACHU]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
// Checking console log to make sure Light Ball is applied when getEffectiveStat (with the appropriate stat) is called
|
||||
partyMember.getEffectiveStat(Stat.DEF);
|
||||
@ -84,7 +84,7 @@ describe("Items - Light Ball", () => {
|
||||
it("LIGHT_BALL held by PIKACHU", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.PIKACHU]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
const spAtkStat = partyMember.getStat(Stat.SPATK);
|
||||
@ -113,8 +113,7 @@ describe("Items - Light Ball", () => {
|
||||
it("LIGHT_BALL held by fused PIKACHU (base)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.PIKACHU, SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -152,8 +151,7 @@ describe("Items - Light Ball", () => {
|
||||
it("LIGHT_BALL held by fused PIKACHU (part)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.PIKACHU]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -191,7 +189,7 @@ describe("Items - Light Ball", () => {
|
||||
it("LIGHT_BALL not held by PIKACHU", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
const spAtkStat = partyMember.getStat(Stat.SPATK);
|
||||
|
@ -33,7 +33,7 @@ describe("Items - Metal Powder", () => {
|
||||
const consoleSpy = vi.spyOn(console, "log");
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
// Checking console log to make sure Metal Powder is applied when getEffectiveStat (with the appropriate stat) is called
|
||||
partyMember.getEffectiveStat(Stat.DEF);
|
||||
@ -84,7 +84,7 @@ describe("Items - Metal Powder", () => {
|
||||
it("METAL_POWDER held by DITTO", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const defStat = partyMember.getStat(Stat.DEF);
|
||||
|
||||
@ -107,8 +107,7 @@ describe("Items - Metal Powder", () => {
|
||||
it("METAL_POWDER held by fused DITTO (base)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO, SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -140,8 +139,7 @@ describe("Items - Metal Powder", () => {
|
||||
it("METAL_POWDER held by fused DITTO (part)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -173,7 +171,7 @@ describe("Items - Metal Powder", () => {
|
||||
it("METAL_POWDER not held by DITTO", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const defStat = partyMember.getStat(Stat.DEF);
|
||||
|
||||
|
@ -33,7 +33,7 @@ describe("Items - Quick Powder", () => {
|
||||
const consoleSpy = vi.spyOn(console, "log");
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
// Checking console log to make sure Quick Powder is applied when getEffectiveStat (with the appropriate stat) is called
|
||||
partyMember.getEffectiveStat(Stat.DEF);
|
||||
@ -84,7 +84,7 @@ describe("Items - Quick Powder", () => {
|
||||
it("QUICK_POWDER held by DITTO", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const spdStat = partyMember.getStat(Stat.SPD);
|
||||
|
||||
@ -107,8 +107,7 @@ describe("Items - Quick Powder", () => {
|
||||
it("QUICK_POWDER held by fused DITTO (base)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.DITTO, SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -140,8 +139,7 @@ describe("Items - Quick Powder", () => {
|
||||
it("QUICK_POWDER held by fused DITTO (part)", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK, SpeciesId.DITTO]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -173,7 +171,7 @@ describe("Items - Quick Powder", () => {
|
||||
it("QUICK_POWDER not held by DITTO", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const spdStat = partyMember.getStat(Stat.SPD);
|
||||
|
||||
|
@ -33,7 +33,7 @@ describe("Items - Thick Club", () => {
|
||||
const consoleSpy = vi.spyOn(console, "log");
|
||||
await game.classicMode.startBattle([SpeciesId.CUBONE]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
// Checking console log to make sure Thick Club is applied when getEffectiveStat (with the appropriate stat) is called
|
||||
partyMember.getEffectiveStat(Stat.DEF);
|
||||
@ -84,7 +84,7 @@ describe("Items - Thick Club", () => {
|
||||
it("THICK_CLUB held by CUBONE", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.CUBONE]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
|
||||
@ -107,7 +107,7 @@ describe("Items - Thick Club", () => {
|
||||
it("THICK_CLUB held by MAROWAK", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
|
||||
@ -130,7 +130,7 @@ describe("Items - Thick Club", () => {
|
||||
it("THICK_CLUB held by ALOLA_MAROWAK", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ALOLA_MAROWAK]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
|
||||
@ -157,8 +157,7 @@ describe("Items - Thick Club", () => {
|
||||
|
||||
await game.classicMode.startBattle([species[randSpecies], SpeciesId.PIKACHU]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -194,8 +193,7 @@ describe("Items - Thick Club", () => {
|
||||
|
||||
await game.classicMode.startBattle([SpeciesId.PIKACHU, species[randSpecies]]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const ally = game.scene.getPlayerParty()[1];
|
||||
const [partyMember, ally] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
partyMember.fusionSpecies = ally.species;
|
||||
@ -227,7 +225,7 @@ describe("Items - Thick Club", () => {
|
||||
it("THICK_CLUB not held by CUBONE", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.PIKACHU]);
|
||||
|
||||
const partyMember = game.scene.getPlayerParty()[0];
|
||||
const partyMember = game.field.getPlayerPokemon();
|
||||
|
||||
const atkStat = partyMember.getStat(Stat.ATK);
|
||||
|
||||
|
@ -46,7 +46,7 @@ describe("Moves - Dragon Rage", () => {
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
partyPokemon = game.scene.getPlayerParty()[0];
|
||||
partyPokemon = game.field.getPlayerPokemon();
|
||||
enemyPokemon = game.field.getEnemyPokemon();
|
||||
});
|
||||
|
||||
|
@ -76,10 +76,9 @@ describe("Moves - Dragon Tail", () => {
|
||||
game.override.battleStyle("double").enemyMoveset(MoveId.SPLASH).enemyAbility(AbilityId.ROUGH_SKIN);
|
||||
await game.classicMode.startBattle([SpeciesId.DRATINI, SpeciesId.DRATINI, SpeciesId.WAILORD, SpeciesId.WAILORD]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerParty()[0]!;
|
||||
const leadPokemon = game.field.getPlayerPokemon();
|
||||
|
||||
const enemyLeadPokemon = game.scene.getEnemyParty()[0]!;
|
||||
const enemySecPokemon = game.scene.getEnemyParty()[1]!;
|
||||
const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty();
|
||||
|
||||
game.move.select(MoveId.DRAGON_TAIL, 0, BattlerIndex.ENEMY);
|
||||
game.move.select(MoveId.SPLASH, 1);
|
||||
@ -105,11 +104,9 @@ describe("Moves - Dragon Tail", () => {
|
||||
game.override.battleStyle("double").enemyMoveset(MoveId.SPLASH).enemyAbility(AbilityId.ROUGH_SKIN);
|
||||
await game.classicMode.startBattle([SpeciesId.DRATINI, SpeciesId.DRATINI, SpeciesId.WAILORD, SpeciesId.WAILORD]);
|
||||
|
||||
const leadPokemon = game.scene.getPlayerParty()[0]!;
|
||||
const secPokemon = game.scene.getPlayerParty()[1]!;
|
||||
const [leadPokemon, secPokemon] = game.scene.getPlayerParty();
|
||||
|
||||
const enemyLeadPokemon = game.scene.getEnemyParty()[0]!;
|
||||
const enemySecPokemon = game.scene.getEnemyParty()[1]!;
|
||||
const [enemyLeadPokemon, enemySecPokemon] = game.scene.getEnemyParty();
|
||||
|
||||
game.move.select(MoveId.DRAGON_TAIL, 0, BattlerIndex.ENEMY);
|
||||
// target the same pokemon, second move should be redirected after first flees
|
||||
|
@ -42,7 +42,7 @@ describe("Moves - Fissure", () => {
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
partyPokemon = game.scene.getPlayerParty()[0];
|
||||
partyPokemon = game.field.getPlayerPokemon();
|
||||
enemyPokemon = game.field.getEnemyPokemon();
|
||||
});
|
||||
|
||||
|
@ -80,19 +80,19 @@ describe("Moves - Parting Shot", () => {
|
||||
// use Memento 3 times to debuff enemy
|
||||
game.move.select(MoveId.MEMENTO);
|
||||
await game.phaseInterceptor.to(FaintPhase);
|
||||
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
|
||||
game.doSelectPartyPokemon(1);
|
||||
|
||||
await game.phaseInterceptor.to(TurnInitPhase, false);
|
||||
game.move.select(MoveId.MEMENTO);
|
||||
await game.phaseInterceptor.to(FaintPhase);
|
||||
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
|
||||
game.doSelectPartyPokemon(2);
|
||||
|
||||
await game.phaseInterceptor.to(TurnInitPhase, false);
|
||||
game.move.select(MoveId.MEMENTO);
|
||||
await game.phaseInterceptor.to(FaintPhase);
|
||||
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
|
||||
game.doSelectPartyPokemon(3);
|
||||
|
||||
// set up done
|
||||
@ -177,8 +177,8 @@ describe("Moves - Parting Shot", () => {
|
||||
game.move.select(MoveId.SPLASH);
|
||||
|
||||
// intentionally kill party pokemon, switch to second slot (now 1 party mon is fainted)
|
||||
await game.killPokemon(game.scene.getPlayerParty()[0]);
|
||||
expect(game.scene.getPlayerParty()[0].isFainted()).toBe(true);
|
||||
await game.killPokemon(game.field.getPlayerPokemon());
|
||||
expect(game.field.getPlayerPokemon().isFainted()).toBe(true);
|
||||
await game.phaseInterceptor.run(MessagePhase);
|
||||
game.doSelectPartyPokemon(1);
|
||||
|
||||
|
@ -133,6 +133,6 @@ describe("Moves - Revival Blessing", () => {
|
||||
await game.toNextTurn();
|
||||
// If there are incorrectly two switch phases into this slot, the fainted pokemon will end up in slot 3
|
||||
// Make sure it's still in slot 1
|
||||
expect(game.scene.getEnemyParty()[0]).toBe(enemyFainting);
|
||||
expect(game.field.getEnemyPokemon()).toBe(enemyFainting);
|
||||
});
|
||||
});
|
||||
|
@ -44,10 +44,10 @@ describe("Moves - Rollout", () => {
|
||||
|
||||
await game.classicMode.startBattle();
|
||||
|
||||
const playerPkm = game.scene.getPlayerParty()[0];
|
||||
const playerPkm = game.field.getPlayerPokemon();
|
||||
vi.spyOn(playerPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
|
||||
const enemyPkm = game.scene.getEnemyParty()[0];
|
||||
const enemyPkm = game.field.getEnemyPokemon();
|
||||
vi.spyOn(enemyPkm, "stats", "get").mockReturnValue([500000, 1, 1, 1, 1, 1]); // HP, ATK, DEF, SPATK, SPDEF, SPD
|
||||
vi.spyOn(enemyPkm, "getHeldItems").mockReturnValue([]); //no berries
|
||||
|
||||
|
@ -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.field.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.field.getPlayerPokemon();
|
||||
const enemyPokemon = game.field.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]);
|
||||
@ -88,8 +87,9 @@ describe("Moves - Sketch", () => {
|
||||
|
||||
game.override.enemyMoveset([MoveId.METRONOME]);
|
||||
await game.classicMode.startBattle([SpeciesId.REGIELEKI]);
|
||||
|
||||
const playerPokemon = game.field.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);
|
||||
|
@ -48,7 +48,7 @@ describe("Moves - Spikes", () => {
|
||||
game.doSwitchPokemon(1);
|
||||
await game.toNextTurn();
|
||||
|
||||
const player = game.scene.getPlayerParty()[0];
|
||||
const player = game.field.getPlayerPokemon();
|
||||
expect(player.hp).toBe(player.getMaxHp());
|
||||
});
|
||||
|
||||
@ -62,7 +62,7 @@ describe("Moves - Spikes", () => {
|
||||
game.move.select(MoveId.ROAR);
|
||||
await game.toNextTurn();
|
||||
|
||||
const enemy = game.scene.getEnemyParty()[0];
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
|
||||
});
|
||||
|
||||
@ -77,7 +77,7 @@ describe("Moves - Spikes", () => {
|
||||
game.forceEnemyToSwitch();
|
||||
await game.toNextTurn();
|
||||
|
||||
const enemy = game.scene.getEnemyParty()[0];
|
||||
const enemy = game.field.getEnemyPokemon();
|
||||
expect(enemy.hp).toBeLessThan(enemy.getMaxHp());
|
||||
});
|
||||
|
||||
|
@ -50,7 +50,7 @@ describe("Moves - Tackle", () => {
|
||||
const moveToUse = MoveId.TACKLE;
|
||||
await game.classicMode.startBattle([SpeciesId.MIGHTYENA]);
|
||||
game.scene.currentBattle.enemyParty[0].stats[Stat.DEF] = 50;
|
||||
game.scene.getPlayerParty()[0].stats[Stat.ATK] = 50;
|
||||
game.field.getPlayerPokemon().stats[Stat.ATK] = 50;
|
||||
|
||||
const hpOpponent = game.scene.currentBattle.enemyParty[0].hp;
|
||||
|
||||
|
@ -72,7 +72,7 @@ describe("Moves - Tera Starstorm", () => {
|
||||
it("targets both opponents in a double battle when used by Terapagos immediately after terastallizing", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.TERAPAGOS]);
|
||||
|
||||
const terapagos = game.scene.getPlayerParty()[0];
|
||||
const terapagos = game.field.getPlayerPokemon();
|
||||
terapagos.isTerastallized = false;
|
||||
|
||||
game.move.selectWithTera(MoveId.TERA_STARSTORM, 0);
|
||||
@ -89,7 +89,7 @@ describe("Moves - Tera Starstorm", () => {
|
||||
it("targets only one opponent in a double battle when used by Terapagos without terastallizing", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.TERAPAGOS]);
|
||||
|
||||
const terapagos = game.scene.getPlayerParty()[0];
|
||||
const terapagos = game.field.getPlayerPokemon();
|
||||
terapagos.isTerastallized = false;
|
||||
|
||||
game.move.select(MoveId.TERA_STARSTORM, 0, BattlerIndex.ENEMY);
|
||||
@ -106,8 +106,7 @@ describe("Moves - Tera Starstorm", () => {
|
||||
it("applies the effects when Terapagos in Stellar Form is fused with another Pokemon", async () => {
|
||||
await game.classicMode.startBattle([SpeciesId.TERAPAGOS, SpeciesId.CHARMANDER, SpeciesId.MAGIKARP]);
|
||||
|
||||
const fusionedMon = game.scene.getPlayerParty()[0];
|
||||
const magikarp = game.scene.getPlayerParty()[2];
|
||||
const [fusionedMon, , magikarp] = game.scene.getPlayerParty();
|
||||
|
||||
// Fuse party members (taken from PlayerPokemon.fuse(...) function)
|
||||
fusionedMon.fusionSpecies = magikarp.species;
|
||||
|
@ -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);
|
||||
|
@ -230,7 +230,7 @@ describe("Clowning Around - Mystery Encounter", () => {
|
||||
// Stop next battle before it runs
|
||||
await game.phaseInterceptor.to(NewBattlePhase, false);
|
||||
|
||||
const leadPokemon = scene.getPlayerParty()[0];
|
||||
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
|
||||
scene.getPlayerParty()[0].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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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, scene.getPlayerParty()[0], 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 = scene.getPlayerParty()[0].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
|
||||
scene.getPlayerParty()[0].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 = scene.getPlayerParty()[0].getTypes();
|
||||
const leadTypesAfter = game.field.getPlayerPokemon().getTypes();
|
||||
const secondaryTypesAfter = scene.getPlayerParty()[1].getTypes();
|
||||
const thirdTypesAfter = scene.getPlayerParty()[2].getTypes();
|
||||
|
||||
|
@ -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 = scene.getPlayerParty()[0];
|
||||
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 = scene.getPlayerParty()[0];
|
||||
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);
|
||||
scene.getPlayerParty()[0].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);
|
||||
scene.getPlayerParty()[0].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;
|
||||
scene.getPlayerParty()[0].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);
|
||||
scene.getPlayerParty()[0].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();
|
||||
|
@ -201,7 +201,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 2 Sitrus berries on party lead
|
||||
scene.modifiers = [];
|
||||
const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!;
|
||||
const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier;
|
||||
const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier;
|
||||
sitrusMod.stackCount = 2;
|
||||
scene.addModifier(sitrusMod, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -222,7 +222,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 1 Reviver Seed on party lead
|
||||
scene.modifiers = [];
|
||||
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!;
|
||||
const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier;
|
||||
const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -248,7 +248,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!;
|
||||
|
||||
// Sitrus berries on party
|
||||
const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier;
|
||||
const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier;
|
||||
sitrusMod.stackCount = 2;
|
||||
scene.addModifier(sitrusMod, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -277,7 +277,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!;
|
||||
const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier;
|
||||
const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -301,7 +301,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]);
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon());
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
|
||||
@ -329,7 +329,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Reviver Seed on party lead
|
||||
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!;
|
||||
const modifier = revSeed.newModifier(scene.getPlayerParty()[0]) as PokemonInstantReviveModifier;
|
||||
const modifier = revSeed.newModifier(game.field.getPlayerPokemon()) as PokemonInstantReviveModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -363,7 +363,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 2 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 2;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -384,7 +384,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -410,7 +410,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
|
||||
// Set 1 Soul Dew on party lead
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -434,7 +434,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 1 Reviver Seed on party lead
|
||||
scene.modifiers = [];
|
||||
const revSeed = generateModifierType(modifierTypes.REVIVER_SEED)!;
|
||||
const modifier = revSeed.newModifier(scene.getPlayerParty()[0]);
|
||||
const modifier = revSeed.newModifier(game.field.getPlayerPokemon());
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
|
||||
@ -463,7 +463,7 @@ describe("Delibird-y - Mystery Encounter", () => {
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
|
@ -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
|
||||
scene.getPlayerParty()[0].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);
|
||||
|
@ -105,14 +105,14 @@ describe("Global Trade System - Mystery Encounter", () => {
|
||||
it("Should trade a Pokemon from the player's party for the first of 3 Pokemon options", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.GLOBAL_TRADE_SYSTEM, defaultParty);
|
||||
|
||||
const speciesBefore = scene.getPlayerParty()[0].species.speciesId;
|
||||
const speciesBefore = game.field.getPlayerPokemon().species.speciesId;
|
||||
await runMysteryEncounterToEnd(game, 1, { pokemonNo: 1, optionNo: 1 });
|
||||
|
||||
const speciesAfter = scene.getPlayerParty().at(-1)?.species.speciesId;
|
||||
|
||||
expect(speciesAfter).toBeDefined();
|
||||
expect(speciesBefore).not.toBe(speciesAfter);
|
||||
expect(defaultParty.includes(speciesAfter!)).toBeFalsy();
|
||||
expect(defaultParty).not.toContain(speciesAfter);
|
||||
});
|
||||
|
||||
it("Should trade a Pokemon from the player's party for the second of 3 Pokemon options", async () => {
|
||||
@ -220,7 +220,7 @@ describe("Global Trade System - Mystery Encounter", () => {
|
||||
// Set 2 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 2;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -247,7 +247,7 @@ describe("Global Trade System - Mystery Encounter", () => {
|
||||
// Set 1 Soul Dew on party lead
|
||||
scene.modifiers = [];
|
||||
const soulDew = generateModifierType(modifierTypes.SOUL_DEW)!;
|
||||
const modifier = soulDew.newModifier(scene.getPlayerParty()[0]) as PokemonNatureWeightModifier;
|
||||
const modifier = soulDew.newModifier(game.field.getPlayerPokemon()) as PokemonNatureWeightModifier;
|
||||
modifier.stackCount = 1;
|
||||
scene.addModifier(modifier, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
|
@ -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 = scene.getPlayerParty()[0].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
|
||||
scene.getPlayerParty()[0].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 = scene.getPlayerParty()[0].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);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,7 +11,6 @@ import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||
import { SpeciesId } from "#enums/species-id";
|
||||
import { Stat } from "#enums/stat";
|
||||
import type { BerryModifier } from "#modifiers/modifier";
|
||||
import { PokemonMove } from "#moves/pokemon-move";
|
||||
import * as EncounterPhaseUtils from "#mystery-encounters/encounter-phase-utils";
|
||||
import { generateModifierType } from "#mystery-encounters/encounter-phase-utils";
|
||||
import * as MysteryEncounters from "#mystery-encounters/mystery-encounters";
|
||||
@ -214,11 +213,11 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
||||
|
||||
// Berries on party lead
|
||||
const sitrus = generateModifierType(modifierTypes.BERRY, [BerryType.SITRUS])!;
|
||||
const sitrusMod = sitrus.newModifier(scene.getPlayerParty()[0]) as BerryModifier;
|
||||
const sitrusMod = sitrus.newModifier(game.field.getPlayerPokemon()) as BerryModifier;
|
||||
sitrusMod.stackCount = 2;
|
||||
scene.addModifier(sitrusMod, true, false, false, true);
|
||||
const ganlon = generateModifierType(modifierTypes.BERRY, [BerryType.GANLON])!;
|
||||
const ganlonMod = ganlon.newModifier(scene.getPlayerParty()[0]) as BerryModifier;
|
||||
const ganlonMod = ganlon.newModifier(game.field.getPlayerPokemon()) as BerryModifier;
|
||||
ganlonMod.stackCount = 3;
|
||||
scene.addModifier(ganlonMod, true, false, false, true);
|
||||
await scene.updateModifiers(true);
|
||||
@ -270,7 +269,7 @@ describe("Uncommon Breed - Mystery Encounter", () => {
|
||||
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.UNCOMMON_BREED, defaultParty);
|
||||
// Mock moveset
|
||||
scene.getPlayerParty()[0].moveset = [new PokemonMove(MoveId.CHARM)];
|
||||
game.move.changeMoveset(game.field.getPlayerPokemon(), MoveId.CHARM);
|
||||
await runMysteryEncounterToEnd(game, 3);
|
||||
|
||||
expect(leaveEncounterWithoutBattleSpy).toBeCalled();
|
||||
|
@ -112,7 +112,7 @@ describe("Weird Dream - Mystery Encounter", () => {
|
||||
it("should transform the new party into new species, 2 at +90/+110, the rest at +40/50 BST", async () => {
|
||||
await game.runToMysteryEncounter(MysteryEncounterType.WEIRD_DREAM, defaultParty);
|
||||
|
||||
const pokemonPrior = scene.getPlayerParty().map(pokemon => pokemon);
|
||||
const pokemonPrior = scene.getPlayerParty().slice();
|
||||
const bstsPrior = pokemonPrior.map(species => species.getSpeciesForm().getBaseStatTotal());
|
||||
|
||||
await runMysteryEncounterToEnd(game, 1);
|
||||
|
@ -38,7 +38,7 @@ describe("Form Change Phase", () => {
|
||||
await game.classicMode.startBattle([SpeciesId.ZACIAN]);
|
||||
|
||||
// Before the form change: Should be Hero form
|
||||
const zacian = game.scene.getPlayerParty()[0];
|
||||
const zacian = game.field.getPlayerPokemon();
|
||||
expect(zacian.getFormKey()).toBe("hero-of-many-battles");
|
||||
expect(zacian.getTypes()).toStrictEqual([PokemonType.FAIRY]);
|
||||
expect(zacian.calculateBaseStats()).toStrictEqual([92, 120, 115, 80, 115, 138]);
|
||||
|
82
test/system/rename-run.test.ts
Normal file
82
test/system/rename-run.test.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import * as account from "#app/account";
|
||||
import * as bypassLoginModule from "#app/global-vars/bypass-login";
|
||||
import { pokerogueApi } from "#app/plugins/api/pokerogue-api";
|
||||
import type { SessionSaveData } from "#app/system/game-data";
|
||||
import { AbilityId } from "#enums/ability-id";
|
||||
import { MoveId } from "#enums/move-id";
|
||||
import { GameManager } from "#test/test-utils/game-manager";
|
||||
import Phaser from "phaser";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
describe("System - Rename Run", () => {
|
||||
let phaserGame: Phaser.Game;
|
||||
let game: GameManager;
|
||||
|
||||
beforeAll(() => {
|
||||
phaserGame = new Phaser.Game({
|
||||
type: Phaser.HEADLESS,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
game = new GameManager(phaserGame);
|
||||
game.override
|
||||
.moveset([MoveId.SPLASH])
|
||||
.battleStyle("single")
|
||||
.enemyAbility(AbilityId.BALL_FETCH)
|
||||
.enemyMoveset(MoveId.SPLASH);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
game.phaseInterceptor.restoreOg();
|
||||
});
|
||||
|
||||
describe("renameSession", () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(false);
|
||||
vi.spyOn(account, "updateUserInfo").mockImplementation(async () => [true, 1]);
|
||||
});
|
||||
|
||||
it("should return false if slotId < 0", async () => {
|
||||
const result = await game.scene.gameData.renameSession(-1, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false if getSession returns null", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue(null as unknown as SessionSaveData);
|
||||
|
||||
const result = await game.scene.gameData.renameSession(-1, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return true if bypassLogin is true", async () => {
|
||||
vi.spyOn(bypassLoginModule, "bypassLogin", "get").mockReturnValue(true);
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
||||
it("should return false if api returns error", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
vi.spyOn(pokerogueApi.savedata.session, "update").mockResolvedValue("Unknown Error!");
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return true if api is succesfull", async () => {
|
||||
vi.spyOn(game.scene.gameData, "getSession").mockResolvedValue({} as SessionSaveData);
|
||||
vi.spyOn(pokerogueApi.savedata.session, "update").mockResolvedValue("");
|
||||
|
||||
const result = await game.scene.gameData.renameSession(0, "Named Run");
|
||||
|
||||
expect(result).toEqual(true);
|
||||
expect(account.updateUserInfo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
@ -90,10 +90,10 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(2);
|
||||
expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.MALE);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(2);
|
||||
expect(game.field.getPlayerPokemon().gender).toBe(Gender.MALE);
|
||||
});
|
||||
|
||||
it("Bulbasaur - shiny - variant 2 female hardy overgrow", async () => {
|
||||
@ -151,11 +151,11 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(2);
|
||||
expect(game.scene.getPlayerParty()[0].nature).toBe(Nature.HARDY);
|
||||
expect(game.scene.getPlayerParty()[0].getAbility().id).toBe(AbilityId.OVERGROW);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(2);
|
||||
expect(game.field.getPlayerPokemon().nature).toBe(Nature.HARDY);
|
||||
expect(game.field.getPlayerPokemon().getAbility().id).toBe(AbilityId.OVERGROW);
|
||||
});
|
||||
|
||||
it("Bulbasaur - shiny - variant 2 female lonely chlorophyl", async () => {
|
||||
@ -215,12 +215,12 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(2);
|
||||
expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.FEMALE);
|
||||
expect(game.scene.getPlayerParty()[0].nature).toBe(Nature.LONELY);
|
||||
expect(game.scene.getPlayerParty()[0].getAbility().id).toBe(AbilityId.CHLOROPHYLL);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(2);
|
||||
expect(game.field.getPlayerPokemon().gender).toBe(Gender.FEMALE);
|
||||
expect(game.field.getPlayerPokemon().nature).toBe(Nature.LONELY);
|
||||
expect(game.field.getPlayerPokemon().getAbility().id).toBe(AbilityId.CHLOROPHYLL);
|
||||
});
|
||||
|
||||
it("Bulbasaur - shiny - variant 2 female", async () => {
|
||||
@ -278,10 +278,10 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(2);
|
||||
expect(game.scene.getPlayerParty()[0].gender).toBe(Gender.FEMALE);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(2);
|
||||
expect(game.field.getPlayerPokemon().gender).toBe(Gender.FEMALE);
|
||||
});
|
||||
|
||||
it("Bulbasaur - not shiny", async () => {
|
||||
@ -339,9 +339,9 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(false);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(0);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(false);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(0);
|
||||
});
|
||||
|
||||
it("Bulbasaur - shiny - variant 1", async () => {
|
||||
@ -401,9 +401,9 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(1);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(1);
|
||||
});
|
||||
|
||||
it("Bulbasaur - shiny - variant 0", async () => {
|
||||
@ -462,9 +462,9 @@ describe("UI - Starter select", () => {
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.scene.getPlayerParty()[0].shiny).toBe(true);
|
||||
expect(game.scene.getPlayerParty()[0].variant).toBe(0);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.BULBASAUR);
|
||||
expect(game.field.getPlayerPokemon().shiny).toBe(true);
|
||||
expect(game.field.getPlayerPokemon().variant).toBe(0);
|
||||
});
|
||||
|
||||
it("Check if first pokemon in party is caterpie from gen 1 and 1rd row, 3rd column", async () => {
|
||||
@ -528,7 +528,7 @@ describe("UI - Starter select", () => {
|
||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.CATERPIE);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.CATERPIE);
|
||||
});
|
||||
|
||||
it("Check if first pokemon in party is nidoran_m from gen 1 and 2nd row, 4th column (cursor (9+4)-1)", async () => {
|
||||
@ -594,6 +594,6 @@ describe("UI - Starter select", () => {
|
||||
saveSlotSelectUiHandler.processInput(Button.ACTION);
|
||||
});
|
||||
await game.phaseInterceptor.whenAboutToRun(EncounterPhase);
|
||||
expect(game.scene.getPlayerParty()[0].species.speciesId).toBe(SpeciesId.NIDORAN_M);
|
||||
expect(game.field.getPlayerPokemon().species.speciesId).toBe(SpeciesId.NIDORAN_M);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user