Merge 'beta' into 'ssui-qol-messages'

This commit is contained in:
Moka 2024-11-18 21:09:52 +01:00
commit ee02232dd2
2933 changed files with 130227 additions and 433024 deletions

View File

@ -1,6 +1,6 @@
VITE_BYPASS_LOGIN=0 VITE_BYPASS_LOGIN=0
VITE_BYPASS_TUTORIAL=0 VITE_BYPASS_TUTORIAL=0
VITE_SERVER_URL=https://api.beta.pokerogue.net VITE_SERVER_URL=https://apibeta.pokerogue.net
VITE_DISCORD_CLIENT_ID=1248062921129459756 VITE_DISCORD_CLIENT_ID=1248062921129459756
VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com VITE_GOOGLE_CLIENT_ID=955345393540-2k6lfftf0fdnb0krqmpthjnqavfvvf73.apps.googleusercontent.com
VITE_I18N_DEBUG=1 VITE_I18N_DEBUG=0

View File

@ -3,5 +3,5 @@ VITE_BYPASS_TUTORIAL=0
VITE_SERVER_URL=http://localhost:8001 VITE_SERVER_URL=http://localhost:8001
VITE_DISCORD_CLIENT_ID=1234567890 VITE_DISCORD_CLIENT_ID=1234567890
VITE_GOOGLE_CLIENT_ID=1234567890 VITE_GOOGLE_CLIENT_ID=1234567890
VITE_I18N_DEBUG=1 VITE_I18N_DEBUG=0
VITE_PORT=8000 VITE_PORT=8000

38
.github/CODEOWNERS vendored
View File

@ -5,41 +5,3 @@
# github actions/templates etc. - Dev Leads # github actions/templates etc. - Dev Leads
/.github @pagefaultgames/dev-leads /.github @pagefaultgames/dev-leads
# --- Translations ---
# all translations - Translation Leads
/src/locales @pagefaultgames/translation-leads
# Catalan (Spain/Spanish)
/src/locales/ca_ES @pagefaultgames/catalan-translation-team
# German
/src/locales/de @pagefaultgames/german-translation-team
# English
/src/locales/en @pagefaultgames/english-translation-team
# Spanish
/src/locales/es @pagefaultgames/spanish-translation-team
# French
/src/locales/fr @pagefaultgames/french-translation-team
# Italian
/src/locales/it @pagefaultgames/italian-translation-team
# Japenese
/src/locales/ja @pagefaultgames/japanese-translation-team
# Korean
/src/locales/ko @pagefaultgames/korean-translation-team
# Brasilian (Brasil/Portuguese)
/src/locales/pt_BR @pagefaultgames/portuguese_br-translation-team
# Chinese (simplified)
/src/locales/zh_CN @pagefaultgames/chinese_simplified-translation-team
# Chinese (traditional)
/src/locales/zh_TW @pagefaultgames/chinese_traditional-translation-team

2
.github/FUNDING.yml vendored
View File

@ -1 +1 @@
github: patapancakes github: pagefaultgames

View File

@ -11,6 +11,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: "20" node-version: "20"

View File

@ -1,8 +1,12 @@
name: Deploy name: Deploy Main
on: on:
push: {} push:
pull_request: {} branches:
- main
pull_request:
branches:
- main
jobs: jobs:
deploy: deploy:
@ -10,6 +14,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with:
submodules: 'recursive'
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: "20" node-version: "20"
@ -20,7 +26,7 @@ jobs:
env: env:
NODE_ENV: production NODE_ENV: production
- name: Set up SSH - name: Set up SSH
if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch if: github.event_name == 'push' && github.ref_name == 'main'
run: | run: |
mkdir ~/.ssh mkdir ~/.ssh
echo "${{ secrets.SSH_PUBLIC_KEY }}" > ~/.ssh/id_ed25519.pub echo "${{ secrets.SSH_PUBLIC_KEY }}" > ~/.ssh/id_ed25519.pub
@ -28,12 +34,12 @@ jobs:
chmod 600 ~/.ssh/* chmod 600 ~/.ssh/*
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy build on server - name: Deploy build on server
if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch if: github.event_name == 'push' && github.ref_name == 'main'
run: | run: |
rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }} rsync --del --no-times --checksum -vrm dist/* ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DESTINATION_DIR }}
ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json" ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json"
- name: Purge Cloudflare Cache - name: Purge Cloudflare Cache
if: github.event_name == 'push' && github.ref_name == github.event.repository.default_branch if: github.event_name == 'push' && github.ref_name == 'main'
id: purge-cache id: purge-cache
uses: NathanVaughn/actions-cloudflare-purge@v3.1.0 uses: NathanVaughn/actions-cloudflare-purge@v3.1.0
with: with:

View File

@ -22,6 +22,8 @@ jobs:
steps: steps:
- name: Check out Git repository # Step to check out the repository - name: Check out Git repository # Step to check out the repository
uses: actions/checkout@v4 # Use the checkout action version 4 uses: actions/checkout@v4 # Use the checkout action version 4
with:
submodules: 'recursive'
- name: Set up Node.js # Step to set up Node.js environment - name: Set up Node.js # Step to set up Node.js environment
uses: actions/setup-node@v4 # Use the setup-node action version 4 uses: actions/setup-node@v4 # Use the setup-node action version 4

View File

@ -26,6 +26,7 @@ jobs:
- name: Checkout repository for Typedoc - name: Checkout repository for Typedoc
uses: actions/checkout@v3 uses: actions/checkout@v3
with: with:
submodules: 'recursive'
path: pokerogue_docs path: pokerogue_docs
- name: Install OS package - name: Install OS package

View File

@ -20,6 +20,8 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
submodules: 'recursive'
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:

View File

@ -22,6 +22,7 @@ jobs:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
submodules: 'recursive'
path: tests-action path: tests-action
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "public/locales"]
path = public/locales
url = https://github.com/pagefaultgames/pokerogue-locales

View File

@ -17,13 +17,21 @@ If you have the motivation and experience with Typescript/Javascript (or are wil
2. Run `npm run start:dev` to locally run the project in `localhost:8000` 2. Run `npm run start:dev` to locally run the project in `localhost:8000`
#### Linting #### Linting
We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. We're using ESLint as our common linter and formatter. It will run automatically during the pre-commit hook but if you would like to manually run it, use the `npm run eslint` script. To view the complete rules, check out the [eslint.config.js](./eslint.config.js) file.
### 📚 Documentation
You can find the auto-generated documentation [here](https://pagefaultgames.github.io/pokerogue/main/index.html).
For information on enemy AI, check out the [enemy-ai.md](./docs/enemy-ai.md) file.
For detailed guidelines on documenting your code, refer to the [comments.md](./docs/comments.md) file.
### ❔ FAQ ### ❔ FAQ
**How do I test a new _______?** **How do I test a new _______?**
- In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing - In the `src/overrides.ts` file there are overrides for most values you'll need to change for testing
**How do I retrieve the translations?**
- The translations were moved to the [dedicated translation repository](https://github.com/pagefaultgames/pokerogue-locales) and are now applied as a submodule in this project.
- The command to retrieve the translations is `git submodule update --init --recursive`. If you still struggle to get it working, please reach out to #dev-corner channel in Discord.
## 🪧 To Do ## 🪧 To Do
Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to see how can you help us! Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to see how can you help us!
@ -56,7 +64,7 @@ Check out [Github Issues](https://github.com/pagefaultgames/pokerogue/issues) to
- Pokémon Legends: Arceus - Pokémon Legends: Arceus
- Pokémon Scarlet/Violet - Pokémon Scarlet/Violet
- Firel (Custom Ice Cave, Laboratory, Metropolis, Plains, Power Plant, Seabed, Space, and Volcano biome music) - Firel (Custom Ice Cave, Laboratory, Metropolis, Plains, Power Plant, Seabed, Space, and Volcano biome music)
- Lmz (Custom Jungle biome music) - Lmz (Custom Ancient Ruins, Jungle, and Lake biome music)
- Andr06 (Custom Slum and Sea biome music) - Andr06 (Custom Slum and Sea biome music)
### 🎵 Sound Effects ### 🎵 Sound Effects

View File

@ -1,82 +1,120 @@
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 in the appropriate
* @param {string} type - The type of test to create. Either "move", "ability", * directory based on the type selected.
* or "item". * @example npm run create-test
* @param {string} fileName - The name of the file to create.
* @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 (${typeChoices.join(", ")})!`);
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 the name of the ${selectedType}:`,
},
]);
// 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 one of the following: ${typeChoices.join(", ")}.`);
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";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, it, expect } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } 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({
@ -91,20 +129,43 @@ describe("${description}", () => {
beforeEach(() => { beforeEach(() => {
game = new GameManager(phaserGame); game = new GameManager(phaserGame);
game.override game.override
.moveset([Moves.SPLASH]) .moveset([ Moves.SPLASH ])
.ability(Abilities.BALL_FETCH)
.battleType("single") .battleType("single")
.disableCrits()
.enemySpecies(Species.MAGIKARP)
.enemyAbility(Abilities.BALL_FETCH) .enemyAbility(Abilities.BALL_FETCH)
.enemyMoveset(Moves.SPLASH); .enemyMoveset(Moves.SPLASH);
}); });
it("test case", async () => { it("should do X", async () => {
// await game.classicMode.startBattle([Species.MAGIKARP]); await game.classicMode.startBattle([ Species.FEEBAS ]);
// game.move.select(Moves.SPLASH);
}, TIMEOUT); game.move.select(Moves.SPLASH);
await game.phaseInterceptor.to("BerryPhase");
expect(true).toBe(true);
});
}); });
`; `;
// 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();

View File

@ -1,5 +1,5 @@
import tseslint from '@typescript-eslint/eslint-plugin'; import tseslint from '@typescript-eslint/eslint-plugin';
import stylisticTs from '@stylistic/eslint-plugin-ts' import stylisticTs from '@stylistic/eslint-plugin-ts';
import parser from '@typescript-eslint/parser'; import parser from '@typescript-eslint/parser';
import importX from 'eslint-plugin-import-x'; import importX from 'eslint-plugin-import-x';
@ -16,15 +16,15 @@ export default [
'@typescript-eslint': tseslint '@typescript-eslint': tseslint
}, },
rules: { rules: {
"eqeqeq": ["error", "always"], // Enforces the use of === and !== instead of == and != "eqeqeq": ["error", "always"], // Enforces the use of `===` and `!==` instead of `==` and `!=`
"indent": ["error", 2], // Enforces a 2-space indentation "indent": ["error", 2, { "SwitchCase": 1 }], // Enforces a 2-space indentation, enforces indentation of `case ...:` statements
"quotes": ["error", "double"], // Enforces the use of double quotes for strings "quotes": ["error", "double"], // Enforces the use of double quotes for strings
"no-var": "error", // Disallows the use of var, enforcing let or const instead "no-var": "error", // Disallows the use of `var`, enforcing `let` or `const` instead
"prefer-const": "error", // Prefers the use of const for variables that are never reassigned "prefer-const": "error", // Enforces the use of `const` for variables that are never reassigned
"no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this) "no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this)
"@typescript-eslint/no-unused-vars": [ "error", { "@typescript-eslint/no-unused-vars": [ "error", {
"args": "none", // Allows unused function parameters. Useful for functions with specific signatures where not all parameters are always used. "args": "none", // Allows unused function parameters. Useful for functions with specific signatures where not all parameters are always used.
"ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the rest. "ignoreRestSiblings": true // Allows unused variables that are part of a rest property in object destructuring. Useful for excluding certain properties from an object while using the others.
}], }],
"eol-last": ["error", "always"], // Enforces at least one newline at the end of files "eol-last": ["error", "always"], // Enforces at least one newline at the end of files
"@stylistic/ts/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax "@stylistic/ts/semi": ["error", "always"], // Requires semicolons for TypeScript-specific syntax
@ -32,15 +32,20 @@ export default [
"no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax "no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax
"brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors "brace-style": "off", // Note: you must disable the base rule as it can report incorrect errors
"curly": ["error", "all"], // Enforces the use of curly braces for all control statements "curly": ["error", "all"], // Enforces the use of curly braces for all control statements
"@stylistic/ts/brace-style": ["error", "1tbs"], "@stylistic/ts/brace-style": ["error", "1tbs"], // Enforces the following brace style: https://eslint.style/rules/js/brace-style#_1tbs
"no-trailing-spaces": ["error", { // Disallows trailing whitespace at the end of lines "no-trailing-spaces": ["error", { // Disallows trailing whitespace at the end of lines
"skipBlankLines": false, // Enforces the rule even on blank lines "skipBlankLines": false, // Enforces the rule even on blank lines
"ignoreComments": false // Enforces the rule on lines containing comments "ignoreComments": false // Enforces the rule on lines containing comments
}], }],
"space-before-blocks": ["error", "always"], // Enforces a space before blocks "space-before-blocks": ["error", "always"], // Enforces a space before blocks
"keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords "keyword-spacing": ["error", { "before": true, "after": true }], // Enforces spacing before and after keywords
"comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after comma "comma-spacing": ["error", { "before": false, "after": true }], // Enforces spacing after commas
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json "import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
"array-bracket-spacing": ["error", "always", { "objectsInArrays": false, "arraysInArrays": false }], // Enforces consistent spacing inside array brackets
"object-curly-spacing": ["error", "always", { "arraysInObjects": false, "objectsInObjects": false }], // Enforces consistent spacing inside braces of object literals, destructuring assignments, and import/export specifiers
"computed-property-spacing": ["error", "never" ], // Enforces consistent spacing inside computed property brackets
"space-infix-ops": ["error", { "int32Hint": false }], // Enforces spacing around infix operators
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], // Disallows multiple empty lines
} }
} }
] ]

14
global.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
import type { SetupServerApi } from "msw/node";
export {};
declare global {
/**
* Only used in testing.
* Can technically be undefined/null but for ease of use we are going to assume it is always defined.
* Used to load i18n files exclusively.
*
* To set up your own server in a test see `game_data.test.ts`
*/
var server: SetupServerApi;
}

View File

@ -13,4 +13,9 @@ pre-push:
commands: commands:
eslint: eslint:
glob: "*.{js,ts,jsx,tsx}" glob: "*.{js,ts,jsx,tsx}"
run: npx eslint --fix {push_files} run: npx eslint --fix {push_files}
post-merge:
commands:
update-submodules:
run: git submodule update --init --recursive

897
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{ {
"name": "pokemon-rogue-battle", "name": "pokemon-rogue-battle",
"private": true, "private": true,
"version": "1.0.4", "version": "1.2.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "vite", "start": "vite",
@ -19,7 +19,8 @@
"docs": "typedoc", "docs": "typedoc",
"depcruise": "depcruise src", "depcruise": "depcruise src",
"depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg", "depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg",
"create-test": "node ./create-test-boilerplate.js" "create-test": "node ./create-test-boilerplate.js",
"postinstall": "npx lefthook install && npx lefthook run post-merge"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.3.0", "@eslint/js": "^9.3.0",
@ -33,13 +34,15 @@
"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",
"msw": "^2.4.9",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
"typedoc": "^0.26.4", "typedoc": "^0.26.4",
"typescript": "^5.5.3", "typescript": "^5.5.3",
"typescript-eslint": "^8.0.0-alpha.54", "typescript-eslint": "^8.0.0-alpha.54",
"vite": "^5.3.5", "vite": "^5.4.8",
"vite-tsconfig-paths": "^4.3.2", "vite-tsconfig-paths": "^4.3.2",
"vitest": "^2.0.4", "vitest": "^2.0.4",
"vitest-canvas-mock": "^0.3.3" "vitest-canvas-mock": "^0.3.3"
@ -49,6 +52,7 @@
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"i18next": "^23.11.1", "i18next": "^23.11.1",
"i18next-browser-languagedetector": "^7.2.1", "i18next-browser-languagedetector": "^7.2.1",
"i18next-http-backend": "^2.6.1",
"i18next-korean-postposition-processor": "^1.0.0", "i18next-korean-postposition-processor": "^1.0.0",
"json-stable-stringify": "^1.1.0", "json-stable-stringify": "^1.1.0",
"phaser": "^3.70.0", "phaser": "^3.70.0",

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4633,11 +4633,7 @@
"690", "690",
"691", "691",
"696", "696",
"696_3",
"696_3",
"697", "697",
"697_3",
"697_3",
"700", "700",
"704", "704",
"705_2", "705_2",

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "berry_bush.png", "image": "berries_abound_bush.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 49, "w": 49,

View File

Before

Width:  |  Height:  |  Size: 719 B

After

Width:  |  Height:  |  Size: 719 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "mad_scientist_m.png", "image": "dark_deal_scientist.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 46, "w": 46,

View File

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 920 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "b2w2_lady.png", "image": "department_store_sale_lady.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 399, "w": 399,

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "teacher.png", "image": "field_trip_teacher.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 43, "w": 43,

View File

Before

Width:  |  Height:  |  Size: 727 B

After

Width:  |  Height:  |  Size: 727 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "carnival_game.png", "image": "fun_and_games_game.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 38, "w": 38,

View File

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "carnival_man.png", "image": "fun_and_games_man.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 50, "w": 50,

View File

Before

Width:  |  Height:  |  Size: 833 B

After

Width:  |  Height:  |  Size: 833 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "carnival_wobbuffet.png", "image": "fun_and_games_wobbuffet.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 45, "w": 45,

View File

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 772 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "chest_blue.png", "image": "mysterious_chest_blue.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 54, "w": 54,

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "chest_red.png", "image": "mysterious_chest_red.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 54, "w": 54,

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "warehouse_crate.png", "image": "part_timer_crate.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 71, "w": 71,

View File

Before

Width:  |  Height:  |  Size: 868 B

After

Width:  |  Height:  |  Size: 868 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "bait.png", "image": "safari_zone_bait.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 14, "w": 14,

View File

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "mud.png", "image": "safari_zone_mud.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 14, "w": 14,

View File

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "b2w2_veteran_m.png", "image": "shady_vitamin_dealer.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 424, "w": 424,

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "teleporter.png", "image": "teleporting_hijinks_teleporter.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 74, "w": 74,

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,7 +1,7 @@
{ {
"textures": [ "textures": [
{ {
"image": "training_gear.png", "image": "training_session_gear.png",
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 76, "w": 76,

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -5,29 +5,29 @@
"format": "RGBA8888", "format": "RGBA8888",
"size": { "size": {
"w": 78, "w": 78,
"h": 87 "h": 86
}, },
"scale": 1, "scale": 1,
"frames": [ "frames": [
{ {
"filename": "0001.png", "filename": "0001.png",
"rotated": false, "rotated": false,
"trimmed": true, "trimmed": false,
"sourceSize": { "sourceSize": {
"w": 80, "w": 78,
"h": 87 "h": 86
}, },
"spriteSourceSize": { "spriteSourceSize": {
"x": 1, "x": 0,
"y": 0, "y": 0,
"w": 78, "w": 78,
"h": 87 "h": 86
}, },
"frame": { "frame": {
"x": 0, "x": 0,
"y": 0, "y": 0,
"w": 78, "w": 78,
"h": 87 "h": 86
} }
} }
] ]
@ -36,6 +36,6 @@
"meta": { "meta": {
"app": "https://www.codeandweb.com/texturepacker", "app": "https://www.codeandweb.com/texturepacker",
"version": "3.0", "version": "3.0",
"smartupdate": "$TexturePacker:SmartUpdate:d3cce87ee0e3a880d840bffe9373d5d4:7c776d33b75abad1fe36b14a5e5734af:56468b7a2883e66dadcd2af13ebd8010$" "smartupdate": "$TexturePacker:SmartUpdate:65266da62e9d2953511c0d68ae431345:c1ca63690bed8dd5af71bb443910c830:56468b7a2883e66dadcd2af13ebd8010$"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 694 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 719 B

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

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