pokerogue/src/test/utils/gameWrapper.ts
ImperialSympathizer acb2b66be4
[Feature] Add Mystery Encounters to the game (#3938)
* add .github/workflows/mystery-event.yml

* update mystery-event.yml

* mystery encounters: resolve review comments:

Lost at Sea:
-fix typo in handlePokemonGuidingYouPhase function

Mysterious Chest:
- remove obsolete commented code

mystery-encounter.ts
- remove unused `onDone` field from MysteryEncounterBuilder

* fix typo in CanLearnMoveRequirementOptions

* remove redundance from Pokemon.isAllowedInBattle()

* chore: jsdoc formatting

* fix lost-at-sea tests

* add fallback for biomeMysteryEncounters if empty

* lost-at-sea-encounter: fix and extend tests

* move "battle:fainted" into `koPlayerPokemon`

* add retries to quick-draw tests

* fix lost-at-sea-encounter tests

* clean up battle animation logic

* Update and rename mystery-event.yml to mystery-events.yml

* Update mystery-events.yml

* Fix typo

* Update mystery-events.yml

Fix debug runs

* clean up unit tests and utils

* attach github issues to all encounter jsdocs

* start dialogue refactor

* update sleeping snorlax encounter

* migrate encounters dialogue to new format

* cleanup and add jsdocs

* finish fiery fallout encounter

* fix unit test breaks

* add skeleton tests to fiery fallout

* commit latest test changes

* finish unit tests for fiery fallout

* bug fix for empty modifier shop

* stash working changes

* stash changes

* Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/test/utils/overridesHelper.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/test/utils/overridesHelper.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/test/utils/overridesHelper.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/test/utils/overridesHelper.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Update src/data/battle-anims.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* nit updates and cleanup

* Update src/data/mystery-encounters/encounters/fiery-fallout-encounter.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* add jsdocs and more cleanup

* add more jsdoc

* add the strong stuff encounter

* add the strong stuff encounter and more unit tests

* cleanup container length checks in ME ui

* add retries to tests

* add retries to tests

* fix trainer wave disable override

* add shuckle juice modifier

* add dialogue bug fixes

* add dialogue bug fixes

* add pokemon salesman encounter and affects pokedex UI display

* add unit tests for pokemon salesman

* temp stash

* add offer you can't refuse

* add unit tests for offer you can't refuse encounter

* remove unnecessary prompt handlers

* add tests for disabled encounter options

* add delibird-y encounter

* add delibird-y encounter

* add absolute avarice encounter

* finish absolute avarice encounter

* add unit tests and enhancements for item overrides in tests

* fix unit test

* cleanup absolute avarice PR

* small bug fixes with latest sync from main

* update visuals loading for safari and stat trainer visuals

* update visuals loading for safari and stat trainer visuals

* update a trainer's test encounter and add unit tests

* add Trash to Treasure encounter

* clean up trash to treasure encounter

* clean up trash to treasure encounter

* add berries abound encounter

* start clowning around encounter

* first implementation pass at clowning around

* add unit tests for clowning around

* add unit tests for clowning around

* clean up ME unit tests

* clean up unit tests

* update unit tests

* add part timer and dancing lessons encounters

* add unit tests for Dancing Lessons and Part-Timer

* reordered biome list and adjusted redirection for project and labels

* Add Weird Dream encounter and slight reworks to Berries Abound/Fight or Flight

* adjusting yml to match new labels

* fix yml whoopsie

* Expanded 'Weird Dream' banlist and fixed a bug with the BST bump range

* adds Winstrate Challenge mystery encounter

* small cleanup for winstrates

* add unit tests for Winstrate Challenge

* fix pokemon not returning after winstrate battle

* commit latest beta merge updates

* fix ME null checks and unit tests with beta update

* fix ME null checks and unit tests with beta update

* MEs to pokerogue beta branch

* test dialogue changes

* test patch fix

* test patch fix

* test patch fix

* adds teleporting hijinks encounter

* add unit tests for Teleporting Hijinks

* small change to teleporting hijinks dialogue

* migrate ME translations to json

* add retries to berries-abound.Option1: should reward the player with X berries based on wave

* add missing ME dialogue back in

* revert template changes

* add ME unique trainer dialogue to both dialogue jsons

* fix hanging comma in json

* fix broken imports

* resolve lint issues

* fix flaky test

* balance tweaks to a few MEs, updates to bug superfan

* add unit tests for Bug-Type Superfan and clean up dialogue

* Adds Fun and Games mystery encounter

* add unit tests for Fun and Games encounter

* update jsdoc

* small ME balance changes

* small ME balance changes

* Adds Uncommon Breed ME and misc. ME bug fixes

* Update getFinalSessionData() to collect Mystery Encounter data

* adds GTS encounter

* various ME bug fixes and balance changes

* latest ME bug fixes

* clean up GTS Encounter and add unit tests

* small cleanup to MEs branch

* add BGM music names for ME music

* bug fixes and balance changes for MEs

* ME data schema updates

* balance changes and bug fixes to MEs

* balance changes and bug fixes to MEs

* update tests for MEs

* add jsdoc to party exp function

* dialogue updates and test fixes for MEs

* dialogue updates and test fixes for MEs

* PR suggestions and fixees

* stash PR feedback and bugfixes

* fix all tests for MEs and cleanup

* PR feedback

* update flaky ME test

* update tests, bug fix MEs, and sprite assets

* remove unintentional console log

* re-enable stubbed function for Phaser text styling

* handle undefined introVisuals properly

* PR feedback from NightKev

* disable Uncommon Breed tests

* locales updates and bug fixes for safari zone

* more PR feedback and update field trip with Rarer Candy

* fix unit test

* Change how reroll button gets disabled in Modifier Shop Phase

* update continue button text logic

* Update src/ui/modifier-select-ui-handler.ts

Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>

* fix money formatting and some nits

* more nits

* more nits

* update ME tsdocs with links

* update ME tsdocs with links

---------

Co-authored-by: Felix Staud <felix.staud@headwire.com>
Co-authored-by: flx-sta <50131232+flx-sta@users.noreply.github.com>
Co-authored-by: ImperialSympathizer <imperialsympathizer@gmail.com>
Co-authored-by: InnocentGameDev <asdargmng@gmail.com>
Co-authored-by: Mumble <171087428+frutescens@users.noreply.github.com>
2024-09-14 03:05:58 +01:00

263 lines
8.3 KiB
TypeScript

/* eslint-disable */
// @ts-nocheck
import BattleScene, * as battleScene from "#app/battle-scene";
import { MoveAnim } from "#app/data/battle-anims";
import Pokemon from "#app/field/pokemon";
import * as Utils from "#app/utils";
import { blobToString } from "#test/utils/gameManagerUtils";
import { MockClock } from "#test/utils/mocks/mockClock";
import mockConsoleLog from "#test/utils/mocks/mockConsoleLog";
import { MockFetch } from "#test/utils/mocks/mockFetch";
import MockLoader from "#test/utils/mocks/mockLoader";
import mockLocalStorage from "#test/utils/mocks/mockLocalStorage";
import MockImage from "#test/utils/mocks/mocksContainer/mockImage";
import MockTextureManager from "#test/utils/mocks/mockTextureManager";
import fs from "fs";
import Phaser from "phaser";
import InputText from "phaser3-rex-plugins/plugins/inputtext";
import { vi } from "vitest";
import { MockGameObjectCreator } from "./mocks/mockGameObjectCreator";
import InputManager = Phaser.Input.InputManager;
import KeyboardManager = Phaser.Input.Keyboard.KeyboardManager;
import KeyboardPlugin = Phaser.Input.Keyboard.KeyboardPlugin;
import GamepadPlugin = Phaser.Input.Gamepad.GamepadPlugin;
import EventEmitter = Phaser.Events.EventEmitter;
import UpdateList = Phaser.GameObjects.UpdateList;
Object.defineProperty(window, "localStorage", {
value: mockLocalStorage(),
});
Object.defineProperty(window, "console", {
value: mockConsoleLog(false),
});
InputText.prototype.setElement = () => null;
InputText.prototype.resize = () => null;
Phaser.GameObjects.Image = MockImage;
window.URL.createObjectURL = (blob: Blob) => {
blobToString(blob).then((data: string) => {
localStorage.setItem("toExport", data);
});
return null;
};
navigator.getGamepads = () => [];
global.fetch = vi.fn(MockFetch);
Utils.setCookie(Utils.sessionIdKey, 'fake_token');
window.matchMedia = () => ({
matches: false,
});
/**
* Sets this object's position relative to another object with a given offset
* @param guideObject {@linkcode Phaser.GameObjects.GameObject} to base the position off of
* @param x The relative x position
* @param y The relative y position
*/
const setPositionRelative = function (guideObject: any, x: number, y: number) {
const offsetX = guideObject.width * (-0.5 + (0.5 - guideObject.originX));
const offsetY = guideObject.height * (-0.5 + (0.5 - guideObject.originY));
this.setPosition(guideObject.x + offsetX + x, guideObject.y + offsetY + y);
};
Phaser.GameObjects.Container.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Sprite.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Image.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.NineSlice.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
export default class GameWrapper {
public game: Phaser.Game;
public scene: BattleScene;
constructor(phaserGame: Phaser.Game, bypassLogin: boolean) {
Phaser.Math.RND.sow([ 'test' ]);
vi.spyOn(Utils, "apiFetch", "get").mockReturnValue(fetch);
if (bypassLogin) {
vi.spyOn(battleScene, "bypassLogin", "get").mockReturnValue(true);
}
this.game = phaserGame;
MoveAnim.prototype.getAnim = () => ({
frames: {},
});
Pokemon.prototype.enableMask = () => null;
Pokemon.prototype.updateFusionPalette = () => null;
Pokemon.prototype.cry = () => null;
Pokemon.prototype.faintCry = (cb) => { if (cb) cb(); };
}
setScene(scene: BattleScene) {
this.scene = scene;
this.injectMandatory();
this.scene.preload && this.scene.preload();
this.scene.create();
}
injectMandatory() {
this.game.config = {
seed: ["test"],
};
this.scene.game = this.game;
this.game.renderer = {
maxTextures: -1,
gl: {},
deleteTexture: () => null,
canvasToTexture: () => ({}),
createCanvasTexture: () => ({}),
pipelines: {
add: () => null,
},
};
this.scene.renderer = this.game.renderer;
this.scene.children = {
removeAll: () => null,
};
this.scene.sound = {
play: () => null,
pause: () => null,
setRate: () => null,
add: () => this.scene.sound,
get: () => ({...this.scene.sound, totalDuration: 0}),
getAllPlaying: () => [],
manager: {
game: this.game,
},
destroy: () => null,
setVolume: () => null,
stop: () => null,
stopByKey: () => null,
on: (evt, callback) => callback(),
key: "",
};
this.scene.cameras = {
main: {
setPostPipeline: () => null,
removePostPipeline: () => null,
},
};
this.scene.tweens = {
add: (data) => {
if (data.onComplete) {
data.onComplete();
}
},
getTweensOf: () => ([]),
killTweensOf: () => ([]),
chain: () => null,
addCounter: (data) => {
if (data.onComplete) {
data.onComplete();
}
},
};
this.scene.anims = this.game.anims;
this.scene.cache = this.game.cache;
this.scene.plugins = this.game.plugins;
this.scene.registry = this.game.registry;
this.scene.scale = this.game.scale;
this.scene.textures = this.game.textures;
this.scene.events = this.game.events;
this.scene.manager = new InputManager(this.game, {});
this.scene.manager.keyboard = new KeyboardManager(this.scene);
this.scene.pluginEvents = new EventEmitter();
this.scene.domContainer = {} as HTMLDivElement;
this.scene.spritePipeline = {};
this.scene.fieldSpritePipeline = {};
this.scene.load = new MockLoader(this.scene);
this.scene.sys = {
queueDepthSort: () => null,
anims: this.game.anims,
game: this.game,
textures: {
addCanvas: () => ({
get: () => ({ // this.frame in Text.js
source: {},
setSize: () => null,
glTexture: () => ({
spectorMetadata: {},
}),
}),
})
},
cache: this.scene.load.cacheManager,
scale: this.game.scale,
// _scene.sys.scale = new ScaleManager(_scene);
// events: {
// on: () => null,
// },
events: new EventEmitter(),
settings: {
loader: {
key: 'battle',
}
},
input: this.game.input,
};
const mockTextureManager = new MockTextureManager(this.scene);
this.scene.add = mockTextureManager.add;
this.scene.textures = mockTextureManager;
this.scene.sys.displayList = this.scene.add.displayList;
this.scene.sys.updateList = new UpdateList(this.scene);
this.scene.systems = this.scene.sys;
this.scene.input = this.game.input;
this.scene.scene = this.scene;
this.scene.input.keyboard = new KeyboardPlugin(this.scene);
this.scene.input.gamepad = new GamepadPlugin(this.scene);
this.scene.cachedFetch = (url, init) => {
return new Promise((resolve) => {
// need to remove that if later we want to test battle-anims
const newUrl = url.includes('./battle-anims/') ? prependPath('./battle-anims/tackle.json') : prependPath(url);
let raw;
try {
raw = fs.readFileSync(newUrl, {encoding: "utf8", flag: "r"});
} catch(e) {
return resolve(createFetchBadResponse({}));
}
const data = JSON.parse(raw);
const response = createFetchResponse(data);
return resolve(response);
});
};
this.scene.make = new MockGameObjectCreator(mockTextureManager);
this.scene.time = new MockClock(this.scene);
this.scene.remove = vi.fn(); // TODO: this should be stubbed differently
}
}
function prependPath(originalPath) {
const prefix = "public";
if (originalPath.startsWith("./")) {
return originalPath.replace("./", `${prefix}/`);
}
return originalPath;
}
// Simulate fetch response
function createFetchResponse(data) {
return {
ok: true,
status: 200,
headers: new Headers(),
json: () => Promise.resolve(data),
text: () => Promise.resolve(JSON.stringify(data)),
};
}
// Simulate fetch response
function createFetchBadResponse(data) {
return {
ok: false,
status: 404,
headers: new Headers(),
json: () => Promise.resolve(data),
text: () => Promise.resolve(JSON.stringify(data)),
};
}