Merge branch 'beta' into new-team

This commit is contained in:
Madmadness65 2024-09-20 18:02:43 -05:00
commit 7b5034b288
105 changed files with 1074 additions and 601 deletions

View File

@ -1,7 +1,3 @@
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
/** /**
* This script creates a test boilerplate file for a move or ability. * This script creates a test boilerplate file for a move or ability.
* @param {string} type - The type of test to create. Either "move", "ability", * @param {string} type - The type of test to create. Either "move", "ability",
@ -10,63 +6,108 @@ import { fileURLToPath } from 'url';
* @example npm run create-test move tackle * @example npm run create-test move tackle
*/ */
import fs from "fs";
import inquirer from "inquirer";
import path from "path";
import { fileURLToPath } from "url";
// Get the directory name of the current module file // Get the directory name of the current module file
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
const typeChoices = ["Move", "Ability", "Item", "Mystery Encounter"];
// Get the arguments from the command line /**
const args = process.argv.slice(2); * Prompts the user to select a type via list.
const type = args[0]; // "move" or "ability" * @returns {Promise<{selectedOption: string}>} the selected type
let fileName = args[1]; // The file name */
async function promptTestType() {
const typeAnswer = await inquirer.prompt([
{
type: "list",
name: "selectedOption",
message: "What type of test would you like to create:",
choices: [...typeChoices, "EXIT"],
},
]);
if (!type || !fileName) { if (typeAnswer.selectedOption === "EXIT") {
console.error('Please provide a type ("move", "ability", or "item") and a file name.'); console.log("Exiting...");
process.exit(1); return process.exit();
} else if (!typeChoices.includes(typeAnswer.selectedOption)) {
console.error('Please provide a valid type ("move", "ability", or "item")!');
return await promptTestType();
}
return typeAnswer;
} }
// Convert fileName from kebab-case or camelCase to snake_case /**
fileName = fileName * Prompts the user to provide a file name.
.replace(/-+/g, '_') // Convert kebab-case (dashes) to underscores * @param {string} selectedType
.replace(/([a-z])([A-Z])/g, '$1_$2') // Convert camelCase to snake_case * @returns {Promise<{userInput: string}>} the selected file name
.toLowerCase(); // Ensure all lowercase */
async function promptFileName(selectedType) {
const fileNameAnswer = await inquirer.prompt([
{
type: "input",
name: "userInput",
message: `Please provide a file name for the ${selectedType} test:`,
},
]);
// Format the description for the test case if (!fileNameAnswer.userInput || fileNameAnswer.userInput.trim().length === 0) {
const formattedName = fileName console.error("Please provide a valid file name!");
.replace(/_/g, ' ') return await promptFileName(selectedType);
.replace(/\b\w/g, char => char.toUpperCase()); }
// Determine the directory based on the type return fileNameAnswer;
let dir;
let description;
if (type === 'move') {
dir = path.join(__dirname, 'src', 'test', 'moves');
description = `Moves - ${formattedName}`;
} else if (type === 'ability') {
dir = path.join(__dirname, 'src', 'test', 'abilities');
description = `Abilities - ${formattedName}`;
} else if (type === "item") {
dir = path.join(__dirname, 'src', 'test', 'items');
description = `Items - ${formattedName}`;
} else {
console.error('Invalid type. Please use "move", "ability", or "item".');
process.exit(1);
} }
// Ensure the directory exists /**
if (!fs.existsSync(dir)) { * Runs the interactive create-test "CLI"
fs.mkdirSync(dir, { recursive: true }); * @returns {Promise<void>}
} */
async function runInteractive() {
const typeAnswer = await promptTestType();
const fileNameAnswer = await promptFileName(typeAnswer.selectedOption);
// Create the file with the given name const type = typeAnswer.selectedOption.toLowerCase();
const filePath = path.join(dir, `${fileName}.test.ts`); // Convert fileName from kebab-case or camelCase to snake_case
const fileName = fileNameAnswer.userInput
.replace(/-+/g, "_") // Convert kebab-case (dashes) to underscores
.replace(/([a-z])([A-Z])/g, "$1_$2") // Convert camelCase to snake_case
.replace(/\s+/g, '_') // Replace spaces with underscores
.toLowerCase(); // Ensure all lowercase
// Format the description for the test case
if (fs.existsSync(filePath)) { const formattedName = fileName.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
console.error(`File "${fileName}.test.ts" already exists.`); // Determine the directory based on the type
process.exit(1); let dir;
} let description;
switch (type) {
case "move":
dir = path.join(__dirname, "src", "test", "moves");
description = `Moves - ${formattedName}`;
break;
case "ability":
dir = path.join(__dirname, "src", "test", "abilities");
description = `Abilities - ${formattedName}`;
break;
case "item":
dir = path.join(__dirname, "src", "test", "items");
description = `Items - ${formattedName}`;
break;
case "mystery encounter":
dir = path.join(__dirname, "src", "test", "mystery-encounter", "encounters");
description = `Mystery Encounter - ${formattedName}`;
break;
default:
console.error('Invalid type. Please use "move", "ability", or "item".');
process.exit(1);
}
// Define the content template // Define the content template
const content = `import { Abilities } from "#enums/abilities"; const content = `import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
@ -76,7 +117,6 @@ import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest";
describe("${description}", () => { describe("${description}", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
@ -100,11 +140,27 @@ describe("${description}", () => {
it("test case", async () => { it("test case", async () => {
// await game.classicMode.startBattle([Species.MAGIKARP]); // await game.classicMode.startBattle([Species.MAGIKARP]);
// game.move.select(Moves.SPLASH); // game.move.select(Moves.SPLASH);
}, TIMEOUT); });
}); });
`; `;
// Write the template content to the file // Ensure the directory exists
fs.writeFileSync(filePath, content, 'utf8'); if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
console.log(`File created at: ${filePath}`); // Create the file with the given name
const filePath = path.join(dir, `${fileName}.test.ts`);
if (fs.existsSync(filePath)) {
console.error(`File "${fileName}.test.ts" already exists.`);
process.exit(1);
}
// Write the template content to the file
fs.writeFileSync(filePath, content, "utf8");
console.log(`File created at: ${filePath}`);
}
runInteractive();

453
package-lock.json generated
View File

@ -29,6 +29,7 @@
"dependency-cruiser": "^16.3.10", "dependency-cruiser": "^16.3.10",
"eslint": "^9.7.0", "eslint": "^9.7.0",
"eslint-plugin-import-x": "^4.2.1", "eslint-plugin-import-x": "^4.2.1",
"inquirer": "^11.0.2",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"lefthook": "^1.6.12", "lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
@ -1070,6 +1071,281 @@
"url": "https://github.com/sponsors/nzakas" "url": "https://github.com/sponsors/nzakas"
} }
}, },
"node_modules/@inquirer/checkbox": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-3.0.1.tgz",
"integrity": "sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/figures": "^1.0.6",
"@inquirer/type": "^2.0.0",
"ansi-escapes": "^4.3.2",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/confirm": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-4.0.1.tgz",
"integrity": "sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/core": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz",
"integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/figures": "^1.0.6",
"@inquirer/type": "^2.0.0",
"@types/mute-stream": "^0.0.4",
"@types/node": "^22.5.5",
"@types/wrap-ansi": "^3.0.0",
"ansi-escapes": "^4.3.2",
"cli-width": "^4.1.0",
"mute-stream": "^1.0.0",
"signal-exit": "^4.1.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^6.2.0",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/core/node_modules/@types/node": {
"version": "22.5.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz",
"integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
}
},
"node_modules/@inquirer/core/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/@inquirer/core/node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@inquirer/core/node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true,
"license": "MIT"
},
"node_modules/@inquirer/core/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@inquirer/editor": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-3.0.1.tgz",
"integrity": "sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0",
"external-editor": "^3.1.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/expand": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-3.0.1.tgz",
"integrity": "sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/figures": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz",
"integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/input": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/input/-/input-3.0.1.tgz",
"integrity": "sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/number": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/number/-/number-2.0.1.tgz",
"integrity": "sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/password": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/password/-/password-3.0.1.tgz",
"integrity": "sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0",
"ansi-escapes": "^4.3.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/prompts": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-6.0.1.tgz",
"integrity": "sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/checkbox": "^3.0.1",
"@inquirer/confirm": "^4.0.1",
"@inquirer/editor": "^3.0.1",
"@inquirer/expand": "^3.0.1",
"@inquirer/input": "^3.0.1",
"@inquirer/number": "^2.0.1",
"@inquirer/password": "^3.0.1",
"@inquirer/rawlist": "^3.0.1",
"@inquirer/search": "^2.0.1",
"@inquirer/select": "^3.0.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/rawlist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-3.0.1.tgz",
"integrity": "sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/type": "^2.0.0",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/search": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/search/-/search-2.0.1.tgz",
"integrity": "sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/figures": "^1.0.6",
"@inquirer/type": "^2.0.0",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/select": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@inquirer/select/-/select-3.0.1.tgz",
"integrity": "sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/figures": "^1.0.6",
"@inquirer/type": "^2.0.0",
"ansi-escapes": "^4.3.2",
"yoctocolors-cjs": "^2.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@inquirer/type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz",
"integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==",
"dev": true,
"license": "MIT",
"dependencies": {
"mute-stream": "^1.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@isaacs/cliui": { "node_modules/@isaacs/cliui": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@ -1563,6 +1839,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/mute-stream": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz",
"integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.14.11", "version": "20.14.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
@ -1585,6 +1871,13 @@
"integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==",
"dev": true "dev": true
}, },
"node_modules/@types/wrap-ansi": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz",
"integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==",
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.0.0-alpha.58", "version": "8.0.0-alpha.58",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0-alpha.58.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.0-alpha.58.tgz",
@ -1970,6 +2263,22 @@
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/ansi-escapes": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.21.3"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-regex": { "node_modules/ansi-regex": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@ -2192,6 +2501,13 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true,
"license": "MIT"
},
"node_modules/check-error": { "node_modules/check-error": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
@ -2202,6 +2518,16 @@
"node": ">= 16" "node": ">= 16"
} }
}, },
"node_modules/cli-width": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">= 12"
}
},
"node_modules/cliui": { "node_modules/cliui": {
"version": "8.0.1", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@ -3057,6 +3383,21 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1" "url": "https://github.com/sindresorhus/execa?sponsor=1"
} }
}, },
"node_modules/external-editor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"license": "MIT",
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
"tmp": "^0.0.33"
},
"engines": {
"node": ">=4"
}
},
"node_modules/fast-deep-equal": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@ -3579,6 +3920,19 @@
"i18next": ">=8.4.0" "i18next": ">=8.4.0"
} }
}, },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ignore": { "node_modules/ignore": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@ -3626,6 +3980,26 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0" "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
} }
}, },
"node_modules/inquirer": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-11.0.2.tgz",
"integrity": "sha512-pnbn3nL+JFrTw/pLhzyE/IQ3+gA3n5JxTAZQDjB6qu4gbjOaiTnpZbxT6HY2DDCT7bzDjTTsd3snRP+B6N//Pg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.2.1",
"@inquirer/prompts": "^6.0.1",
"@inquirer/type": "^2.0.0",
"@types/mute-stream": "^0.0.4",
"ansi-escapes": "^4.3.2",
"mute-stream": "^1.0.0",
"run-async": "^3.0.0",
"rxjs": "^7.8.1"
},
"engines": {
"node": ">=18"
}
},
"node_modules/interpret": { "node_modules/interpret": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
@ -4456,6 +4830,16 @@
"mustache": "bin/mustache" "mustache": "bin/mustache"
} }
}, },
"node_modules/mute-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
"integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.7", "version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@ -4605,6 +4989,16 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/p-limit": { "node_modules/p-limit": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@ -5092,6 +5486,16 @@
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
"dev": true "dev": true
}, },
"node_modules/run-async": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
"integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/run-parallel": { "node_modules/run-parallel": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@ -5116,6 +5520,16 @@
"queue-microtask": "^1.2.2" "queue-microtask": "^1.2.2"
} }
}, },
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/safe-regex": { "node_modules/safe-regex": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz",
@ -5538,6 +5952,19 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"license": "MIT",
"dependencies": {
"os-tmpdir": "~1.0.2"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/to-fast-properties": { "node_modules/to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@ -5673,6 +6100,19 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typedoc": { "node_modules/typedoc": {
"version": "0.26.5", "version": "0.26.5",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.5.tgz", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.5.tgz",
@ -6346,6 +6786,19 @@
"funding": { "funding": {
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
},
"node_modules/yoctocolors-cjs": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz",
"integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
} }
} }
} }

View File

@ -33,6 +33,7 @@
"dependency-cruiser": "^16.3.10", "dependency-cruiser": "^16.3.10",
"eslint": "^9.7.0", "eslint": "^9.7.0",
"eslint-plugin-import-x": "^4.2.1", "eslint-plugin-import-x": "^4.2.1",
"inquirer": "^11.0.2",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"lefthook": "^1.6.12", "lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",

View File

@ -782,6 +782,14 @@ export default class BattleScene extends SceneBase {
return this.getPlayerField().find(p => p.isActive()); return this.getPlayerField().find(p => p.isActive());
} }
/**
* Finds the first {@linkcode Pokemon.isActive() | active PlayerPokemon} that isn't also currently switching out
* @returns Either the first {@linkcode PlayerPokemon} satisfying, or undefined if no player pokemon on the field satisfy
*/
getNonSwitchedPlayerPokemon(): PlayerPokemon | undefined {
return this.getPlayerField().find(p => p.isActive() && p.switchOutStatus === false);
}
/** /**
* Returns an array of PlayerPokemon of length 1 or 2 depending on if double battles or not * Returns an array of PlayerPokemon of length 1 or 2 depending on if double battles or not
* @returns array of {@linkcode PlayerPokemon} * @returns array of {@linkcode PlayerPokemon}
@ -799,6 +807,14 @@ export default class BattleScene extends SceneBase {
return this.getEnemyField().find(p => p.isActive()); return this.getEnemyField().find(p => p.isActive());
} }
/**
* Finds the first {@linkcode Pokemon.isActive() | active EnemyPokemon} pokemon from the enemy that isn't also currently switching out
* @returns Either the first {@linkcode EnemyPokemon} satisfying, or undefined if no player pokemon on the field satisfy
*/
getNonSwitchedEnemyPokemon(): EnemyPokemon | undefined {
return this.getEnemyField().find(p => p.isActive() && p.switchOutStatus === false);
}
/** /**
* Returns an array of EnemyPokemon of length 1 or 2 depending on if double battles or not * Returns an array of EnemyPokemon of length 1 or 2 depending on if double battles or not
* @returns array of {@linkcode EnemyPokemon} * @returns array of {@linkcode EnemyPokemon}

View File

@ -428,7 +428,7 @@ class AnimTimedAddBgEvent extends AnimTimedBgEvent {
moveAnim.bgSprite.setScale(1.25); moveAnim.bgSprite.setScale(1.25);
moveAnim.bgSprite.setAlpha(this.opacity / 255); moveAnim.bgSprite.setAlpha(this.opacity / 255);
scene.field.add(moveAnim.bgSprite); scene.field.add(moveAnim.bgSprite);
const fieldPokemon = scene.getEnemyPokemon() || scene.getPlayerPokemon(); const fieldPokemon = scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon();
if (!isNullOrUndefined(priority)) { if (!isNullOrUndefined(priority)) {
scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority!); scene.field.moveTo(moveAnim.bgSprite as Phaser.GameObjects.GameObject, priority!);
} else if (fieldPokemon?.isOnField()) { } else if (fieldPokemon?.isOnField()) {
@ -989,7 +989,7 @@ export abstract class BattleAnim {
const setSpritePriority = (priority: integer) => { const setSpritePriority = (priority: integer) => {
switch (priority) { switch (priority) {
case 0: case 0:
scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getEnemyPokemon() || scene.getPlayerPokemon()!); // TODO: is this bang correct? scene.field.moveBelow(moveSprite as Phaser.GameObjects.GameObject, scene.getNonSwitchedEnemyPokemon() || scene.getNonSwitchedPlayerPokemon()!); // This bang assumes that if (the EnemyPokemon is undefined, then the PlayerPokemon function must return an object), correct assumption?
break; break;
case 1: case 1:
scene.field.moveTo(moveSprite, scene.field.getAll().length - 1); scene.field.moveTo(moveSprite, scene.field.getAll().length - 1);

View File

@ -5221,7 +5221,6 @@ export class ForceSwitchOutAttr extends MoveEffectAttr {
switchOutTarget.leaveField(false); switchOutTarget.leaveField(false);
if (switchOutTarget.hp) { if (switchOutTarget.hp) {
switchOutTarget.setWildFlee(true);
user.scene.queueMessage(i18next.t("moveTriggers:fled", {pokemonName: getPokemonNameWithAffix(switchOutTarget)}), null, true, 500); user.scene.queueMessage(i18next.t("moveTriggers:fled", {pokemonName: getPokemonNameWithAffix(switchOutTarget)}), null, true, 500);
// in double battles redirect potential moves off fled pokemon // in double battles redirect potential moves off fled pokemon

View File

@ -162,10 +162,10 @@ export const BerriesAboundEncounter: MysteryEncounter =
.withOptionPhase(async (scene: BattleScene) => { .withOptionPhase(async (scene: BattleScene) => {
// Pick race for berries // Pick race for berries
const encounter = scene.currentBattle.mysteryEncounter!; const encounter = scene.currentBattle.mysteryEncounter!;
const fastestPokemon = encounter.misc.fastestPokemon; const fastestPokemon: PlayerPokemon = encounter.misc.fastestPokemon;
const enemySpeed = encounter.misc.enemySpeed; const enemySpeed: number = encounter.misc.enemySpeed;
const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1); const speedDiff = fastestPokemon.getStat(Stat.SPD) / (enemySpeed * 1.1);
const numBerries = encounter.misc.numBerries; const numBerries: number = encounter.misc.numBerries;
const shopOptions: ModifierTypeOption[] = []; const shopOptions: ModifierTypeOption[] = [];
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {

View File

@ -379,7 +379,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
trainerType: TrainerType.EXPERT_POKEMON_BREEDER, trainerType: TrainerType.EXPERT_POKEMON_BREEDER,
pokemonConfigs: [ pokemonConfigs: [
{ {
nickname: i18next.t(`${namespace}.cleffa_1_nickname`), nickname: i18next.t(`${namespace}.cleffa_1_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
species: getPokemonSpecies(cleffaSpecies), species: getPokemonSpecies(cleffaSpecies),
isBoss: false, isBoss: false,
abilityIndex: 1, // Magic Guard abilityIndex: 1, // Magic Guard
@ -407,7 +407,7 @@ function getPartyConfig(scene: BattleScene): EnemyPartyConfig {
if (scene.arena.biomeType === Biome.SPACE) { if (scene.arena.biomeType === Biome.SPACE) {
// All 3 members always Cleffa line, but different configs // All 3 members always Cleffa line, but different configs
baseConfig.pokemonConfigs!.push({ baseConfig.pokemonConfigs!.push({
nickname: i18next.t(`${namespace}.cleffa_2_nickname`), nickname: i18next.t(`${namespace}.cleffa_2_nickname`, { speciesName: getPokemonSpecies(cleffaSpecies).getName() }),
species: getPokemonSpecies(cleffaSpecies), species: getPokemonSpecies(cleffaSpecies),
isBoss: false, isBoss: false,
abilityIndex: 1, // Magic Guard abilityIndex: 1, // Magic Guard

View File

@ -949,7 +949,7 @@ export class TrainerConfig {
if (!getIsInitialized()) { if (!getIsInitialized()) {
initI18n(); initI18n();
} }
this.name = i18next.t(`trainerNames:${name.toLowerCase()}`); this.name = i18next.t(`trainerNames:${name.toLowerCase().replace(/\s/g, "_")}`);
return this; return this;
} }
@ -2439,7 +2439,7 @@ export const trainerConfigs: TrainerConfigs = {
.setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(2, PartyMemberStrength.STRONG))), .setPartyTemplates(new TrainerPartyCompoundTemplate(new TrainerPartyTemplate(3, PartyMemberStrength.AVERAGE), new TrainerPartyTemplate(2, PartyMemberStrength.STRONG))),
[TrainerType.BUG_TYPE_SUPERFAN]: new TrainerConfig(++t).setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER) [TrainerType.BUG_TYPE_SUPERFAN]: new TrainerConfig(++t).setMoneyMultiplier(2.25).setEncounterBgm(TrainerType.ACE_TRAINER)
.setPartyTemplates(new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE)), .setPartyTemplates(new TrainerPartyTemplate(2, PartyMemberStrength.AVERAGE)),
[TrainerType.EXPERT_POKEMON_BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(3).setEncounterBgm(TrainerType.ACE_TRAINER) [TrainerType.EXPERT_POKEMON_BREEDER]: new TrainerConfig(++t).setMoneyMultiplier(3).setEncounterBgm(TrainerType.ACE_TRAINER).setLocalizedName("Expert Pokemon Breeder")
.setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.STRONG)) .setPartyTemplates(new TrainerPartyTemplate(3, PartyMemberStrength.STRONG))
}; };

View File

@ -99,7 +99,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
public luck: integer; public luck: integer;
public pauseEvolutions: boolean; public pauseEvolutions: boolean;
public pokerus: boolean; public pokerus: boolean;
public wildFlee: boolean; public switchOutStatus: boolean;
public evoCounter: integer; public evoCounter: integer;
public fusionSpecies: PokemonSpecies | null; public fusionSpecies: PokemonSpecies | null;
@ -145,7 +145,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.species = species; this.species = species;
this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL; this.pokeball = dataSource?.pokeball || PokeballType.POKEBALL;
this.level = level; this.level = level;
this.wildFlee = false; this.switchOutStatus = false;
// Determine the ability index // Determine the ability index
if (abilityIndex !== undefined) { if (abilityIndex !== undefined) {
@ -343,7 +343,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
isAllowed(): boolean { isAllowed(): boolean {
const challengeAllowed = new Utils.BooleanHolder(true); const challengeAllowed = new Utils.BooleanHolder(true);
applyChallenges(this.scene.gameMode, ChallengeType.POKEMON_IN_BATTLE, this, challengeAllowed); applyChallenges(this.scene.gameMode, ChallengeType.POKEMON_IN_BATTLE, this, challengeAllowed);
return !this.wildFlee && challengeAllowed.value; return !this.isFainted() && challengeAllowed.value;
} }
isActive(onField?: boolean): boolean { isActive(onField?: boolean): boolean {
@ -2152,11 +2152,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
/** /**
* sets if the pokemon has fled (implies it's a wild pokemon) * sets if the pokemon is switching out (if it's a enemy wild implies it's going to flee)
* @param status - boolean * @param status - boolean
*/ */
setWildFlee(status: boolean): void { setSwitchOutStatus(status: boolean): void {
this.wildFlee = status; this.switchOutStatus = status;
} }
updateInfo(instant?: boolean): Promise<void> { updateInfo(instant?: boolean): Promise<void> {
@ -3384,6 +3384,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.updateFusionPalette(); this.updateFusionPalette();
} }
this.summonData = new PokemonSummonData(); this.summonData = new PokemonSummonData();
this.setSwitchOutStatus(false);
if (!this.battleData) { if (!this.battleData) {
this.resetBattleData(); this.resetBattleData();
} }
@ -3789,6 +3790,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.hideInfo(); this.hideInfo();
} }
this.scene.field.remove(this); this.scene.field.remove(this);
this.setSwitchOutStatus(true);
this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true); this.scene.triggerPokemonFormChange(this, SpeciesFormChangeActiveTrigger, true);
} }
@ -4747,8 +4749,15 @@ export class EnemyPokemon extends Pokemon {
return true; return true;
} }
/**
* Go through a boss' health segments and give stats boosts for each newly cleared segment
* The base boost is 1 to a random stat that's not already maxed out per broken shield
* For Pokemon with 3 health segments or more, breaking the last shield gives +2 instead
* For Pokemon with 5 health segments or more, breaking the last two shields give +2 each
* @param segmentIndex index of the segment to get down to (0 = no shield left, 1 = 1 shield left, etc.)
*/
handleBossSegmentCleared(segmentIndex: integer): void { handleBossSegmentCleared(segmentIndex: integer): void {
while (segmentIndex - 1 < this.bossSegmentIndex) { while (this.bossSegmentIndex > 0 && segmentIndex - 1 < this.bossSegmentIndex) {
// Filter out already maxed out stat stages and weigh the rest based on existing stats // Filter out already maxed out stat stages and weigh the rest based on existing stats
const leftoverStats = EFFECTIVE_STATS.filter((s: EffectiveStat) => this.getStatStage(s) < 6); const leftoverStats = EFFECTIVE_STATS.filter((s: EffectiveStat) => this.getStatStage(s) < 6);
const statWeights = leftoverStats.map((s: EffectiveStat) => this.getStat(s, false)); const statWeights = leftoverStats.map((s: EffectiveStat) => this.getStat(s, false));

View File

@ -40,7 +40,7 @@ export class EggLapsePhase extends Phase {
this.showSummary(); this.showSummary();
}, () => { }, () => {
this.hatchEggsRegular(eggsToHatch); this.hatchEggsRegular(eggsToHatch);
this.showSummary(); this.end();
} }
); );
}, 100, true); }, 100, true);

View File

@ -7,7 +7,7 @@ import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - BATTLE BOND", () => { describe("Abilities - BATTLE BOND", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,6 +60,5 @@ describe("Abilities - BATTLE BOND", () => {
expect(greninja!.formIndex).toBe(baseForm); expect(greninja!.formIndex).toBe(baseForm);
}, },
TIMEOUT
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - COSTAR", () => { describe("Abilities - COSTAR", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -59,7 +59,6 @@ describe("Abilities - COSTAR", () => {
expect(leftPokemon.getStatStage(Stat.SPATK)).toBe(2); expect(leftPokemon.getStatStage(Stat.SPATK)).toBe(2);
expect(rightPokemon.getStatStage(Stat.SPATK)).toBe(2); expect(rightPokemon.getStatStage(Stat.SPATK)).toBe(2);
}, },
TIMEOUT,
); );
test( test(
@ -83,6 +82,5 @@ describe("Abilities - COSTAR", () => {
expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(leftPokemon.getStatStage(Stat.ATK)).toBe(-2);
expect(rightPokemon.getStatStage(Stat.ATK)).toBe(-2); expect(rightPokemon.getStatStage(Stat.ATK)).toBe(-2);
}, },
TIMEOUT,
); );
}); });

View File

@ -7,7 +7,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Dancer", () => { describe("Abilities - Dancer", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,5 +60,5 @@ describe("Abilities - Dancer", () => {
// doesn't use PP if copied move is also in moveset // doesn't use PP if copied move is also in moveset
expect(oricorio.moveset[0]?.ppUsed).toBe(0); expect(oricorio.moveset[0]?.ppUsed).toBe(0);
}, TIMEOUT); });
}); });

View File

@ -7,7 +7,7 @@ import { Stat } from "#enums/stat";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Disguise", () => { describe("Abilities - Disguise", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -33,7 +33,7 @@ describe("Abilities - Disguise", () => {
.enemyMoveset(Moves.SPLASH) .enemyMoveset(Moves.SPLASH)
.starterSpecies(Species.REGIELEKI) .starterSpecies(Species.REGIELEKI)
.moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]); .moveset([Moves.SHADOW_SNEAK, Moves.VACUUM_WAVE, Moves.TOXIC_THREAD, Moves.SPLASH]);
}, TIMEOUT); });
it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => { it("takes no damage from attacking move and transforms to Busted form, takes 1/8 max HP damage from the disguise breaking", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -50,7 +50,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.hp).equals(maxHp - disguiseDamage); expect(mimikyu.hp).equals(maxHp - disguiseDamage);
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); });
it("doesn't break disguise when attacked with ineffective move", async () => { it("doesn't break disguise when attacked with ineffective move", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -64,7 +64,7 @@ describe("Abilities - Disguise", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
}, TIMEOUT); });
it("takes no damage from the first hit of a multihit move and transforms to Busted form, then takes damage from the second hit", async () => { it("takes no damage from the first hit of a multihit move and transforms to Busted form, then takes damage from the second hit", async () => {
game.override.moveset([ Moves.SURGING_STRIKES ]); game.override.moveset([ Moves.SURGING_STRIKES ]);
@ -88,7 +88,7 @@ describe("Abilities - Disguise", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(mimikyu.hp).lessThan(maxHp - disguiseDamage); expect(mimikyu.hp).lessThan(maxHp - disguiseDamage);
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); });
it("takes effects from status moves and damage from status effects", async () => { it("takes effects from status moves and damage from status effects", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -104,7 +104,7 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.status?.effect).toBe(StatusEffect.POISON); expect(mimikyu.status?.effect).toBe(StatusEffect.POISON);
expect(mimikyu.getStatStage(Stat.SPD)).toBe(-1); expect(mimikyu.getStatStage(Stat.SPD)).toBe(-1);
expect(mimikyu.hp).toBeLessThan(mimikyu.getMaxHp()); expect(mimikyu.hp).toBeLessThan(mimikyu.getMaxHp());
}, TIMEOUT); });
it("persists form change when switched out", async () => { it("persists form change when switched out", async () => {
game.override.enemyMoveset([Moves.SHADOW_SNEAK]); game.override.enemyMoveset([Moves.SHADOW_SNEAK]);
@ -129,7 +129,7 @@ describe("Abilities - Disguise", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); });
it("persists form change when wave changes with no arena reset", async () => { it("persists form change when wave changes with no arena reset", async () => {
game.override.starterSpecies(0); game.override.starterSpecies(0);
@ -146,7 +146,7 @@ describe("Abilities - Disguise", () => {
await game.toNextWave(); await game.toNextWave();
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
}, TIMEOUT); });
it("reverts to Disguised form on arena reset", async () => { it("reverts to Disguised form on arena reset", async () => {
game.override.startingWave(4); game.override.startingWave(4);
@ -166,7 +166,7 @@ describe("Abilities - Disguise", () => {
await game.toNextWave(); await game.toNextWave();
expect(mimikyu.formIndex).toBe(disguisedForm); expect(mimikyu.formIndex).toBe(disguisedForm);
}, TIMEOUT); });
it("reverts to Disguised form on biome change when fainted", async () => { it("reverts to Disguised form on biome change when fainted", async () => {
game.override.startingWave(10); game.override.startingWave(10);
@ -190,7 +190,7 @@ describe("Abilities - Disguise", () => {
await game.phaseInterceptor.to("PartyHealPhase"); await game.phaseInterceptor.to("PartyHealPhase");
expect(mimikyu1.formIndex).toBe(disguisedForm); expect(mimikyu1.formIndex).toBe(disguisedForm);
}, TIMEOUT); });
it("doesn't faint twice when fainting due to Disguise break damage, nor prevent faint from Disguise break damage if using Endure", async () => { it("doesn't faint twice when fainting due to Disguise break damage, nor prevent faint from Disguise break damage if using Endure", async () => {
game.override.enemyMoveset([Moves.ENDURE]); game.override.enemyMoveset([Moves.ENDURE]);
@ -204,7 +204,7 @@ describe("Abilities - Disguise", () => {
expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase"); expect(game.scene.getCurrentPhase()?.constructor.name).toBe("CommandPhase");
expect(game.scene.currentBattle.waveIndex).toBe(2); expect(game.scene.currentBattle.waveIndex).toBe(2);
}, TIMEOUT); });
it("activates when Aerilate circumvents immunity to the move's base type", async () => { it("activates when Aerilate circumvents immunity to the move's base type", async () => {
game.override.ability(Abilities.AERILATE); game.override.ability(Abilities.AERILATE);
@ -222,5 +222,5 @@ describe("Abilities - Disguise", () => {
expect(mimikyu.formIndex).toBe(bustedForm); expect(mimikyu.formIndex).toBe(bustedForm);
expect(mimikyu.hp).toBe(maxHp - disguiseDamage); expect(mimikyu.hp).toBe(maxHp - disguiseDamage);
}, TIMEOUT); });
}); });

View File

@ -9,7 +9,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Galvanize", () => { describe("Abilities - Galvanize", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -59,7 +59,7 @@ describe("Abilities - Galvanize", () => {
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.EFFECTIVE); expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.EFFECTIVE);
expect(move.calculateBattlePower).toHaveReturnedWith(48); expect(move.calculateBattlePower).toHaveReturnedWith(48);
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT); });
it("should cause Normal-type attacks to activate Volt Absorb", async () => { it("should cause Normal-type attacks to activate Volt Absorb", async () => {
game.override.enemyAbility(Abilities.VOLT_ABSORB); game.override.enemyAbility(Abilities.VOLT_ABSORB);
@ -81,7 +81,7 @@ describe("Abilities - Galvanize", () => {
expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC); expect(playerPokemon.getMoveType).toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT); expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT); });
it("should not change the type of variable-type moves", async () => { it("should not change the type of variable-type moves", async () => {
game.override.enemySpecies(Species.MIGHTYENA); game.override.enemySpecies(Species.MIGHTYENA);
@ -100,7 +100,7 @@ describe("Abilities - Galvanize", () => {
expect(playerPokemon.getMoveType).not.toHaveLastReturnedWith(Type.ELECTRIC); expect(playerPokemon.getMoveType).not.toHaveLastReturnedWith(Type.ELECTRIC);
expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT); expect(enemyPokemon.apply).toHaveReturnedWith(HitResult.NO_EFFECT);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT); });
it("should affect all hits of a Normal-type multi-hit move", async () => { it("should affect all hits of a Normal-type multi-hit move", async () => {
await game.startBattle(); await game.startBattle();
@ -128,5 +128,5 @@ describe("Abilities - Galvanize", () => {
} }
expect(enemyPokemon.apply).not.toHaveReturnedWith(HitResult.NO_EFFECT); expect(enemyPokemon.apply).not.toHaveReturnedWith(HitResult.NO_EFFECT);
}, TIMEOUT); });
}); });

View File

@ -10,8 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Abilities - Gorilla Tactics", () => { describe("Abilities - Gorilla Tactics", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -49,7 +47,7 @@ describe("Abilities - Gorilla Tactics", () => {
// Other moves should be restricted // Other moves should be restricted
expect(darmanitan.isMoveRestricted(Moves.TACKLE)).toBe(true); expect(darmanitan.isMoveRestricted(Moves.TACKLE)).toBe(true);
expect(darmanitan.isMoveRestricted(Moves.SPLASH)).toBe(false); expect(darmanitan.isMoveRestricted(Moves.SPLASH)).toBe(false);
}, TIMEOUT); });
it("should struggle if the only usable move is disabled", async () => { it("should struggle if the only usable move is disabled", async () => {
await game.classicMode.startBattle([Species.GALAR_DARMANITAN]); await game.classicMode.startBattle([Species.GALAR_DARMANITAN]);
@ -79,5 +77,5 @@ describe("Abilities - Gorilla Tactics", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(darmanitan.hp).toBeLessThan(darmanitan.getMaxHp()); expect(darmanitan.hp).toBeLessThan(darmanitan.getMaxHp());
}, TIMEOUT); });
}); });

View File

@ -12,7 +12,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Libero", () => { describe("Abilities - Libero", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -52,7 +52,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH);
}, },
TIMEOUT,
); );
test.skip( test.skip(
@ -92,7 +91,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH);
}, },
TIMEOUT,
); );
test( test(
@ -115,7 +113,6 @@ describe("Abilities - Libero", () => {
moveType = Type[Type.FIRE]; moveType = Type[Type.FIRE];
expect(leadPokemonType).toBe(moveType); expect(leadPokemonType).toBe(moveType);
}, },
TIMEOUT,
); );
test( test(
@ -138,7 +135,6 @@ describe("Abilities - Libero", () => {
moveType = Type[Type.ICE]; moveType = Type[Type.ICE];
expect(leadPokemonType).toBe(moveType); expect(leadPokemonType).toBe(moveType);
}, },
TIMEOUT,
); );
test( test(
@ -157,7 +153,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.AIR_SLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.AIR_SLASH);
}, },
TIMEOUT,
); );
test( test(
@ -175,7 +170,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.DIG); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.DIG);
}, },
TIMEOUT,
); );
test( test(
@ -197,7 +191,6 @@ describe("Abilities - Libero", () => {
expect(enemyPokemon.isFullHp()).toBe(true); expect(enemyPokemon.isFullHp()).toBe(true);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -216,7 +209,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -235,7 +227,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -254,7 +245,6 @@ describe("Abilities - Libero", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO);
}, },
TIMEOUT,
); );
test( test(
@ -274,7 +264,6 @@ describe("Abilities - Libero", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO);
}, },
TIMEOUT,
); );
test( test(
@ -292,7 +281,6 @@ describe("Abilities - Libero", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO);
}, },
TIMEOUT,
); );
test( test(
@ -310,7 +298,6 @@ describe("Abilities - Libero", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.LIBERO);
}, },
TIMEOUT,
); );
test( test(
@ -329,7 +316,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TRICK_OR_TREAT); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TRICK_OR_TREAT);
}, },
TIMEOUT,
); );
test( test(
@ -348,7 +334,6 @@ describe("Abilities - Libero", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE);
expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined); expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined);
}, },
TIMEOUT,
); );
}); });

View File

@ -11,8 +11,6 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000; // 20 sec timeout
describe("Abilities - Magic Guard", () => { describe("Abilities - Magic Guard", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -67,7 +65,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -91,7 +89,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(getStatusEffectCatchRateMultiplier(leadPokemon.status!.effect)).toBe(1.5); expect(getStatusEffectCatchRateMultiplier(leadPokemon.status!.effect)).toBe(1.5);
}, TIMEOUT }
); );
it( it(
@ -113,7 +111,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (that just lost its Magic Guard ability) has taken damage from poison * - The player Pokemon (that just lost its Magic Guard ability) has taken damage from poison
*/ */
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
@ -138,7 +136,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status!.effect)).toBe(1.5); expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status!.effect)).toBe(1.5);
}, TIMEOUT }
); );
it("Magic Guard prevents damage caused by toxic but other non-damaging effects are still applied", it("Magic Guard prevents damage caused by toxic but other non-damaging effects are still applied",
@ -166,7 +164,7 @@ describe("Abilities - Magic Guard", () => {
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(enemyPokemon.status!.turnCount).toBeGreaterThan(toxicStartCounter); expect(enemyPokemon.status!.turnCount).toBeGreaterThan(toxicStartCounter);
expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status!.effect)).toBe(1.5); expect(getStatusEffectCatchRateMultiplier(enemyPokemon.status!.effect)).toBe(1.5);
}, TIMEOUT }
); );
@ -191,7 +189,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard does not prevent poison from Toxic Spikes", async () => { it("Magic Guard does not prevent poison from Toxic Spikes", async () => {
@ -220,7 +218,7 @@ describe("Abilities - Magic Guard", () => {
expect(enemyPokemon.status!.effect).toBe(StatusEffect.POISON); expect(enemyPokemon.status!.effect).toBe(StatusEffect.POISON);
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents against damage from volatile status effects", it("Magic Guard prevents against damage from volatile status effects",
@ -246,7 +244,7 @@ describe("Abilities - Magic Guard", () => {
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
expect(enemyPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined); expect(enemyPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents crash damage", async () => { it("Magic Guard prevents crash damage", async () => {
@ -265,7 +263,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) misses High Jump Kick but does not lose HP as a result * - The player Pokemon (with Magic Guard) misses High Jump Kick but does not lose HP as a result
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents damage from recoil", async () => { it("Magic Guard prevents damage from recoil", async () => {
@ -283,7 +281,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) uses a recoil move but does not lose HP from recoil * - The player Pokemon (with Magic Guard) uses a recoil move but does not lose HP from recoil
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard does not prevent damage from Struggle's recoil", async () => { it("Magic Guard does not prevent damage from Struggle's recoil", async () => {
@ -301,7 +299,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) uses Struggle but does lose HP from Struggle's recoil * - The player Pokemon (with Magic Guard) uses Struggle but does lose HP from Struggle's recoil
*/ */
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
//This tests different move attributes than the recoil tests above //This tests different move attributes than the recoil tests above
@ -320,7 +318,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) uses a move with an HP cost but does not lose HP from using it * - The player Pokemon (with Magic Guard) uses a move with an HP cost but does not lose HP from using it
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
/* /*
@ -348,7 +346,7 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) uses a non-attacking move with an HP cost and thus loses HP from using it * - The player Pokemon (with Magic Guard) uses a non-attacking move with an HP cost and thus loses HP from using it
*/ */
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents damage from abilities with PostTurnHurtIfSleepingAbAttr", async () => { it("Magic Guard prevents damage from abilities with PostTurnHurtIfSleepingAbAttr", async () => {
@ -373,7 +371,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(leadPokemon.status!.effect).toBe(StatusEffect.SLEEP); expect(leadPokemon.status!.effect).toBe(StatusEffect.SLEEP);
}, TIMEOUT }
); );
it("Magic Guard prevents damage from abilities with PostFaintContactDamageAbAttr", async () => { it("Magic Guard prevents damage from abilities with PostFaintContactDamageAbAttr", async () => {
@ -398,7 +396,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(enemyPokemon.hp).toBe(0); expect(enemyPokemon.hp).toBe(0);
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents damage from abilities with PostDefendContactDamageAbAttr", async () => { it("Magic Guard prevents damage from abilities with PostDefendContactDamageAbAttr", async () => {
@ -422,7 +420,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents damage from abilities with ReverseDrainAbAttr", async () => { it("Magic Guard prevents damage from abilities with ReverseDrainAbAttr", async () => {
@ -446,7 +444,7 @@ describe("Abilities - Magic Guard", () => {
*/ */
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
it("Magic Guard prevents HP loss from abilities with PostWeatherLapseDamageAbAttr", async () => { it("Magic Guard prevents HP loss from abilities with PostWeatherLapseDamageAbAttr", async () => {
@ -464,6 +462,6 @@ describe("Abilities - Magic Guard", () => {
* - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute * - The player Pokemon (with Magic Guard) should not lose HP due to this ability attribute
*/ */
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Parental Bond", () => { describe("Abilities - Parental Bond", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -62,7 +62,7 @@ describe("Abilities - Parental Bond", () => {
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
expect(secondStrikeDamage).toBe(toDmgValue(0.25 * firstStrikeDamage)); expect(secondStrikeDamage).toBe(toDmgValue(0.25 * firstStrikeDamage));
}, TIMEOUT }
); );
it( it(
@ -81,7 +81,7 @@ describe("Abilities - Parental Bond", () => {
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -98,7 +98,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
}, TIMEOUT }
); );
it( it(
@ -116,7 +116,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -133,7 +133,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("DamagePhase", false); await game.phaseInterceptor.to("DamagePhase", false);
expect(leadPokemon.turnData.hitCount).toBe(1); expect(leadPokemon.turnData.hitCount).toBe(1);
}, TIMEOUT }
); );
it( it(
@ -151,7 +151,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("DamagePhase", false); await game.phaseInterceptor.to("DamagePhase", false);
expect(leadPokemon.turnData.hitCount).toBe(1); expect(leadPokemon.turnData.hitCount).toBe(1);
}, TIMEOUT }
); );
it( it(
@ -167,7 +167,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - 80); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - 80);
}, TIMEOUT }
); );
it( it(
@ -189,7 +189,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - 4 * playerDamage); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp() - 4 * playerDamage);
}, TIMEOUT }
); );
it( it(
@ -209,7 +209,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
playerPokemon.forEach(p => expect(p.turnData.hitCount).toBe(1)); playerPokemon.forEach(p => expect(p.turnData.hitCount).toBe(1));
}, TIMEOUT }
); );
it( it(
@ -225,7 +225,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("DamagePhase", false); await game.phaseInterceptor.to("DamagePhase", false);
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -247,7 +247,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() / 2)); expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() / 2));
}, TIMEOUT }
); );
it( it(
@ -271,7 +271,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.isOfType(Type.FIRE)).toBe(false); expect(leadPokemon.isOfType(Type.FIRE)).toBe(false);
}, TIMEOUT }
); );
it( it(
@ -289,7 +289,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("DamagePhase"); await game.phaseInterceptor.to("DamagePhase");
expect(leadPokemon.turnData.hitCount).toBe(4); expect(leadPokemon.turnData.hitCount).toBe(4);
}, TIMEOUT }
); );
it( it(
@ -313,7 +313,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
expect(enemyPokemon.hp).toBe(Math.ceil(enemyPokemon.getMaxHp() * 0.25)); expect(enemyPokemon.hp).toBe(Math.ceil(enemyPokemon.getMaxHp() * 0.25));
}, TIMEOUT }
); );
it( it(
@ -339,7 +339,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
expect(enemyPokemon.hp).toBe(enemyStartingHp - 200); expect(enemyPokemon.hp).toBe(enemyStartingHp - 200);
}, TIMEOUT }
); );
it( it(
@ -362,7 +362,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(leadPokemon.getTag(BattlerTagType.RECHARGING)).toBeDefined(); expect(leadPokemon.getTag(BattlerTagType.RECHARGING)).toBeDefined();
}, TIMEOUT }
); );
it( it(
@ -389,7 +389,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined(); expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined();
}, TIMEOUT }
); );
it( it(
@ -413,7 +413,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined();
}, TIMEOUT }
); );
it( it(
@ -433,7 +433,7 @@ describe("Abilities - Parental Bond", () => {
// This will cause this test to time out if the switch was forced on the first hit. // This will cause this test to time out if the switch was forced on the first hit.
await game.phaseInterceptor.to("MoveEffectPhase", false); await game.phaseInterceptor.to("MoveEffectPhase", false);
}, TIMEOUT }
); );
it( it(
@ -457,7 +457,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).toBeUndefined(); expect(enemyPokemon.status?.effect).toBeUndefined();
}, TIMEOUT }
); );
it( it(
@ -475,7 +475,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(-1);
}, TIMEOUT }
); );
it( it(
@ -493,7 +493,7 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(1); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(1);
}, TIMEOUT }
); );
it( it(
@ -519,6 +519,6 @@ describe("Abilities - Parental Bond", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
enemyPokemon.forEach((p, i) => expect(enemyStartingHp[i] - p.hp).toBe(2 * enemyFirstHitDamage[i])); enemyPokemon.forEach((p, i) => expect(enemyStartingHp[i] - p.hp).toBe(2 * enemyFirstHitDamage[i]));
}, TIMEOUT }
); );
}); });

View File

@ -7,7 +7,7 @@ import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - POWER CONSTRUCT", () => { describe("Abilities - POWER CONSTRUCT", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,6 +60,5 @@ describe("Abilities - POWER CONSTRUCT", () => {
expect(zygarde!.formIndex).toBe(baseForm); expect(zygarde!.formIndex).toBe(baseForm);
}, },
TIMEOUT
); );
}); });

View File

@ -12,7 +12,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Protean", () => { describe("Abilities - Protean", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -52,7 +52,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH);
}, },
TIMEOUT,
); );
test.skip( test.skip(
@ -92,7 +91,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.SPLASH);
}, },
TIMEOUT,
); );
test( test(
@ -115,7 +113,6 @@ describe("Abilities - Protean", () => {
moveType = Type[Type.FIRE]; moveType = Type[Type.FIRE];
expect(leadPokemonType).toBe(moveType); expect(leadPokemonType).toBe(moveType);
}, },
TIMEOUT,
); );
test( test(
@ -138,7 +135,6 @@ describe("Abilities - Protean", () => {
moveType = Type[Type.ICE]; moveType = Type[Type.ICE];
expect(leadPokemonType).toBe(moveType); expect(leadPokemonType).toBe(moveType);
}, },
TIMEOUT,
); );
test( test(
@ -157,7 +153,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.AIR_SLASH); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.AIR_SLASH);
}, },
TIMEOUT,
); );
test( test(
@ -175,7 +170,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.DIG); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.DIG);
}, },
TIMEOUT,
); );
test( test(
@ -197,7 +191,6 @@ describe("Abilities - Protean", () => {
expect(enemyPokemon.isFullHp()).toBe(true); expect(enemyPokemon.isFullHp()).toBe(true);
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -216,7 +209,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -235,7 +227,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TACKLE);
}, },
TIMEOUT,
); );
test( test(
@ -254,7 +245,6 @@ describe("Abilities - Protean", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN);
}, },
TIMEOUT,
); );
test( test(
@ -274,7 +264,6 @@ describe("Abilities - Protean", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN);
}, },
TIMEOUT,
); );
test( test(
@ -292,7 +281,6 @@ describe("Abilities - Protean", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN);
}, },
TIMEOUT,
); );
test( test(
@ -310,7 +298,6 @@ describe("Abilities - Protean", () => {
expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN); expect(leadPokemon.summonData.abilitiesApplied).not.toContain(Abilities.PROTEAN);
}, },
TIMEOUT,
); );
test( test(
@ -329,7 +316,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TRICK_OR_TREAT); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.TRICK_OR_TREAT);
}, },
TIMEOUT,
); );
test( test(
@ -348,7 +334,6 @@ describe("Abilities - Protean", () => {
testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE); testPokemonTypeMatchesDefaultMoveType(leadPokemon, Moves.CURSE);
expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined); expect(leadPokemon.getTag(BattlerTagType.CURSED)).not.toBe(undefined);
}, },
TIMEOUT,
); );
}); });

View File

@ -55,7 +55,6 @@ describe("Abilities - Quick Draw", () => {
}, 20000); }, 20000);
test("does not triggered by non damage moves", { test("does not triggered by non damage moves", {
timeout: 20000,
retry: 5 retry: 5
}, async () => { }, async () => {
await game.startBattle(); await game.startBattle();

View File

@ -11,7 +11,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Sand Veil", () => { describe("Abilities - Sand Veil", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -75,6 +75,6 @@ describe("Abilities - Sand Veil", () => {
expect(leadPokemon[0].isFullHp()).toBe(true); expect(leadPokemon[0].isFullHp()).toBe(true);
expect(leadPokemon[1].hp).toBeLessThan(leadPokemon[1].getMaxHp()); expect(leadPokemon[1].hp).toBeLessThan(leadPokemon[1].getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -7,7 +7,7 @@ import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - SCHOOLING", () => { describe("Abilities - SCHOOLING", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,6 +60,5 @@ describe("Abilities - SCHOOLING", () => {
expect(wishiwashi.formIndex).toBe(soloForm); expect(wishiwashi.formIndex).toBe(soloForm);
}, },
TIMEOUT
); );
}); });

View File

@ -7,7 +7,7 @@ import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - SHIELDS DOWN", () => { describe("Abilities - SHIELDS DOWN", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,6 +60,5 @@ describe("Abilities - SHIELDS DOWN", () => {
expect(minior.formIndex).toBe(meteorForm); expect(minior.formIndex).toBe(meteorForm);
}, },
TIMEOUT
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - Sturdy", () => { describe("Abilities - Sturdy", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -45,7 +45,6 @@ describe("Abilities - Sturdy", () => {
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
expect(game.scene.getEnemyParty()[0].hp).toBe(1); expect(game.scene.getEnemyParty()[0].hp).toBe(1);
}, },
TIMEOUT
); );
test( test(
@ -62,7 +61,6 @@ describe("Abilities - Sturdy", () => {
expect(enemyPokemon.hp).toBe(0); expect(enemyPokemon.hp).toBe(0);
expect(enemyPokemon.isFainted()).toBe(true); expect(enemyPokemon.isFainted()).toBe(true);
}, },
TIMEOUT
); );
test( test(
@ -75,7 +73,6 @@ describe("Abilities - Sturdy", () => {
const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0]; const enemyPokemon: EnemyPokemon = game.scene.getEnemyParty()[0];
expect(enemyPokemon.isFullHp()).toBe(true); expect(enemyPokemon.isFullHp()).toBe(true);
}, },
TIMEOUT
); );
test( test(
@ -91,7 +88,6 @@ describe("Abilities - Sturdy", () => {
expect(enemyPokemon.hp).toBe(0); expect(enemyPokemon.hp).toBe(0);
expect(enemyPokemon.isFainted()).toBe(true); expect(enemyPokemon.isFainted()).toBe(true);
}, },
TIMEOUT
); );
}); });

View File

@ -6,8 +6,6 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 10 * 1000; // 10 second timeout
describe("Abilities - Tera Shell", () => { describe("Abilities - Tera Shell", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -54,7 +52,7 @@ describe("Abilities - Tera Shell", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT }
); );
it( it(
@ -71,7 +69,7 @@ describe("Abilities - Tera Shell", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(0); expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(0);
}, TIMEOUT }
); );
it( it(
@ -88,7 +86,7 @@ describe("Abilities - Tera Shell", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(0.25); expect(playerPokemon.getMoveEffectiveness).toHaveLastReturnedWith(0.25);
}, TIMEOUT }
); );
it( it(
@ -106,6 +104,6 @@ describe("Abilities - Tera Shell", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(playerPokemon.apply).toHaveLastReturnedWith(HitResult.EFFECTIVE); expect(playerPokemon.apply).toHaveLastReturnedWith(HitResult.EFFECTIVE);
expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp() - 40); expect(playerPokemon.hp).toBe(playerPokemon.getMaxHp() - 40);
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { BattlerTagType } from "#app/enums/battler-tag-type"; import { BattlerTagType } from "#app/enums/battler-tag-type";
import { BerryPhase } from "#app/phases/berry-phase"; import { BerryPhase } from "#app/phases/berry-phase";
const TIMEOUT = 20 * 1000;
describe("Abilities - Unseen Fist", () => { describe("Abilities - Unseen Fist", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -37,13 +37,11 @@ describe("Abilities - Unseen Fist", () => {
it( it(
"should cause a contact move to ignore Protect", "should cause a contact move to ignore Protect",
() => testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true), () => testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, true),
TIMEOUT
); );
it( it(
"should not cause a non-contact move to ignore Protect", "should not cause a non-contact move to ignore Protect",
() => testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false), () => testUnseenFistHitResult(game, Moves.ABSORB, Moves.PROTECT, false),
TIMEOUT
); );
it( it(
@ -51,19 +49,17 @@ describe("Abilities - Unseen Fist", () => {
() => { () => {
game.override.passiveAbility(Abilities.LONG_REACH); game.override.passiveAbility(Abilities.LONG_REACH);
testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false); testUnseenFistHitResult(game, Moves.QUICK_ATTACK, Moves.PROTECT, false);
}, TIMEOUT }
); );
it( it(
"should cause a contact move to ignore Wide Guard", "should cause a contact move to ignore Wide Guard",
() => testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true), () => testUnseenFistHitResult(game, Moves.BREAKING_SWIPE, Moves.WIDE_GUARD, true),
TIMEOUT
); );
it( it(
"should not cause a non-contact move to ignore Wide Guard", "should not cause a non-contact move to ignore Wide Guard",
() => testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false), () => testUnseenFistHitResult(game, Moves.BULLDOZE, Moves.WIDE_GUARD, false),
TIMEOUT
); );
it( it(
@ -83,7 +79,7 @@ describe("Abilities - Unseen Fist", () => {
expect(enemyPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeUndefined(); expect(enemyPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeUndefined();
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -19,7 +19,7 @@ import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
import { Status, StatusEffect } from "#app/data/status-effect"; import { Status, StatusEffect } from "#app/data/status-effect";
const TIMEOUT = 20 * 1000;
describe("Abilities - ZEN MODE", () => { describe("Abilities - ZEN MODE", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -67,7 +67,6 @@ describe("Abilities - ZEN MODE", () => {
expect(game.scene.getParty()[0].hp).toBeLessThan(100); expect(game.scene.getParty()[0].hp).toBeLessThan(100);
expect(game.scene.getParty()[0].formIndex).toBe(0); expect(game.scene.getParty()[0].formIndex).toBe(0);
}, },
TIMEOUT
); );
test( test(
@ -87,7 +86,6 @@ describe("Abilities - ZEN MODE", () => {
expect(game.scene.getParty()[0].hp).not.toBe(100); expect(game.scene.getParty()[0].hp).not.toBe(100);
expect(game.scene.getParty()[0].formIndex).not.toBe(0); expect(game.scene.getParty()[0].formIndex).not.toBe(0);
}, },
TIMEOUT
); );
test( test(
@ -125,7 +123,6 @@ describe("Abilities - ZEN MODE", () => {
await game.phaseInterceptor.to(PostSummonPhase); await game.phaseInterceptor.to(PostSummonPhase);
expect(game.scene.getParty()[1].formIndex).toBe(1); expect(game.scene.getParty()[1].formIndex).toBe(1);
}, },
TIMEOUT
); );
test( test(
@ -156,6 +153,5 @@ describe("Abilities - ZEN MODE", () => {
expect(darmanitan.formIndex).toBe(baseForm); expect(darmanitan.formIndex).toBe(baseForm);
}, },
TIMEOUT
); );
}); });

View File

@ -7,7 +7,7 @@ import { Species } from "#enums/species";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Abilities - ZERO TO HERO", () => { describe("Abilities - ZERO TO HERO", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -59,7 +59,7 @@ describe("Abilities - ZERO TO HERO", () => {
expect(palafin1.formIndex).toBe(baseForm); expect(palafin1.formIndex).toBe(baseForm);
expect(palafin2.formIndex).toBe(baseForm); expect(palafin2.formIndex).toBe(baseForm);
}, TIMEOUT); });
it("should swap to Hero form when switching out during a battle", async () => { it("should swap to Hero form when switching out during a battle", async () => {
await game.startBattle([Species.PALAFIN, Species.FEEBAS]); await game.startBattle([Species.PALAFIN, Species.FEEBAS]);
@ -70,7 +70,7 @@ describe("Abilities - ZERO TO HERO", () => {
game.doSwitchPokemon(1); game.doSwitchPokemon(1);
await game.phaseInterceptor.to(QuietFormChangePhase); await game.phaseInterceptor.to(QuietFormChangePhase);
expect(palafin.formIndex).toBe(heroForm); expect(palafin.formIndex).toBe(heroForm);
}, TIMEOUT); });
it("should not swap to Hero form if switching due to faint", async () => { it("should not swap to Hero form if switching due to faint", async () => {
await game.startBattle([Species.PALAFIN, Species.FEEBAS]); await game.startBattle([Species.PALAFIN, Species.FEEBAS]);
@ -83,7 +83,7 @@ describe("Abilities - ZERO TO HERO", () => {
game.doSelectPartyPokemon(1); game.doSelectPartyPokemon(1);
await game.toNextTurn(); await game.toNextTurn();
expect(palafin.formIndex).toBe(baseForm); expect(palafin.formIndex).toBe(baseForm);
}, TIMEOUT); });
it("should stay hero form if fainted and then revived", async () => { it("should stay hero form if fainted and then revived", async () => {
game.override.starterForms({ game.override.starterForms({
@ -105,5 +105,5 @@ describe("Abilities - ZERO TO HERO", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(palafin.formIndex).toBe(heroForm); expect(palafin.formIndex).toBe(heroForm);
}, TIMEOUT); });
}); });

View File

@ -9,8 +9,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
describe("Arena - Grassy Terrain", () => { describe("Arena - Grassy Terrain", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -52,7 +50,7 @@ describe("Arena - Grassy Terrain", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(eq.calculateBattlePower).toHaveReturnedWith(50); expect(eq.calculateBattlePower).toHaveReturnedWith(50);
}, TIMEOUT); });
it("Does not halve the damage of Earthquake if opponent is not grounded", async () => { it("Does not halve the damage of Earthquake if opponent is not grounded", async () => {
await game.classicMode.startBattle([Species.NINJASK]); await game.classicMode.startBattle([Species.NINJASK]);
@ -67,5 +65,5 @@ describe("Arena - Grassy Terrain", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(eq.calculateBattlePower).toHaveReturnedWith(100); expect(eq.calculateBattlePower).toHaveReturnedWith(100);
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Inverse Battle", () => { describe("Inverse Battle", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -56,7 +56,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT); });
it("2x effective types are 0.5x effective - Thunderbolt against Flying Type", async () => { it("2x effective types are 0.5x effective - Thunderbolt against Flying Type", async () => {
game.override game.override
@ -73,7 +73,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.5); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.5);
}, TIMEOUT); });
it("0.5x effective types are 2x effective - Thunderbolt against Electric Type", async () => { it("0.5x effective types are 2x effective - Thunderbolt against Electric Type", async () => {
game.override game.override
@ -90,7 +90,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT); });
it("Stealth Rock follows the inverse matchups - Stealth Rock against Charizard deals 1/32 of max HP", async () => { it("Stealth Rock follows the inverse matchups - Stealth Rock against Charizard deals 1/32 of max HP", async () => {
game.scene.arena.addTag(ArenaTagType.STEALTH_ROCK, 1, Moves.STEALTH_ROCK, 0); game.scene.arena.addTag(ArenaTagType.STEALTH_ROCK, 1, Moves.STEALTH_ROCK, 0);
@ -110,7 +110,7 @@ describe("Inverse Battle", () => {
console.log("Charizard's max HP: " + maxHp, "Damage: " + damage_prediction, "Current HP: " + currentHp, "Expected HP: " + expectedHP); console.log("Charizard's max HP: " + maxHp, "Damage: " + damage_prediction, "Current HP: " + currentHp, "Expected HP: " + expectedHP);
expect(currentHp).toBeGreaterThan(maxHp * 31 / 32 - 1); expect(currentHp).toBeGreaterThan(maxHp * 31 / 32 - 1);
}, TIMEOUT); });
it("Freeze Dry is 2x effective against Water Type like other Ice type Move - Freeze Dry against Squirtle", async () => { it("Freeze Dry is 2x effective against Water Type like other Ice type Move - Freeze Dry against Squirtle", async () => {
game.override game.override
@ -127,7 +127,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT); });
it("Water Absorb should heal against water moves - Water Absorb against Water gun", async () => { it("Water Absorb should heal against water moves - Water Absorb against Water gun", async () => {
game.override game.override
@ -143,7 +143,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.hp).toBe(enemy.getMaxHp()); expect(enemy.hp).toBe(enemy.getMaxHp());
}, TIMEOUT); });
it("Fire type does not get burned - Will-O-Wisp against Charmander", async () => { it("Fire type does not get burned - Will-O-Wisp against Charmander", async () => {
game.override game.override
@ -160,7 +160,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.status?.effect).not.toBe(StatusEffect.BURN); expect(enemy.status?.effect).not.toBe(StatusEffect.BURN);
}, TIMEOUT); });
it("Electric type does not get paralyzed - Nuzzle against Pikachu", async () => { it("Electric type does not get paralyzed - Nuzzle against Pikachu", async () => {
game.override game.override
@ -177,7 +177,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.status?.effect).not.toBe(StatusEffect.PARALYSIS); expect(enemy.status?.effect).not.toBe(StatusEffect.PARALYSIS);
}, TIMEOUT); });
it("Ground type is not immune to Thunder Wave - Thunder Wave against Sandshrew", async () => { it("Ground type is not immune to Thunder Wave - Thunder Wave against Sandshrew", async () => {
game.override game.override
@ -194,7 +194,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.status?.effect).toBe(StatusEffect.PARALYSIS); expect(enemy.status?.effect).toBe(StatusEffect.PARALYSIS);
}, TIMEOUT); });
it("Anticipation should trigger on 2x effective moves - Anticipation against Thunderbolt", async () => { it("Anticipation should trigger on 2x effective moves - Anticipation against Thunderbolt", async () => {
@ -206,7 +206,7 @@ describe("Inverse Battle", () => {
await game.challengeMode.startBattle(); await game.challengeMode.startBattle();
expect(game.scene.getEnemyPokemon()?.summonData.abilitiesApplied[0]).toBe(Abilities.ANTICIPATION); expect(game.scene.getEnemyPokemon()?.summonData.abilitiesApplied[0]).toBe(Abilities.ANTICIPATION);
}, TIMEOUT); });
it("Conversion 2 should change the type to the resistive type - Conversion 2 against Dragonite", async () => { it("Conversion 2 should change the type to the resistive type - Conversion 2 against Dragonite", async () => {
game.override game.override
@ -223,7 +223,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(player.getTypes()[0]).toBe(Type.DRAGON); expect(player.getTypes()[0]).toBe(Type.DRAGON);
}, TIMEOUT); });
it("Flying Press should be 0.25x effective against Grass + Dark Type - Flying Press against Meowscarada", async () => { it("Flying Press should be 0.25x effective against Grass + Dark Type - Flying Press against Meowscarada", async () => {
game.override game.override
@ -240,7 +240,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.25); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(0.25);
}, TIMEOUT); });
it("Scrappy ability has no effect - Tackle against Ghost Type still 2x effective with Scrappy", async () => { it("Scrappy ability has no effect - Tackle against Ghost Type still 2x effective with Scrappy", async () => {
game.override game.override
@ -258,7 +258,7 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT); });
it("FORESIGHT has no effect - Tackle against Ghost Type still 2x effective with Foresight", async () => { it("FORESIGHT has no effect - Tackle against Ghost Type still 2x effective with Foresight", async () => {
game.override game.override
@ -279,5 +279,5 @@ describe("Inverse Battle", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveLastReturnedWith(2);
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ vi.mock("#app/battle-scene.js");
describe("BattlerTag - OctolockTag", () => { describe("BattlerTag - OctolockTag", () => {
describe("lapse behavior", () => { describe("lapse behavior", () => {
it("unshifts a StatStageChangePhase with expected stat stage changes", { timeout: 10000 }, async () => { it("unshifts a StatStageChangePhase with expected stat stage changes", async () => {
const mockPokemon = { const mockPokemon = {
scene: new BattleScene(), scene: new BattleScene(),
getBattlerIndex: () => 0, getBattlerIndex: () => 0,
@ -30,11 +30,11 @@ describe("BattlerTag - OctolockTag", () => {
}); });
}); });
it ("traps its target (extends TrappedTag)", { timeout: 2000 }, async () => { it ("traps its target (extends TrappedTag)", async () => {
expect(new OctolockTag(1)).toBeInstanceOf(TrappedTag); expect(new OctolockTag(1)).toBeInstanceOf(TrappedTag);
}); });
it("can be added to pokemon who are not octolocked", { timeout: 2000 }, async => { it("can be added to pokemon who are not octolocked", async => {
const mockPokemon = { const mockPokemon = {
getTag: vi.fn().mockReturnValue(undefined) as Pokemon["getTag"], getTag: vi.fn().mockReturnValue(undefined) as Pokemon["getTag"],
} as Pokemon; } as Pokemon;
@ -47,7 +47,7 @@ describe("BattlerTag - OctolockTag", () => {
expect(mockPokemon.getTag).toHaveBeenCalledWith(BattlerTagType.OCTOLOCK); expect(mockPokemon.getTag).toHaveBeenCalledWith(BattlerTagType.OCTOLOCK);
}); });
it("cannot be added to pokemon who are octolocked", { timeout: 2000 }, async => { it("cannot be added to pokemon who are octolocked", async => {
const mockPokemon = { const mockPokemon = {
getTag: vi.fn().mockReturnValue(new BattlerTag(null!, null!, null!, null!)) as Pokemon["getTag"], getTag: vi.fn().mockReturnValue(new BattlerTag(null!, null!, null!, null!)) as Pokemon["getTag"],
} as Pokemon; } as Pokemon;

View File

@ -12,7 +12,7 @@ beforeEach(() => {
describe("BattlerTag - StockpilingTag", () => { describe("BattlerTag - StockpilingTag", () => {
describe("onAdd", () => { describe("onAdd", () => {
it("unshifts a StatStageChangePhase with expected stat stage changes on add", { timeout: 10000 }, async () => { it("unshifts a StatStageChangePhase with expected stat stage changes on add", async () => {
const mockPokemon = { const mockPokemon = {
scene: vi.mocked(new BattleScene()) as BattleScene, scene: vi.mocked(new BattleScene()) as BattleScene,
getBattlerIndex: () => 0, getBattlerIndex: () => 0,
@ -35,7 +35,7 @@ describe("BattlerTag - StockpilingTag", () => {
expect(mockPokemon.scene.unshiftPhase).toBeCalledTimes(1); expect(mockPokemon.scene.unshiftPhase).toBeCalledTimes(1);
}); });
it("unshifts a StatStageChangePhase with expected stat changes on add (one stat maxed)", { timeout: 10000 }, async () => { it("unshifts a StatStageChangePhase with expected stat changes on add (one stat maxed)", async () => {
const mockPokemon = { const mockPokemon = {
scene: new BattleScene(), scene: new BattleScene(),
summonData: new PokemonSummonData(), summonData: new PokemonSummonData(),
@ -64,7 +64,7 @@ describe("BattlerTag - StockpilingTag", () => {
}); });
describe("onOverlap", () => { describe("onOverlap", () => {
it("unshifts a StatStageChangePhase with expected stat changes on overlap", { timeout: 10000 }, async () => { it("unshifts a StatStageChangePhase with expected stat changes on overlap", async () => {
const mockPokemon = { const mockPokemon = {
scene: new BattleScene(), scene: new BattleScene(),
getBattlerIndex: () => 0, getBattlerIndex: () => 0,
@ -89,7 +89,7 @@ describe("BattlerTag - StockpilingTag", () => {
}); });
describe("stack limit, stat tracking, and removal", () => { describe("stack limit, stat tracking, and removal", () => {
it("can be added up to three times, even when one stat does not change", { timeout: 10000 }, async () => { it("can be added up to three times, even when one stat does not change", async () => {
const mockPokemon = { const mockPokemon = {
scene: new BattleScene(), scene: new BattleScene(),
summonData: new PokemonSummonData(), summonData: new PokemonSummonData(),

View File

@ -10,8 +10,6 @@ import { MoveEffectPhase } from "#app/phases/move-effect-phase";
vi.mock("#app/battle-scene.js"); vi.mock("#app/battle-scene.js");
const TIMEOUT = 5 * 1000; // 5 sec timeout
describe("BattlerTag - SubstituteTag", () => { describe("BattlerTag - SubstituteTag", () => {
let mockPokemon: Pokemon; let mockPokemon: Pokemon;
@ -45,7 +43,7 @@ describe("BattlerTag - SubstituteTag", () => {
subject.onAdd(mockPokemon); subject.onAdd(mockPokemon);
expect(subject.hp).toBe(25); expect(subject.hp).toBe(25);
}, TIMEOUT }
); );
it( it(
@ -67,7 +65,7 @@ describe("BattlerTag - SubstituteTag", () => {
expect(subject.sourceInFocus).toBeFalsy(); expect(subject.sourceInFocus).toBeFalsy();
expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1);
expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1);
}, TIMEOUT }
); );
it( it(
@ -79,7 +77,7 @@ describe("BattlerTag - SubstituteTag", () => {
subject.onAdd(mockPokemon); subject.onAdd(mockPokemon);
expect(mockPokemon.findAndRemoveTags).toHaveBeenCalledTimes(1); expect(mockPokemon.findAndRemoveTags).toHaveBeenCalledTimes(1);
}, TIMEOUT }
); );
}); });
@ -114,7 +112,7 @@ describe("BattlerTag - SubstituteTag", () => {
expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1);
expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1);
}, TIMEOUT }
); );
}); });
@ -150,7 +148,7 @@ describe("BattlerTag - SubstituteTag", () => {
expect(subject.sourceInFocus).toBeTruthy(); expect(subject.sourceInFocus).toBeTruthy();
expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1);
expect(mockPokemon.scene.queueMessage).not.toHaveBeenCalled(); expect(mockPokemon.scene.queueMessage).not.toHaveBeenCalled();
}, TIMEOUT }
); );
it( it(
@ -172,7 +170,7 @@ describe("BattlerTag - SubstituteTag", () => {
expect(subject.sourceInFocus).toBeFalsy(); expect(subject.sourceInFocus).toBeFalsy();
expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.triggerPokemonBattleAnim).toHaveBeenCalledTimes(1);
expect(mockPokemon.scene.queueMessage).not.toHaveBeenCalled(); expect(mockPokemon.scene.queueMessage).not.toHaveBeenCalled();
}, TIMEOUT }
); );
/** TODO: Figure out how to mock a MoveEffectPhase correctly for this test */ /** TODO: Figure out how to mock a MoveEffectPhase correctly for this test */
@ -200,7 +198,7 @@ describe("BattlerTag - SubstituteTag", () => {
expect(mockPokemon.scene.triggerPokemonBattleAnim).not.toHaveBeenCalled(); expect(mockPokemon.scene.triggerPokemonBattleAnim).not.toHaveBeenCalled();
expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1); expect(mockPokemon.scene.queueMessage).toHaveBeenCalledTimes(1);
}, TIMEOUT }
); );
it( it(
@ -212,7 +210,7 @@ describe("BattlerTag - SubstituteTag", () => {
vi.spyOn(mockPokemon.scene, "queueMessage").mockReturnValue(); vi.spyOn(mockPokemon.scene, "queueMessage").mockReturnValue();
expect(subject.lapse(mockPokemon, BattlerTagLapseType.CUSTOM)).toBeFalsy(); expect(subject.lapse(mockPokemon, BattlerTagLapseType.CUSTOM)).toBeFalsy();
}, TIMEOUT }
); );
it( it(

View File

@ -9,8 +9,6 @@ import { EnemyPokemon } from "#app/field/pokemon";
import { toDmgValue } from "#app/utils"; import { toDmgValue } from "#app/utils";
describe("Boss Pokemon / Shields", () => { describe("Boss Pokemon / Shields", () => {
const TIMEOUT = 20 * 1000;
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -35,7 +33,7 @@ describe("Boss Pokemon / Shields", () => {
.enemyMoveset(Moves.SPLASH) .enemyMoveset(Moves.SPLASH)
.enemyHeldItems([]) .enemyHeldItems([])
.startingLevel(1000) .startingLevel(1000)
.moveset([Moves.FALSE_SWIPE, Moves.SUPER_FANG, Moves.SPLASH]) .moveset([Moves.FALSE_SWIPE, Moves.SUPER_FANG, Moves.SPLASH, Moves.PSYCHIC])
.ability(Abilities.NO_GUARD); .ability(Abilities.NO_GUARD);
}); });
@ -62,7 +60,7 @@ describe("Boss Pokemon / Shields", () => {
// Pokemon above level 100 get an extra shield // Pokemon above level 100 get an extra shield
level = 100; level = 100;
expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(7); expect(game.scene.getEncounterBossSegments(wave, level, getPokemonSpecies(Species.RATTATA))).toBe(7);
}, TIMEOUT); });
it("should reduce the number of shields if we are in a double battle", async () => { it("should reduce the number of shields if we are in a double battle", async () => {
game.override game.override
@ -77,7 +75,7 @@ describe("Boss Pokemon / Shields", () => {
expect(boss1.bossSegments).toBe(2); expect(boss1.bossSegments).toBe(2);
expect(boss2.isBoss()).toBe(true); expect(boss2.isBoss()).toBe(true);
expect(boss2.bossSegments).toBe(2); expect(boss2.bossSegments).toBe(2);
}, TIMEOUT); });
it("shields should stop overflow damage and give stat stage boosts when broken", async () => { it("shields should stop overflow damage and give stat stage boosts when broken", async () => {
game.override.startingWave(150); // Floor 150 > 2 shields / 3 health segments game.override.startingWave(150); // Floor 150 > 2 shields / 3 health segments
@ -107,7 +105,7 @@ describe("Boss Pokemon / Shields", () => {
// Breaking the last shield gives a +2 boost to ATK, DEF, SP ATK, SP DEF or SPD // Breaking the last shield gives a +2 boost to ATK, DEF, SP ATK, SP DEF or SPD
expect(getTotalStatStageBoosts(enemyPokemon)).toBe(3); expect(getTotalStatStageBoosts(enemyPokemon)).toBe(3);
}, TIMEOUT); });
it("breaking multiple shields at once requires extra damage", async () => { it("breaking multiple shields at once requires extra damage", async () => {
game.override game.override
@ -143,7 +141,7 @@ describe("Boss Pokemon / Shields", () => {
expect(boss2.bossSegmentIndex).toBe(0); expect(boss2.bossSegmentIndex).toBe(0);
expect(boss2.hp).toBe(boss2.getMaxHp() - toDmgValue(boss2SegmentHp * 4)); expect(boss2.hp).toBe(boss2.getMaxHp() - toDmgValue(boss2SegmentHp * 4));
}, TIMEOUT); });
it("the number of stat stage boosts is consistent when several shields are broken at once", async () => { it("the number of stat stage boosts is consistent when several shields are broken at once", async () => {
const shieldsToBreak = 4; const shieldsToBreak = 4;
@ -196,7 +194,29 @@ describe("Boss Pokemon / Shields", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(getTotalStatStageBoosts(boss2)).toBe(totalStatStages); expect(getTotalStatStageBoosts(boss2)).toBe(totalStatStages);
}, TIMEOUT); });
it("the boss enduring does not proc an extra stat boost", async () => {
game.override
.enemyHealthSegments(2)
.enemyAbility(Abilities.STURDY);
await game.classicMode.startBattle([ Species.MEWTWO ]);
const enemyPokemon = game.scene.getEnemyPokemon()!;
expect(enemyPokemon.isBoss()).toBe(true);
expect(enemyPokemon.bossSegments).toBe(2);
expect(getTotalStatStageBoosts(enemyPokemon)).toBe(0);
game.move.select(Moves.PSYCHIC);
await game.toNextTurn();
// Enemy survived with Sturdy
expect(enemyPokemon.bossSegmentIndex).toBe(0);
expect(enemyPokemon.hp).toBe(1);
expect(getTotalStatStageBoosts(enemyPokemon)).toBe(1);
});
/** /**
* Gets the sum of the effective stat stage boosts for the given Pokemon * Gets the sum of the effective stat stage boosts for the given Pokemon

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
const NUM_TRIALS = 300; const NUM_TRIALS = 300;
type MoveChoiceSet = { [key: number]: number }; type MoveChoiceSet = { [key: number]: number };
@ -74,7 +74,7 @@ describe("Enemy Commands - Move Selection", () => {
expect(moveChoices[mv.moveId]).toBe(0); expect(moveChoices[mv.moveId]).toBe(0);
} }
}); });
}, TIMEOUT }
); );
it( it(
@ -101,6 +101,6 @@ describe("Enemy Commands - Move Selection", () => {
expect(moveChoices[mv.moveId]).toBe(0); expect(moveChoices[mv.moveId]).toBe(0);
} }
}); });
}, TIMEOUT }
); );
}); });

View File

@ -10,7 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
describe("Evolution", () => { describe("Evolution", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 1000 * 20;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
@ -46,7 +45,7 @@ describe("Evolution", () => {
trapinch.evolve(pokemonEvolutions[Species.TRAPINCH][0], trapinch.getSpeciesForm()); trapinch.evolve(pokemonEvolutions[Species.TRAPINCH][0], trapinch.getSpeciesForm());
expect(trapinch.abilityIndex).toBe(1); expect(trapinch.abilityIndex).toBe(1);
}, TIMEOUT); });
it("should keep same ability slot after evolving", async () => { it("should keep same ability slot after evolving", async () => {
await game.classicMode.runToSummon([Species.BULBASAUR, Species.CHARMANDER]); await game.classicMode.runToSummon([Species.BULBASAUR, Species.CHARMANDER]);
@ -61,7 +60,7 @@ describe("Evolution", () => {
charmander.evolve(pokemonEvolutions[Species.CHARMANDER][0], charmander.getSpeciesForm()); charmander.evolve(pokemonEvolutions[Species.CHARMANDER][0], charmander.getSpeciesForm());
expect(charmander.abilityIndex).toBe(1); expect(charmander.abilityIndex).toBe(1);
}, TIMEOUT); });
it("should handle illegal abilityIndex values", async () => { it("should handle illegal abilityIndex values", async () => {
await game.classicMode.runToSummon([Species.SQUIRTLE]); await game.classicMode.runToSummon([Species.SQUIRTLE]);
@ -71,7 +70,7 @@ describe("Evolution", () => {
squirtle.evolve(pokemonEvolutions[Species.SQUIRTLE][0], squirtle.getSpeciesForm()); squirtle.evolve(pokemonEvolutions[Species.SQUIRTLE][0], squirtle.getSpeciesForm());
expect(squirtle.abilityIndex).toBe(0); expect(squirtle.abilityIndex).toBe(0);
}, TIMEOUT); });
it("should handle nincada's unique evolution", async () => { it("should handle nincada's unique evolution", async () => {
await game.classicMode.runToSummon([Species.NINCADA]); await game.classicMode.runToSummon([Species.NINCADA]);
@ -87,7 +86,7 @@ describe("Evolution", () => {
expect(shedinja.abilityIndex).toBe(1); expect(shedinja.abilityIndex).toBe(1);
// Regression test for https://github.com/pagefaultgames/pokerogue/issues/3842 // Regression test for https://github.com/pagefaultgames/pokerogue/issues/3842
expect(shedinja.metBiome).toBe(-1); expect(shedinja.metBiome).toBe(-1);
}, TIMEOUT); });
it("should set wild delay to NONE by default", () => { it("should set wild delay to NONE by default", () => {
const speciesFormEvo = new SpeciesFormEvolution(Species.ABRA, null, null, 1000, null, null); const speciesFormEvo = new SpeciesFormEvolution(Species.ABRA, null, null, 1000, null, null);
@ -120,7 +119,7 @@ describe("Evolution", () => {
expect(totodile.hp).toBe(totodile.getMaxHp()); expect(totodile.hp).toBe(totodile.getMaxHp());
expect(totodile.hp).toBeGreaterThan(hpBefore); expect(totodile.hp).toBeGreaterThan(hpBefore);
}, TIMEOUT); });
it("should not fully heal HP when evolving", async () => { it("should not fully heal HP when evolving", async () => {
game.override.moveset([Moves.SURF]) game.override.moveset([Moves.SURF])
@ -150,7 +149,7 @@ describe("Evolution", () => {
expect(cyndaquil.getMaxHp()).toBeGreaterThan(maxHpBefore); expect(cyndaquil.getMaxHp()).toBeGreaterThan(maxHpBefore);
expect(cyndaquil.hp).toBeGreaterThan(hpBefore); expect(cyndaquil.hp).toBeGreaterThan(hpBefore);
expect(cyndaquil.hp).toBeLessThan(cyndaquil.getMaxHp()); expect(cyndaquil.hp).toBeLessThan(cyndaquil.getMaxHp());
}, TIMEOUT); });
it("should handle rng-based split evolution", async () => { it("should handle rng-based split evolution", async () => {
/* this test checks to make sure that tandemaus will /* this test checks to make sure that tandemaus will
@ -174,5 +173,5 @@ describe("Evolution", () => {
const fourForm = playerPokemon.getEvolution()!; const fourForm = playerPokemon.getEvolution()!;
expect(fourForm.evoFormKey).toBe(null); // meanwhile, according to the pokemon-forms, the evoFormKey for a 4 family maushold is null expect(fourForm.evoFormKey).toBe(null); // meanwhile, according to the pokemon-forms, the evoFormKey for a 4 family maushold is null
} }
}, TIMEOUT); });
}); });

View File

@ -12,8 +12,6 @@ import { Button } from "#app/enums/buttons";
describe("Items - Double Battle Chance Boosters", () => { describe("Items - Double Battle Chance Boosters", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -39,7 +37,7 @@ describe("Items - Double Battle Chance Boosters", () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
expect(game.scene.getEnemyField().length).toBe(2); expect(game.scene.getEnemyField().length).toBe(2);
}, TIMEOUT); });
it("should guarantee double boss battle with 3 unique tiers", async () => { it("should guarantee double boss battle with 3 unique tiers", async () => {
game.override game.override
@ -57,7 +55,7 @@ describe("Items - Double Battle Chance Boosters", () => {
expect(enemyField.length).toBe(2); expect(enemyField.length).toBe(2);
expect(enemyField[0].isBoss()).toBe(true); expect(enemyField[0].isBoss()).toBe(true);
expect(enemyField[1].isBoss()).toBe(true); expect(enemyField[1].isBoss()).toBe(true);
}, TIMEOUT); });
it("should renew how many battles are left of existing booster when picking up new booster of same tier", async() => { it("should renew how many battles are left of existing booster when picking up new booster of same tier", async() => {
game.override game.override
@ -100,5 +98,5 @@ describe("Items - Double Battle Chance Boosters", () => {
} }
} }
expect(count).toBe(1); expect(count).toBe(1);
}, TIMEOUT); });
}); });

View File

@ -9,8 +9,6 @@ import { StatBoosterModifier } from "#app/modifier/modifier";
describe("Items - Eviolite", () => { describe("Items - Eviolite", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phase.Game({ phaserGame = new Phase.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -50,7 +48,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.5)); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.5));
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.5)); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.5));
}, TIMEOUT); });
it("should not provide a boost for fully evolved, unfused pokemon", async() => { it("should not provide a boost for fully evolved, unfused pokemon", async() => {
await game.classicMode.startBattle([ await game.classicMode.startBattle([
@ -74,7 +72,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat);
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat);
}, TIMEOUT); });
it("should provide 50% boost to DEF and SPDEF for completely unevolved, fused pokemon", async() => { it("should provide 50% boost to DEF and SPDEF for completely unevolved, fused pokemon", async() => {
await game.classicMode.startBattle([ await game.classicMode.startBattle([
@ -107,7 +105,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.5)); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.5));
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.5)); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.5));
}, TIMEOUT); });
it("should provide 25% boost to DEF and SPDEF for partially unevolved (base), fused pokemon", async() => { it("should provide 25% boost to DEF and SPDEF for partially unevolved (base), fused pokemon", async() => {
await game.classicMode.startBattle([ await game.classicMode.startBattle([
@ -140,7 +138,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.25)); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.25));
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.25)); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.25));
}, TIMEOUT); });
it("should provide 25% boost to DEF and SPDEF for partially unevolved (fusion), fused pokemon", async() => { it("should provide 25% boost to DEF and SPDEF for partially unevolved (fusion), fused pokemon", async() => {
await game.classicMode.startBattle([ await game.classicMode.startBattle([
@ -173,7 +171,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.25)); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(Math.floor(defStat * 1.25));
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.25)); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(Math.floor(spDefStat * 1.25));
}, TIMEOUT); });
it("should not provide a boost for fully evolved, fused pokemon", async() => { it("should not provide a boost for fully evolved, fused pokemon", async() => {
await game.classicMode.startBattle([ await game.classicMode.startBattle([
@ -206,7 +204,7 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat);
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat);
}, TIMEOUT); });
it("should not provide a boost for Gigantamax Pokémon", async() => { it("should not provide a boost for Gigantamax Pokémon", async() => {
game.override.starterForms({ game.override.starterForms({
@ -238,5 +236,5 @@ describe("Items - Eviolite", () => {
expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat); expect(partyMember.getEffectiveStat(Stat.DEF)).toBe(defStat);
expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat); expect(partyMember.getEffectiveStat(Stat.SPDEF)).toBe(spDefStat);
}, TIMEOUT); });
}); });

View File

@ -9,7 +9,7 @@ import GameManager from "#test/utils/gameManager";
import Phase from "phaser"; import Phase from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000; // 20 seconds // 20 seconds
describe("Items - Grip Claw", () => { describe("Items - Grip Claw", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -63,6 +63,6 @@ describe("Items - Grip Claw", () => {
await game.phaseInterceptor.to(MoveEndPhase, false); await game.phaseInterceptor.to(MoveEndPhase, false);
expect(enemyPokemon[1].getHeldItems.length).toBe(enemyHeldItemCt[1]); expect(enemyPokemon[1].getHeldItems.length).toBe(enemyHeldItemCt[1]);
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - After You", () => { describe("Moves - After You", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -47,7 +47,7 @@ describe("Moves - After You", () => {
const phase = game.scene.getCurrentPhase() as MovePhase; const phase = game.scene.getCurrentPhase() as MovePhase;
expect(phase.pokemon).toBe(game.scene.getPlayerField()[1]); expect(phase.pokemon).toBe(game.scene.getPlayerField()[1]);
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
}, TIMEOUT); });
it("fails if target already moved", async () => { it("fails if target already moved", async () => {
game.override.enemySpecies(Species.SHUCKLE); game.override.enemySpecies(Species.SHUCKLE);
@ -61,5 +61,5 @@ describe("Moves - After You", () => {
await game.phaseInterceptor.to(MovePhase); await game.phaseInterceptor.to(MovePhase);
expect(game.scene.getPlayerField()[1].getLastXMoves(1)[0].result).toBe(MoveResult.FAIL); expect(game.scene.getPlayerField()[1].getLastXMoves(1)[0].result).toBe(MoveResult.FAIL);
}, TIMEOUT); });
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Alluring Voice", () => { describe("Moves - Alluring Voice", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,5 +50,5 @@ describe("Moves - Alluring Voice", () => {
await game.phaseInterceptor.to(BerryPhase); await game.phaseInterceptor.to(BerryPhase);
expect(enemy.getTag(BattlerTagType.CONFUSED)?.tagType).toBe("CONFUSED"); expect(enemy.getTag(BattlerTagType.CONFUSED)?.tagType).toBe("CONFUSED");
}, TIMEOUT); });
}); });

View File

@ -11,7 +11,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Astonish", () => { describe("Moves - Astonish", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -67,6 +67,6 @@ describe("Moves - Astonish", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -8,8 +8,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Baddy Bad", () => { describe("Moves - Baddy Bad", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -39,5 +37,5 @@ describe("Moves - Baddy Bad", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(game.scene.arena.tags.length).toBe(0); expect(game.scene.arena.tags.length).toBe(0);
}, TIMEOUT); });
}); });

View File

@ -7,7 +7,7 @@ import { Moves } from "#enums/moves";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { StatusEffect } from "#app/enums/status-effect"; import { StatusEffect } from "#app/enums/status-effect";
const TIMEOUT = 20 * 1000;
describe("Moves - Baneful Bunker", () => { describe("Moves - Baneful Bunker", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,7 +50,7 @@ describe("Moves - Baneful Bunker", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy(); expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy();
}, TIMEOUT }
); );
test( test(
"should protect the user and poison attackers that make contact, regardless of accuracy checks", "should protect the user and poison attackers that make contact, regardless of accuracy checks",
@ -68,7 +68,7 @@ describe("Moves - Baneful Bunker", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy(); expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeTruthy();
}, TIMEOUT }
); );
test( test(
@ -88,6 +88,6 @@ describe("Moves - Baneful Bunker", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeFalsy(); expect(leadPokemon.status?.effect === StatusEffect.POISON).toBeFalsy();
}, TIMEOUT }
); );
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Beak Blast", () => { describe("Moves - Beak Blast", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -54,7 +54,7 @@ describe("Moves - Beak Blast", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN); expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN);
}, TIMEOUT }
); );
it( it(
@ -74,7 +74,7 @@ describe("Moves - Beak Blast", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN); expect(enemyPokemon.status?.effect).toBe(StatusEffect.BURN);
}, TIMEOUT }
); );
it( it(
@ -94,7 +94,7 @@ describe("Moves - Beak Blast", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.BURN); expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.BURN);
}, TIMEOUT }
); );
it( it(
@ -110,7 +110,7 @@ describe("Moves - Beak Blast", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(leadPokemon.turnData.hitCount).toBe(2); expect(leadPokemon.turnData.hitCount).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -131,6 +131,6 @@ describe("Moves - Beak Blast", () => {
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeUndefined(); expect(leadPokemon.getTag(BattlerTagType.BEAK_BLAST_CHARGING)).toBeUndefined();
}, TIMEOUT }
); );
}); });

View File

@ -7,8 +7,6 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000; // 20 sec timeout
describe("Moves - Beat Up", () => { describe("Moves - Beat Up", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -57,7 +55,7 @@ describe("Moves - Beat Up", () => {
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to(MoveEffectPhase);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
} }
}, TIMEOUT }
); );
it( it(
@ -74,7 +72,7 @@ describe("Moves - Beat Up", () => {
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to(MoveEffectPhase);
expect(playerPokemon.turnData.hitCount).toBe(5); expect(playerPokemon.turnData.hitCount).toBe(5);
}, TIMEOUT }
); );
it( it(
@ -99,6 +97,6 @@ describe("Moves - Beat Up", () => {
await game.phaseInterceptor.to(MoveEffectPhase); await game.phaseInterceptor.to(MoveEffectPhase);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
} }
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
import { Abilities } from "#app/enums/abilities"; import { Abilities } from "#app/enums/abilities";
const TIMEOUT = 20 * 1000;
// RATIO : HP Cost of Move // RATIO : HP Cost of Move
const RATIO = 2; const RATIO = 2;
// PREDAMAGE : Amount of extra HP lost // PREDAMAGE : Amount of extra HP lost
@ -54,7 +54,7 @@ describe("Moves - BELLY DRUM", () => {
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6);
}, TIMEOUT }
); );
test("will still take effect if an uninvolved stat stage is at max", test("will still take effect if an uninvolved stat stage is at max",
@ -74,7 +74,7 @@ describe("Moves - BELLY DRUM", () => {
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp() - hpLost);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6);
}, TIMEOUT }
); );
test("fails if the pokemon's ATK stat stage is at its maximum", test("fails if the pokemon's ATK stat stage is at its maximum",
@ -90,7 +90,7 @@ describe("Moves - BELLY DRUM", () => {
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6);
}, TIMEOUT }
); );
test("fails if the user's health is less than 1/2", test("fails if the user's health is less than 1/2",
@ -106,6 +106,6 @@ describe("Moves - BELLY DRUM", () => {
expect(leadPokemon.hp).toBe(hpLost - PREDAMAGE); expect(leadPokemon.hp).toBe(hpLost - PREDAMAGE);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0);
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Burning Jealousy", () => { describe("Moves - Burning Jealousy", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,7 +50,7 @@ describe("Moves - Burning Jealousy", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy.status?.effect).toBe(StatusEffect.BURN); expect(enemy.status?.effect).toBe(StatusEffect.BURN);
}, TIMEOUT); });
it("should still burn the opponent if their stat stages were both raised and lowered in the same turn", async () => { it("should still burn the opponent if their stat stages were both raised and lowered in the same turn", async () => {
game.override game.override
@ -66,7 +66,7 @@ describe("Moves - Burning Jealousy", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy.status?.effect).toBe(StatusEffect.BURN); expect(enemy.status?.effect).toBe(StatusEffect.BURN);
}, TIMEOUT); });
it("should ignore stat stages raised by IMPOSTER", async () => { it("should ignore stat stages raised by IMPOSTER", async () => {
game.override game.override
@ -81,11 +81,11 @@ describe("Moves - Burning Jealousy", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy.status?.effect).toBeUndefined(); expect(enemy.status?.effect).toBeUndefined();
}, TIMEOUT); });
it.skip("should ignore weakness policy", async () => { // TODO: Make this test if WP is implemented it.skip("should ignore weakness policy", async () => { // TODO: Make this test if WP is implemented
await game.classicMode.startBattle(); await game.classicMode.startBattle();
}, TIMEOUT); });
it("should be boosted by Sheer Force even if opponent didn't raise stat stages", async () => { it("should be boosted by Sheer Force even if opponent didn't raise stat stages", async () => {
game.override game.override
@ -98,5 +98,5 @@ describe("Moves - Burning Jealousy", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(allMoves[Moves.BURNING_JEALOUSY].calculateBattlePower).toHaveReturnedWith(allMoves[Moves.BURNING_JEALOUSY].power * 5461 / 4096); expect(allMoves[Moves.BURNING_JEALOUSY].calculateBattlePower).toHaveReturnedWith(allMoves[Moves.BURNING_JEALOUSY].power * 5461 / 4096);
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Ceaseless Edge", () => { describe("Moves - Ceaseless Edge", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -61,7 +61,7 @@ describe("Moves - Ceaseless Edge", () => {
expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter instanceof ArenaTrapTag).toBeTruthy();
expect(tagAfter.layers).toBe(1); expect(tagAfter.layers).toBe(1);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
}, TIMEOUT }
); );
test( test(
@ -86,7 +86,7 @@ describe("Moves - Ceaseless Edge", () => {
expect(tagAfter instanceof ArenaTrapTag).toBeTruthy(); expect(tagAfter instanceof ArenaTrapTag).toBeTruthy();
expect(tagAfter.layers).toBe(2); expect(tagAfter.layers).toBe(2);
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
}, TIMEOUT }
); );
test( test(
@ -114,6 +114,6 @@ describe("Moves - Ceaseless Edge", () => {
game.move.select(Moves.SPLASH); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to(TurnEndPhase, false); await game.phaseInterceptor.to(TurnEndPhase, false);
expect(game.scene.currentBattle.enemyParty[0].hp).toBeLessThan(hpBeforeSpikes); expect(game.scene.currentBattle.enemyParty[0].hp).toBeLessThan(hpBeforeSpikes);
}, TIMEOUT }
); );
}); });

View File

@ -6,7 +6,7 @@ import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { Stat } from "#enums/stat"; import { Stat } from "#enums/stat";
const TIMEOUT = 20 * 1000;
/** HP Cost of Move */ /** HP Cost of Move */
const RATIO = 3; const RATIO = 3;
/** Amount of extra HP lost */ /** Amount of extra HP lost */
@ -54,7 +54,7 @@ describe("Moves - Clangorous Soul", () => {
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(1); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(1);
expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(1); expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(1);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(1); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(1);
}, TIMEOUT }
); );
it("will still take effect if one or more of the involved stat stages are not at max", it("will still take effect if one or more of the involved stat stages are not at max",
@ -79,7 +79,7 @@ describe("Moves - Clangorous Soul", () => {
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(5); expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(5);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(1); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(1);
}, TIMEOUT }
); );
it("fails if all stat stages involved are at max", it("fails if all stat stages involved are at max",
@ -103,7 +103,7 @@ describe("Moves - Clangorous Soul", () => {
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(6);
}, TIMEOUT }
); );
it("fails if the user's health is less than 1/3", it("fails if the user's health is less than 1/3",
@ -123,6 +123,6 @@ describe("Moves - Clangorous Soul", () => {
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(0); expect(leadPokemon.getStatStage(Stat.SPDEF)).toBe(0);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(0); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(0);
}, TIMEOUT }
); );
}); });

View File

@ -9,7 +9,7 @@ import { BattlerTagType } from "#app/enums/battler-tag-type";
import { BerryPhase } from "#app/phases/berry-phase"; import { BerryPhase } from "#app/phases/berry-phase";
import { CommandPhase } from "#app/phases/command-phase"; import { CommandPhase } from "#app/phases/command-phase";
const TIMEOUT = 20 * 1000;
describe("Moves - Crafty Shield", () => { describe("Moves - Crafty Shield", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -56,7 +56,7 @@ describe("Moves - Crafty Shield", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0)); leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0));
}, TIMEOUT }
); );
test( test(
@ -77,7 +77,7 @@ describe("Moves - Crafty Shield", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(leadPokemon.some(p => p.hp < p.getMaxHp())).toBeTruthy(); expect(leadPokemon.some(p => p.hp < p.getMaxHp())).toBeTruthy();
}, TIMEOUT }
); );
test( test(
@ -99,7 +99,7 @@ describe("Moves - Crafty Shield", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.getTag(BattlerTagType.CURSED)).toBeUndefined()); leadPokemon.forEach(p => expect(p.getTag(BattlerTagType.CURSED)).toBeUndefined());
}, TIMEOUT }
); );
test( test(

View File

@ -10,8 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
describe("Moves - Dragon Cheer", () => { describe("Moves - Dragon Cheer", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -47,7 +45,7 @@ describe("Moves - Dragon Cheer", () => {
// After Tackle // After Tackle
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.getCritStage).toHaveReturnedWith(1); // getCritStage is called on defender expect(enemy.getCritStage).toHaveReturnedWith(1); // getCritStage is called on defender
}, TIMEOUT); });
it("increases the user's Dragon-type allies' critical hit ratio by two stages", async () => { it("increases the user's Dragon-type allies' critical hit ratio by two stages", async () => {
await game.classicMode.startBattle([Species.MAGIKARP, Species.DRAGONAIR]); await game.classicMode.startBattle([Species.MAGIKARP, Species.DRAGONAIR]);
@ -64,7 +62,7 @@ describe("Moves - Dragon Cheer", () => {
// After Tackle // After Tackle
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.getCritStage).toHaveReturnedWith(2); // getCritStage is called on defender expect(enemy.getCritStage).toHaveReturnedWith(2); // getCritStage is called on defender
}, TIMEOUT); });
it("applies the effect based on the allies' type upon use of the move, and do not change if the allies' type changes later in battle", async () => { it("applies the effect based on the allies' type upon use of the move, and do not change if the allies' type changes later in battle", async () => {
await game.classicMode.startBattle([Species.DRAGONAIR, Species.MAGIKARP]); await game.classicMode.startBattle([Species.DRAGONAIR, Species.MAGIKARP]);
@ -96,5 +94,5 @@ describe("Moves - Dragon Cheer", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getCritStage).toHaveReturnedWith(1); // getCritStage is called on defender expect(enemy.getCritStage).toHaveReturnedWith(1); // getCritStage is called on defender
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
import GameManager from "../utils/gameManager"; import GameManager from "../utils/gameManager";
const TIMEOUT = 20 * 1000;
describe("Moves - Dragon Tail", () => { describe("Moves - Dragon Tail", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,12 +50,12 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase); await game.phaseInterceptor.to(BerryPhase);
const isVisible = enemyPokemon.visible; const isVisible = enemyPokemon.visible;
const hasFled = enemyPokemon.wildFlee; const hasFled = enemyPokemon.switchOutStatus;
expect(!isVisible && hasFled).toBe(true); expect(!isVisible && hasFled).toBe(true);
// simply want to test that the game makes it this far without crashing // simply want to test that the game makes it this far without crashing
await game.phaseInterceptor.to(BattleEndPhase); await game.phaseInterceptor.to(BattleEndPhase);
}, TIMEOUT }
); );
test( test(
@ -72,10 +72,10 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase); await game.phaseInterceptor.to(BerryPhase);
const isVisible = enemyPokemon.visible; const isVisible = enemyPokemon.visible;
const hasFled = enemyPokemon.wildFlee; const hasFled = enemyPokemon.switchOutStatus;
expect(!isVisible && hasFled).toBe(true); expect(!isVisible && hasFled).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -97,9 +97,9 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(TurnEndPhase); await game.phaseInterceptor.to(TurnEndPhase);
const isVisibleLead = enemyLeadPokemon.visible; const isVisibleLead = enemyLeadPokemon.visible;
const hasFledLead = enemyLeadPokemon.wildFlee; const hasFledLead = enemyLeadPokemon.switchOutStatus;
const isVisibleSec = enemySecPokemon.visible; const isVisibleSec = enemySecPokemon.visible;
const hasFledSec = enemySecPokemon.wildFlee; const hasFledSec = enemySecPokemon.switchOutStatus;
expect(!isVisibleLead && hasFledLead && isVisibleSec && !hasFledSec).toBe(true); expect(!isVisibleLead && hasFledLead && isVisibleSec && !hasFledSec).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
@ -109,7 +109,7 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase); await game.phaseInterceptor.to(BerryPhase);
expect(enemySecPokemon.hp).toBeLessThan(enemySecPokemon.getMaxHp()); expect(enemySecPokemon.hp).toBeLessThan(enemySecPokemon.getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -133,14 +133,14 @@ describe("Moves - Dragon Tail", () => {
await game.phaseInterceptor.to(BerryPhase); await game.phaseInterceptor.to(BerryPhase);
const isVisibleLead = enemyLeadPokemon.visible; const isVisibleLead = enemyLeadPokemon.visible;
const hasFledLead = enemyLeadPokemon.wildFlee; const hasFledLead = enemyLeadPokemon.switchOutStatus;
const isVisibleSec = enemySecPokemon.visible; const isVisibleSec = enemySecPokemon.visible;
const hasFledSec = enemySecPokemon.wildFlee; const hasFledSec = enemySecPokemon.switchOutStatus;
expect(!isVisibleLead && hasFledLead && !isVisibleSec && hasFledSec).toBe(true); expect(!isVisibleLead && hasFledLead && !isVisibleSec && hasFledSec).toBe(true);
expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBeLessThan(leadPokemon.getMaxHp());
expect(secPokemon.hp).toBeLessThan(secPokemon.getMaxHp()); expect(secPokemon.hp).toBeLessThan(secPokemon.getMaxHp());
expect(enemyLeadPokemon.hp).toBeLessThan(enemyLeadPokemon.getMaxHp()); expect(enemyLeadPokemon.hp).toBeLessThan(enemyLeadPokemon.getMaxHp());
expect(enemySecPokemon.hp).toBeLessThan(enemySecPokemon.getMaxHp()); expect(enemySecPokemon.hp).toBeLessThan(enemySecPokemon.getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -7,7 +7,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
/** HP Cost of Move */ /** HP Cost of Move */
const RATIO = 2; const RATIO = 2;
/** Amount of extra HP lost */ /** Amount of extra HP lost */
@ -53,7 +53,7 @@ describe("Moves - FILLET AWAY", () => {
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2);
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(2); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(2);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(2); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(2);
}, TIMEOUT }
); );
test("still takes effect if one or more of the involved stat stages are not at max", test("still takes effect if one or more of the involved stat stages are not at max",
@ -74,7 +74,7 @@ describe("Moves - FILLET AWAY", () => {
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(5); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(5);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(2); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(2);
}, TIMEOUT }
); );
test("fails if all stat stages involved are at max", test("fails if all stat stages involved are at max",
@ -94,7 +94,7 @@ describe("Moves - FILLET AWAY", () => {
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(6);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(6); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(6);
}, TIMEOUT }
); );
test("fails if the user's health is less than 1/2", test("fails if the user's health is less than 1/2",
@ -112,6 +112,6 @@ describe("Moves - FILLET AWAY", () => {
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(leadPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(leadPokemon.getStatStage(Stat.SPD)).toBe(0); expect(leadPokemon.getStatStage(Stat.SPD)).toBe(0);
}, TIMEOUT }
); );
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Focus Punch", () => { describe("Moves - Focus Punch", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -61,7 +61,7 @@ describe("Moves - Focus Punch", () => {
expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp); expect(enemyPokemon.hp).toBeLessThan(enemyStartingHp);
expect(leadPokemon.getMoveHistory().length).toBe(1); expect(leadPokemon.getMoveHistory().length).toBe(1);
expect(leadPokemon.turnData.damageDealt).toBe(enemyStartingHp - enemyPokemon.hp); expect(leadPokemon.turnData.damageDealt).toBe(enemyStartingHp - enemyPokemon.hp);
}, TIMEOUT }
); );
it( it(
@ -88,7 +88,7 @@ describe("Moves - Focus Punch", () => {
expect(enemyPokemon.hp).toBe(enemyStartingHp); expect(enemyPokemon.hp).toBe(enemyStartingHp);
expect(leadPokemon.getMoveHistory().length).toBe(1); expect(leadPokemon.getMoveHistory().length).toBe(1);
expect(leadPokemon.turnData.damageDealt).toBe(0); expect(leadPokemon.turnData.damageDealt).toBe(0);
}, TIMEOUT }
); );
it( it(
@ -111,7 +111,7 @@ describe("Moves - Focus Punch", () => {
expect(leadPokemon.getMoveHistory().length).toBe(1); expect(leadPokemon.getMoveHistory().length).toBe(1);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -129,6 +129,6 @@ describe("Moves - Focus Punch", () => {
expect(game.scene.getCurrentPhase() instanceof SwitchSummonPhase).toBeTruthy(); expect(game.scene.getCurrentPhase() instanceof SwitchSummonPhase).toBeTruthy();
expect(game.scene.phaseQueue.find(phase => phase instanceof MoveHeaderPhase)).toBeDefined(); expect(game.scene.phaseQueue.find(phase => phase instanceof MoveHeaderPhase)).toBeDefined();
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Follow Me", () => { describe("Moves - Follow Me", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -54,7 +54,7 @@ describe("Moves - Follow Me", () => {
expect(playerPokemon[0].hp).toBeLessThan(playerPokemon[0].getMaxHp()); expect(playerPokemon[0].hp).toBeLessThan(playerPokemon[0].getMaxHp());
expect(playerPokemon[1].hp).toBe(playerPokemon[1].getMaxHp()); expect(playerPokemon[1].hp).toBe(playerPokemon[1].getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -77,7 +77,7 @@ describe("Moves - Follow Me", () => {
expect(playerPokemon[1].hp).toBeLessThan(playerPokemon[1].getMaxHp()); expect(playerPokemon[1].hp).toBeLessThan(playerPokemon[1].getMaxHp());
expect(playerPokemon[0].hp).toBe(playerPokemon[0].getMaxHp()); expect(playerPokemon[0].hp).toBe(playerPokemon[0].getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -102,7 +102,7 @@ describe("Moves - Follow Me", () => {
// If redirection was bypassed, both enemies should be damaged // If redirection was bypassed, both enemies should be damaged
expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp()); expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -125,6 +125,6 @@ describe("Moves - Follow Me", () => {
// If redirection was bypassed, both enemies should be damaged // If redirection was bypassed, both enemies should be damaged
expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp()); expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[1].getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -9,8 +9,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
describe("Moves - Freeze-Dry", () => { describe("Moves - Freeze-Dry", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -44,7 +42,7 @@ describe("Moves - Freeze-Dry", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2);
}, TIMEOUT); });
it("should deal 4x damage to water/flying types", async () => { it("should deal 4x damage to water/flying types", async () => {
game.override.enemySpecies(Species.WINGULL); game.override.enemySpecies(Species.WINGULL);
@ -58,7 +56,7 @@ describe("Moves - Freeze-Dry", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4);
}, TIMEOUT); });
it("should deal 1x damage to water/fire types", async () => { it("should deal 1x damage to water/fire types", async () => {
game.override.enemySpecies(Species.VOLCANION); game.override.enemySpecies(Species.VOLCANION);
@ -72,7 +70,7 @@ describe("Moves - Freeze-Dry", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(1); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(1);
}, TIMEOUT); });
// enable if this is ever fixed (lol) // enable if this is ever fixed (lol)
it.todo("should deal 2x damage to water types under Normalize", async () => { it.todo("should deal 2x damage to water types under Normalize", async () => {
@ -87,7 +85,7 @@ describe("Moves - Freeze-Dry", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2);
}, TIMEOUT); });
// enable once Electrify is implemented (and the interaction is fixed, as above) // enable once Electrify is implemented (and the interaction is fixed, as above)
it.todo("should deal 2x damage to water types under Electrify", async () => { it.todo("should deal 2x damage to water types under Electrify", async () => {
@ -102,5 +100,5 @@ describe("Moves - Freeze-Dry", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2);
}, TIMEOUT); });
}); });

View File

@ -6,7 +6,7 @@ import { MoveResult } from "#app/field/pokemon";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Gastro Acid", () => { describe("Moves - Gastro Acid", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,7 +60,7 @@ describe("Moves - Gastro Acid", () => {
expect(enemyField[0].hp).toBeLessThan(enemyField[0].getMaxHp()); expect(enemyField[0].hp).toBeLessThan(enemyField[0].getMaxHp());
expect(enemyField[1].isFullHp()).toBe(true); expect(enemyField[1].isFullHp()).toBe(true);
}, TIMEOUT); });
it("fails if used on an enemy with an already-suppressed ability", async () => { it("fails if used on an enemy with an already-suppressed ability", async () => {
game.override.battleType(null); game.override.battleType(null);
@ -78,5 +78,5 @@ describe("Moves - Gastro Acid", () => {
await game.phaseInterceptor.to("TurnInitPhase"); await game.phaseInterceptor.to("TurnInitPhase");
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
}, TIMEOUT); });
}); });

View File

@ -6,7 +6,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Glaive Rush", () => { describe("Moves - Glaive Rush", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -49,7 +49,7 @@ describe("Moves - Glaive Rush", () => {
await game.phaseInterceptor.to("DamagePhase"); await game.phaseInterceptor.to("DamagePhase");
expect(enemy.hp).toBeLessThanOrEqual(1001 - (damageDealt * 3)); expect(enemy.hp).toBeLessThanOrEqual(1001 - (damageDealt * 3));
}, TIMEOUT); });
it("always gets hit by attacks", async () => { it("always gets hit by attacks", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -62,7 +62,7 @@ describe("Moves - Glaive Rush", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(enemy.hp).toBeLessThan(1000); expect(enemy.hp).toBeLessThan(1000);
}, TIMEOUT); });
it("interacts properly with multi-lens", async () => { it("interacts properly with multi-lens", async () => {
game.override game.override
@ -85,7 +85,7 @@ describe("Moves - Glaive Rush", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(player.hp).toBe(1000); expect(player.hp).toBe(1000);
}, TIMEOUT); });
it("secondary effects only last until next move", async () => { it("secondary effects only last until next move", async () => {
game.override.enemyMoveset([Moves.SHADOW_SNEAK]); game.override.enemyMoveset([Moves.SHADOW_SNEAK]);
@ -111,7 +111,7 @@ describe("Moves - Glaive Rush", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(player.hp).toBe(damagedHp); expect(player.hp).toBe(damagedHp);
}, TIMEOUT); });
it("secondary effects are removed upon switching", async () => { it("secondary effects are removed upon switching", async () => {
game.override game.override
@ -135,7 +135,7 @@ describe("Moves - Glaive Rush", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(player.hp).toBe(player.getMaxHp()); expect(player.hp).toBe(player.getMaxHp());
}, TIMEOUT); });
it("secondary effects don't activate if move fails", async () => { it("secondary effects don't activate if move fails", async () => {
game.override.moveset([Moves.SHADOW_SNEAK, Moves.PROTECT, Moves.SPLASH, Moves.GLAIVE_RUSH]); game.override.moveset([Moves.SHADOW_SNEAK, Moves.PROTECT, Moves.SPLASH, Moves.GLAIVE_RUSH]);
@ -161,5 +161,5 @@ describe("Moves - Glaive Rush", () => {
const damagedHP2 = 1000 - enemy.hp; const damagedHP2 = 1000 - enemy.hp;
expect(damagedHP2).toBeGreaterThanOrEqual((damagedHP1 * 2) - 1); expect(damagedHP2).toBeGreaterThanOrEqual((damagedHP1 * 2) - 1);
}, TIMEOUT); });
}); });

View File

@ -11,8 +11,6 @@ import { MoveEndPhase } from "#app/phases/move-end-phase";
describe("Moves - Guard Swap", () => { describe("Moves - Guard Swap", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -65,5 +63,5 @@ describe("Moves - Guard Swap", () => {
expect(enemy.getStatStage(s)).toBe(1); expect(enemy.getStatStage(s)).toBe(1);
} }
} }
}, TIMEOUT); });
}); });

View File

@ -35,7 +35,7 @@ describe("Moves - Haze", () => {
game.override.ability(Abilities.NONE); game.override.ability(Abilities.NONE);
}); });
it("should reset all stat changes of all Pokemon on field", { timeout: 10000 }, async () => { it("should reset all stat changes of all Pokemon on field", async () => {
await game.startBattle([Species.RATTATA]); await game.startBattle([Species.RATTATA]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
const enemy = game.scene.getEnemyPokemon()!; const enemy = game.scene.getEnemyPokemon()!;

View File

@ -11,8 +11,6 @@ import { MoveEndPhase } from "#app/phases/move-end-phase";
describe("Moves - Heart Swap", () => { describe("Moves - Heart Swap", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -60,5 +58,5 @@ describe("Moves - Heart Swap", () => {
expect(enemy.getStatStage(s)).toBe(0); expect(enemy.getStatStage(s)).toBe(0);
expect(player.getStatStage(s)).toBe(1); expect(player.getStatStage(s)).toBe(1);
} }
}, TIMEOUT); });
}); });

View File

@ -9,8 +9,6 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000; // 20 sec timeout for all tests
describe("Moves - Hyper Beam", () => { describe("Moves - Hyper Beam", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -67,6 +65,6 @@ describe("Moves - Hyper Beam", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(enemyPokemon.hp).toBeLessThan(enemyPostAttackHp); expect(enemyPokemon.hp).toBeLessThan(enemyPostAttackHp);
}, TIMEOUT }
); );
}); });

View File

@ -11,7 +11,7 @@ import { Species } from "#enums/species";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Jaw Lock", () => { describe("Moves - Jaw Lock", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -61,7 +61,7 @@ describe("Moves - Jaw Lock", () => {
expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined(); expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined();
expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined(); expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeDefined();
}, TIMEOUT }
); );
it( it(
@ -90,7 +90,7 @@ describe("Moves - Jaw Lock", () => {
expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined();
expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined();
}, TIMEOUT }
); );
it( it(
@ -114,7 +114,7 @@ describe("Moves - Jaw Lock", () => {
await game.doKillOpponents(); await game.doKillOpponents();
expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(leadPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined();
}, TIMEOUT }
); );
it( it(
@ -146,7 +146,7 @@ describe("Moves - Jaw Lock", () => {
expect(enemyPokemon[1].getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(enemyPokemon[1].getTag(BattlerTagType.TRAPPED)).toBeUndefined();
expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined(); expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)).toBeDefined();
expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)?.sourceId).toBe(enemyPokemon[0].id); expect(playerPokemon[0].getTag(BattlerTagType.TRAPPED)?.sourceId).toBe(enemyPokemon[0].id);
}, TIMEOUT }
); );
it( it(
@ -165,6 +165,6 @@ describe("Moves - Jaw Lock", () => {
expect(playerPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(playerPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined();
expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined(); expect(enemyPokemon.getTag(BattlerTagType.TRAPPED)).toBeUndefined();
}, TIMEOUT }
); );
}); });

View File

@ -7,7 +7,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Lash Out", () => { describe("Moves - Lash Out", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -48,5 +48,5 @@ describe("Moves - Lash Out", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(allMoves[Moves.LASH_OUT].calculateBattlePower).toHaveReturnedWith(150); expect(allMoves[Moves.LASH_OUT].calculateBattlePower).toHaveReturnedWith(150);
}, TIMEOUT); });
}); });

View File

@ -7,7 +7,7 @@ import { TurnEndPhase } from "#app/phases/turn-end-phase";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import GameManager from "../utils/gameManager"; import GameManager from "../utils/gameManager";
const TIMEOUT = 20 * 1000;
describe("Moves - Lucky Chant", () => { describe("Moves - Lucky Chant", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -55,7 +55,7 @@ describe("Moves - Lucky Chant", () => {
const secondTurnDamage = playerPokemon.getMaxHp() - playerPokemon.hp - firstTurnDamage; const secondTurnDamage = playerPokemon.getMaxHp() - playerPokemon.hp - firstTurnDamage;
expect(secondTurnDamage).toBeLessThan(firstTurnDamage); expect(secondTurnDamage).toBeLessThan(firstTurnDamage);
}, TIMEOUT }
); );
it( it(
@ -81,7 +81,7 @@ describe("Moves - Lucky Chant", () => {
const secondTurnDamage = playerPokemon[0].getMaxHp() - playerPokemon[0].hp - firstTurnDamage; const secondTurnDamage = playerPokemon[0].getMaxHp() - playerPokemon[0].hp - firstTurnDamage;
expect(secondTurnDamage).toBeLessThan(firstTurnDamage); expect(secondTurnDamage).toBeLessThan(firstTurnDamage);
}, TIMEOUT }
); );
it( it(
@ -108,6 +108,6 @@ describe("Moves - Lucky Chant", () => {
const secondTurnDamage = playerPokemon.getMaxHp() - playerPokemon.hp - firstTurnDamage; const secondTurnDamage = playerPokemon.getMaxHp() - playerPokemon.hp - firstTurnDamage;
expect(secondTurnDamage).toBeLessThan(firstTurnDamage); expect(secondTurnDamage).toBeLessThan(firstTurnDamage);
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { MoveEndPhase } from "#app/phases/move-end-phase"; import { MoveEndPhase } from "#app/phases/move-end-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
const TIMEOUT = 20 * 1000;
describe("Moves - Make It Rain", () => { describe("Moves - Make It Rain", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -46,7 +46,7 @@ describe("Moves - Make It Rain", () => {
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1);
}, TIMEOUT); });
it("should apply effects even if the target faints", async () => { it("should apply effects even if the target faints", async () => {
game.override.enemyLevel(1); // ensures the enemy will faint game.override.enemyLevel(1); // ensures the enemy will faint
@ -63,7 +63,7 @@ describe("Moves - Make It Rain", () => {
expect(enemyPokemon.isFainted()).toBe(true); expect(enemyPokemon.isFainted()).toBe(true);
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1);
}, TIMEOUT); });
it("should reduce Sp. Atk. once after KOing two enemies", async () => { it("should reduce Sp. Atk. once after KOing two enemies", async () => {
game.override.enemyLevel(1); // ensures the enemy will faint game.override.enemyLevel(1); // ensures the enemy will faint
@ -80,7 +80,7 @@ describe("Moves - Make It Rain", () => {
enemyPokemon.forEach(p => expect(p.isFainted()).toBe(true)); enemyPokemon.forEach(p => expect(p.isFainted()).toBe(true));
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1);
}, TIMEOUT); });
it("should lower SPATK stat stage by 1 if it only hits the second target", async () => { it("should lower SPATK stat stage by 1 if it only hits the second target", async () => {
await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]); await game.startBattle([Species.CHARIZARD, Species.BLASTOISE]);
@ -96,5 +96,5 @@ describe("Moves - Make It Rain", () => {
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1); expect(playerPokemon.getStatStage(Stat.SPATK)).toBe(-1);
}, TIMEOUT); });
}); });

View File

@ -9,7 +9,7 @@ import { BerryPhase } from "#app/phases/berry-phase";
import { CommandPhase } from "#app/phases/command-phase"; import { CommandPhase } from "#app/phases/command-phase";
import { TurnEndPhase } from "#app/phases/turn-end-phase"; import { TurnEndPhase } from "#app/phases/turn-end-phase";
const TIMEOUT = 20 * 1000;
describe("Moves - Mat Block", () => { describe("Moves - Mat Block", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -56,7 +56,7 @@ describe("Moves - Mat Block", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp())); leadPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp()));
}, TIMEOUT }
); );
test( test(
@ -77,7 +77,7 @@ describe("Moves - Mat Block", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(-2)); leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(-2));
}, TIMEOUT }
); );
test( test(
@ -103,6 +103,6 @@ describe("Moves - Mat Block", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(leadPokemon.some((p, i) => p.hp < leadStartingHp[i])).toBeTruthy(); expect(leadPokemon.some((p, i) => p.hp < leadStartingHp[i])).toBeTruthy();
}, TIMEOUT }
); );
}); });

View File

@ -7,7 +7,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Multi-target damage reduction", () => { describe("Multi-target damage reduction", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -75,7 +75,7 @@ describe("Multi-target damage reduction", () => {
// Moves that target all enemies get reduced if there's more than one enemy // Moves that target all enemies get reduced if there's more than one enemy
expect(gleam1).toBeLessThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) + 1); expect(gleam1).toBeLessThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) + 1);
expect(gleam1).toBeGreaterThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) - 1); expect(gleam1).toBeGreaterThanOrEqual(Utils.toDmgValue(gleam2 * 0.75) - 1);
}, TIMEOUT); });
it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => { it("should reduce earthquake when more than one pokemon other than user is not fainted", async () => {
await game.startBattle([Species.MAGIKARP, Species.FEEBAS]); await game.startBattle([Species.MAGIKARP, Species.FEEBAS]);
@ -126,5 +126,5 @@ describe("Multi-target damage reduction", () => {
// Turn 3: 1 target, should be no damage reduction // Turn 3: 1 target, should be no damage reduction
expect(damageEnemy1Turn1).toBeLessThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) + 1); expect(damageEnemy1Turn1).toBeLessThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) + 1);
expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) - 1); expect(damageEnemy1Turn1).toBeGreaterThanOrEqual(Utils.toDmgValue(damageEnemy1Turn3 * 0.75) - 1);
}, TIMEOUT); });
}); });

View File

@ -8,8 +8,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Obstruct", () => { describe("Moves - Obstruct", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -41,7 +39,7 @@ describe("Moves - Obstruct", () => {
expect(player.isFullHp()).toBe(true); expect(player.isFullHp()).toBe(true);
expect(enemy.getStatStage(Stat.DEF)).toBe(-2); expect(enemy.getStatStage(Stat.DEF)).toBe(-2);
}, TIMEOUT); });
it("bypasses accuracy checks when applying protection and defense reduction", async () => { it("bypasses accuracy checks when applying protection and defense reduction", async () => {
game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH)); game.override.enemyMoveset(Array(4).fill(Moves.ICE_PUNCH));
@ -57,7 +55,7 @@ describe("Moves - Obstruct", () => {
await game.phaseInterceptor.to("TurnEndPhase"); await game.phaseInterceptor.to("TurnEndPhase");
expect(player.isFullHp()).toBe(true); expect(player.isFullHp()).toBe(true);
expect(enemy.getStatStage(Stat.DEF)).toBe(-2); expect(enemy.getStatStage(Stat.DEF)).toBe(-2);
}, TIMEOUT }
); );
it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => { it("protects from non-contact damaging moves and doesn't lower the opponent's defense by 2 stages", async () => {
@ -72,7 +70,7 @@ describe("Moves - Obstruct", () => {
expect(player.isFullHp()).toBe(true); expect(player.isFullHp()).toBe(true);
expect(enemy.getStatStage(Stat.DEF)).toBe(0); expect(enemy.getStatStage(Stat.DEF)).toBe(0);
}, TIMEOUT); });
it("doesn't protect from status moves", async () => { it("doesn't protect from status moves", async () => {
game.override.enemyMoveset(Array(4).fill(Moves.GROWL)); game.override.enemyMoveset(Array(4).fill(Moves.GROWL));
@ -84,5 +82,5 @@ describe("Moves - Obstruct", () => {
const player = game.scene.getPlayerPokemon()!; const player = game.scene.getPlayerPokemon()!;
expect(player.getStatStage(Stat.ATK)).toBe(-1); expect(player.getStatStage(Stat.ATK)).toBe(-1);
}, TIMEOUT); });
}); });

View File

@ -36,7 +36,7 @@ describe("Moves - Octolock", () => {
.ability(Abilities.BALL_FETCH); .ability(Abilities.BALL_FETCH);
}); });
it("lowers DEF and SPDEF stat stages of the target Pokemon by 1 each turn", { timeout: 10000 }, async () => { it("lowers DEF and SPDEF stat stages of the target Pokemon by 1 each turn", async () => {
await game.classicMode.startBattle([ Species.GRAPPLOCT ]); await game.classicMode.startBattle([ Species.GRAPPLOCT ]);
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;
@ -57,7 +57,7 @@ describe("Moves - Octolock", () => {
expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(-2); expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(-2);
}); });
it("if target pokemon has BIG_PECKS, should only lower SPDEF stat stage by 1", { timeout: 10000 }, async () => { it("if target pokemon has BIG_PECKS, should only lower SPDEF stat stage by 1", async () => {
game.override.enemyAbility(Abilities.BIG_PECKS); game.override.enemyAbility(Abilities.BIG_PECKS);
await game.classicMode.startBattle([ Species.GRAPPLOCT ]); await game.classicMode.startBattle([ Species.GRAPPLOCT ]);
@ -71,7 +71,7 @@ describe("Moves - Octolock", () => {
expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(-1);
}); });
it("if target pokemon has WHITE_SMOKE, should not reduce any stat stages", { timeout: 10000 }, async () => { it("if target pokemon has WHITE_SMOKE, should not reduce any stat stages", async () => {
game.override.enemyAbility(Abilities.WHITE_SMOKE); game.override.enemyAbility(Abilities.WHITE_SMOKE);
await game.classicMode.startBattle([ Species.GRAPPLOCT ]); await game.classicMode.startBattle([ Species.GRAPPLOCT ]);
@ -85,7 +85,7 @@ describe("Moves - Octolock", () => {
expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(0);
}); });
it("if target pokemon has CLEAR_BODY, should not reduce any stat stages", { timeout: 10000 }, async () => { it("if target pokemon has CLEAR_BODY, should not reduce any stat stages", async () => {
game.override.enemyAbility(Abilities.CLEAR_BODY); game.override.enemyAbility(Abilities.CLEAR_BODY);
await game.classicMode.startBattle([ Species.GRAPPLOCT ]); await game.classicMode.startBattle([ Species.GRAPPLOCT ]);
@ -99,7 +99,7 @@ describe("Moves - Octolock", () => {
expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPDEF)).toBe(0);
}); });
it("traps the target pokemon", { timeout: 10000 }, async () => { it("traps the target pokemon", async () => {
await game.classicMode.startBattle([ Species.GRAPPLOCT ]); await game.classicMode.startBattle([ Species.GRAPPLOCT ]);
const enemyPokemon = game.scene.getEnemyPokemon()!; const enemyPokemon = game.scene.getEnemyPokemon()!;

View File

@ -10,7 +10,7 @@ import { FaintPhase } from "#app/phases/faint-phase";
import { MessagePhase } from "#app/phases/message-phase"; import { MessagePhase } from "#app/phases/message-phase";
import { TurnInitPhase } from "#app/phases/turn-init-phase"; import { TurnInitPhase } from "#app/phases/turn-init-phase";
const TIMEOUT = 20 * 1000;
describe("Moves - Parting Shot", () => { describe("Moves - Parting Shot", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -53,7 +53,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
test( test(
@ -73,7 +73,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
it.skip( // TODO: fix this bug to pass the test! it.skip( // TODO: fix this bug to pass the test!
@ -115,7 +115,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-6);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-6);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
it.skip( // TODO: fix this bug to pass the test! it.skip( // TODO: fix this bug to pass the test!
@ -136,7 +136,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
it.skip( // TODO: fix this bug to pass the test! it.skip( // TODO: fix this bug to pass the test!
@ -156,7 +156,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
it.skip( // TODO: fix this bug to pass the test! it.skip( // TODO: fix this bug to pass the test!
@ -173,7 +173,7 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(-1);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-1); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(-1);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MURKROW);
}, TIMEOUT }
); );
it.skip( // TODO: fix this bug to pass the test! it.skip( // TODO: fix this bug to pass the test!
@ -196,6 +196,6 @@ describe("Moves - Parting Shot", () => {
expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.ATK)).toBe(0);
expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0); expect(enemyPokemon.getStatStage(Stat.SPATK)).toBe(0);
expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MEOWTH); expect(game.scene.getPlayerField()[0].species.speciesId).toBe(Species.MEOWTH);
}, TIMEOUT }
); );
}); });

View File

@ -9,8 +9,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Power Shift", () => { describe("Moves - Power Shift", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -59,5 +57,5 @@ describe("Moves - Power Shift", () => {
// Raw stats are swapped // Raw stats are swapped
expect(playerPokemon.getStat(Stat.ATK, false)).toBe(20); expect(playerPokemon.getStat(Stat.ATK, false)).toBe(20);
expect(playerPokemon.getStat(Stat.DEF, false)).toBe(10); expect(playerPokemon.getStat(Stat.DEF, false)).toBe(10);
}, TIMEOUT); });
}); });

View File

@ -11,8 +11,6 @@ import { MoveEndPhase } from "#app/phases/move-end-phase";
describe("Moves - Power Swap", () => { describe("Moves - Power Swap", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -65,5 +63,5 @@ describe("Moves - Power Swap", () => {
expect(enemy.getStatStage(s)).toBe(1); expect(enemy.getStatStage(s)).toBe(1);
} }
} }
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ import { ArenaTagSide, ArenaTrapTag } from "#app/data/arena-tag";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { MoveResult } from "#app/field/pokemon"; import { MoveResult } from "#app/field/pokemon";
const TIMEOUT = 20 * 1000;
describe("Moves - Protect", () => { describe("Moves - Protect", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -53,7 +53,7 @@ describe("Moves - Protect", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -72,7 +72,7 @@ describe("Moves - Protect", () => {
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(game.scene.arena.getTagOnSide(ArenaTrapTag, ArenaTagSide.ENEMY)).toBeUndefined(); expect(game.scene.arena.getTagOnSide(ArenaTrapTag, ArenaTagSide.ENEMY)).toBeUndefined();
}, TIMEOUT }
); );
test( test(
@ -89,7 +89,7 @@ describe("Moves - Protect", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(0);
}, TIMEOUT }
); );
test( test(
@ -108,7 +108,7 @@ describe("Moves - Protect", () => {
expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp()); expect(leadPokemon.hp).toBe(leadPokemon.getMaxHp());
expect(enemyPokemon.turnData.hitCount).toBe(1); expect(enemyPokemon.turnData.hitCount).toBe(1);
}, TIMEOUT }
); );
test( test(
@ -129,6 +129,6 @@ describe("Moves - Protect", () => {
expect(enemyPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); expect(enemyPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
expect(leadPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(leadPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Purify", () => { describe("Moves - Purify", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -55,7 +55,6 @@ describe("Moves - Purify", () => {
expect(enemyPokemon.status).toBeNull(); expect(enemyPokemon.status).toBeNull();
expect(playerPokemon.isFullHp()).toBe(true); expect(playerPokemon.isFullHp()).toBe(true);
}, },
TIMEOUT
); );
test( test(
@ -74,7 +73,6 @@ describe("Moves - Purify", () => {
expect(playerPokemon.hp).toBe(playerInitialHp); expect(playerPokemon.hp).toBe(playerInitialHp);
}, },
TIMEOUT
); );
}); });

View File

@ -8,7 +8,7 @@ import { Stat } from "#enums/stat";
import { BattlerIndex } from "#app/battle"; import { BattlerIndex } from "#app/battle";
import { MoveResult } from "#app/field/pokemon"; import { MoveResult } from "#app/field/pokemon";
const TIMEOUT = 20 * 1000;
describe("Moves - Quick Guard", () => { describe("Moves - Quick Guard", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -52,7 +52,7 @@ describe("Moves - Quick Guard", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
playerPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp())); playerPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp()));
}, TIMEOUT }
); );
test( test(
@ -71,7 +71,7 @@ describe("Moves - Quick Guard", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
playerPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0)); playerPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0));
}, TIMEOUT }
); );
test( test(
@ -113,6 +113,6 @@ describe("Moves - Quick Guard", () => {
expect(enemyPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); expect(enemyPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
}, TIMEOUT }
); );
}); });

View File

@ -6,7 +6,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Rage Powder", () => { describe("Moves - Rage Powder", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,7 +50,7 @@ describe("Moves - Rage Powder", () => {
// If redirection was bypassed, both enemies should be damaged // If redirection was bypassed, both enemies should be damaged
expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[1].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -76,6 +76,6 @@ describe("Moves - Rage Powder", () => {
// If redirection was bypassed, both enemies should be damaged // If redirection was bypassed, both enemies should be damaged
expect(enemyPokemon[0].hp).toBeLessThan(enemyStartingHp[0]); expect(enemyPokemon[0].hp).toBeLessThan(enemyStartingHp[0]);
expect(enemyPokemon[1].hp).toBeLessThan(enemyStartingHp[1]); expect(enemyPokemon[1].hp).toBeLessThan(enemyStartingHp[1]);
}, TIMEOUT }
); );
}); });

View File

@ -10,8 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
describe("Moves - Relic Song", () => { describe("Moves - Relic Song", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -47,7 +45,7 @@ describe("Moves - Relic Song", () => {
await game.phaseInterceptor.to("BerryPhase"); await game.phaseInterceptor.to("BerryPhase");
expect(meloetta.formIndex).toBe(0); expect(meloetta.formIndex).toBe(0);
}, TIMEOUT); });
it("doesn't swap Meloetta's form during a mono-type challenge", async () => { it("doesn't swap Meloetta's form during a mono-type challenge", async () => {
game.challengeMode.addChallenge(Challenges.SINGLE_TYPE, Type.PSYCHIC + 1, 0); game.challengeMode.addChallenge(Challenges.SINGLE_TYPE, Type.PSYCHIC + 1, 0);
@ -62,7 +60,7 @@ describe("Moves - Relic Song", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(meloetta.formIndex).toBe(0); expect(meloetta.formIndex).toBe(0);
}, TIMEOUT); });
it("doesn't swap Meloetta's form during biome change (arena reset)", async () => { it("doesn't swap Meloetta's form during biome change (arena reset)", async () => {
game.override game.override
@ -77,5 +75,5 @@ describe("Moves - Relic Song", () => {
await game.toNextWave(); await game.toNextWave();
expect(meloetta.formIndex).toBe(1); expect(meloetta.formIndex).toBe(1);
}, TIMEOUT); });
}); });

View File

@ -9,7 +9,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Roost", () => { describe("Moves - Roost", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -72,7 +72,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes[0] === Type.NORMAL).toBeTruthy(); expect(playerPokemonTypes[0] === Type.NORMAL).toBeTruthy();
expect(playerPokemonTypes.length === 1).toBeTruthy(); expect(playerPokemonTypes.length === 1).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeTruthy(); expect(playerPokemon.isGrounded()).toBeTruthy();
}, TIMEOUT }
); );
test( test(
@ -100,7 +100,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy(); expect(playerPokemonTypes[0] === Type.FLYING).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
test( test(
@ -128,7 +128,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy(); expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
test( test(
@ -157,7 +157,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy(); expect(playerPokemonTypes[1] === Type.FLYING).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
test( test(
@ -196,7 +196,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes.length === 1).toBeTruthy(); expect(playerPokemonTypes.length === 1).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
test( test(
@ -236,7 +236,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes.length === 1).toBeTruthy(); expect(playerPokemonTypes.length === 1).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
test( test(
@ -263,7 +263,7 @@ describe("Moves - Roost", () => {
expect(playerPokemonTypes.length === 3).toBeTruthy(); expect(playerPokemonTypes.length === 3).toBeTruthy();
expect(playerPokemon.isGrounded()).toBeFalsy(); expect(playerPokemon.isGrounded()).toBeFalsy();
}, TIMEOUT }
); );
}); });

View File

@ -8,7 +8,7 @@ import { Species } from "#enums/species";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Safeguard", () => { describe("Moves - Safeguard", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -46,7 +46,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemy.status).toBeUndefined(); expect(enemy.status).toBeUndefined();
}, TIMEOUT); });
it("protects from status moves", async () => { it("protects from status moves", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -57,7 +57,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.status).toBeUndefined(); expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT); });
it("protects from confusion", async () => { it("protects from confusion", async () => {
game.override.moveset([Moves.CONFUSE_RAY]); game.override.moveset([Moves.CONFUSE_RAY]);
@ -69,7 +69,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.summonData.tags).toEqual([]); expect(enemyPokemon.summonData.tags).toEqual([]);
}, TIMEOUT); });
it("protects ally from status", async () => { it("protects ally from status", async () => {
game.override.battleType("double"); game.override.battleType("double");
@ -87,7 +87,7 @@ describe("Moves - Safeguard", () => {
expect(enemyPokemon[0].status).toBeUndefined(); expect(enemyPokemon[0].status).toBeUndefined();
expect(enemyPokemon[1].status).toBeUndefined(); expect(enemyPokemon[1].status).toBeUndefined();
}, TIMEOUT); });
it("protects from Yawn", async () => { it("protects from Yawn", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -98,7 +98,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.summonData.tags).toEqual([]); expect(enemyPokemon.summonData.tags).toEqual([]);
}, TIMEOUT); });
it("doesn't protect from already existing Yawn", async () => { it("doesn't protect from already existing Yawn", async () => {
await game.classicMode.startBattle(); await game.classicMode.startBattle();
@ -112,7 +112,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.status?.effect).toEqual(StatusEffect.SLEEP); expect(enemyPokemon.status?.effect).toEqual(StatusEffect.SLEEP);
}, TIMEOUT); });
it("doesn't protect from self-inflicted via Rest or Flame Orb", async () => { it("doesn't protect from self-inflicted via Rest or Flame Orb", async () => {
game.override.enemyHeldItems([{name: "FLAME_ORB"}]); game.override.enemyHeldItems([{name: "FLAME_ORB"}]);
@ -135,7 +135,7 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.status?.effect).toEqual(StatusEffect.SLEEP); expect(enemyPokemon.status?.effect).toEqual(StatusEffect.SLEEP);
}, TIMEOUT); });
it("protects from ability-inflicted status", async () => { it("protects from ability-inflicted status", async () => {
game.override.ability(Abilities.STATIC); game.override.ability(Abilities.STATIC);
@ -151,5 +151,5 @@ describe("Moves - Safeguard", () => {
await game.toNextTurn(); await game.toNextTurn();
expect(enemyPokemon.status).toBeUndefined(); expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT); });
}); });

View File

@ -10,8 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, it, expect, vi } from "vite
describe("Moves - Shell Side Arm", () => { describe("Moves - Shell Side Arm", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -47,7 +45,7 @@ describe("Moves - Shell Side Arm", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(shellSideArmAttr.apply).toHaveLastReturnedWith(true); expect(shellSideArmAttr.apply).toHaveLastReturnedWith(true);
}, TIMEOUT); });
it("remains a special attack if forecasted to deal more damage as special", async () => { it("remains a special attack if forecasted to deal more damage as special", async () => {
game.override.enemySpecies(Species.SLOWBRO); game.override.enemySpecies(Species.SLOWBRO);
@ -63,7 +61,7 @@ describe("Moves - Shell Side Arm", () => {
await game.phaseInterceptor.to("MoveEffectPhase"); await game.phaseInterceptor.to("MoveEffectPhase");
expect(shellSideArmAttr.apply).toHaveLastReturnedWith(false); expect(shellSideArmAttr.apply).toHaveLastReturnedWith(false);
}, TIMEOUT); });
it("respects stat stage changes when forecasting base damage", async () => { it("respects stat stage changes when forecasting base damage", async () => {
game.override game.override
@ -83,5 +81,5 @@ describe("Moves - Shell Side Arm", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(shellSideArmAttr.apply).toHaveLastReturnedWith(false); expect(shellSideArmAttr.apply).toHaveLastReturnedWith(false);
}, TIMEOUT); });
}); });

View File

@ -10,7 +10,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Shell Trap", () => { describe("Moves - Shell Trap", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -60,7 +60,7 @@ describe("Moves - Shell Trap", () => {
await game.phaseInterceptor.to(MoveEndPhase); await game.phaseInterceptor.to(MoveEndPhase);
enemyPokemon.forEach(p => expect(p.hp).toBeLessThan(p.getMaxHp())); enemyPokemon.forEach(p => expect(p.hp).toBeLessThan(p.getMaxHp()));
}, TIMEOUT }
); );
it( it(
@ -86,7 +86,7 @@ describe("Moves - Shell Trap", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
enemyPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp())); enemyPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp()));
}, TIMEOUT }
); );
it( it(
@ -112,7 +112,7 @@ describe("Moves - Shell Trap", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
enemyPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp())); enemyPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp()));
}, TIMEOUT }
); );
it( it(
@ -138,7 +138,7 @@ describe("Moves - Shell Trap", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
enemyPokemon.forEach((p, i) => expect(p.hp).toBe(enemyStartingHp[i])); enemyPokemon.forEach((p, i) => expect(p.hp).toBe(enemyStartingHp[i]));
}, TIMEOUT }
); );
it( it(
@ -158,6 +158,6 @@ describe("Moves - Shell Trap", () => {
expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -43,7 +43,7 @@ describe("Moves - Spit Up", () => {
}); });
describe("consumes all stockpile stacks to deal damage (scaling with stacks)", () => { describe("consumes all stockpile stacks to deal damage (scaling with stacks)", () => {
it("1 stack -> 100 power", { timeout: 10000 }, async () => { it("1 stack -> 100 power", async () => {
const stacksToSetup = 1; const stacksToSetup = 1;
const expectedPower = 100; const expectedPower = 100;
@ -65,7 +65,7 @@ describe("Moves - Spit Up", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("2 stacks -> 200 power", { timeout: 10000 }, async () => { it("2 stacks -> 200 power", async () => {
const stacksToSetup = 2; const stacksToSetup = 2;
const expectedPower = 200; const expectedPower = 200;
@ -88,7 +88,7 @@ describe("Moves - Spit Up", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("3 stacks -> 300 power", { timeout: 10000 }, async () => { it("3 stacks -> 300 power", async () => {
const stacksToSetup = 3; const stacksToSetup = 3;
const expectedPower = 300; const expectedPower = 300;
@ -113,7 +113,7 @@ describe("Moves - Spit Up", () => {
}); });
}); });
it("fails without stacks", { timeout: 10000 }, async () => { it("fails without stacks", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;
@ -130,7 +130,7 @@ describe("Moves - Spit Up", () => {
}); });
describe("restores stat boosts granted by stacks", () => { describe("restores stat boosts granted by stacks", () => {
it("decreases stats based on stored values (both boosts equal)", { timeout: 10000 }, async () => { it("decreases stats based on stored values (both boosts equal)", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;
@ -157,7 +157,7 @@ describe("Moves - Spit Up", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("decreases stats based on stored values (different boosts)", { timeout: 10000 }, async () => { it("decreases stats based on stored values (different boosts)", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;

View File

@ -6,7 +6,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, test } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Spotlight", () => { describe("Moves - Spotlight", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -50,7 +50,7 @@ describe("Moves - Spotlight", () => {
expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp()); expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp());
}, TIMEOUT }
); );
test( test(
@ -70,6 +70,6 @@ describe("Moves - Spotlight", () => {
expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp()); expect(enemyPokemon[0].hp).toBeLessThan(enemyPokemon[0].getMaxHp());
expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp()); expect(enemyPokemon[1].hp).toBe(enemyPokemon[1].getMaxHp());
}, TIMEOUT }
); );
}); });

View File

@ -37,7 +37,7 @@ describe("Moves - Stockpile", () => {
game.override.ability(Abilities.NONE); game.override.ability(Abilities.NONE);
}); });
it("gains a stockpile stack and raises user's DEF and SPDEF stat stages by 1 on each use, fails at max stacks (3)", { timeout: 10000 }, async () => { it("gains a stockpile stack and raises user's DEF and SPDEF stat stages by 1 on each use, fails at max stacks (3)", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;
@ -76,7 +76,7 @@ describe("Moves - Stockpile", () => {
} }
}); });
it("gains a stockpile stack even if user's DEF and SPDEF stat stages are at +6", { timeout: 10000 }, async () => { it("gains a stockpile stack even if user's DEF and SPDEF stat stages are at +6", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const user = game.scene.getPlayerPokemon()!; const user = game.scene.getPlayerPokemon()!;

View File

@ -16,8 +16,6 @@ import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const TIMEOUT = 20 * 1000; // 20 sec timeout
describe("Moves - Substitute", () => { describe("Moves - Substitute", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
@ -57,7 +55,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3/4)); expect(leadPokemon.hp).toBe(Math.ceil(leadPokemon.getMaxHp() * 3/4));
}, TIMEOUT }
); );
it( it(
@ -81,7 +79,7 @@ describe("Moves - Substitute", () => {
expect(leadPokemon.hp).toBe(postSubHp); expect(leadPokemon.hp).toBe(postSubHp);
expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined(); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined();
}, TIMEOUT }
); );
it( it(
@ -107,7 +105,7 @@ describe("Moves - Substitute", () => {
expect(leadPokemon.hp).toBe(postSubHp); expect(leadPokemon.hp).toBe(postSubHp);
expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeUndefined(); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeUndefined();
}, TIMEOUT }
); );
it( it(
@ -148,7 +146,7 @@ describe("Moves - Substitute", () => {
expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined(); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined();
expect(leadPokemon.hp).toBeLessThan(postSubHp); expect(leadPokemon.hp).toBeLessThan(postSubHp);
}, TIMEOUT }
); );
it( it(
@ -172,7 +170,7 @@ describe("Moves - Substitute", () => {
expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined(); expect(leadPokemon.getTag(BattlerTagType.SUBSTITUTE)).toBeDefined();
expect(leadPokemon.hp).toBeLessThan(postSubHp); expect(leadPokemon.hp).toBeLessThan(postSubHp);
}, TIMEOUT }
); );
it( it(
@ -192,7 +190,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -213,7 +211,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -233,7 +231,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getTag(TrappedTag)).toBeUndefined(); expect(leadPokemon.getTag(TrappedTag)).toBeUndefined();
}, TIMEOUT }
); );
it( it(
@ -253,7 +251,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getStatStage(Stat.DEF)).toBe(0); expect(leadPokemon.getStatStage(Stat.DEF)).toBe(0);
}, TIMEOUT }
); );
it( it(
@ -272,7 +270,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS); expect(leadPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS);
}, TIMEOUT }
); );
it( it(
@ -293,7 +291,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getHeldItems().length).toBe(1); expect(leadPokemon.getHeldItems().length).toBe(1);
}, TIMEOUT }
); );
it( it(
@ -314,7 +312,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("MoveEndPhase", false); await game.phaseInterceptor.to("MoveEndPhase", false);
expect(enemyPokemon.getHeldItems().length).toBe(enemyNumItems); expect(enemyPokemon.getHeldItems().length).toBe(enemyNumItems);
}, TIMEOUT }
); );
it( it(
@ -339,7 +337,7 @@ describe("Moves - Substitute", () => {
expect(leadPokemon.getHeldItems().length).toBe(1); expect(leadPokemon.getHeldItems().length).toBe(1);
expect(enemyPokemon.hp).toBe(enemyPostAttackHp); expect(enemyPokemon.hp).toBe(enemyPostAttackHp);
}, TIMEOUT }
); );
it( it(
@ -358,7 +356,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2); expect(leadPokemon.getStatStage(Stat.ATK)).toBe(2);
}, TIMEOUT }
); );
it( it(
@ -404,7 +402,7 @@ describe("Moves - Substitute", () => {
const subTag = switchedPokemon.getTag(SubstituteTag)!; const subTag = switchedPokemon.getTag(SubstituteTag)!;
expect(subTag).toBeDefined(); expect(subTag).toBeDefined();
expect(subTag.hp).toBe(Math.floor(leadPokemon.getMaxHp() * 1/4)); expect(subTag.hp).toBe(Math.floor(leadPokemon.getMaxHp() * 1/4));
}, TIMEOUT }
); );
it( it(
@ -422,7 +420,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBe(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -447,7 +445,7 @@ describe("Moves - Substitute", () => {
expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS); expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.SUCCESS);
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -467,7 +465,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL); expect(playerPokemon.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
}, TIMEOUT }
); );
it( it(
@ -488,7 +486,7 @@ describe("Moves - Substitute", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.BURN); expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.BURN);
}, TIMEOUT }
); );
it( it(

View File

@ -38,7 +38,7 @@ describe("Moves - Swallow", () => {
}); });
describe("consumes all stockpile stacks to heal (scaling with stacks)", () => { describe("consumes all stockpile stacks to heal (scaling with stacks)", () => {
it("1 stack -> 25% heal", { timeout: 10000 }, async () => { it("1 stack -> 25% heal", async () => {
const stacksToSetup = 1; const stacksToSetup = 1;
const expectedHeal = 25; const expectedHeal = 25;
@ -65,7 +65,7 @@ describe("Moves - Swallow", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("2 stacks -> 50% heal", { timeout: 10000 }, async () => { it("2 stacks -> 50% heal", async () => {
const stacksToSetup = 2; const stacksToSetup = 2;
const expectedHeal = 50; const expectedHeal = 50;
@ -93,7 +93,7 @@ describe("Moves - Swallow", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("3 stacks -> 100% heal", { timeout: 10000 }, async () => { it("3 stacks -> 100% heal", async () => {
const stacksToSetup = 3; const stacksToSetup = 3;
const expectedHeal = 100; const expectedHeal = 100;
@ -123,7 +123,7 @@ describe("Moves - Swallow", () => {
}); });
}); });
it("fails without stacks", { timeout: 10000 }, async () => { it("fails without stacks", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;
@ -138,7 +138,7 @@ describe("Moves - Swallow", () => {
}); });
describe("restores stat stage boosts granted by stacks", () => { describe("restores stat stage boosts granted by stacks", () => {
it("decreases stats based on stored values (both boosts equal)", { timeout: 10000 }, async () => { it("decreases stats based on stored values (both boosts equal)", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;
@ -163,7 +163,7 @@ describe("Moves - Swallow", () => {
expect(pokemon.getTag(StockpilingTag)).toBeUndefined(); expect(pokemon.getTag(StockpilingTag)).toBeUndefined();
}); });
it("lower stat stages based on stored values (different boosts)", { timeout: 10000 }, async () => { it("lower stat stages based on stored values (different boosts)", async () => {
await game.startBattle([Species.ABOMASNOW]); await game.startBattle([Species.ABOMASNOW]);
const pokemon = game.scene.getPlayerPokemon()!; const pokemon = game.scene.getPlayerPokemon()!;

View File

@ -11,8 +11,6 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
describe("Moves - Tar Shot", () => { describe("Moves - Tar Shot", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -54,7 +52,7 @@ describe("Moves - Tar Shot", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4);
}, TIMEOUT); });
it("will not double the effectiveness of Fire-type moves used on a target that is already under the effect of Tar Shot (but may still lower its Speed)", async () => { it("will not double the effectiveness of Fire-type moves used on a target that is already under the effect of Tar Shot (but may still lower its Speed)", async () => {
await game.classicMode.startBattle([Species.PIKACHU]); await game.classicMode.startBattle([Species.PIKACHU]);
@ -82,7 +80,7 @@ describe("Moves - Tar Shot", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4);
}, TIMEOUT); });
it("does not double the effectiveness of Fire-type moves against a Pokémon that is Terastallized", async () => { it("does not double the effectiveness of Fire-type moves against a Pokémon that is Terastallized", async () => {
game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]).enemySpecies(Species.SPRIGATITO); game.override.enemyHeldItems([{ name: "TERA_SHARD", type: Type.GRASS }]).enemySpecies(Species.SPRIGATITO);
@ -104,7 +102,7 @@ describe("Moves - Tar Shot", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(2);
}, TIMEOUT); });
it("doubles the effectiveness of Fire-type moves against a Pokémon that is already under the effects of Tar Shot before it Terastallized", async () => { it("doubles the effectiveness of Fire-type moves against a Pokémon that is already under the effects of Tar Shot before it Terastallized", async () => {
game.override.enemySpecies(Species.SPRIGATITO); game.override.enemySpecies(Species.SPRIGATITO);
@ -128,5 +126,5 @@ describe("Moves - Tar Shot", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4); expect(enemy.getMoveEffectiveness).toHaveReturnedWith(4);
}, TIMEOUT); });
}); });

View File

@ -8,7 +8,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Thousand Arrows", () => { describe("Moves - Thousand Arrows", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -51,7 +51,7 @@ describe("Moves - Thousand Arrows", () => {
expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined();
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(
@ -74,7 +74,7 @@ describe("Moves - Thousand Arrows", () => {
expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined(); expect(enemyPokemon.getTag(BattlerTagType.IGNORE_FLYING)).toBeDefined();
expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp()); expect(enemyPokemon.hp).toBeLessThan(enemyPokemon.getMaxHp());
}, TIMEOUT }
); );
it( it(

View File

@ -10,8 +10,6 @@ import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest";
describe("Moves - Throat Chop", () => { describe("Moves - Throat Chop", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
let game: GameManager; let game: GameManager;
const TIMEOUT = 20 * 1000;
beforeAll(() => { beforeAll(() => {
phaserGame = new Phaser.Game({ phaserGame = new Phaser.Game({
type: Phaser.HEADLESS, type: Phaser.HEADLESS,
@ -53,5 +51,5 @@ describe("Moves - Throat Chop", () => {
await game.phaseInterceptor.to("MoveEndPhase"); await game.phaseInterceptor.to("MoveEndPhase");
expect(enemy.isFullHp()).toBe(false); expect(enemy.isFullHp()).toBe(false);
}, TIMEOUT); });
}); });

View File

@ -7,7 +7,7 @@ import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
const TIMEOUT = 20 * 1000;
describe("Moves - Thunder Wave", () => { describe("Moves - Thunder Wave", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -45,7 +45,7 @@ describe("Moves - Thunder Wave", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS); expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
}, TIMEOUT); });
it("does not paralyze if the Pokemon is a Ground-type", async () => { it("does not paralyze if the Pokemon is a Ground-type", async () => {
game.override.enemySpecies(Species.DIGLETT); game.override.enemySpecies(Species.DIGLETT);
@ -58,7 +58,7 @@ describe("Moves - Thunder Wave", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status).toBeUndefined(); expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT); });
it("does not paralyze if the Pokemon already has a status effect", async () => { it("does not paralyze if the Pokemon already has a status effect", async () => {
game.override.enemySpecies(Species.MAGIKARP).enemyStatusEffect(StatusEffect.BURN); game.override.enemySpecies(Species.MAGIKARP).enemyStatusEffect(StatusEffect.BURN);
@ -71,7 +71,7 @@ describe("Moves - Thunder Wave", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS); expect(enemyPokemon.status?.effect).not.toBe(StatusEffect.PARALYSIS);
}, TIMEOUT); });
it("affects Ground types if the user has Normalize", async () => { it("affects Ground types if the user has Normalize", async () => {
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.DIGLETT); game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.DIGLETT);
@ -84,7 +84,7 @@ describe("Moves - Thunder Wave", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS); expect(enemyPokemon.status?.effect).toBe(StatusEffect.PARALYSIS);
}, TIMEOUT); });
it("does not affect Ghost types if the user has Normalize", async () => { it("does not affect Ghost types if the user has Normalize", async () => {
game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.HAUNTER); game.override.ability(Abilities.NORMALIZE).enemySpecies(Species.HAUNTER);
@ -97,5 +97,5 @@ describe("Moves - Thunder Wave", () => {
await game.phaseInterceptor.to("BerryPhase", false); await game.phaseInterceptor.to("BerryPhase", false);
expect(enemyPokemon.status).toBeUndefined(); expect(enemyPokemon.status).toBeUndefined();
}, TIMEOUT); });
}); });

View File

@ -8,7 +8,7 @@ import { Stat } from "#enums/stat";
import { BerryPhase } from "#app/phases/berry-phase"; import { BerryPhase } from "#app/phases/berry-phase";
import { CommandPhase } from "#app/phases/command-phase"; import { CommandPhase } from "#app/phases/command-phase";
const TIMEOUT = 20 * 1000;
describe("Moves - Wide Guard", () => { describe("Moves - Wide Guard", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;
@ -55,7 +55,7 @@ describe("Moves - Wide Guard", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp())); leadPokemon.forEach(p => expect(p.hp).toBe(p.getMaxHp()));
}, TIMEOUT }
); );
test( test(
@ -76,7 +76,7 @@ describe("Moves - Wide Guard", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0)); leadPokemon.forEach(p => expect(p.getStatStage(Stat.ATK)).toBe(0));
}, TIMEOUT }
); );
test( test(
@ -97,7 +97,7 @@ describe("Moves - Wide Guard", () => {
await game.phaseInterceptor.to(BerryPhase, false); await game.phaseInterceptor.to(BerryPhase, false);
expect(leadPokemon.some(p => p.hp < p.getMaxHp())).toBeTruthy(); expect(leadPokemon.some(p => p.hp < p.getMaxHp())).toBeTruthy();
}, TIMEOUT }
); );
test( test(
@ -120,6 +120,6 @@ describe("Moves - Wide Guard", () => {
expect(leadPokemon[0].hp).toBe(leadPokemon[0].getMaxHp()); expect(leadPokemon[0].hp).toBe(leadPokemon[0].getMaxHp());
enemyPokemon.forEach(p => expect(p.hp).toBeLessThan(p.getMaxHp())); enemyPokemon.forEach(p => expect(p.hp).toBeLessThan(p.getMaxHp()));
}, TIMEOUT }
); );
}); });

View File

@ -231,7 +231,7 @@ describe("An Offer You Can't Refuse - Mystery Encounter", () => {
}); });
describe("Option 3 - Leave", () => { describe("Option 3 - Leave", () => {
it("should leave encounter without battle", async () => { it.each(Array.from({length: 30}))("should leave encounter without battle", async () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.AN_OFFER_YOU_CANT_REFUSE, defaultParty);

View File

@ -19,7 +19,7 @@ import { CommandPhase } from "#app/phases/command-phase";
import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
const namespace = "mysteryEncounter:berriesAbound"; const namespace = "mysteryEncounter:berriesAbound";
const defaultParty = [Species.PYUKUMUKU]; const defaultParty = [Species.PYUKUMUKU, Species.MAGIKARP, Species.PIKACHU];
const defaultBiome = Biome.CAVE; const defaultBiome = Biome.CAVE;
const defaultWave = 45; const defaultWave = 45;
@ -116,7 +116,9 @@ describe("Berries Abound - Mystery Encounter", () => {
expect(enemyField[0].species.speciesId).toBe(speciesToSpawn); expect(enemyField[0].species.speciesId).toBe(speciesToSpawn);
}); });
// TODO: there is some severe test flakiness occurring for this file, needs to be looked at/addressed in separate issue /**
* Related issue-comment: {@link https://github.com/pagefaultgames/pokerogue/issues/4300#issuecomment-2362849444}
*/
it("should reward the player with X berries based on wave", async () => { it("should reward the player with X berries based on wave", async () => {
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
@ -188,15 +190,14 @@ describe("Berries Abound - Mystery Encounter", () => {
}); });
it("Should skip battle when fastest pokemon is faster than boss", async () => { it("Should skip battle when fastest pokemon is faster than boss", async () => {
const leaveEncounterWithoutBattleSpy = vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle"); vi.spyOn(EncounterPhaseUtils, "leaveEncounterWithoutBattle");
const encounterTextSpy = vi.spyOn(EncounterDialogueUtils, "showEncounterText"); vi.spyOn(EncounterDialogueUtils, "showEncounterText");
await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.BERRIES_ABOUND, defaultParty);
// Setting party pokemon's level arbitrarily high to outspeed scene.getParty().forEach(pkm => {
const fastestPokemon = scene.getParty()[0]; vi.spyOn(pkm, "getStat").mockReturnValue(9999); // for ease return for every stat
fastestPokemon.level = 1000; });
fastestPokemon.calculateStats();
await runMysteryEncounterToEnd(game, 2); await runMysteryEncounterToEnd(game, 2);
await game.phaseInterceptor.to(SelectModifierPhase, false); await game.phaseInterceptor.to(SelectModifierPhase, false);
@ -210,8 +211,8 @@ describe("Berries Abound - Mystery Encounter", () => {
expect(option.modifierTypeOption.type.id).toContain("BERRY"); expect(option.modifierTypeOption.type.id).toContain("BERRY");
} }
expect(encounterTextSpy).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.selected`); expect(EncounterDialogueUtils.showEncounterText).toHaveBeenCalledWith(expect.any(BattleScene), `${namespace}.option.2.selected`);
expect(leaveEncounterWithoutBattleSpy).toBeCalled(); expect(EncounterPhaseUtils.leaveEncounterWithoutBattle).toBeCalled();
}); });
}); });

View File

@ -15,6 +15,7 @@ import { TeleportingHijinksEncounter } from "#app/data/mystery-encounters/encoun
import { SelectModifierPhase } from "#app/phases/select-modifier-phase"; import { SelectModifierPhase } from "#app/phases/select-modifier-phase";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler";
import { Abilities } from "#app/enums/abilities";
const namespace = "mysteryEncounter:teleportingHijinks"; const namespace = "mysteryEncounter:teleportingHijinks";
const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA]; const defaultParty = [Species.LAPRAS, Species.GENGAR, Species.ABRA];
@ -36,10 +37,12 @@ describe("Teleporting Hijinks - Mystery Encounter", () => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
scene = game.scene; scene = game.scene;
scene.money = 20000; scene.money = 20000;
game.override.mysteryEncounterChance(100); game.override
game.override.startingWave(defaultWave); .mysteryEncounterChance(100)
game.override.startingBiome(defaultBiome); .startingWave(defaultWave)
game.override.disableTrainerWaves(); .startingBiome(defaultBiome)
.disableTrainerWaves()
.enemyPassiveAbility(Abilities.BALL_FETCH);
vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue( vi.spyOn(MysteryEncounters, "mysteryEncountersByBiome", "get").mockReturnValue(
new Map<Biome, MysteryEncounterType[]>([ new Map<Biome, MysteryEncounterType[]>([

View File

@ -53,19 +53,22 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
}); });
it("should have the correct properties", async () => { it("should have the correct properties", async () => {
const { encounterType, encounterTier, dialogue, options } = ThePokemonSalesmanEncounter;
await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty); await game.runToMysteryEncounter(MysteryEncounterType.THE_POKEMON_SALESMAN, defaultParty);
expect(ThePokemonSalesmanEncounter.encounterType).toBe(MysteryEncounterType.THE_POKEMON_SALESMAN); expect(encounterType).toBe(MysteryEncounterType.THE_POKEMON_SALESMAN);
expect(ThePokemonSalesmanEncounter.encounterTier).toBe(MysteryEncounterTier.ULTRA); expect(encounterTier).toBe(MysteryEncounterTier.ULTRA);
expect(ThePokemonSalesmanEncounter.dialogue).toBeDefined(); expect(dialogue).toBeDefined();
expect(ThePokemonSalesmanEncounter.dialogue.intro).toStrictEqual([ expect(dialogue.intro).toStrictEqual([
{ text: `${namespace}.intro` }, { text: `${namespace}.intro` },
{ speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` } { speaker: `${namespace}.speaker`, text: `${namespace}.intro_dialogue` }
]); ]);
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.title).toBe(`${namespace}.title`); const { title, description, query } = dialogue.encounterOptionsDialogue!;
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.description).toBe(`${namespace}.description`); expect(title).toBe(`${namespace}.title`);
expect(ThePokemonSalesmanEncounter.dialogue.encounterOptionsDialogue?.query).toBe(`${namespace}.query`); expect(description).toMatch(new RegExp(`^${namespace}\\.description(_shiny)?$`));
expect(ThePokemonSalesmanEncounter.options.length).toBe(2); expect(query).toBe(`${namespace}.query`);
expect(options.length).toBe(2);
}); });
it("should not spawn outside of HUMAN_TRANSITABLE_BIOMES", async () => { it("should not spawn outside of HUMAN_TRANSITABLE_BIOMES", async () => {
@ -104,12 +107,13 @@ describe("The Pokemon Salesman - Mystery Encounter", () => {
describe("Option 1 - Purchase the pokemon", () => { describe("Option 1 - Purchase the pokemon", () => {
it("should have the correct properties", () => { it("should have the correct properties", () => {
const option = ThePokemonSalesmanEncounter.options[0]; const { optionMode, dialogue } = ThePokemonSalesmanEncounter.options[0];
expect(option.optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT);
expect(option.dialogue).toBeDefined(); expect(optionMode).toBe(MysteryEncounterOptionMode.DISABLED_OR_DEFAULT);
expect(option.dialogue).toStrictEqual({ expect(dialogue).toBeDefined();
expect(dialogue).toStrictEqual({
buttonLabel: `${namespace}.option.1.label`, buttonLabel: `${namespace}.option.1.label`,
buttonTooltip: `${namespace}.option.1.tooltip`, buttonTooltip: expect.stringMatching(new RegExp(`^${namespace}\\.option\\.1\\.tooltip(_shiny)?$`)),
selected: [ selected: [
{ {
text: `${namespace}.option.1.selected_message`, text: `${namespace}.option.1.selected_message`,

Some files were not shown because too many files have changed in this diff Show More