diff --git a/.dependency-cruiser.cjs b/.dependency-cruiser.cjs index 40a9785aeaf..eccec089f1e 100644 --- a/.dependency-cruiser.cjs +++ b/.dependency-cruiser.cjs @@ -218,7 +218,7 @@ module.exports = { module systems it knows of. It's the default because it's the safe option It might come at a performance penalty, though. moduleSystems: ['amd', 'cjs', 'es6', 'tsd'] - + As in practice only commonjs ('cjs') and ecmascript modules ('es6') are widely used, you can limit the moduleSystems to those. */ @@ -226,7 +226,7 @@ module.exports = { // moduleSystems: ['cjs', 'es6'], /* prefix for links in html and svg output (e.g. 'https://github.com/you/yourrepo/blob/main/' - to open it on your online repo or `vscode://file/${process.cwd()}/` to + to open it on your online repo or `vscode://file/${process.cwd()}/` to open it in visual studio code), */ // prefix: `vscode://file/${process.cwd()}/`, @@ -271,7 +271,7 @@ module.exports = { to './webpack.conf.js'. The (optional) `env` and `arguments` attributes contain the parameters - to be passed if your webpack config is a function and takes them (see + to be passed if your webpack config is a function and takes them (see webpack documentation for details) */ // webpackConfig: { @@ -322,8 +322,8 @@ module.exports = { A list of alias fields in package.jsons See [this specification](https://github.com/defunctzombie/package-browser-field-spec) and the webpack [resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealiasfields) - documentation - + documentation + Defaults to an empty array (= don't use alias fields). */ // aliasFields: ["browser"], diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 79ab1bdc38a..979b94f84d6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,7 +8,7 @@ # Art Team /public/**/*.png @pagefaultgames/art-team -/public/**/*.json @pagefaultgames/art-team +/public/**/*.json @pagefaultgames/art-team /public/images @pagefaultgames/art-team /public/battle-anims @pagefaultgames/art-team diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a25a2f807f3..c7d8b1e4d9c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,25 +2,28 @@ + ## What are the changes the user will see? @@ -66,11 +69,11 @@ Do the reviewers need to do something special in order to test your changes? - [ ] Have I provided a clear explanation of the changes? - [ ] Have I tested the changes manually? - [ ] Are all unit tests still passing? (`npm run test:silent`) - - [ ] Have I created new automated tests (`npm run create-test`) or updated existing tests related to the PR's changes? + - [ ] Have I created new automated tests (`npm run test:create`) or updated existing tests related to the PR's changes? - [ ] Have I provided screenshots/videos of the changes (if applicable)? - [ ] Have I made sure that any UI change works for both UI themes (default and legacy)? Are there any localization additions or changes? If so: - [ ] Has a locales PR been created on the [locales](https://github.com/pagefaultgames/pokerogue-locales) repo? - [ ] If so, please leave a link to it here: -- [ ] Has the translation team been contacted for proofreading/translation? \ No newline at end of file +- [ ] Has the translation team been contacted for proofreading/translation? diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 00190e477d5..a233a2fccab 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -35,7 +35,7 @@ jobs: ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts - name: Deploy build on server 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 }} ssh -t ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/prmanifest --inpath ${{ secrets.DESTINATION_DIR }} --outpath ${{ secrets.DESTINATION_DIR }}/manifest.json" - name: Purge Cloudflare Cache diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index d9592662998..36233248472 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -33,7 +33,7 @@ jobs: - name: Install Node.js dependencies # Step to install Node.js dependencies run: npm ci # Use 'npm ci' to install dependencies - + - name: eslint # Step to run linters run: npm run eslint-ci diff --git a/biome.jsonc b/biome.jsonc index dc4f788407a..d183334ad58 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -46,8 +46,8 @@ "correctness": { "noUndeclaredVariables": "off", "noUnusedVariables": "error", - "noSwitchDeclarations": "warn", // TODO: refactor and make this an error - "noVoidTypeReturn": "warn", // TODO: Refactor and make this an error + "noSwitchDeclarations": "error", + "noVoidTypeReturn": "error", "noUnusedImports": "error" }, "style": { @@ -84,7 +84,7 @@ "useLiteralKeys": "off", "noForEach": "off", // Foreach vs for of is not that simple. "noUselessSwitchCase": "off", // Explicit > Implicit - "noUselessConstructor": "warn", // TODO: Refactor and make this an error + "noUselessConstructor": "error", "noBannedTypes": "warn" // TODO: Refactor and make this an error }, "nursery": { diff --git a/global.d.ts b/global.d.ts index c896a4983e4..d2ed6438c0b 100644 --- a/global.d.ts +++ b/global.d.ts @@ -7,7 +7,7 @@ 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; diff --git a/package.json b/package.json index 36c3c2b919f..b927542788d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "eslint": "eslint --fix .", "eslint-ci": "eslint .", "biome": "biome check --write --changed --no-errors-on-unmatched", - "biome-ci": "biome ci --diagnostic-level=error --reporter=github --changed --no-errors-on-unmatched", + "biome-ci": "biome ci --diagnostic-level=error --reporter=github --no-errors-on-unmatched", "docs": "typedoc", "depcruise": "depcruise src", "depcruise:graph": "depcruise src --output-type dot | node dependency-graph.js > dependency-graph.svg", diff --git a/src/@types/modifier-types.ts b/src/@types/modifier-types.ts index 6c0136e655e..80b92c35622 100644 --- a/src/@types/modifier-types.ts +++ b/src/@types/modifier-types.ts @@ -29,4 +29,4 @@ export type ModifierString = keyof ModifierConstructorMap; export type ModifierPool = { [tier: string]: WeightedModifierType[]; -} \ No newline at end of file +}; diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 6cf6702489b..1738ef064e3 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -132,16 +132,6 @@ export interface TerrainBattlerTag { * Players and enemies should not be allowed to select restricted moves. */ export abstract class MoveRestrictionBattlerTag extends BattlerTag { - constructor( - tagType: BattlerTagType, - lapseType: BattlerTagLapseType | BattlerTagLapseType[], - turnCount: number, - sourceMove?: MoveId, - sourceId?: number, - ) { - super(tagType, lapseType, turnCount, sourceMove, sourceId); - } - /** @override */ override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean { if (lapseType === BattlerTagLapseType.PRE_MOVE) { @@ -1463,16 +1453,6 @@ export class WrapTag extends DamagingTrapTag { } export abstract class VortexTrapTag extends DamagingTrapTag { - constructor( - tagType: BattlerTagType, - commonAnim: CommonAnim, - turnCount: number, - sourceMove: MoveId, - sourceId: number, - ) { - super(tagType, commonAnim, turnCount, sourceMove, sourceId); - } - getTrapMessage(pokemon: Pokemon): string { return i18next.t("battlerTags:vortexOnTrap", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 6a60d34b61c..f61e8debc9f 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -2148,6 +2148,7 @@ export class PlantHealAttr extends WeatherHealAttr { case WeatherType.SANDSTORM: case WeatherType.HAIL: case WeatherType.SNOW: + case WeatherType.FOG: case WeatherType.HEAVY_RAIN: return 0.25; default: @@ -4160,6 +4161,7 @@ export class AntiSunlightPowerDecreaseAttr extends VariablePowerAttr { case WeatherType.SANDSTORM: case WeatherType.HAIL: case WeatherType.SNOW: + case WeatherType.FOG: case WeatherType.HEAVY_RAIN: power.value *= 0.5; return true; diff --git a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts index f925452e143..c53ff610c48 100644 --- a/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts +++ b/src/data/mystery-encounters/encounters/fight-or-flight-encounter.ts @@ -11,10 +11,7 @@ import { STEALING_MOVES } from "#app/data/mystery-encounters/requirements/requir import type Pokemon from "#app/field/pokemon"; import { ModifierTier } from "#enums/modifier-tier"; import type { ModifierTypeOption } from "#app/modifier/modifier-type"; -import { - getPlayerModifierTypeOptions, - regenerateModifierPoolThresholds, -} from "#app/modifier/modifier-type"; +import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; diff --git a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts index 1b188915de7..0393bcdaa62 100644 --- a/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts +++ b/src/data/mystery-encounters/encounters/global-trade-system-encounter.ts @@ -7,10 +7,7 @@ import { TrainerSlot } from "#enums/trainer-slot"; import { ModifierTier } from "#enums/modifier-tier"; import { MusicPreference } from "#app/system/settings/settings"; import type { ModifierTypeOption } from "#app/modifier/modifier-type"; -import { - getPlayerModifierTypeOptions, - regenerateModifierPoolThresholds, -} from "#app/modifier/modifier-type"; +import { getPlayerModifierTypeOptions, regenerateModifierPoolThresholds } from "#app/modifier/modifier-type"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { MysteryEncounterType } from "#enums/mystery-encounter-type"; import { globalScene } from "#app/global-scene"; diff --git a/src/field/arena.ts b/src/field/arena.ts index 149204da3bd..aece908d653 100644 --- a/src/field/arena.ts +++ b/src/field/arena.ts @@ -262,7 +262,7 @@ export class Arena { return 5; } break; - case SpeciesId.LYCANROC: + case SpeciesId.LYCANROC: { const timeOfDay = this.getTimeOfDay(); switch (timeOfDay) { case TimeOfDay.DAY: @@ -274,6 +274,7 @@ export class Arena { return 1; } break; + } } return 0; diff --git a/src/field/pokemon.ts b/src/field/pokemon.ts index 0ee8b12f62f..730d2ab2c2a 100644 --- a/src/field/pokemon.ts +++ b/src/field/pokemon.ts @@ -4416,14 +4416,16 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { // biome-ignore lint: there are a ton of issues.. faintCry(callback: Function): void { if (this.fusionSpecies && this.getSpeciesForm() !== this.getFusionSpeciesForm()) { - return this.fusionFaintCry(callback); + this.fusionFaintCry(callback); + return; } const key = this.species.getCryKey(this.formIndex); let rate = 0.85; const cry = globalScene.playSound(key, { rate: rate }) as AnySound; if (!cry || globalScene.fieldVolume === 0) { - return callback(); + callback(); + return; } const sprite = this.getSprite(); const tintSprite = this.getTintSprite(); @@ -4491,7 +4493,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container { rate: rate, }) as AnySound; if (!cry || !fusionCry || globalScene.fieldVolume === 0) { - return callback(); + callback(); + return; } fusionCry.stop(); duration = Math.min(duration, fusionCry.totalDuration * 1000); diff --git a/src/modifier/modifier-type.ts b/src/modifier/modifier-type.ts index 2c848c69e18..cf373e6441a 100644 --- a/src/modifier/modifier-type.ts +++ b/src/modifier/modifier-type.ts @@ -2393,8 +2393,6 @@ export interface ModifierPool { [tier: string]: WeightedModifierType[]; } -const modifierPool: ModifierPool = {}; - let modifierPoolThresholds = {}; let ignoredPoolIndexes = {}; @@ -2859,7 +2857,7 @@ function getNewModifierTypeOption( } tier += upgradeCount; - while (tier && (!modifierPool.hasOwnProperty(tier) || !modifierPool[tier].length)) { + while (tier && (!pool.hasOwnProperty(tier) || !pool[tier].length)) { tier--; if (upgradeCount) { upgradeCount--; @@ -2870,7 +2868,7 @@ function getNewModifierTypeOption( if (tier < ModifierTier.MASTER && allowLuckUpgrades) { const partyLuckValue = getPartyLuckValue(party); const upgradeOdds = Math.floor(128 / ((partyLuckValue + 4) / 4)); - while (modifierPool.hasOwnProperty(tier + upgradeCount + 1) && modifierPool[tier + upgradeCount + 1].length) { + while (pool.hasOwnProperty(tier + upgradeCount + 1) && pool[tier + upgradeCount + 1].length) { if (randSeedInt(upgradeOdds) < 4) { upgradeCount++; } else { @@ -2920,6 +2918,7 @@ function getNewModifierTypeOption( } export function getDefaultModifierTypeForTier(tier: ModifierTier): ModifierType { + const modifierPool = getModifierPoolForType(ModifierPoolType.PLAYER); let modifierType: ModifierType | WeightedModifierType = modifierPool[tier || ModifierTier.COMMON][0]; if (modifierType instanceof WeightedModifierType) { modifierType = (modifierType as WeightedModifierType).modifierType; diff --git a/src/phases/add-enemy-buff-modifier-phase.ts b/src/phases/add-enemy-buff-modifier-phase.ts index 185464670d3..218a3a653ff 100644 --- a/src/phases/add-enemy-buff-modifier-phase.ts +++ b/src/phases/add-enemy-buff-modifier-phase.ts @@ -1,8 +1,5 @@ import { ModifierTier } from "#enums/modifier-tier"; -import { - regenerateModifierPoolThresholds, - getEnemyBuffModifierForWave, -} from "#app/modifier/modifier-type"; +import { regenerateModifierPoolThresholds, getEnemyBuffModifierForWave } from "#app/modifier/modifier-type"; import { ModifierPoolType } from "#enums/modifier-pool-type"; import { EnemyPersistentModifier } from "#app/modifier/modifier"; import { Phase } from "#app/phase"; diff --git a/src/phases/command-phase.ts b/src/phases/command-phase.ts index a7f866d0c90..754d54de70a 100644 --- a/src/phases/command-phase.ts +++ b/src/phases/command-phase.ts @@ -157,7 +157,7 @@ export class CommandPhase extends FieldPhase { switch (command) { // TODO: We don't need 2 args for this - moveUseMode is carried over from queuedMove case Command.TERA: - case Command.FIGHT: + case Command.FIGHT: { let useStruggle = false; const turnMove: TurnMove | undefined = args.length === 2 ? (args[1] as TurnMove) : undefined; if ( @@ -241,7 +241,8 @@ export class CommandPhase extends FieldPhase { ); } break; - case Command.BALL: + } + case Command.BALL: { const notInDex = globalScene .getEnemyField() @@ -345,8 +346,9 @@ export class CommandPhase extends FieldPhase { } } break; + } case Command.POKEMON: - case Command.RUN: + case Command.RUN: { const isSwitch = command === Command.POKEMON; const { currentBattle, arena } = globalScene; const mysteryEncounterFleeAllowed = currentBattle.mysteryEncounter?.fleeAllowed; @@ -453,6 +455,7 @@ export class CommandPhase extends FieldPhase { } } break; + } } if (success) { diff --git a/src/phases/move-phase.ts b/src/phases/move-phase.ts index 2885b6ab5b9..41a1042387b 100644 --- a/src/phases/move-phase.ts +++ b/src/phases/move-phase.ts @@ -321,7 +321,8 @@ export class MovePhase extends BattlePhase { if (fail) { this.showMoveText(); this.showFailedText(); - return this.end(); + this.end(); + return; } } diff --git a/src/phases/pokemon-anim-phase.ts b/src/phases/pokemon-anim-phase.ts index b1a21446996..314bddb981d 100644 --- a/src/phases/pokemon-anim-phase.ts +++ b/src/phases/pokemon-anim-phase.ts @@ -53,7 +53,8 @@ export class PokemonAnimPhase extends BattlePhase { private doSubstituteAddAnim(): void { const substitute = this.pokemon.getTag(SubstituteTag); if (isNullOrUndefined(substitute)) { - return this.end(); + this.end(); + return; } const getSprite = () => { @@ -116,12 +117,14 @@ export class PokemonAnimPhase extends BattlePhase { private doSubstitutePreMoveAnim(): void { if (this.fieldAssets.length !== 1) { - return this.end(); + this.end(); + return; } const subSprite = this.fieldAssets[0]; if (subSprite === undefined) { - return this.end(); + this.end(); + return; } globalScene.tweens.add({ @@ -145,12 +148,14 @@ export class PokemonAnimPhase extends BattlePhase { private doSubstitutePostMoveAnim(): void { if (this.fieldAssets.length !== 1) { - return this.end(); + this.end(); + return; } const subSprite = this.fieldAssets[0]; if (subSprite === undefined) { - return this.end(); + this.end(); + return; } globalScene.tweens.add({ @@ -174,12 +179,14 @@ export class PokemonAnimPhase extends BattlePhase { private doSubstituteRemoveAnim(): void { if (this.fieldAssets.length !== 1) { - return this.end(); + this.end(); + return; } const subSprite = this.fieldAssets[0]; if (subSprite === undefined) { - return this.end(); + this.end(); + return; } const getSprite = () => { @@ -244,12 +251,14 @@ export class PokemonAnimPhase extends BattlePhase { private doCommanderApplyAnim(): void { if (!globalScene.currentBattle?.double) { - return this.end(); + this.end(); + return; } const dondozo = this.pokemon.getAlly(); if (dondozo?.species?.speciesId !== SpeciesId.DONDOZO) { - return this.end(); + this.end(); + return; } const tatsugiriX = this.pokemon.x + this.pokemon.getSprite().x; @@ -329,7 +338,8 @@ export class PokemonAnimPhase extends BattlePhase { const tatsugiri = this.pokemon.getAlly(); if (isNullOrUndefined(tatsugiri)) { console.warn("Aborting COMMANDER_REMOVE anim: Tatsugiri is undefined"); - return this.end(); + this.end(); + return; } const tatsuSprite = globalScene.addPokemonSprite( diff --git a/src/phases/pokemon-transform-phase.ts b/src/phases/pokemon-transform-phase.ts index 03e9f42bb00..938915309d9 100644 --- a/src/phases/pokemon-transform-phase.ts +++ b/src/phases/pokemon-transform-phase.ts @@ -29,7 +29,8 @@ export class PokemonTransformPhase extends PokemonPhase { const target = globalScene.getField(true).find(p => p.getBattlerIndex() === this.targetIndex); if (!target) { - return this.end(); + this.end(); + return; } user.summonData.speciesForm = target.getSpeciesForm(); diff --git a/src/phases/quiet-form-change-phase.ts b/src/phases/quiet-form-change-phase.ts index e6a00c73756..41b691844bf 100644 --- a/src/phases/quiet-form-change-phase.ts +++ b/src/phases/quiet-form-change-phase.ts @@ -29,7 +29,8 @@ export class QuietFormChangePhase extends BattlePhase { super.start(); if (this.pokemon.formIndex === this.pokemon.species.forms.findIndex(f => f.formKey === this.formChange.formKey)) { - return this.end(); + this.end(); + return; } const preName = getPokemonNameWithAffix(this.pokemon); diff --git a/src/pipelines/glsl/fieldSpriteFragShader.frag b/src/pipelines/glsl/fieldSpriteFragShader.frag index e79dea86fe9..0eb95ece5e3 100644 --- a/src/pipelines/glsl/fieldSpriteFragShader.frag +++ b/src/pipelines/glsl/fieldSpriteFragShader.frag @@ -51,7 +51,7 @@ float hue2rgb(float f1, float f2, float hue) { vec3 rgb2hsl(vec3 color) { vec3 hsl; - + float fmin = min(min(color.r, color.g), color.b); float fmax = max(max(color.r, color.g), color.b); float delta = fmax - fmin; @@ -66,7 +66,7 @@ vec3 rgb2hsl(vec3 color) { hsl.y = delta / (fmax + fmin); else hsl.y = delta / (2.0 - fmax - fmin); - + float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta; float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta; float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta; @@ -89,24 +89,24 @@ vec3 rgb2hsl(vec3 color) { vec3 hsl2rgb(vec3 hsl) { vec3 rgb; - + if (hsl.y == 0.0) rgb = vec3(hsl.z); else { float f2; - + if (hsl.z < 0.5) f2 = hsl.z * (1.0 + hsl.y); else f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z); - + float f1 = 2.0 * hsl.z - f2; - + rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); rgb.g = hue2rgb(f1, f2, hsl.x); rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0)); } - + return rgb; } diff --git a/src/pipelines/glsl/spriteFragShader.frag b/src/pipelines/glsl/spriteFragShader.frag index 03f8c8c27bc..9328cc4d96d 100644 --- a/src/pipelines/glsl/spriteFragShader.frag +++ b/src/pipelines/glsl/spriteFragShader.frag @@ -83,7 +83,7 @@ vec3 rgb2hsl(vec3 color) { hsl.y = delta / (fmax + fmin); else hsl.y = delta / (2.0 - fmax - fmin); - + float deltaR = (((fmax - color.r) / 6.0) + (delta / 2.0)) / delta; float deltaG = (((fmax - color.g) / 6.0) + (delta / 2.0)) / delta; float deltaB = (((fmax - color.b) / 6.0) + (delta / 2.0)) / delta; @@ -106,24 +106,24 @@ vec3 rgb2hsl(vec3 color) { vec3 hsl2rgb(vec3 hsl) { vec3 rgb; - + if (hsl.y == 0.0) rgb = vec3(hsl.z); else { float f2; - + if (hsl.z < 0.5) f2 = hsl.z * (1.0 + hsl.y); else f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z); - + float f1 = 2.0 * hsl.z - f2; - + rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); rgb.g = hue2rgb(f1, f2, hsl.x); rgb.b= hue2rgb(f1, f2, hsl.x - (1.0/3.0)); } - + return rgb; } diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts index 515d9aec528..8ca9005096f 100644 --- a/src/plugins/i18n.ts +++ b/src/plugins/i18n.ts @@ -174,7 +174,24 @@ export async function initI18n(): Promise { "es-MX": ["es-ES", "en"], default: ["en"], }, - supportedLngs: ["en", "es-ES", "es-MX", "fr", "it", "de", "zh-CN", "zh-TW", "pt-BR", "ko", "ja", "ca", "da", "tr", "ro", "ru"], + supportedLngs: [ + "en", + "es-ES", + "es-MX", + "fr", + "it", + "de", + "zh-CN", + "zh-TW", + "pt-BR", + "ko", + "ja", + "ca", + "da", + "tr", + "ro", + "ru", + ], backend: { loadPath(lng: string, [ns]: string[]) { let fileName: string; diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 69abc669870..ca5395a5af7 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -959,7 +959,7 @@ export function setSetting(setting: string, value: number): boolean { }, { label: "Türkçe (Needs Help)", - handler: () => changeLocaleHandler("tr") + handler: () => changeLocaleHandler("tr"), }, { label: "Русский (Needs Help)", @@ -967,11 +967,11 @@ export function setSetting(setting: string, value: number): boolean { }, { label: "Dansk (Needs Help)", - handler: () => changeLocaleHandler("da") + handler: () => changeLocaleHandler("da"), }, { label: "Română (Needs Help)", - handler: () => changeLocaleHandler("ro") + handler: () => changeLocaleHandler("ro"), }, { label: i18next.t("settings:back"), diff --git a/src/ui/abstact-option-select-ui-handler.ts b/src/ui/abstact-option-select-ui-handler.ts index 07609648a4e..e1263bc088c 100644 --- a/src/ui/abstact-option-select-ui-handler.ts +++ b/src/ui/abstact-option-select-ui-handler.ts @@ -56,10 +56,6 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler { protected defaultTextStyle: TextStyle = TextStyle.WINDOW; protected textContent: string; - constructor(mode: UiMode | null) { - super(mode); - } - abstract getWindowWidth(): number; getWindowHeight(): number { diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index 67ae3118863..c8c8e43802b 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -69,7 +69,7 @@ export default class AdminUiHandler extends FormModalUiHandler { case AdminMode.SEARCH: inputFieldConfigs.push({ label: "Username" }); break; - case AdminMode.ADMIN: + case AdminMode.ADMIN: { const adminResult = this.adminResult ?? { username: "", discordId: "", @@ -90,6 +90,7 @@ export default class AdminUiHandler extends FormModalUiHandler { inputFieldConfigs.push({ label: "Last played", isReadOnly: true }); inputFieldConfigs.push({ label: "Registered", isReadOnly: true }); break; + } } return inputFieldConfigs; } diff --git a/src/ui/daily-run-scoreboard.ts b/src/ui/daily-run-scoreboard.ts index 076a782908b..e19882b09cc 100644 --- a/src/ui/daily-run-scoreboard.ts +++ b/src/ui/daily-run-scoreboard.ts @@ -169,12 +169,13 @@ export class DailyRunScoreboard extends Phaser.GameObjects.Container { entryContainer.add(scoreLabel); switch (this.category) { - case ScoreboardCategory.DAILY: + case ScoreboardCategory.DAILY: { const waveLabel = addTextObject(68, 0, wave, TextStyle.WINDOW, { fontSize: "54px", }); entryContainer.add(waveLabel); break; + } case ScoreboardCategory.WEEKLY: scoreLabel.x -= 16; break; diff --git a/src/ui/egg-gacha-ui-handler.ts b/src/ui/egg-gacha-ui-handler.ts index d6b1b630a05..1b1aed91203 100644 --- a/src/ui/egg-gacha-ui-handler.ts +++ b/src/ui/egg-gacha-ui-handler.ts @@ -131,7 +131,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { gachaInfoContainer.add(gachaUpLabel); switch (gachaType as GachaType) { - case GachaType.LEGENDARY: + case GachaType.LEGENDARY: { if (["de", "es-ES"].includes(currentLanguage)) { gachaUpLabel.setAlign("center"); gachaUpLabel.setY(0); @@ -152,6 +152,7 @@ export default class EggGachaUiHandler extends MessageUiHandler { gachaInfoContainer.add(pokemonIcon); break; + } case GachaType.MOVE: if (["de", "es-ES", "fr", "pt-BR", "ru"].includes(currentLanguage)) { gachaUpLabel.setAlign("center"); @@ -623,11 +624,12 @@ export default class EggGachaUiHandler extends MessageUiHandler { updateGachaInfo(gachaType: GachaType): void { const infoContainer = this.gachaInfoContainers[gachaType]; switch (gachaType as GachaType) { - case GachaType.LEGENDARY: + case GachaType.LEGENDARY: { const species = getPokemonSpecies(getLegendaryGachaSpeciesForTimestamp(new Date().getTime())); const pokemonIcon = infoContainer.getAt(1) as Phaser.GameObjects.Sprite; pokemonIcon.setTexture(species.getIconAtlasKey(), species.getIconId(false)); break; + } } } diff --git a/src/ui/menu-ui-handler.ts b/src/ui/menu-ui-handler.ts index e68cc706aba..5ab1d4f9e96 100644 --- a/src/ui/menu-ui-handler.ts +++ b/src/ui/menu-ui-handler.ts @@ -686,7 +686,7 @@ export default class MenuUiHandler extends MessageUiHandler { error = true; } break; - case MenuOptions.LOG_OUT: + case MenuOptions.LOG_OUT: { success = true; const doLogout = () => { ui.setMode(UiMode.LOADING, { @@ -718,6 +718,7 @@ export default class MenuUiHandler extends MessageUiHandler { doLogout(); } break; + } } } else if (button === Button.CANCEL) { success = true; diff --git a/src/ui/party-ui-handler.ts b/src/ui/party-ui-handler.ts index 6675c2bb9f1..cf6333f4580 100644 --- a/src/ui/party-ui-handler.ts +++ b/src/ui/party-ui-handler.ts @@ -1385,7 +1385,7 @@ export default class PartyUiHandler extends MessageUiHandler { case PartyOption.MOVE_1: case PartyOption.MOVE_2: case PartyOption.MOVE_3: - case PartyOption.MOVE_4: + case PartyOption.MOVE_4: { const move = pokemon.moveset[option - PartyOption.MOVE_1]; if (this.showMovePp) { const maxPP = move.getMovePp(); @@ -1395,7 +1395,8 @@ export default class PartyUiHandler extends MessageUiHandler { optionName = move.getName(); } break; - default: + } + default: { const formChangeItemModifiers = this.getFormChangeItemsModifiers(pokemon); if (formChangeItemModifiers && option >= PartyOption.FORM_CHANGE_ITEM) { const modifier = formChangeItemModifiers[option - PartyOption.FORM_CHANGE_ITEM]; @@ -1410,6 +1411,7 @@ export default class PartyUiHandler extends MessageUiHandler { } } break; + } } } else if (this.partyUiMode === PartyUiMode.REMEMBER_MOVE_MODIFIER) { const learnableLevelMoves = pokemon.getLearnableLevelMoves(); diff --git a/src/ui/run-info-ui-handler.ts b/src/ui/run-info-ui-handler.ts index a4de2215fa4..78ab4a40407 100644 --- a/src/ui/run-info-ui-handler.ts +++ b/src/ui/run-info-ui-handler.ts @@ -567,7 +567,7 @@ export default class RunInfoUiHandler extends UiHandler { case GameModes.SPLICED_ENDLESS: modeText.appendText(`${i18next.t("gameMode:endlessSpliced")}`, false); break; - case GameModes.CHALLENGE: + case GameModes.CHALLENGE: { modeText.appendText(`${i18next.t("gameMode:challenge")}`, false); modeText.appendText(`${i18next.t("runHistory:challengeRules")}: `); modeText.setWrapMode(1); // wrap by word @@ -582,6 +582,7 @@ export default class RunInfoUiHandler extends UiHandler { } } break; + } case GameModes.ENDLESS: modeText.appendText(`${i18next.t("gameMode:endless")}`, false); break; @@ -687,7 +688,7 @@ export default class RunInfoUiHandler extends UiHandler { case Challenges.SINGLE_GENERATION: rules.push(i18next.t(`runHistory:challengeMonoGen${this.runInfo.challenges[i].value}`)); break; - case Challenges.SINGLE_TYPE: + case Challenges.SINGLE_TYPE: { const typeRule = PokemonType[this.runInfo.challenges[i].value - 1]; const typeTextColor = `[color=${TypeColor[typeRule]}]`; const typeShadowColor = `[shadow=${TypeShadow[typeRule]}]`; @@ -695,16 +696,18 @@ export default class RunInfoUiHandler extends UiHandler { typeTextColor + typeShadowColor + i18next.t(`pokemonInfo:Type.${typeRule}`)! + "[/color]" + "[/shadow]"; rules.push(typeText); break; + } case Challenges.INVERSE_BATTLE: rules.push(i18next.t("challenges:inverseBattle.shortName")); break; - default: + default: { const localisationKey = Challenges[this.runInfo.challenges[i].id] .split("_") .map((f, i) => (i ? `${f[0]}${f.slice(1).toLowerCase()}` : f.toLowerCase())) .join(""); rules.push(i18next.t(`challenges:${localisationKey}.name`)); break; + } } } } diff --git a/src/ui/settings/abstract-control-settings-ui-handler.ts b/src/ui/settings/abstract-control-settings-ui-handler.ts index 495a0f68540..e3631c062df 100644 --- a/src/ui/settings/abstract-control-settings-ui-handler.ts +++ b/src/ui/settings/abstract-control-settings-ui-handler.ts @@ -126,6 +126,11 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler ); this.actionsBg.setOrigin(0, 0); + /* + * If there isn't enough space to fit all the icons and texts, there will be an overlap + * This currently doesn't happen, but it's something to keep in mind. + */ + const iconAction = globalScene.add.sprite(0, 0, "keyboard"); iconAction.setOrigin(0, -0.1); iconAction.setPositionRelative(this.actionsBg, this.navigationContainer.width - 32, 4); @@ -137,7 +142,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const iconCancel = globalScene.add.sprite(0, 0, "keyboard"); iconCancel.setOrigin(0, -0.1); - iconCancel.setPositionRelative(this.actionsBg, this.navigationContainer.width - 100, 4); + iconCancel.setPositionRelative(this.actionsBg, actionText.x - 28, 4); this.navigationIcons["BUTTON_CANCEL"] = iconCancel; const cancelText = addTextObject(0, 0, i18next.t("settings:back"), TextStyle.SETTINGS_LABEL); @@ -146,7 +151,7 @@ export default abstract class AbstractControlSettingsUiHandler extends UiHandler const iconReset = globalScene.add.sprite(0, 0, "keyboard"); iconReset.setOrigin(0, -0.1); - iconReset.setPositionRelative(this.actionsBg, this.navigationContainer.width - 180, 4); + iconReset.setPositionRelative(this.actionsBg, cancelText.x - 28, 4); this.navigationIcons["BUTTON_HOME"] = iconReset; const resetText = addTextObject(0, 0, i18next.t("settings:reset"), TextStyle.SETTINGS_LABEL); diff --git a/src/ui/settings/abstract-settings-ui-handler.ts b/src/ui/settings/abstract-settings-ui-handler.ts index 1fb4b6d34dc..6db9840a818 100644 --- a/src/ui/settings/abstract-settings-ui-handler.ts +++ b/src/ui/settings/abstract-settings-ui-handler.ts @@ -94,7 +94,7 @@ export default class AbstractSettingsUiHandler extends MessageUiHandler { const iconCancel = globalScene.add.sprite(0, 0, "keyboard"); iconCancel.setOrigin(0, -0.1); - iconCancel.setPositionRelative(actionsBg, this.navigationContainer.width - 100, 4); + iconCancel.setPositionRelative(actionsBg, actionText.x - 28, 4); this.navigationIcons["BUTTON_CANCEL"] = iconCancel; const cancelText = addTextObject(0, 0, i18next.t("settings:back"), TextStyle.SETTINGS_LABEL); @@ -332,12 +332,13 @@ export default class AbstractSettingsUiHandler extends MessageUiHandler { case Button.CYCLE_SHINY: success = this.navigationContainer.navigate(button); break; - case Button.ACTION: + case Button.ACTION: { const setting: Setting = this.settings[cursor]; if (setting?.activatable) { success = this.activateSetting(setting); } break; + } } } diff --git a/src/ui/settings/move-touch-controls-handler.ts b/src/ui/settings/move-touch-controls-handler.ts index 44377c8c2ab..f684d27f748 100644 --- a/src/ui/settings/move-touch-controls-handler.ts +++ b/src/ui/settings/move-touch-controls-handler.ts @@ -98,7 +98,7 @@ export default class MoveTouchControlsHandler {
${i18next.t("settings:touchCancel")}
-
+
${i18next.t("settings:orientation")} ${this.isLandscapeMode ? i18next.t("settings:landscape") : i18next.t("settings:portrait")} diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 88f881746bb..7c8b05b6f76 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1763,7 +1763,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } } else if (this.randomCursorObj.visible) { switch (button) { - case Button.ACTION: + case Button.ACTION: { if (this.starterSpecies.length >= 6) { error = true; break; @@ -1815,6 +1815,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { } }); break; + } case Button.UP: this.randomCursorObj.setVisible(false); this.filterBarCursor = this.filterBar.numFilters - 1; diff --git a/src/ui/test-dialogue-ui-handler.ts b/src/ui/test-dialogue-ui-handler.ts index 9ecf1641e7b..b1e5047955a 100644 --- a/src/ui/test-dialogue-ui-handler.ts +++ b/src/ui/test-dialogue-ui-handler.ts @@ -10,10 +10,6 @@ import { UiMode } from "#enums/ui-mode"; export default class TestDialogueUiHandler extends FormModalUiHandler { keys: string[]; - constructor(mode) { - super(mode); - } - setup() { super.setup(); diff --git a/test/moves/last_respects.test.ts b/test/moves/last_respects.test.ts index b2eb4c6695b..08256d3ebfb 100644 --- a/test/moves/last_respects.test.ts +++ b/test/moves/last_respects.test.ts @@ -164,15 +164,13 @@ describe("Moves - Last Respects", () => { await game.toNextWave(); expect(game.scene.currentBattle.enemyFaints).toBe(0); + game.removeEnemyHeldItems(); + game.move.select(MoveId.LAST_RESPECTS); await game.setTurnOrder([BattlerIndex.ENEMY, BattlerIndex.PLAYER]); await game.phaseInterceptor.to("MoveEndPhase"); - const enemy = game.field.getEnemyPokemon(); - const player = game.field.getPlayerPokemon(); - const items = `Player items: ${player.getHeldItems()} | Enemy Items: ${enemy.getHeldItems()} |`; - - expect(move.calculateBattlePower, items).toHaveLastReturnedWith(50); + expect(move.calculateBattlePower).toHaveLastReturnedWith(50); }); it("should reset playerFaints count if we enter new trainer battle", async () => {