Compare commits

..

No commits in common. "b10b6e111f2b28f911953a97f2f58e2a0540f397" and "965e626495f9dc188aac7b8dd3383bc6f3df4871" have entirely different histories.

20 changed files with 230 additions and 386 deletions

View File

@ -1,30 +0,0 @@
name: Test Template
on:
workflow_call:
inputs:
project:
required: true
type: string
shard:
required: true
type: number
totalShards:
required: true
type: number
jobs:
test:
name: Shard ${{ inputs.shard }} of ${{ inputs.totalShards }}
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: Run tests
run: npx vitest --project ${{ inputs.project }} --shard=${{ inputs.shard }}/${{ inputs.totalShards }} ${{ !runner.debug && '--silent' || '' }}

View File

@ -15,33 +15,91 @@ on:
types: [checks_requested] types: [checks_requested]
jobs: jobs:
pre-test: run-misc-tests: # Define a job named "run-tests"
name: Run Pre-test name: Run misc tests # Human-readable name for the job
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
steps:
- name: Check out Git repository # Step to check out the repository
uses: actions/checkout@v4 # Use the checkout action version 4
- name: Set up Node.js # Step to set up Node.js environment
uses: actions/setup-node@v4 # Use the setup-node action version 4
with:
node-version: 20 # Specify Node.js version 20
- name: Install Node.js dependencies # Step to install Node.js dependencies
run: npm ci # Use 'npm ci' to install dependencies
- name: pre-test # pre-test to check overrides
run: npx vitest run --project pre
- name: test misc
run: npx vitest --project misc
run-abilities-tests:
name: Run abilities tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
path: tests-action
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20 node-version: 20
- name: Install Node.js dependencies - name: Install Node.js dependencies
working-directory: tests-action
run: npm ci run: npm ci
- name: Run Pre-test - name: pre-test
working-directory: tests-action run: npx vitest run --project pre
run: npx vitest run --project pre ${{ !runner.debug && '--silent' || '' }} - name: test abilities
run: npx vitest --project abilities
run-tests: run-items-tests:
name: Run Tests name: Run items tests
needs: [pre-test] runs-on: ubuntu-latest
strategy: steps:
matrix: - name: Check out Git repository
shard: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] uses: actions/checkout@v4
uses: ./.github/workflows/test-shard-template.yml - name: Set up Node.js
uses: actions/setup-node@v4
with: with:
project: main node-version: 20
shard: ${{ matrix.shard }} - name: Install Node.js dependencies
totalShards: 10 run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test items
run: npx vitest --project items
run-moves-tests:
name: Run moves tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test moves
run: npx vitest --project moves
run-battle-tests:
name: Run battle tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test battle
run: npx vitest --project battle

View File

@ -1,7 +1,7 @@
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 imports from 'eslint-plugin-import'; // Disabled due to not being compatible with eslint v9
export default [ export default [
{ {
@ -11,7 +11,7 @@ export default [
parser: parser parser: parser
}, },
plugins: { plugins: {
"import-x": importX, // imports: imports.configs.recommended // Disabled due to not being compatible with eslint v9
'@stylistic/ts': stylisticTs, '@stylistic/ts': stylisticTs,
'@typescript-eslint': tseslint '@typescript-eslint': tseslint
}, },
@ -39,8 +39,7 @@ export default [
}], }],
"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 comma
"import-x/extensions": ["error", "never", { "json": "always" }], // Enforces no extension for imports unless json
} }
} }
] ]

200
package-lock.json generated
View File

@ -28,7 +28,6 @@
"@vitest/coverage-istanbul": "^2.0.4", "@vitest/coverage-istanbul": "^2.0.4",
"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",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"lefthook": "^1.6.12", "lefthook": "^1.6.12",
"phaser3spectorjs": "^0.0.8", "phaser3spectorjs": "^0.0.8",
@ -2506,19 +2505,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"esutils": "^2.0.2"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/eastasianwidth": { "node_modules/eastasianwidth": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@ -2701,155 +2687,6 @@
"url": "https://opencollective.com/eslint" "url": "https://opencollective.com/eslint"
} }
}, },
"node_modules/eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
"integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"license": "MIT",
"dependencies": {
"debug": "^3.2.7",
"is-core-module": "^2.13.0",
"resolve": "^1.22.4"
}
},
"node_modules/eslint-import-resolver-node/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import-x": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.2.1.tgz",
"integrity": "sha512-WWi2GedccIJa0zXxx3WDnTgouGQTtdYK1nhXMwywbqqAgB0Ov+p1pYBsWh3VaB0bvBOwLse6OfVII7jZD9xo5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/utils": "^8.1.0",
"debug": "^4.3.4",
"doctrine": "^3.0.0",
"eslint-import-resolver-node": "^0.3.9",
"get-tsconfig": "^4.7.3",
"is-glob": "^4.0.3",
"minimatch": "^9.0.3",
"semver": "^7.6.3",
"stable-hash": "^0.0.4",
"tslib": "^2.6.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/scope-manager": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz",
"integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/types": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz",
"integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/typescript-estree": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz",
"integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/visitor-keys": "8.5.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/utils": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz",
"integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.5.0",
"@typescript-eslint/types": "8.5.0",
"@typescript-eslint/typescript-estree": "8.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-import-x/node_modules/@typescript-eslint/visitor-keys": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz",
"integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.5.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz",
@ -3306,19 +3143,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/get-tsconfig": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.0.tgz",
"integrity": "sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==",
"dev": true,
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/glob-parent": { "node_modules/glob-parent": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@ -5030,16 +4854,6 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"license": "MIT",
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@ -5255,13 +5069,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/stable-hash": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz",
"integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==",
"dev": true,
"license": "MIT"
},
"node_modules/stackback": { "node_modules/stackback": {
"version": "0.0.2", "version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@ -5653,13 +5460,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View File

@ -32,7 +32,6 @@
"@vitest/coverage-istanbul": "^2.0.4", "@vitest/coverage-istanbul": "^2.0.4",
"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",
"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

@ -1,46 +1,46 @@
{ {
"SITRUS": { "SITRUS": {
"name": "Baie Sitrus", "name": "Baie Sitrus",
"effect": "Restaure 25% des PV du porteur sils sont inférieurs à 50%." "effect": "Restaure 25% des PV sils sont inférieurs à 50%."
}, },
"LUM": { "LUM": {
"name": "Baie Prine", "name": "Baie Prine",
"effect": "Soigne tout problème de statut et la confusion du porteur." "effect": "Soigne tout problème de statut permanant et la confusion."
}, },
"ENIGMA": { "ENIGMA": {
"name": "Baie Enigma", "name": "Baie Enigma",
"effect": "Restaure 25% des PV du porteur sil est touché par une capacité super efficace." "effect": "Restaure 25% des PV si touché par une capacité super efficace."
}, },
"LIECHI": { "LIECHI": {
"name": "Baie Lichii", "name": "Baie Lichii",
"effect": "Augmente lAttaque du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente lAttaque si les PV sont inférieurs à 25%."
}, },
"GANLON": { "GANLON": {
"name": "Baie Lingan", "name": "Baie Lingan",
"effect": "Augmente la Défense du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente la Défense si les PV sont inférieurs à 25%."
}, },
"PETAYA": { "PETAYA": {
"name": "Baie Pitaye", "name": "Baie Pitaye",
"effect": "Augmente lAtq. Spé. du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente lAtq. Spé. si les PV sont inférieurs à 25%."
}, },
"APICOT": { "APICOT": {
"name": "Baie Abriko", "name": "Baie Abriko",
"effect": "Augmente la Déf. Spé. du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente la Déf. Spé. si les PV sont inférieurs à 25%."
}, },
"SALAC": { "SALAC": {
"name": "Baie Sailak", "name": "Baie Sailak",
"effect": "Augmente la Vitesse du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente la Vitesse si les PV sont inférieurs à 25%."
}, },
"LANSAT": { "LANSAT": {
"name": "Baie Lansat", "name": "Baie Lansat",
"effect": "Augmente le taux de coups critiques du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente le taux de coups critiques si les PV sont inférieurs à 25%."
}, },
"STARF": { "STARF": {
"name": "Baie Frista", "name": "Baie Frista",
"effect": "Augmente énormément une statistique au hasard du porteur si ses PV sont inférieurs à 25%." "effect": "Augmente énormément une statistique au hasard si les PV sont inférieurs à 25%."
}, },
"LEPPA": { "LEPPA": {
"name": "Baie Mepo", "name": "Baie Mepo",
"effect": "Restaure 10 PP à une capacité du porteur dès que ses PP tombent à 0." "effect": "Restaure 10 PP à une capacité dès que ses PP tombent à 0."
} }
} }

View File

@ -202,7 +202,7 @@
"GOLDEN_PUNCH": { "name": "Poing Doré", "description": "La moitié des dégâts infligés sont convertis en argent." }, "GOLDEN_PUNCH": { "name": "Poing Doré", "description": "La moitié des dégâts infligés sont convertis en argent." },
"COIN_CASE": { "name": "Boite Jetons", "description": "Tous les 10 combats, recevez 10% de votre argent en intérêts." }, "COIN_CASE": { "name": "Boite Jetons", "description": "Tous les 10 combats, recevez 10% de votre argent en intérêts." },
"LOCK_CAPSULE": { "name": "Poké Écrin", "description": "Permet de choisir de bloquer le niveau de rareté lors dune relance des objets gratuits proposés." }, "LOCK_CAPSULE": { "name": "Poké Écrin", "description": "Permet de conserver la rareté des objets si vous relancez les objets proposés." },
"GRIP_CLAW": { "name": "Accro Griffe" }, "GRIP_CLAW": { "name": "Accro Griffe" },
"WIDE_LENS": { "name": "Loupe" }, "WIDE_LENS": { "name": "Loupe" },

View File

@ -17,7 +17,7 @@
"HPStat": "PV" "HPStat": "PV"
}, },
"Type": { "Type": {
"UNKNOWN": "???", "UNKNOWN": "Inconnu",
"NORMAL": "Normal", "NORMAL": "Normal",
"FIGHTING": "Combat", "FIGHTING": "Combat",
"FLYING": "Vol", "FLYING": "Vol",

View File

@ -4,5 +4,5 @@
"accuracy": "命中", "accuracy": "命中",
"abilityFlyInText": " {{pokemonName}} 的\n{{passive}}{{abilityName}}", "abilityFlyInText": " {{pokemonName}} 的\n{{passive}}{{abilityName}}",
"passive": "被动 ", "passive": "被动 ",
"teraHover": "{{type}} 太晶化" "teraHover": "{{type}} Terastallized"
} }

View File

@ -4,5 +4,5 @@
"accuracy": "命中率", "accuracy": "命中率",
"abilityFlyInText": " {{pokemonName}} 的\n{{passive}}{{abilityName}}", "abilityFlyInText": " {{pokemonName}} 的\n{{passive}}{{abilityName}}",
"passive": "被動能力 ", "passive": "被動能力 ",
"teraHover": "{{type}} 太晶化" "teraHover": "{{type}} Terastallized"
} }

View File

@ -1,5 +1,5 @@
import BattleScene from "#app/battle-scene"; import BattleScene from "#app/battle-scene";
import { applyPreWeatherEffectAbAttrs, SuppressWeatherEffectAbAttr, PreWeatherDamageAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPostWeatherLapseAbAttrs, PostWeatherLapseAbAttr } from "#app/data/ability"; import { applyPreWeatherEffectAbAttrs, SuppressWeatherEffectAbAttr, PreWeatherDamageAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPostWeatherLapseAbAttrs, PostWeatherLapseAbAttr } from "#app/data/ability.js";
import { CommonAnim } from "#app/data/battle-anims"; import { CommonAnim } from "#app/data/battle-anims";
import { Weather, getWeatherDamageMessage, getWeatherLapseMessage } from "#app/data/weather"; import { Weather, getWeatherDamageMessage, getWeatherLapseMessage } from "#app/data/weather";
import { BattlerTagType } from "#app/enums/battler-tag-type"; import { BattlerTagType } from "#app/enums/battler-tag-type";

View File

@ -1,4 +1,4 @@
import { allSpecies } from "#app/data/pokemon-species"; import { allSpecies } from "#app/data/pokemon-species.js";
import { AbilityAttr, defaultStarterSpecies, DexAttr, SessionSaveData, SystemSaveData } from "./game-data"; import { AbilityAttr, defaultStarterSpecies, DexAttr, SessionSaveData, SystemSaveData } from "./game-data";
import { SettingKeys } from "./settings/settings"; import { SettingKeys } from "./settings/settings";

View File

@ -1,13 +1,13 @@
import { Moves } from "#app/enums/moves"; import { Moves } from "#app/enums/moves.js";
import { Species } from "#app/enums/species"; import { Species } from "#app/enums/species.js";
import { DoubleBattleChanceBoosterModifier } from "#app/modifier/modifier"; import { DoubleBattleChanceBoosterModifier } from "#app/modifier/modifier";
import GameManager from "#test/utils/gameManager"; import GameManager from "#test/utils/gameManager";
import Phaser from "phaser"; import Phaser from "phaser";
import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest"; import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; import { ShopCursorTarget } from "#app/enums/shop-cursor-target.js";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui.js";
import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler"; import ModifierSelectUiHandler from "#app/ui/modifier-select-ui-handler.js";
import { Button } from "#app/enums/buttons"; import { Button } from "#app/enums/buttons.js";
describe("Items - Double Battle Chance Boosters", () => { describe("Items - Double Battle Chance Boosters", () => {
let phaserGame: Phaser.Game; let phaserGame: Phaser.Game;

View File

@ -1,3 +1,4 @@
import "#test/fontFace.setup";
import "vitest-canvas-mock"; import "vitest-canvas-mock";
import { initLoggedInUser } from "#app/account"; import { initLoggedInUser } from "#app/account";

View File

@ -21,7 +21,6 @@ import { getVariantTint } from "#app/data/variant";
import * as Modifier from "../modifier/modifier"; import * as Modifier from "../modifier/modifier";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { SettingKeyboard } from "#app/system/settings/settings-keyboard";
/** /**
* RunInfoUiMode indicates possible overlays of RunInfoUiHandler. * RunInfoUiMode indicates possible overlays of RunInfoUiHandler.
@ -152,13 +151,7 @@ export default class RunInfoUiHandler extends UiHandler {
const headerBgCoords = headerBg.getTopRight(); const headerBgCoords = headerBg.getTopRight();
const abilityButtonContainer = this.scene.add.container(0, 0); const abilityButtonContainer = this.scene.add.container(0, 0);
const abilityButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHeldItems"), TextStyle.WINDOW, {fontSize:"34px"}); const abilityButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHeldItems"), TextStyle.WINDOW, {fontSize:"34px"});
const gamepadType = this.getUi().getGamepadType(); const abilityButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 2, "keyboard", "E.png");
let abilityButtonElement: Phaser.GameObjects.Sprite;
if (gamepadType === "touch") {
abilityButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 2, "keyboard", "E.png");
} else {
abilityButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 2, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Ability));
}
abilityButtonContainer.add([abilityButtonText, abilityButtonElement]); abilityButtonContainer.add([abilityButtonText, abilityButtonElement]);
abilityButtonContainer.setPosition(headerBgCoords.x - abilityButtonText.displayWidth - abilityButtonElement.displayWidth - 8, 10); abilityButtonContainer.setPosition(headerBgCoords.x - abilityButtonText.displayWidth - abilityButtonElement.displayWidth - 8, 10);
this.runContainer.add(abilityButtonContainer); this.runContainer.add(abilityButtonContainer);
@ -187,19 +180,11 @@ export default class RunInfoUiHandler extends UiHandler {
if (this.isVictory) { if (this.isVictory) {
const hallofFameInstructionContainer = this.scene.add.container(0, 0); const hallofFameInstructionContainer = this.scene.add.container(0, 0);
const shinyButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHallOfFame"), TextStyle.WINDOW, {fontSize:"65px"}); const shinyButtonText = addTextObject(this.scene, 8, 0, i18next.t("runHistory:viewHallOfFame"), TextStyle.WINDOW, {fontSize:"65px"});
const formButtonText = addTextObject(this.scene, 8, 12, i18next.t("runHistory:viewEndingSplash"), TextStyle.WINDOW, {fontSize:"65px"}); const shinyButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 4, "keyboard", "R.png");
const gamepadType = this.getUi().getGamepadType();
let shinyButtonElement: Phaser.GameObjects.Sprite;
let formButtonElement: Phaser.GameObjects.Sprite;
if (gamepadType === "touch") {
shinyButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 4, "keyboard", "R.png");
formButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 16, "keyboard", "F.png");
} else {
shinyButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 4, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Shiny));
formButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 16, gamepadType, this.scene.inputController?.getIconForLatestInputRecorded(SettingKeyboard.Button_Cycle_Form));
}
hallofFameInstructionContainer.add([shinyButtonText, shinyButtonElement]); hallofFameInstructionContainer.add([shinyButtonText, shinyButtonElement]);
const formButtonText = addTextObject(this.scene, 8, 12, i18next.t("runHistory:viewEndingSplash"), TextStyle.WINDOW, {fontSize:"65px"});
const formButtonElement = new Phaser.GameObjects.Sprite(this.scene, 0, 16, "keyboard", "F.png");
hallofFameInstructionContainer.add([formButtonText, formButtonElement]); hallofFameInstructionContainer.add([formButtonText, formButtonElement]);
hallofFameInstructionContainer.setPosition(12, 25); hallofFameInstructionContainer.setPosition(12, 25);

View File

@ -1220,19 +1220,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
} }
} }
/**
* Update the display of candy upgrade icons or animations for the given StarterContainer
* @param starterContainer the container for the Pokemon to update
*/
updateCandyUpgradeDisplay(starterContainer: StarterContainer) {
if (this.isUpgradeIconEnabled() ) {
this.setUpgradeIcon(starterContainer);
}
if (this.isUpgradeAnimationEnabled()) {
this.setUpgradeAnimation(starterContainer.icon, this.lastSpecies, true);
}
}
/** /**
* Processes an {@linkcode CandyUpgradeNotificationChangedEvent} sent when the corresponding setting changes * Processes an {@linkcode CandyUpgradeNotificationChangedEvent} sent when the corresponding setting changes
* @param event {@linkcode Event} sent by the callback * @param event {@linkcode Event} sent by the callback
@ -1637,7 +1624,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
} }
}); });
} }
const candyCount = starterData.candyCount;
const passiveAttr = starterData.passiveAttr; const passiveAttr = starterData.passiveAttr;
if (passiveAttr & PassiveAttr.UNLOCKED) { // this is for enabling and disabling the passive if (passiveAttr & PassiveAttr.UNLOCKED) { // this is for enabling and disabling the passive
if (!(passiveAttr & PassiveAttr.ENABLED)) { if (!(passiveAttr & PassiveAttr.ENABLED)) {
@ -1718,13 +1705,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
return true; return true;
} }
}); });
const showUseCandies = () => { // this lets you use your candies
// Purchases with Candy
const candyCount = starterData.candyCount;
const showUseCandies = () => {
const options: any[] = []; // TODO: add proper type const options: any[] = []; // TODO: add proper type
// Unlock passive option
if (!(passiveAttr & PassiveAttr.UNLOCKED)) { if (!(passiveAttr & PassiveAttr.UNLOCKED)) {
const passiveCost = getPassiveCandyCount(speciesStarters[this.lastSpecies.speciesId]); const passiveCost = getPassiveCandyCount(speciesStarters[this.lastSpecies.speciesId]);
options.push({ options.push({
@ -1745,9 +1727,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
this.setSpeciesDetails(this.lastSpecies); this.setSpeciesDetails(this.lastSpecies);
this.scene.playSound("se/buy"); this.scene.playSound("se/buy");
// update the passive background and icon/animation for available upgrade // if starterContainer exists, update the passive background
if (starterContainer) { if (starterContainer) {
this.updateCandyUpgradeDisplay(starterContainer); // Update the candy upgrade display
if (this.isUpgradeIconEnabled() ) {
this.setUpgradeIcon(starterContainer);
}
if (this.isUpgradeAnimationEnabled()) {
this.setUpgradeAnimation(starterContainer.icon, this.lastSpecies, true);
}
starterContainer.starterPassiveBgs.setVisible(!!this.scene.gameData.starterData[this.lastSpecies.speciesId].passiveAttr); starterContainer.starterPassiveBgs.setVisible(!!this.scene.gameData.starterData[this.lastSpecies.speciesId].passiveAttr);
} }
return true; return true;
@ -1758,8 +1747,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
itemArgs: starterColors[this.lastSpecies.speciesId] itemArgs: starterColors[this.lastSpecies.speciesId]
}); });
} }
// Reduce cost option
const valueReduction = starterData.valueReduction; const valueReduction = starterData.valueReduction;
if (valueReduction < valueReductionMax) { if (valueReduction < valueReductionMax) {
const reductionCost = getValueReductionCandyCounts(speciesStarters[this.lastSpecies.speciesId])[valueReduction]; const reductionCost = getValueReductionCandyCounts(speciesStarters[this.lastSpecies.speciesId])[valueReduction];
@ -1781,10 +1768,19 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
ui.setMode(Mode.STARTER_SELECT); ui.setMode(Mode.STARTER_SELECT);
this.scene.playSound("se/buy"); this.scene.playSound("se/buy");
// update the value label and icon/animation for available upgrade // if starterContainer exists, update the value reduction background
if (starterContainer) { if (starterContainer) {
this.updateStarterValueLabel(starterContainer); this.updateStarterValueLabel(starterContainer);
this.updateCandyUpgradeDisplay(starterContainer);
// If the notification setting is set to 'On', update the candy upgrade display
if (this.scene.candyUpgradeNotification === 2) {
if (this.isUpgradeIconEnabled() ) {
this.setUpgradeIcon(starterContainer);
}
if (this.isUpgradeAnimationEnabled()) {
this.setUpgradeAnimation(starterContainer.icon, this.lastSpecies, true);
}
}
} }
return true; return true;
} }
@ -1817,11 +1813,6 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
ui.setMode(Mode.STARTER_SELECT); ui.setMode(Mode.STARTER_SELECT);
this.scene.playSound("se/buy"); this.scene.playSound("se/buy");
// update the icon/animation for available upgrade
if (starterContainer) {
this.updateCandyUpgradeDisplay(starterContainer);
}
return true; return true;
} }
return false; return false;

View File

@ -52,7 +52,6 @@ import RunInfoUiHandler from "./run-info-ui-handler";
import EggSummaryUiHandler from "./egg-summary-ui-handler"; import EggSummaryUiHandler from "./egg-summary-ui-handler";
import TestDialogueUiHandler from "#app/ui/test-dialogue-ui-handler"; import TestDialogueUiHandler from "#app/ui/test-dialogue-ui-handler";
import AutoCompleteUiHandler from "./autocomplete-ui-handler"; import AutoCompleteUiHandler from "./autocomplete-ui-handler";
import { Device } from "#enums/devices";
export enum Mode { export enum Mode {
MESSAGE, MESSAGE,
@ -579,20 +578,4 @@ export default class UI extends Phaser.GameObjects.Container {
public getModeChain(): Mode[] { public getModeChain(): Mode[] {
return this.modeChain; return this.modeChain;
} }
/**
* getGamepadType - returns the type of gamepad being used
* inputMethod could be "keyboard" or "touch" or "gamepad"
* if inputMethod is "keyboard" or "touch", then the inputMethod is returned
* if inputMethod is "gamepad", then the gamepad type is returned it could be "xbox" or "dualshock"
* @returns gamepad type
*/
public getGamepadType(): string {
const scene = this.scene as BattleScene;
if (scene.inputMethod === "gamepad") {
return scene.inputController.getConfig(scene.inputController.selectedDevice[Device.GAMEPAD]).padType;
} else {
return scene.inputMethod;
}
}
} }

View File

@ -1,25 +1,23 @@
import { defineProject } from "vitest/config"; import { defineProject, UserWorkspaceConfig } from 'vitest/config';
import { defaultConfig } from "./vite.config"; import { defaultConfig } from './vite.config';
export default defineProject(({ mode }) => ({ export const defaultProjectTestConfig: UserWorkspaceConfig["test"] = {
...defaultConfig, setupFiles: ['./src/test/vitest.setup.ts'],
test: {
setupFiles: ["./src/test/fontFace.setup.ts", "./src/test/vitest.setup.ts"],
server: { server: {
deps: { deps: {
inline: ["vitest-canvas-mock"], inline: ['vitest-canvas-mock'],
//@ts-ignore //@ts-ignore
optimizer: { optimizer: {
web: { web: {
include: ["vitest-canvas-mock"], include: ['vitest-canvas-mock'],
}
}
}
}, },
}, environment: 'jsdom' as const,
},
},
environment: "jsdom" as const,
environmentOptions: { environmentOptions: {
jsdom: { jsdom: {
resources: "usable", resources: 'usable',
}, },
}, },
threads: false, threads: false,
@ -27,16 +25,22 @@ export default defineProject(({ mode }) => ({
restoreMocks: true, restoreMocks: true,
watch: false, watch: false,
coverage: { coverage: {
provider: "istanbul" as const, provider: 'istanbul' as const,
reportsDirectory: "coverage" as const, reportsDirectory: 'coverage' as const,
reporters: ["text-summary", "html"], reporters: ['text-summary', 'html'],
}, },
}
export default defineProject(({ mode }) => ({
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "main", name: "main",
include: ["./src/test/**/*.{test,spec}.ts"], include: ["./src/test/**/*.{test,spec}.ts"],
exclude: ["./src/test/pre.test.ts"], exclude: ["./src/test/pre.test.ts"],
}, },
esbuild: { esbuild: {
pure: mode === "production" ? ["console.log"] : [], pure: mode === 'production' ? [ 'console.log' ] : [],
keepNames: true, keepNames: true,
}, },
})); }))

View File

@ -1,5 +1,6 @@
import { defineWorkspace } from "vitest/config"; import { defineWorkspace } from "vitest/config";
import { defaultConfig } from "./vite.config"; import { defaultConfig } from "./vite.config";
import { defaultProjectTestConfig } from "./vitest.config";
export default defineWorkspace([ export default defineWorkspace([
{ {
@ -10,5 +11,58 @@ export default defineWorkspace([
environment: "jsdom", environment: "jsdom",
}, },
}, },
{
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "misc",
include: [
"src/test/achievements/**/*.{test,spec}.ts",
"src/test/arena/**/*.{test,spec}.ts",
"src/test/battlerTags/**/*.{test,spec}.ts",
"src/test/eggs/**/*.{test,spec}.ts",
"src/test/field/**/*.{test,spec}.ts",
"src/test/inputs/**/*.{test,spec}.ts",
"src/test/localization/**/*.{test,spec}.ts",
"src/test/phases/**/*.{test,spec}.ts",
"src/test/settingMenu/**/*.{test,spec}.ts",
"src/test/sprites/**/*.{test,spec}.ts",
"src/test/ui/**/*.{test,spec}.ts",
"src/test/*.{test,spec}.ts",
],
},
},
{
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "abilities",
include: ["src/test/abilities/**/*.{test,spec}.ts"],
},
},
{
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "battle",
include: ["src/test/battle/**/*.{test,spec}.ts"],
},
},
{
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "items",
include: ["src/test/items/**/*.{test,spec}.ts"],
},
},
{
...defaultConfig,
test: {
...defaultProjectTestConfig,
name: "moves",
include: ["src/test/moves/**/*.{test,spec}.ts"],
},
},
"./vitest.config.ts", "./vitest.config.ts",
]); ]);