mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-20 07:12:32 +02:00
Fix all remaining biome lints
This commit is contained in:
parent
852e70e2c3
commit
5c53f54d80
@ -2,92 +2,86 @@
|
||||
module.exports = {
|
||||
forbidden: [
|
||||
{
|
||||
name: 'no-circular-at-runtime',
|
||||
severity: 'warn',
|
||||
name: "no-circular-at-runtime",
|
||||
severity: "warn",
|
||||
comment:
|
||||
'This dependency is part of a circular relationship. You might want to revise ' +
|
||||
'your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ',
|
||||
"This dependency is part of a circular relationship. You might want to revise " +
|
||||
"your solution (i.e. use dependency inversion, make sure the modules have a single responsibility) ",
|
||||
from: {},
|
||||
to: {
|
||||
circular: true,
|
||||
viaOnly: {
|
||||
dependencyTypesNot: [
|
||||
'type-only'
|
||||
]
|
||||
}
|
||||
}
|
||||
dependencyTypesNot: ["type-only"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'no-orphans',
|
||||
name: "no-orphans",
|
||||
comment:
|
||||
"This is an orphan module - it's likely not used (anymore?). Either use it or " +
|
||||
"remove it. If it's logical this module is an orphan (i.e. it's a config file), " +
|
||||
"add an exception for it in your dependency-cruiser configuration. By default " +
|
||||
"this rule does not scrutinize dot-files (e.g. .eslintrc.js), TypeScript declaration " +
|
||||
"files (.d.ts), tsconfig.json and some of the babel and webpack configs.",
|
||||
severity: 'warn',
|
||||
severity: "warn",
|
||||
from: {
|
||||
orphan: true,
|
||||
pathNot: [
|
||||
'(^|/)[.][^/]+[.](?:js|cjs|mjs|ts|cts|mts|json)$', // dot files
|
||||
'[.]d[.]ts$', // TypeScript declaration files
|
||||
'(^|/)tsconfig[.]json$', // TypeScript config
|
||||
'(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$' // other configs
|
||||
]
|
||||
"(^|/)[.][^/]+[.](?:js|cjs|mjs|ts|cts|mts|json)$", // dot files
|
||||
"[.]d[.]ts$", // TypeScript declaration files
|
||||
"(^|/)tsconfig[.]json$", // TypeScript config
|
||||
"(^|/)(?:babel|webpack)[.]config[.](?:js|cjs|mjs|ts|cts|mts|json)$", // other configs
|
||||
],
|
||||
},
|
||||
to: {},
|
||||
},
|
||||
{
|
||||
name: 'no-deprecated-core',
|
||||
name: "no-deprecated-core",
|
||||
comment:
|
||||
'A module depends on a node core module that has been deprecated. Find an alternative - these are ' +
|
||||
"A module depends on a node core module that has been deprecated. Find an alternative - these are " +
|
||||
"bound to exist - node doesn't deprecate lightly.",
|
||||
severity: 'warn',
|
||||
severity: "warn",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'core'
|
||||
],
|
||||
dependencyTypes: ["core"],
|
||||
path: [
|
||||
'^v8/tools/codemap$',
|
||||
'^v8/tools/consarray$',
|
||||
'^v8/tools/csvparser$',
|
||||
'^v8/tools/logreader$',
|
||||
'^v8/tools/profile_view$',
|
||||
'^v8/tools/profile$',
|
||||
'^v8/tools/SourceMap$',
|
||||
'^v8/tools/splaytree$',
|
||||
'^v8/tools/tickprocessor-driver$',
|
||||
'^v8/tools/tickprocessor$',
|
||||
'^node-inspect/lib/_inspect$',
|
||||
'^node-inspect/lib/internal/inspect_client$',
|
||||
'^node-inspect/lib/internal/inspect_repl$',
|
||||
'^async_hooks$',
|
||||
'^punycode$',
|
||||
'^domain$',
|
||||
'^constants$',
|
||||
'^sys$',
|
||||
'^_linklist$',
|
||||
'^_stream_wrap$'
|
||||
"^v8/tools/codemap$",
|
||||
"^v8/tools/consarray$",
|
||||
"^v8/tools/csvparser$",
|
||||
"^v8/tools/logreader$",
|
||||
"^v8/tools/profile_view$",
|
||||
"^v8/tools/profile$",
|
||||
"^v8/tools/SourceMap$",
|
||||
"^v8/tools/splaytree$",
|
||||
"^v8/tools/tickprocessor-driver$",
|
||||
"^v8/tools/tickprocessor$",
|
||||
"^node-inspect/lib/_inspect$",
|
||||
"^node-inspect/lib/internal/inspect_client$",
|
||||
"^node-inspect/lib/internal/inspect_repl$",
|
||||
"^async_hooks$",
|
||||
"^punycode$",
|
||||
"^domain$",
|
||||
"^constants$",
|
||||
"^sys$",
|
||||
"^_linklist$",
|
||||
"^_stream_wrap$",
|
||||
],
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'not-to-deprecated',
|
||||
name: "not-to-deprecated",
|
||||
comment:
|
||||
'This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later ' +
|
||||
'version of that module, or find an alternative. Deprecated modules are a security risk.',
|
||||
severity: 'warn',
|
||||
"This module uses a (version of an) npm module that has been deprecated. Either upgrade to a later " +
|
||||
"version of that module, or find an alternative. Deprecated modules are a security risk.",
|
||||
severity: "warn",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'deprecated'
|
||||
]
|
||||
}
|
||||
dependencyTypes: ["deprecated"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'no-non-package-json',
|
||||
severity: 'error',
|
||||
name: "no-non-package-json",
|
||||
severity: "error",
|
||||
comment:
|
||||
"This module depends on an npm package that isn't in the 'dependencies' section of your package.json. " +
|
||||
"That's problematic as the package either (1) won't be available on live (2 - worse) will be " +
|
||||
@ -95,87 +89,75 @@ module.exports = {
|
||||
"in your package.json.",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'npm-no-pkg',
|
||||
'npm-unknown'
|
||||
]
|
||||
}
|
||||
dependencyTypes: ["npm-no-pkg", "npm-unknown"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'not-to-unresolvable',
|
||||
name: "not-to-unresolvable",
|
||||
comment:
|
||||
"This module depends on a module that cannot be found ('resolved to disk'). If it's an npm " +
|
||||
'module: add it to your package.json. In all other cases you likely already know what to do.',
|
||||
severity: 'error',
|
||||
"module: add it to your package.json. In all other cases you likely already know what to do.",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
couldNotResolve: true
|
||||
}
|
||||
couldNotResolve: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'no-duplicate-dep-types',
|
||||
name: "no-duplicate-dep-types",
|
||||
comment:
|
||||
"Likely this module depends on an external ('npm') package that occurs more than once " +
|
||||
"in your package.json i.e. bot as a devDependencies and in dependencies. This will cause " +
|
||||
"maintenance problems later on.",
|
||||
severity: 'warn',
|
||||
severity: "warn",
|
||||
from: {},
|
||||
to: {
|
||||
moreThanOneDependencyType: true,
|
||||
// as it's pretty common to have a type import be a type only import
|
||||
// as it's pretty common to have a type import be a type only import
|
||||
// _and_ (e.g.) a devDependency - don't consider type-only dependency
|
||||
// types for this rule
|
||||
dependencyTypesNot: ["type-only"]
|
||||
}
|
||||
dependencyTypesNot: ["type-only"],
|
||||
},
|
||||
},
|
||||
|
||||
/* rules you might want to tweak for your specific situation: */
|
||||
|
||||
{
|
||||
name: 'not-to-spec',
|
||||
name: "not-to-spec",
|
||||
comment:
|
||||
'This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. ' +
|
||||
"This module depends on a spec (test) file. The sole responsibility of a spec file is to test code. " +
|
||||
"If there's something in a spec that's of use to other modules, it doesn't have that single " +
|
||||
'responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.',
|
||||
severity: 'error',
|
||||
"responsibility anymore. Factor it out into (e.g.) a separate utility/ helper or a mock.",
|
||||
severity: "error",
|
||||
from: {},
|
||||
to: {
|
||||
path: '[.](?:spec|test)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$'
|
||||
}
|
||||
path: "[.](?:spec|test)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'not-to-dev-dep',
|
||||
severity: 'error',
|
||||
name: "not-to-dev-dep",
|
||||
severity: "error",
|
||||
comment:
|
||||
"This module depends on an npm package from the 'devDependencies' section of your " +
|
||||
'package.json. It looks like something that ships to production, though. To prevent problems ' +
|
||||
"package.json. It looks like something that ships to production, though. To prevent problems " +
|
||||
"with npm packages that aren't there on production declare it (only!) in the 'dependencies'" +
|
||||
'section of your package.json. If this module is development only - add it to the ' +
|
||||
'from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration',
|
||||
"section of your package.json. If this module is development only - add it to the " +
|
||||
"from.pathNot re of the not-to-dev-dep rule in the dependency-cruiser configuration",
|
||||
from: {
|
||||
path: '^(src)',
|
||||
pathNot: [
|
||||
'[.](?:spec|test|setup|script)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$',
|
||||
'./test'
|
||||
]
|
||||
path: "^(src)",
|
||||
pathNot: ["[.](?:spec|test|setup|script)[.](?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$", "./test"],
|
||||
},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'npm-dev',
|
||||
],
|
||||
dependencyTypes: ["npm-dev"],
|
||||
// type only dependencies are not a problem as they don't end up in the
|
||||
// production code or are ignored by the runtime.
|
||||
dependencyTypesNot: [
|
||||
'type-only'
|
||||
],
|
||||
pathNot: [
|
||||
'node_modules/@types/'
|
||||
]
|
||||
}
|
||||
dependencyTypesNot: ["type-only"],
|
||||
pathNot: ["node_modules/@types/"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'optional-deps-used',
|
||||
severity: 'info',
|
||||
name: "optional-deps-used",
|
||||
severity: "info",
|
||||
comment:
|
||||
"This module depends on an npm package that is declared as an optional dependency " +
|
||||
"in your package.json. As this makes sense in limited situations only, it's flagged here. " +
|
||||
@ -183,33 +165,28 @@ module.exports = {
|
||||
"dependency-cruiser configuration.",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'npm-optional'
|
||||
]
|
||||
}
|
||||
dependencyTypes: ["npm-optional"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'peer-deps-used',
|
||||
name: "peer-deps-used",
|
||||
comment:
|
||||
"This module depends on an npm package that is declared as a peer dependency " +
|
||||
"in your package.json. This makes sense if your package is e.g. a plugin, but in " +
|
||||
"other cases - maybe not so much. If the use of a peer dependency is intentional " +
|
||||
"add an exception to your dependency-cruiser configuration.",
|
||||
severity: 'warn',
|
||||
severity: "warn",
|
||||
from: {},
|
||||
to: {
|
||||
dependencyTypes: [
|
||||
'npm-peer'
|
||||
]
|
||||
}
|
||||
}
|
||||
dependencyTypes: ["npm-peer"],
|
||||
},
|
||||
},
|
||||
],
|
||||
options: {
|
||||
|
||||
/* Which modules not to follow further when encountered */
|
||||
doNotFollow: {
|
||||
/* path: an array of regular expressions in strings to match against */
|
||||
path: ['node_modules']
|
||||
path: ["node_modules"],
|
||||
},
|
||||
|
||||
/* Which modules to exclude */
|
||||
@ -271,7 +248,7 @@ module.exports = {
|
||||
defaults to './tsconfig.json'.
|
||||
*/
|
||||
tsConfig: {
|
||||
fileName: 'tsconfig.json'
|
||||
fileName: "tsconfig.json",
|
||||
},
|
||||
|
||||
/* Webpack configuration to use to get resolve options from.
|
||||
@ -345,7 +322,7 @@ module.exports = {
|
||||
collapses everything in node_modules to one folder deep so you see
|
||||
the external modules, but their innards.
|
||||
*/
|
||||
collapsePattern: 'node_modules/(?:@[^/]+/[^/]+|[^/]+)',
|
||||
collapsePattern: "node_modules/(?:@[^/]+/[^/]+|[^/]+)",
|
||||
|
||||
/* Options to tweak the appearance of your graph.See
|
||||
https://github.com/sverweij/dependency-cruiser/blob/main/doc/options-reference.md#reporteroptions
|
||||
@ -367,7 +344,8 @@ module.exports = {
|
||||
dependency graph reporter (`archi`) you probably want to tweak
|
||||
this collapsePattern to your situation.
|
||||
*/
|
||||
collapsePattern: '^(?:packages|src|lib(s?)|app(s?)|bin|test(s?)|spec(s?))/[^/]+|node_modules/(?:@[^/]+/[^/]+|[^/]+)',
|
||||
collapsePattern:
|
||||
"^(?:packages|src|lib(s?)|app(s?)|bin|test(s?)|spec(s?))/[^/]+|node_modules/(?:@[^/]+/[^/]+|[^/]+)",
|
||||
|
||||
/* Options to tweak the appearance of your graph. If you don't specify a
|
||||
theme for 'archi' dependency-cruiser will use the one specified in the
|
||||
@ -375,10 +353,10 @@ module.exports = {
|
||||
*/
|
||||
// theme: { },
|
||||
},
|
||||
"text": {
|
||||
"highlightFocused": true
|
||||
text: {
|
||||
highlightFocused: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
// generated: dependency-cruiser@16.3.3 on 2024-06-13T23:26:36.169Z
|
||||
|
@ -27,7 +27,7 @@
|
||||
"*.css", // TODO?
|
||||
"*.html", // TODO?
|
||||
// TODO: these files are too big and complex, ignore them until their respective refactors
|
||||
"src/data/move.ts",
|
||||
"src/data/moves/move.ts",
|
||||
"src/data/ability.ts",
|
||||
"src/field/pokemon.ts",
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
"complexity": {
|
||||
"noExcessiveCognitiveComplexity": "warn",
|
||||
"useLiteralKeys": "off",
|
||||
"noForEach": "info", // TODO: Refactor use of foreach and remove this line.
|
||||
"noForEach": "off", // Foreach vs for of is not that simple.
|
||||
"noUselessSwitchCase": "off", // Explicit > Implicit
|
||||
"noUselessConstructor": "warn", // TODO: Refactor and make this an error
|
||||
"noBannedTypes": "warn" // TODO: Refactor and make this an error
|
||||
|
@ -31,7 +31,8 @@ async function promptTestType() {
|
||||
if (typeAnswer.selectedOption === "EXIT") {
|
||||
console.log("Exiting...");
|
||||
return process.exit();
|
||||
} else if (!typeChoices.includes(typeAnswer.selectedOption)) {
|
||||
}
|
||||
if (!typeChoices.includes(typeAnswer.selectedOption)) {
|
||||
console.error(`Please provide a valid type (${typeChoices.join(", ")})!`);
|
||||
return await promptTestType();
|
||||
}
|
||||
|
14354
package-lock.json
generated
14354
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,8 @@
|
||||
import { globalScene } from "#app/global-scene";
|
||||
import {
|
||||
AttackMove,
|
||||
BeakBlastHeaderAttr,
|
||||
DelayedAttackAttr,
|
||||
SelfStatusMove,
|
||||
allMoves,
|
||||
} from "./moves/move";
|
||||
import { AttackMove, BeakBlastHeaderAttr, DelayedAttackAttr, SelfStatusMove, allMoves } from "./moves/move";
|
||||
import { MoveFlags } from "#enums/MoveFlags";
|
||||
import type Pokemon from "../field/pokemon";
|
||||
import {
|
||||
type nil,
|
||||
getFrameMs,
|
||||
getEnumKeys,
|
||||
getEnumValues,
|
||||
animationFileName,
|
||||
} from "../utils";
|
||||
import { type nil, getFrameMs, getEnumKeys, getEnumValues, animationFileName } from "../utils";
|
||||
import type { BattlerIndex } from "../battle";
|
||||
import type { Element } from "json-stable-stringify";
|
||||
import { Moves } from "#enums/moves";
|
||||
@ -1122,103 +1110,113 @@ export abstract class BattleAnim {
|
||||
spritePriorities.push(1);
|
||||
}
|
||||
|
||||
const graphicIndex = g++;
|
||||
const moveSprite = sprites[graphicIndex];
|
||||
if (spritePriorities[graphicIndex] !== frame.priority) {
|
||||
spritePriorities[graphicIndex] = frame.priority;
|
||||
/** Move the position that the moveSprite is rendered in based on the priority.
|
||||
* @param priority The priority level to draw the sprite.
|
||||
* - 0: Draw the sprite in front of the pokemon on the field.
|
||||
* - 1: Draw the sprite in front of the user pokemon.
|
||||
* - 2: Draw the sprite in front of its `bgSprite` (if it has one), or its
|
||||
* `AnimFocus` (if that is user/target), otherwise behind everything.
|
||||
* - 3: Draw the sprite behind its `AnimFocus` (if that is user/target), otherwise in front of everything.
|
||||
*/
|
||||
const setSpritePriority = (priority: number) => {
|
||||
/** The sprite we are moving the moveSprite in relation to */
|
||||
let targetSprite: Phaser.GameObjects.GameObject | nil;
|
||||
/** The method that is being used to move the sprite.*/
|
||||
let moveFunc: ((sprite: Phaser.GameObjects.GameObject, target: Phaser.GameObjects.GameObject) => void) |
|
||||
((sprite: Phaser.GameObjects.GameObject) => void) = globalScene.field.bringToTop;
|
||||
const graphicIndex = g++;
|
||||
const moveSprite = sprites[graphicIndex];
|
||||
if (spritePriorities[graphicIndex] !== frame.priority) {
|
||||
spritePriorities[graphicIndex] = frame.priority;
|
||||
/** Move the position that the moveSprite is rendered in based on the priority.
|
||||
* @param priority The priority level to draw the sprite.
|
||||
* - 0: Draw the sprite in front of the pokemon on the field.
|
||||
* - 1: Draw the sprite in front of the user pokemon.
|
||||
* - 2: Draw the sprite in front of its `bgSprite` (if it has one), or its
|
||||
* `AnimFocus` (if that is user/target), otherwise behind everything.
|
||||
* - 3: Draw the sprite behind its `AnimFocus` (if that is user/target), otherwise in front of everything.
|
||||
*/
|
||||
const setSpritePriority = (priority: number) => {
|
||||
/** The sprite we are moving the moveSprite in relation to */
|
||||
let targetSprite: Phaser.GameObjects.GameObject | nil;
|
||||
/** The method that is being used to move the sprite.*/
|
||||
let moveFunc:
|
||||
| ((sprite: Phaser.GameObjects.GameObject, target: Phaser.GameObjects.GameObject) => void)
|
||||
| ((sprite: Phaser.GameObjects.GameObject) => void) = globalScene.field.bringToTop;
|
||||
|
||||
if (priority === 0) { // Place the sprite in front of the pokemon on the field.
|
||||
targetSprite = globalScene.getEnemyField().find(p => p) ?? globalScene.getPlayerField().find(p => p);
|
||||
console.log(typeof targetSprite);
|
||||
moveFunc = globalScene.field.moveBelow;
|
||||
} else if (priority === 2 && this.bgSprite) {
|
||||
moveFunc = globalScene.field.moveAbove;
|
||||
targetSprite = this.bgSprite;
|
||||
} else if (priority === 2 || priority === 3) {
|
||||
moveFunc = priority === 2 ? globalScene.field.moveBelow : globalScene.field.moveAbove;
|
||||
if (frame.focus === AnimFocus.USER) {
|
||||
targetSprite = this.user;
|
||||
} else if (frame.focus === AnimFocus.TARGET) {
|
||||
targetSprite = this.target;
|
||||
}
|
||||
if (priority === 0) {
|
||||
// Place the sprite in front of the pokemon on the field.
|
||||
targetSprite = globalScene.getEnemyField().find(p => p) ?? globalScene.getPlayerField().find(p => p);
|
||||
console.log(typeof targetSprite);
|
||||
moveFunc = globalScene.field.moveBelow;
|
||||
} else if (priority === 2 && this.bgSprite) {
|
||||
moveFunc = globalScene.field.moveAbove;
|
||||
targetSprite = this.bgSprite;
|
||||
} else if (priority === 2 || priority === 3) {
|
||||
moveFunc = priority === 2 ? globalScene.field.moveBelow : globalScene.field.moveAbove;
|
||||
if (frame.focus === AnimFocus.USER) {
|
||||
targetSprite = this.user;
|
||||
} else if (frame.focus === AnimFocus.TARGET) {
|
||||
targetSprite = this.target;
|
||||
}
|
||||
// If target sprite is not undefined and exists in the field container, then move the sprite using the moveFunc.
|
||||
// Otherwise, default to just bringing it to the top.
|
||||
targetSprite && globalScene.field.exists(targetSprite) ? moveFunc.bind(globalScene.field)(moveSprite as Phaser.GameObjects.GameObject, targetSprite) : globalScene.field.bringToTop(moveSprite as Phaser.GameObjects.GameObject);
|
||||
};
|
||||
setSpritePriority(frame.priority);
|
||||
}
|
||||
moveSprite.setFrame(frame.graphicFrame);
|
||||
//console.log(AnimFocus[frame.focus]);
|
||||
}
|
||||
// If target sprite is not undefined and exists in the field container, then move the sprite using the moveFunc.
|
||||
// Otherwise, default to just bringing it to the top.
|
||||
targetSprite && globalScene.field.exists(targetSprite)
|
||||
? moveFunc.bind(globalScene.field)(moveSprite as Phaser.GameObjects.GameObject, targetSprite)
|
||||
: globalScene.field.bringToTop(moveSprite as Phaser.GameObjects.GameObject);
|
||||
};
|
||||
setSpritePriority(frame.priority);
|
||||
}
|
||||
moveSprite.setFrame(frame.graphicFrame);
|
||||
//console.log(AnimFocus[frame.focus]);
|
||||
|
||||
const graphicFrameData = frameData.get(frame.target)!.get(graphicIndex)!; // TODO: are those bangs correct?
|
||||
moveSprite.setPosition(graphicFrameData.x, graphicFrameData.y);
|
||||
moveSprite.setAngle(graphicFrameData.angle);
|
||||
moveSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
|
||||
|
||||
moveSprite.setAlpha(frame.opacity / 255);
|
||||
moveSprite.setVisible(frame.visible);
|
||||
moveSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
|
||||
}
|
||||
moveSprite.setAlpha(frame.opacity / 255);
|
||||
moveSprite.setVisible(frame.visible);
|
||||
moveSprite.setBlendMode(
|
||||
frame.blendType === AnimBlendType.NORMAL
|
||||
? Phaser.BlendModes.NORMAL
|
||||
: frame.blendType === AnimBlendType.ADD
|
||||
? Phaser.BlendModes.ADD
|
||||
: Phaser.BlendModes.DIFFERENCE,
|
||||
);
|
||||
}
|
||||
if (anim?.frameTimedEvents.has(f)) {
|
||||
const base = anim.frames.length - f;
|
||||
// Bang is correct due to `has` check above, which cannot return true for an undefined / null `f`
|
||||
for (const event of anim.frameTimedEvents.get(f)!) {
|
||||
r = Math.max(base + event.execute(this), r);
|
||||
}
|
||||
}
|
||||
if (anim?.frameTimedEvents.has(f)) {
|
||||
const base = anim.frames.length - f;
|
||||
// Bang is correct due to `has` check above, which cannot return true for an undefined / null `f`
|
||||
for (const event of anim.frameTimedEvents.get(f)!) {
|
||||
r = Math.max(base + event.execute(this), r);
|
||||
}
|
||||
const targets = getEnumValues(AnimFrameTarget);
|
||||
for (const i of targets) {
|
||||
const count = i === AnimFrameTarget.GRAPHIC ? g : i === AnimFrameTarget.USER ? u : t;
|
||||
if (count < spriteCache[i].length) {
|
||||
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
|
||||
for (const rs of spritesToRemove) {
|
||||
if (!rs.getData("locked") as boolean) {
|
||||
const spriteCacheIndex = spriteCache[i].indexOf(rs);
|
||||
spriteCache[i].splice(spriteCacheIndex, 1);
|
||||
if (i === AnimFrameTarget.GRAPHIC) {
|
||||
spritePriorities.splice(spriteCacheIndex, 1);
|
||||
}
|
||||
rs.destroy();
|
||||
}
|
||||
const targets = getEnumValues(AnimFrameTarget);
|
||||
for (const i of targets) {
|
||||
const count = i === AnimFrameTarget.GRAPHIC ? g : i === AnimFrameTarget.USER ? u : t;
|
||||
if (count < spriteCache[i].length) {
|
||||
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
|
||||
for (const rs of spritesToRemove) {
|
||||
if (!rs.getData("locked") as boolean) {
|
||||
const spriteCacheIndex = spriteCache[i].indexOf(rs);
|
||||
spriteCache[i].splice(spriteCacheIndex, 1);
|
||||
if (i === AnimFrameTarget.GRAPHIC) {
|
||||
spritePriorities.splice(spriteCacheIndex, 1);
|
||||
}
|
||||
rs.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
f++;
|
||||
r--;
|
||||
},
|
||||
onComplete: () => {
|
||||
for (const ms of Object.values(spriteCache).flat()) {
|
||||
if (ms && !ms.getData("locked")) {
|
||||
ms.destroy();
|
||||
}
|
||||
}
|
||||
if (r) {
|
||||
globalScene.tweens.addCounter({
|
||||
duration: getFrameMs(r),
|
||||
onComplete: () => cleanUpAndComplete()
|
||||
});
|
||||
} else {
|
||||
cleanUpAndComplete();
|
||||
}
|
||||
f++;
|
||||
r--;
|
||||
},
|
||||
onComplete: () => {
|
||||
for (const ms of Object.values(spriteCache).flat()) {
|
||||
if (ms && !ms.getData("locked")) {
|
||||
ms.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (r) {
|
||||
globalScene.tweens.addCounter({
|
||||
duration: getFrameMs(r),
|
||||
onComplete: () => cleanUpAndComplete(),
|
||||
});
|
||||
} else {
|
||||
cleanUpAndComplete();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private getGraphicFrameDataWithoutTarget(
|
||||
frames: AnimFrame[],
|
||||
@ -1356,51 +1354,57 @@ export abstract class BattleAnim {
|
||||
moveSprite.setAngle(graphicFrameData.angle);
|
||||
moveSprite.setScale(graphicFrameData.scaleX, graphicFrameData.scaleY);
|
||||
|
||||
moveSprite.setAlpha(frame.opacity / 255);
|
||||
moveSprite.setVisible(frame.visible);
|
||||
moveSprite.setBlendMode(frame.blendType === AnimBlendType.NORMAL ? Phaser.BlendModes.NORMAL : frame.blendType === AnimBlendType.ADD ? Phaser.BlendModes.ADD : Phaser.BlendModes.DIFFERENCE);
|
||||
}
|
||||
moveSprite.setAlpha(frame.opacity / 255);
|
||||
moveSprite.setVisible(frame.visible);
|
||||
moveSprite.setBlendMode(
|
||||
frame.blendType === AnimBlendType.NORMAL
|
||||
? Phaser.BlendModes.NORMAL
|
||||
: frame.blendType === AnimBlendType.ADD
|
||||
? Phaser.BlendModes.ADD
|
||||
: Phaser.BlendModes.DIFFERENCE,
|
||||
);
|
||||
}
|
||||
if (anim?.frameTimedEvents.get(frameCount)) {
|
||||
const base = anim.frames.length - frameCount;
|
||||
for (const event of anim.frameTimedEvents.get(frameCount)!) {
|
||||
totalFrames = Math.max(base + event.execute(this, frameTimedEventPriority), totalFrames);
|
||||
}
|
||||
}
|
||||
if (anim?.frameTimedEvents.get(frameCount)) {
|
||||
const base = anim.frames.length - frameCount;
|
||||
for (const event of anim.frameTimedEvents.get(frameCount)!) {
|
||||
totalFrames = Math.max(base + event.execute(this, frameTimedEventPriority), totalFrames);
|
||||
}
|
||||
const targets = getEnumValues(AnimFrameTarget);
|
||||
for (const i of targets) {
|
||||
const count = graphicFrameCount;
|
||||
if (count < spriteCache[i].length) {
|
||||
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
|
||||
for (const sprite of spritesToRemove) {
|
||||
if (!sprite.getData("locked") as boolean) {
|
||||
const spriteCacheIndex = spriteCache[i].indexOf(sprite);
|
||||
spriteCache[i].splice(spriteCacheIndex, 1);
|
||||
sprite.destroy();
|
||||
}
|
||||
}
|
||||
const targets = getEnumValues(AnimFrameTarget);
|
||||
for (const i of targets) {
|
||||
const count = graphicFrameCount;
|
||||
if (count < spriteCache[i].length) {
|
||||
const spritesToRemove = spriteCache[i].slice(count, spriteCache[i].length);
|
||||
for (const sprite of spritesToRemove) {
|
||||
if (!sprite.getData("locked") as boolean) {
|
||||
const spriteCacheIndex = spriteCache[i].indexOf(sprite);
|
||||
spriteCache[i].splice(spriteCacheIndex, 1);
|
||||
sprite.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
frameCount++;
|
||||
totalFrames--;
|
||||
},
|
||||
onComplete: () => {
|
||||
for (const sprite of Object.values(spriteCache).flat()) {
|
||||
if (sprite && !sprite.getData("locked")) {
|
||||
sprite.destroy();
|
||||
}
|
||||
}
|
||||
if (totalFrames) {
|
||||
globalScene.tweens.addCounter({
|
||||
duration: getFrameMs(totalFrames),
|
||||
onComplete: () => cleanUpAndComplete()
|
||||
});
|
||||
} else {
|
||||
cleanUpAndComplete();
|
||||
}
|
||||
frameCount++;
|
||||
totalFrames--;
|
||||
},
|
||||
onComplete: () => {
|
||||
for (const sprite of Object.values(spriteCache).flat()) {
|
||||
if (sprite && !sprite.getData("locked")) {
|
||||
sprite.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (totalFrames) {
|
||||
globalScene.tweens.addCounter({
|
||||
duration: getFrameMs(totalFrames),
|
||||
onComplete: () => cleanUpAndComplete(),
|
||||
});
|
||||
} else {
|
||||
cleanUpAndComplete();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class CommonBattleAnim extends BattleAnim {
|
||||
|
@ -2125,7 +2125,13 @@ export class TypeBoostTag extends BattlerTag {
|
||||
public boostValue: number;
|
||||
public oneUse: boolean;
|
||||
|
||||
constructor(tagType: BattlerTagType, sourceMove: Moves, boostedType: PokemonType, boostValue: number, oneUse: boolean) {
|
||||
constructor(
|
||||
tagType: BattlerTagType,
|
||||
sourceMove: Moves,
|
||||
boostedType: PokemonType,
|
||||
boostValue: number,
|
||||
oneUse: boolean,
|
||||
) {
|
||||
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
||||
|
||||
this.boostedType = boostedType;
|
||||
@ -2334,8 +2340,10 @@ export class RoostedTag extends BattlerTag {
|
||||
const currentTypes = pokemon.getTypes();
|
||||
const baseTypes = pokemon.getTypes(false, false, true);
|
||||
|
||||
const forestsCurseApplied: boolean = currentTypes.includes(PokemonType.GRASS) && !baseTypes.includes(PokemonType.GRASS);
|
||||
const trickOrTreatApplied: boolean = currentTypes.includes(PokemonType.GHOST) && !baseTypes.includes(PokemonType.GHOST);
|
||||
const forestsCurseApplied: boolean =
|
||||
currentTypes.includes(PokemonType.GRASS) && !baseTypes.includes(PokemonType.GRASS);
|
||||
const trickOrTreatApplied: boolean =
|
||||
currentTypes.includes(PokemonType.GHOST) && !baseTypes.includes(PokemonType.GHOST);
|
||||
|
||||
if (this.isBaseFlying) {
|
||||
let modifiedTypes: PokemonType[] = [];
|
||||
|
@ -735,7 +735,9 @@ interface monotypeOverride {
|
||||
* Implements a mono type challenge.
|
||||
*/
|
||||
export class SingleTypeChallenge extends Challenge {
|
||||
private static TYPE_OVERRIDES: monotypeOverride[] = [{ species: Species.CASTFORM, type: PokemonType.NORMAL, fusion: false }];
|
||||
private static TYPE_OVERRIDES: monotypeOverride[] = [
|
||||
{ species: Species.CASTFORM, type: PokemonType.NORMAL, fusion: false },
|
||||
];
|
||||
// TODO: Find a solution for all Pokemon with this ssui issue, including Basculin and Burmy
|
||||
private static SPECIES_OVERRIDES: Species[] = [Species.MELOETTA];
|
||||
|
||||
|
@ -969,7 +969,12 @@ export class AttackTypeBoosterHeldItemTypeRequirement extends EncounterPokemonRe
|
||||
invertQuery: boolean;
|
||||
requireTransferable: boolean;
|
||||
|
||||
constructor(heldItemTypes: PokemonType | PokemonType[], minNumberOfPokemon = 1, invertQuery = false, requireTransferable = true) {
|
||||
constructor(
|
||||
heldItemTypes: PokemonType | PokemonType[],
|
||||
minNumberOfPokemon = 1,
|
||||
invertQuery = false,
|
||||
requireTransferable = true,
|
||||
) {
|
||||
super();
|
||||
this.minNumberOfPokemon = minNumberOfPokemon;
|
||||
this.invertQuery = invertQuery;
|
||||
|
@ -210,8 +210,8 @@ export async function initBattleWithEnemyConfig(partyConfig: EnemyPartyConfig):
|
||||
battle.enemyLevels = battle.enemyLevels.map(level => level + additive);
|
||||
|
||||
battle.enemyLevels.forEach((level, e) => {
|
||||
let enemySpecies;
|
||||
let dataSource;
|
||||
let enemySpecies: PokemonSpecies | undefined;
|
||||
let dataSource: PokemonData | undefined;
|
||||
let isBoss = false;
|
||||
if (!loaded) {
|
||||
if ((!isNullOrUndefined(trainerType) || trainerConfig) && battle.trainer) {
|
||||
@ -991,7 +991,7 @@ export function handleMysteryEncounterBattleStartEffects() {
|
||||
) {
|
||||
const effects = encounter.startOfBattleEffects;
|
||||
effects.forEach(effect => {
|
||||
let source;
|
||||
let source: EnemyPokemon | Pokemon;
|
||||
if (effect.sourcePokemon) {
|
||||
source = effect.sourcePokemon;
|
||||
} else if (!isNullOrUndefined(effect.sourceBattlerIndex)) {
|
||||
@ -1009,6 +1009,7 @@ export function handleMysteryEncounterBattleStartEffects() {
|
||||
} else {
|
||||
source = globalScene.getEnemyField()[0];
|
||||
}
|
||||
// @ts-ignore: source cannot be undefined
|
||||
globalScene.pushPhase(new MovePhase(source, effect.targets, effect.move, effect.followUp, effect.ignorePp));
|
||||
});
|
||||
|
||||
@ -1045,7 +1046,7 @@ export function getRandomEncounterSpecies(level: number, isBoss = false, rerollH
|
||||
let bossSpecies: PokemonSpecies;
|
||||
let isEventEncounter = false;
|
||||
const eventEncounters = globalScene.eventManager.getEventEncounters();
|
||||
let formIndex;
|
||||
let formIndex: number | undefined;
|
||||
|
||||
if (eventEncounters.length > 0 && randSeedInt(2) === 1) {
|
||||
const eventEncounter = randSeedItem(eventEncounters);
|
||||
|
@ -60,15 +60,15 @@ export class TrainerPartyTemplate {
|
||||
this.balanced = !!balanced;
|
||||
}
|
||||
|
||||
getStrength(index: number): PartyMemberStrength {
|
||||
getStrength(_index: number): PartyMemberStrength {
|
||||
return this.strength;
|
||||
}
|
||||
|
||||
isSameSpecies(index: number): boolean {
|
||||
isSameSpecies(_index: number): boolean {
|
||||
return this.sameSpecies;
|
||||
}
|
||||
|
||||
isBalanced(index: number): boolean {
|
||||
isBalanced(_index: number): boolean {
|
||||
return this.balanced;
|
||||
}
|
||||
}
|
||||
@ -1230,10 +1230,10 @@ export class TrainerConfig {
|
||||
|
||||
/**
|
||||
* Initializes the trainer configuration for a Stat Trainer, as part of the Trainer's Test Mystery Encounter.
|
||||
* @param isMale Whether the stat trainer is Male or Female (for localization of the title).
|
||||
* @param _isMale Whether the stat trainer is Male or Female (for localization of the title).
|
||||
* @returns {TrainerConfig} The updated TrainerConfig instance.
|
||||
**/
|
||||
initForStatTrainer(isMale = false): TrainerConfig {
|
||||
initForStatTrainer(_isMale = false): TrainerConfig {
|
||||
if (!getIsInitialized()) {
|
||||
initI18n();
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ import {
|
||||
getTerrainStartMessage,
|
||||
getWeatherClearMessage,
|
||||
getWeatherStartMessage,
|
||||
getLegendaryWeatherContinuesMessage, Weather,
|
||||
getLegendaryWeatherContinuesMessage,
|
||||
Weather,
|
||||
} from "#app/data/weather";
|
||||
import { CommonAnim } from "#app/data/battle-anims";
|
||||
import type { PokemonType } from "#enums/pokemon-type";
|
||||
@ -319,8 +320,13 @@ export class Arena {
|
||||
|
||||
const oldWeatherType = this.weather?.weatherType || WeatherType.NONE;
|
||||
|
||||
if (this.weather?.isImmutable() && ![ WeatherType.HARSH_SUN, WeatherType.HEAVY_RAIN, WeatherType.STRONG_WINDS, WeatherType.NONE ].includes(weather)) {
|
||||
globalScene.unshiftPhase(new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (oldWeatherType - 1), true));
|
||||
if (
|
||||
this.weather?.isImmutable() &&
|
||||
![WeatherType.HARSH_SUN, WeatherType.HEAVY_RAIN, WeatherType.STRONG_WINDS, WeatherType.NONE].includes(weather)
|
||||
) {
|
||||
globalScene.unshiftPhase(
|
||||
new CommonAnimPhase(undefined, undefined, CommonAnim.SUNNY + (oldWeatherType - 1), true),
|
||||
);
|
||||
globalScene.queueMessage(getLegendaryWeatherContinuesMessage(oldWeatherType)!);
|
||||
return false;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import TransitionImagePackPlugin from "phaser3-rex-plugins/templates/transitioni
|
||||
import { initI18n } from "./plugins/i18n";
|
||||
|
||||
// Catch global errors and display them in an alert so users can report the issue.
|
||||
window.onerror = (message, source, lineno, colno, error) => {
|
||||
window.onerror = (_message, _source, _lineno, _colno, error) => {
|
||||
console.error(error);
|
||||
// const errorString = `Received unhandled error. Open browser console and click OK to see details.\nError: ${message}\nSource: ${source}\nLine: ${lineno}\nColumn: ${colno}\nStack: ${error.stack}`;
|
||||
//alert(errorString);
|
||||
@ -40,7 +40,7 @@ Phaser.GameObjects.Text.prototype.setPositionRelative = setPositionRelative;
|
||||
Phaser.GameObjects.Rectangle.prototype.setPositionRelative = setPositionRelative;
|
||||
|
||||
document.fonts.load("16px emerald").then(() => document.fonts.load("10px pkmnems"));
|
||||
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let game;
|
||||
|
||||
const startGame = async (manifest?: any) => {
|
||||
|
@ -373,7 +373,7 @@ export class MovePhase extends BattlePhase {
|
||||
* TODO: is this sustainable?
|
||||
*/
|
||||
let failedDueToTerrain = false;
|
||||
let failedDueToWeather: boolean = false;
|
||||
let failedDueToWeather = false;
|
||||
if (success) {
|
||||
const passesConditions = move.applyConditions(this.pokemon, targets[0], move);
|
||||
failedDueToWeather = globalScene.arena.isMoveWeatherCancelled(this.pokemon, move);
|
||||
@ -517,7 +517,8 @@ export class MovePhase extends BattlePhase {
|
||||
// Handle interaction between the rage powder center-of-attention tag and moves used by grass types/overcoat-havers (which are immune to RP's redirect)
|
||||
if (
|
||||
redirectTag &&
|
||||
(!redirectTag.powder || (!this.pokemon.isOfType(PokemonType.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))
|
||||
(!redirectTag.powder ||
|
||||
(!this.pokemon.isOfType(PokemonType.GRASS) && !this.pokemon.hasAbility(Abilities.OVERCOAT)))
|
||||
) {
|
||||
redirectTarget.value = p.getBattlerIndex();
|
||||
redirectedByAbility = false;
|
||||
|
@ -221,10 +221,6 @@ export class MysteryEncounterOptionSelectedPhase extends Phase {
|
||||
* See {@linkcode TurnEndPhase} for more details
|
||||
*/
|
||||
export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up `TURN_END` tags, any {@linkcode PostTurnStatusEffectPhase}s, checks for Pokemon switches, then continues
|
||||
*/
|
||||
@ -250,7 +246,7 @@ export class MysteryEncounterBattleStartCleanupPhase extends Phase {
|
||||
});
|
||||
|
||||
// Remove any status tick phases
|
||||
while (!!globalScene.findPhase(p => p instanceof PostTurnStatusEffectPhase)) {
|
||||
while (globalScene.findPhase(p => p instanceof PostTurnStatusEffectPhase)) {
|
||||
globalScene.tryRemovePhase(p => p instanceof PostTurnStatusEffectPhase);
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ export class RevivalBlessingPhase extends BattlePhase {
|
||||
Mode.PARTY,
|
||||
PartyUiMode.REVIVAL_BLESSING,
|
||||
this.user.getFieldIndex(),
|
||||
(slotIndex: integer, option: PartyOption) => {
|
||||
(slotIndex: integer, _option: PartyOption) => {
|
||||
if (slotIndex >= 0 && slotIndex < 6) {
|
||||
const pokemon = globalScene.getPlayerParty()[slotIndex];
|
||||
if (!pokemon || !pokemon.isFainted()) {
|
||||
|
@ -51,7 +51,7 @@ export class SelectBiomePhase extends BattlePhase {
|
||||
? [biomeLinks[currentBiome] as Biome]
|
||||
: (biomeLinks[currentBiome] as (Biome | [Biome, number])[])
|
||||
)
|
||||
.filter((b, i) => !Array.isArray(b) || !Utils.randSeedInt(b[1]))
|
||||
.filter((b, _i) => !Array.isArray(b) || !Utils.randSeedInt(b[1]))
|
||||
.map(b => (Array.isArray(b) ? b[0] : b));
|
||||
}, globalScene.currentBattle.waveIndex);
|
||||
const biomeSelectItems = biomeChoices.map(b => {
|
||||
|
@ -74,7 +74,7 @@ export class SelectModifierPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
// If custom modifiers are specified, overrides default item count
|
||||
if (!!this.customModifierSettings) {
|
||||
if (this.customModifierSettings) {
|
||||
const newItemCount =
|
||||
(this.customModifierSettings.guaranteedModifierTiers?.length || 0) +
|
||||
(this.customModifierSettings.guaranteedModifierTypeOptions?.length || 0) +
|
||||
|
@ -185,7 +185,7 @@ export class StatStageChangePhase extends PokemonPhase {
|
||||
: Math.max(pokemon.getStatStage(s) + stages.value, -6)) - pokemon.getStatStage(s),
|
||||
);
|
||||
|
||||
this.onChange && this.onChange(this.getPokemon(), filteredStats, relLevels);
|
||||
this.onChange?.(this.getPokemon(), filteredStats, relLevels);
|
||||
|
||||
const end = () => {
|
||||
if (this.showMessage) {
|
||||
|
@ -221,7 +221,7 @@ export class TurnStartPhase extends FieldPhase {
|
||||
let runningPokemon = pokemon;
|
||||
if (globalScene.currentBattle.double) {
|
||||
const playerActivePokemon = field.filter(pokemon => {
|
||||
if (!!pokemon) {
|
||||
if (pokemon) {
|
||||
return pokemon.isPlayer() && pokemon.isActive();
|
||||
}
|
||||
return;
|
||||
|
@ -265,31 +265,30 @@ export interface StarterPreferences {
|
||||
const StarterPrefers_DEFAULT: string = "{}";
|
||||
let StarterPrefers_private_latest: string = StarterPrefers_DEFAULT;
|
||||
|
||||
// called on starter selection show once
|
||||
export function loadStarterPreferences(): StarterPreferences {
|
||||
return JSON.parse(
|
||||
(StarterPrefers_private_latest =
|
||||
localStorage.getItem(`starterPrefs_${loggedInUser?.username}`) || StarterPrefers_DEFAULT),
|
||||
);
|
||||
}
|
||||
|
||||
// called on starter selection clear, always
|
||||
export function saveStarterPreferences(prefs: StarterPreferences): void {
|
||||
const pStr: string = JSON.stringify(prefs);
|
||||
if (pStr !== StarterPrefers_private_latest) {
|
||||
// something changed, store the update
|
||||
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
||||
// update the latest prefs
|
||||
StarterPrefers_private_latest = pStr;
|
||||
}
|
||||
}
|
||||
// This is its own class as StarterPreferences...
|
||||
// - don't need to be loaded on startup
|
||||
// - isn't stored with other data
|
||||
// - don't require to be encrypted
|
||||
// - shouldn't require calls outside of the starter selection
|
||||
export class StarterPrefs {
|
||||
// called on starter selection show once
|
||||
static load(): StarterPreferences {
|
||||
return JSON.parse(
|
||||
(StarterPrefers_private_latest =
|
||||
localStorage.getItem(`starterPrefs_${loggedInUser?.username}`) || StarterPrefers_DEFAULT),
|
||||
);
|
||||
}
|
||||
|
||||
// called on starter selection clear, always
|
||||
static save(prefs: StarterPreferences): void {
|
||||
const pStr: string = JSON.stringify(prefs);
|
||||
if (pStr !== StarterPrefers_private_latest) {
|
||||
// something changed, store the update
|
||||
localStorage.setItem(`starterPrefs_${loggedInUser?.username}`, pStr);
|
||||
// update the latest prefs
|
||||
StarterPrefers_private_latest = pStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
export class StarterPrefs {}
|
||||
|
||||
export interface StarterDataEntry {
|
||||
moveset: StarterMoveset | StarterFormMoveData | null;
|
||||
@ -424,7 +423,7 @@ export class GameData {
|
||||
const data = this.getSystemSaveData();
|
||||
|
||||
const maxIntAttrValue = 0x80000000;
|
||||
const systemData = JSON.stringify(data, (k: any, v: any) =>
|
||||
const systemData = JSON.stringify(data, (_k: any, v: any) =>
|
||||
typeof v === "bigint" ? (v <= maxIntAttrValue ? Number(v) : v.toString()) : v,
|
||||
);
|
||||
|
||||
@ -1319,7 +1318,7 @@ export class GameData {
|
||||
}
|
||||
localStorage.removeItem(`sessionData${slotId ? slotId : ""}_${loggedInUser?.username}`);
|
||||
} else {
|
||||
if (jsonResponse && jsonResponse.error?.startsWith("session out of date")) {
|
||||
if (jsonResponse?.error?.startsWith("session out of date")) {
|
||||
globalScene.clearPhaseQueue();
|
||||
globalScene.unshiftPhase(new ReloadSessionPhase());
|
||||
}
|
||||
@ -1439,7 +1438,7 @@ export class GameData {
|
||||
localStorage.setItem(
|
||||
`data_${loggedInUser?.username}`,
|
||||
encrypt(
|
||||
JSON.stringify(systemData, (k: any, v: any) =>
|
||||
JSON.stringify(systemData, (_k: any, v: any) =>
|
||||
typeof v === "bigint" ? (v <= maxIntAttrValue ? Number(v) : v.toString()) : v,
|
||||
),
|
||||
bypassLogin,
|
||||
@ -1636,11 +1635,9 @@ export class GameData {
|
||||
`An error occurred while updating ${dataName} data. Please contact the administrator.`,
|
||||
);
|
||||
}
|
||||
window.location = window.location;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
window.location = window.location;
|
||||
}
|
||||
},
|
||||
() => {
|
||||
@ -2108,7 +2105,7 @@ export class GameData {
|
||||
return ret;
|
||||
}
|
||||
|
||||
getSpeciesDexAttrProps(species: PokemonSpecies, dexAttr: bigint): DexAttrProps {
|
||||
getSpeciesDexAttrProps(_species: PokemonSpecies, dexAttr: bigint): DexAttrProps {
|
||||
const shiny = !(dexAttr & DexAttr.NON_SHINY);
|
||||
const female = !(dexAttr & DexAttr.MALE);
|
||||
let variant: Variant = 0;
|
||||
|
@ -28,7 +28,7 @@ export default class ModifierData {
|
||||
this.className = sourceModifier ? sourceModifier.constructor.name : source.className;
|
||||
}
|
||||
|
||||
toModifier(constructor: any): PersistentModifier | null {
|
||||
toModifier(_constructor: any): PersistentModifier | null {
|
||||
const typeFunc = getModifierTypeFuncById(this.typeId);
|
||||
if (!typeFunc) {
|
||||
return null;
|
||||
@ -46,7 +46,7 @@ export default class ModifierData {
|
||||
}
|
||||
|
||||
const ret = Reflect.construct(
|
||||
constructor,
|
||||
_constructor,
|
||||
([type] as any[]).concat(this.args).concat(this.stackCount),
|
||||
) as PersistentModifier;
|
||||
|
||||
|
@ -14,7 +14,8 @@ export const systemMigrators = [
|
||||
Object.keys(data.starterData).forEach(sd => {
|
||||
const caughtAttr = data.dexData[sd]?.caughtAttr;
|
||||
const speciesNumber = Number(sd);
|
||||
if (!speciesNumber) { // An unknown bug at some point in time caused some accounts to have starter data for pokedex number 0 which crashes
|
||||
if (!speciesNumber) {
|
||||
// An unknown bug at some point in time caused some accounts to have starter data for pokedex number 0 which crashes
|
||||
return;
|
||||
}
|
||||
const species = getPokemonSpecies(speciesNumber);
|
||||
|
@ -31,10 +31,10 @@ export class Voucher {
|
||||
|
||||
/**
|
||||
* Get the name of the voucher
|
||||
* @param playerGender - this is ignored here. It's only there to match the signature of the function in the Achv class
|
||||
* @param _playerGender - this is ignored here. It's only there to match the signature of the function in the Achv class
|
||||
* @returns the name of the voucher
|
||||
*/
|
||||
getName(playerGender: PlayerGender): string {
|
||||
getName(_playerGender: PlayerGender): string {
|
||||
return getVoucherTypeName(this.voucherType);
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ export default class AchvBar extends Phaser.GameObjects.Container {
|
||||
this.shown = true;
|
||||
}
|
||||
|
||||
protected hide(playerGender: PlayerGender): void {
|
||||
protected hide(_playerGender: PlayerGender): void {
|
||||
if (!this.shown) {
|
||||
return;
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
globalScene.eventTarget.addEventListener(BattleSceneEventType.TURN_END, this.onTurnEndEvent);
|
||||
}
|
||||
|
||||
private onNewArena(event: Event) {
|
||||
private onNewArena(_event: Event) {
|
||||
this.fieldEffectInfo.length = 0;
|
||||
|
||||
// Subscribes to required events available on battle start
|
||||
@ -282,7 +282,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
|
||||
let foundIndex: number;
|
||||
switch (arenaEffectChangedEvent.constructor) {
|
||||
case TagAddedEvent:
|
||||
case TagAddedEvent: {
|
||||
const tagAddedEvent = arenaEffectChangedEvent as TagAddedEvent;
|
||||
const isArenaTrapTag = globalScene.arena.getTag(tagAddedEvent.arenaTagType) instanceof ArenaTrapTag;
|
||||
let arenaEffectType: ArenaEffectType;
|
||||
@ -321,7 +321,8 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
tagType: tagAddedEvent.arenaTagType,
|
||||
});
|
||||
break;
|
||||
case TagRemovedEvent:
|
||||
}
|
||||
case TagRemovedEvent: {
|
||||
const tagRemovedEvent = arenaEffectChangedEvent as TagRemovedEvent;
|
||||
foundIndex = this.fieldEffectInfo.findIndex(info => info.tagType === tagRemovedEvent.arenaTagType);
|
||||
|
||||
@ -330,9 +331,10 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
this.fieldEffectInfo.splice(foundIndex, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WeatherChangedEvent:
|
||||
case TerrainChangedEvent:
|
||||
case TerrainChangedEvent: {
|
||||
const fieldEffectChangedEvent = arenaEffectChangedEvent as WeatherChangedEvent | TerrainChangedEvent;
|
||||
|
||||
// Stores the old Weather/Terrain name in case it's in the array already
|
||||
@ -365,6 +367,7 @@ export class ArenaFlyout extends Phaser.GameObjects.Container {
|
||||
this.fieldEffectInfo[foundIndex] = newInfo; // Otherwise, replace the old info
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateFieldText();
|
||||
|
@ -107,12 +107,12 @@ export class BaseStatsOverlay extends Phaser.GameObjects.Container implements In
|
||||
}
|
||||
|
||||
// width of this element
|
||||
static getWidth(scale: number): number {
|
||||
static getWidth(_scale: number): number {
|
||||
return globalScene.game.canvas.width / GLOBAL_SCALE / 2;
|
||||
}
|
||||
|
||||
// height of this element
|
||||
static getHeight(scale: number, onSide?: boolean): number {
|
||||
static getHeight(scale: number, _onSide?: boolean): number {
|
||||
return HEIGHT * scale;
|
||||
}
|
||||
}
|
||||
|
@ -958,5 +958,5 @@ export class EnemyBattleInfo extends BattleInfo {
|
||||
super(140, -141, false);
|
||||
}
|
||||
|
||||
setMini(mini: boolean): void {} // Always mini
|
||||
setMini(_mini: boolean): void {} // Always mini
|
||||
}
|
||||
|
@ -197,7 +197,8 @@ export default class CommandUiHandler extends UiHandler {
|
||||
canTera(): boolean {
|
||||
const hasTeraMod = !!globalScene.getModifiers(TerastallizeAccessModifier).length;
|
||||
const activePokemon = globalScene.getField()[this.fieldIndex];
|
||||
const isBlockedForm = activePokemon.isMega() || activePokemon.isMax() || activePokemon.hasSpecies(Species.NECROZMA, "ultra");
|
||||
const isBlockedForm =
|
||||
activePokemon.isMega() || activePokemon.isMax() || activePokemon.hasSpecies(Species.NECROZMA, "ultra");
|
||||
const currentTeras = globalScene.arena.playerTerasUsed;
|
||||
const plannedTera =
|
||||
globalScene.currentBattle.preTurnCommands[0]?.command === Command.TERA && this.fieldIndex > 0 ? 1 : 0;
|
||||
|
@ -158,8 +158,8 @@ export default class LoginFormUiHandler extends FormModalUiHandler {
|
||||
const [usernameInput, passwordInput] = this.inputs;
|
||||
|
||||
pokerogueApi.account.login({ username: usernameInput.text, password: passwordInput.text }).then(error => {
|
||||
if (!error) {
|
||||
originalLoginAction && originalLoginAction();
|
||||
if (!error && originalLoginAction) {
|
||||
originalLoginAction();
|
||||
} else {
|
||||
onFail(error);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default abstract class MessageUiHandler extends AwaitableUiHandler {
|
||||
|
||||
showDialogue(
|
||||
text: string,
|
||||
name?: string,
|
||||
_name?: string,
|
||||
delay?: number | null,
|
||||
callback?: Function | null,
|
||||
callbackDelay?: number | null,
|
||||
|
@ -168,7 +168,7 @@ export abstract class ModalUiHandler extends UiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
processInput(_button: Button): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args.length !== 4 || !(args[1] instanceof Array) || !(args[2] instanceof Function)) {
|
||||
if (args.length !== 4 || !Array.isArray(args[1]) || !(args[2] instanceof Function)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ export default class MoveInfoOverlay extends Phaser.GameObjects.Container implem
|
||||
}
|
||||
|
||||
// width of this element
|
||||
static getWidth(scale: number): number {
|
||||
static getWidth(_scale: number): number {
|
||||
return globalScene.game.canvas.width / GLOBAL_SCALE / 2;
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
}
|
||||
} else {
|
||||
switch (this.optionsContainer.getAll()?.length) {
|
||||
// biome-ignore lint/suspicious/useDefaultSwitchClauseLast: Default shares logic with case 3 and it makes more sense for the statements to be ordered by the case value
|
||||
default:
|
||||
case 3:
|
||||
success = this.handleTwoOptionMoveInput(button);
|
||||
@ -376,6 +377,7 @@ export default class MysteryEncounterUiHandler extends UiHandler {
|
||||
|
||||
let optionText: BBCodeText;
|
||||
switch (this.encounterOptions.length) {
|
||||
// biome-ignore lint/suspicious/useDefaultSwitchClauseLast: default shares logic with case 2 and it makes more sense for the statements to be ordered by the case number
|
||||
default:
|
||||
case 2:
|
||||
optionText = addBBCodeTextObject(i % 2 === 0 ? 0 : 100, 8, "-", TextStyle.WINDOW, {
|
||||
|
@ -572,7 +572,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
shiny: pokemon.shiny,
|
||||
variant: pokemon.variant,
|
||||
form: pokemon.formIndex,
|
||||
female: pokemon.gender === Gender.FEMALE ? true : false,
|
||||
female: pokemon.gender === Gender.FEMALE,
|
||||
};
|
||||
ui.setOverlayMode(Mode.POKEDEX_PAGE, pokemon.species, pokemon.formIndex, attributes).then(() =>
|
||||
this.clearOptions(),
|
||||
@ -1301,7 +1301,7 @@ export default class PartyUiHandler extends MessageUiHandler {
|
||||
if (this.partyUiMode === PartyUiMode.RELEASE) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
selectCallback && selectCallback(this.cursor, PartyOption.RELEASE);
|
||||
selectCallback?.(this.cursor, PartyOption.RELEASE);
|
||||
}
|
||||
this.showText("", 0);
|
||||
},
|
||||
|
@ -168,12 +168,12 @@ export default class PokedexInfoOverlay extends Phaser.GameObjects.Container imp
|
||||
}
|
||||
|
||||
// width of this element
|
||||
static getWidth(scale: number): number {
|
||||
static getWidth(_scale: number): number {
|
||||
return globalScene.game.canvas.width / GLOBAL_SCALE / 2;
|
||||
}
|
||||
|
||||
// height of this element
|
||||
static getHeight(scale: number, onSide?: boolean): number {
|
||||
static getHeight(scale: number, _onSide?: boolean): number {
|
||||
return DESC_HEIGHT * scale;
|
||||
}
|
||||
}
|
||||
|
@ -763,7 +763,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
|
||||
this.tmMoves =
|
||||
speciesTmMoves[species.speciesId]
|
||||
?.filter(m => (Array.isArray(m) ? (m[0] === formKey ? true : false) : true))
|
||||
?.filter(m => (Array.isArray(m) ? m[0] === formKey : true))
|
||||
.map(m => (Array.isArray(m) ? m[1] : m))
|
||||
.sort((a, b) => (allMoves[a].name > allMoves[b].name ? 1 : -1)) ?? [];
|
||||
|
||||
@ -1539,7 +1539,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
});
|
||||
this.evolutions.map(evo => {
|
||||
const evoSpecies = allSpecies.find(species => species.speciesId === evo.speciesId);
|
||||
const isCaughtEvo = this.isCaught(evoSpecies) ? true : false;
|
||||
const isCaughtEvo = !!this.isCaught(evoSpecies);
|
||||
// Attempts to find the formIndex of the evolved species
|
||||
const newFormKey = evo.evoFormKey
|
||||
? evo.evoFormKey
|
||||
@ -1664,7 +1664,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
const natures = globalScene.gameData.getNaturesForAttr(this.speciesStarterDexEntry?.natureAttr);
|
||||
ui.setModeWithoutClear(Mode.OPTION_SELECT, {
|
||||
options: natures
|
||||
.map((n: Nature, i: number) => {
|
||||
.map((n: Nature, _i: number) => {
|
||||
const option: OptionSelectItem = {
|
||||
label: getNatureName(n, true, true, true, globalScene.uiTheme),
|
||||
handler: () => {
|
||||
@ -2029,6 +2029,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
updateButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let iconPath;
|
||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||
@ -2074,6 +2075,8 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.hideInstructions();
|
||||
this.instructionsContainer.removeAll();
|
||||
this.filterInstructionsContainer.removeAll();
|
||||
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let gamepadType;
|
||||
if (globalScene.inputMethod === "gamepad") {
|
||||
gamepadType = globalScene.inputController.getConfig(
|
||||
@ -2166,7 +2169,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
return ret;
|
||||
}
|
||||
|
||||
getFriendship(speciesId: number) {
|
||||
getFriendship(_speciesId: number) {
|
||||
let currentFriendship = globalScene.gameData.starterData[this.starterId].friendship;
|
||||
if (!currentFriendship || currentFriendship === undefined) {
|
||||
currentFriendship = 0;
|
||||
@ -2399,7 +2402,7 @@ export default class PokedexPageUiHandler extends MessageUiHandler {
|
||||
this.assetLoadCancelled = assetLoadCancelled;
|
||||
|
||||
if (shouldUpdateSprite) {
|
||||
const back = this.showBackSprite ? true : false;
|
||||
const back = !!this.showBackSprite;
|
||||
species.loadAssets(female!, formIndex, shiny, variant as Variant, true, back).then(() => {
|
||||
// TODO: is this bang correct?
|
||||
if (assetLoadCancelled.value) {
|
||||
|
@ -20,10 +20,6 @@ export default class PokedexScanUiHandler extends FormModalUiHandler {
|
||||
abilityKeys: string[];
|
||||
row: number;
|
||||
|
||||
constructor(mode) {
|
||||
super(mode);
|
||||
}
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
|
||||
@ -32,19 +28,19 @@ export default class PokedexScanUiHandler extends FormModalUiHandler {
|
||||
this.abilityKeys = allAbilities.map(a => a.name);
|
||||
}
|
||||
|
||||
getModalTitle(config?: ModalConfig): string {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return i18next.t("pokedexUiHandler:scanChooseOption");
|
||||
}
|
||||
|
||||
getWidth(config?: ModalConfig): number {
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 300;
|
||||
}
|
||||
|
||||
getMargin(config?: ModalConfig): [number, number, number, number] {
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
getButtonLabels(config?: ModalConfig): string[] {
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return [i18next.t("pokedexUiHandler:scanSelect"), i18next.t("pokedexUiHandler:scanCancel")];
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import { getStarterValueFriendshipCap, speciesStarterCosts, POKERUS_STARTER_COUN
|
||||
import { catchableSpecies } from "#app/data/balance/biomes";
|
||||
import { PokemonType } from "#enums/pokemon-type";
|
||||
import type { DexAttrProps, DexEntry, StarterAttributes, StarterPreferences } from "#app/system/game-data";
|
||||
import { AbilityAttr, DexAttr, StarterPrefs } from "#app/system/game-data";
|
||||
import { AbilityAttr, DexAttr, loadStarterPreferences, saveStarterPreferences } from "#app/system/game-data";
|
||||
import MessageUiHandler from "#app/ui/message-ui-handler";
|
||||
import PokemonIconAnimHandler, { PokemonIconAnimMode } from "#app/ui/pokemon-icon-anim-handler";
|
||||
import { TextStyle, addTextObject } from "#app/ui/text";
|
||||
@ -612,7 +612,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (!this.starterPreferences) {
|
||||
this.starterPreferences = StarterPrefs.load();
|
||||
this.starterPreferences = loadStarterPreferences();
|
||||
}
|
||||
|
||||
this.pokerusSpecies = getPokerusStarters();
|
||||
@ -675,11 +675,12 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
||||
if (starterAttributes.shiny && !hasShiny) {
|
||||
// shiny form wasn't unlocked, purging shiny and variant setting
|
||||
delete starterAttributes.shiny;
|
||||
delete starterAttributes.variant;
|
||||
|
||||
starterAttributes.shiny = undefined;
|
||||
starterAttributes.variant = undefined;
|
||||
} else if (starterAttributes.shiny === false && !hasNonShiny) {
|
||||
// non shiny form wasn't unlocked, purging shiny setting
|
||||
delete starterAttributes.shiny;
|
||||
starterAttributes.shiny = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.variant !== undefined) {
|
||||
@ -694,14 +695,14 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
!unlockedVariants[starterAttributes.variant]
|
||||
) {
|
||||
// variant value is invalid or requested variant wasn't unlocked, purging setting
|
||||
delete starterAttributes.variant;
|
||||
starterAttributes.variant = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (starterAttributes.female !== undefined) {
|
||||
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
delete starterAttributes.female;
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,7 +721,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
];
|
||||
if (!unlockedAbilities[starterAttributes.ability]) {
|
||||
// requested ability wasn't unlocked, purging setting
|
||||
delete starterAttributes.ability;
|
||||
starterAttributes.ability = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,14 +732,14 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
!(caughtAttr & globalScene.gameData.getFormAttr(selectedForm)))
|
||||
) {
|
||||
// requested form wasn't unlocked/isn't a starter form, purging setting
|
||||
delete starterAttributes.form;
|
||||
starterAttributes.form = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.nature !== undefined) {
|
||||
const unlockedNatures = globalScene.gameData.getNaturesForAttr(dexEntry.natureAttr);
|
||||
if (unlockedNatures.indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
||||
// requested nature wasn't unlocked, purging setting
|
||||
delete starterAttributes.nature;
|
||||
starterAttributes.nature = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1236,12 +1237,13 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
case Button.CYCLE_FORM:
|
||||
case Button.CYCLE_FORM: {
|
||||
const species = this.pokemonContainers[this.cursor].species;
|
||||
if (this.canShowFormTray) {
|
||||
success = this.openFormTray(species);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1256,6 +1258,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
updateButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let iconPath;
|
||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||
@ -1283,6 +1286,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
}
|
||||
|
||||
updateFilterButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let iconPath;
|
||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||
@ -1461,8 +1465,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
if (biomes.length === 0) {
|
||||
biomes.push("Uncatchable");
|
||||
}
|
||||
const showNoBiome =
|
||||
biomes.length === 0 && this.filterBar.getVals(DropDownColumn.BIOME).length === 36 ? true : false;
|
||||
const showNoBiome = !!(biomes.length === 0 && this.filterBar.getVals(DropDownColumn.BIOME).length === 36);
|
||||
const fitsBiome =
|
||||
this.filterBar.getVals(DropDownColumn.BIOME).some(item => biomes.includes(indexToBiome.get(item) ?? "")) ||
|
||||
showNoBiome;
|
||||
@ -1650,19 +1653,18 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
const sort = this.filterBar.getVals(DropDownColumn.SORT)[0];
|
||||
this.filteredPokemonData.sort((a, b) => {
|
||||
switch (sort.val) {
|
||||
default:
|
||||
break;
|
||||
case SortCriteria.NUMBER:
|
||||
return (a.species.speciesId - b.species.speciesId) * -sort.dir;
|
||||
case SortCriteria.COST:
|
||||
return (a.cost - b.cost) * -sort.dir;
|
||||
case SortCriteria.CANDY:
|
||||
case SortCriteria.CANDY: {
|
||||
const candyCountA =
|
||||
globalScene.gameData.starterData[this.getStarterSpeciesId(a.species.speciesId)].candyCount;
|
||||
const candyCountB =
|
||||
globalScene.gameData.starterData[this.getStarterSpeciesId(b.species.speciesId)].candyCount;
|
||||
return (candyCountA - candyCountB) * -sort.dir;
|
||||
case SortCriteria.IV:
|
||||
}
|
||||
case SortCriteria.IV: {
|
||||
const avgIVsA =
|
||||
globalScene.gameData.dexData[a.species.speciesId].ivs.reduce((a, b) => a + b, 0) /
|
||||
globalScene.gameData.dexData[a.species.speciesId].ivs.length;
|
||||
@ -1670,6 +1672,7 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
globalScene.gameData.dexData[b.species.speciesId].ivs.reduce((a, b) => a + b, 0) /
|
||||
globalScene.gameData.dexData[b.species.speciesId].ivs.length;
|
||||
return (avgIVsA - avgIVsB) * -sort.dir;
|
||||
}
|
||||
case SortCriteria.NAME:
|
||||
return a.species.name.localeCompare(b.species.name) * -sort.dir;
|
||||
case SortCriteria.CAUGHT:
|
||||
@ -1684,6 +1687,8 @@ export default class PokedexUiHandler extends MessageUiHandler {
|
||||
globalScene.gameData.dexData[this.getStarterSpeciesId(b.species.speciesId)].hatchedCount) *
|
||||
-sort.dir
|
||||
);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
@ -169,7 +169,9 @@ export default class PokemonHatchInfoContainer extends PokemonInfoContainer {
|
||||
for (let em = 0; em < 4; em++) {
|
||||
const eggMove = hasEggMoves ? allMoves[speciesEggMoves[species.speciesId][em]] : null;
|
||||
const eggMoveUnlocked = eggMove && globalScene.gameData.starterData[species.speciesId].eggMoves & Math.pow(2, em);
|
||||
this.pokemonEggMoveBgs[em].setFrame(PokemonType[eggMove ? eggMove.type : PokemonType.UNKNOWN].toString().toLowerCase());
|
||||
this.pokemonEggMoveBgs[em].setFrame(
|
||||
PokemonType[eggMove ? eggMove.type : PokemonType.UNKNOWN].toString().toLowerCase(),
|
||||
);
|
||||
|
||||
this.pokemonEggMoveLabels[em].setText(eggMove && eggMoveUnlocked ? eggMove.name : "???");
|
||||
if (!(eggMove && hatchInfo.starterDataEntryBeforeUpdate.eggMoves & Math.pow(2, em)) && eggMoveUnlocked) {
|
||||
|
@ -21,15 +21,15 @@ const languageSettings: { [key: string]: LanguageSetting } = {
|
||||
};
|
||||
|
||||
export default class RegistrationFormUiHandler extends FormModalUiHandler {
|
||||
getModalTitle(config?: ModalConfig): string {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return i18next.t("menu:register");
|
||||
}
|
||||
|
||||
getWidth(config?: ModalConfig): number {
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 160;
|
||||
}
|
||||
|
||||
getMargin(config?: ModalConfig): [number, number, number, number] {
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler {
|
||||
return 8;
|
||||
}
|
||||
|
||||
getButtonLabels(config?: ModalConfig): string[] {
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return [i18next.t("menu:register"), i18next.t("menu:backToLogin")];
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler {
|
||||
})
|
||||
.then(loginError => {
|
||||
if (!loginError) {
|
||||
originalRegistrationAction && originalRegistrationAction();
|
||||
originalRegistrationAction?.();
|
||||
} else {
|
||||
onFail(loginError);
|
||||
}
|
||||
|
@ -5,19 +5,19 @@ import i18next from "i18next";
|
||||
import type { PlayerPokemon } from "#app/field/pokemon";
|
||||
|
||||
export default class RenameFormUiHandler extends FormModalUiHandler {
|
||||
getModalTitle(config?: ModalConfig): string {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return i18next.t("menu:renamePokemon");
|
||||
}
|
||||
|
||||
getWidth(config?: ModalConfig): number {
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 160;
|
||||
}
|
||||
|
||||
getMargin(config?: ModalConfig): [number, number, number, number] {
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
getButtonLabels(config?: ModalConfig): string[] {
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return [i18next.t("menu:rename"), i18next.t("menu:cancel")];
|
||||
}
|
||||
|
||||
|
@ -113,16 +113,16 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
switch (this.uiMode) {
|
||||
case SaveSlotUiMode.LOAD:
|
||||
this.saveSlotSelectCallback = null;
|
||||
originalCallback && originalCallback(cursor);
|
||||
originalCallback?.(cursor);
|
||||
break;
|
||||
case SaveSlotUiMode.SAVE:
|
||||
case SaveSlotUiMode.SAVE: {
|
||||
const saveAndCallback = () => {
|
||||
const originalCallback = this.saveSlotSelectCallback;
|
||||
this.saveSlotSelectCallback = null;
|
||||
ui.revertMode();
|
||||
ui.showText("", 0);
|
||||
ui.setMode(Mode.MESSAGE);
|
||||
originalCallback && originalCallback(cursor);
|
||||
originalCallback?.(cursor);
|
||||
};
|
||||
if (this.sessionSlots[cursor].hasData) {
|
||||
ui.showText(i18next.t("saveSlotSelectUiHandler:overwriteData"), null, () => {
|
||||
@ -153,12 +153,13 @@ export default class SaveSlotSelectUiHandler extends MessageUiHandler {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
this.saveSlotSelectCallback = null;
|
||||
originalCallback && originalCallback(-1);
|
||||
originalCallback?.(-1);
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -43,7 +43,7 @@ export default class SessionReloadModalUiHandler extends ModalUiHandler {
|
||||
this.modalContainer.add(label);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
show(_args: any[]): boolean {
|
||||
const config: ModalConfig = {
|
||||
buttonActions: [],
|
||||
};
|
||||
|
@ -123,7 +123,7 @@ export default abstract class AbstractBindingUiHandler extends UiHandler {
|
||||
if (this.timeLeftAutoClose >= 0) {
|
||||
this.manageAutoCloseTimer();
|
||||
} else {
|
||||
this.cancelFn && this.cancelFn();
|
||||
this.cancelFn?.();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
@ -185,19 +185,19 @@ export default abstract class AbstractBindingUiHandler extends UiHandler {
|
||||
let success = false;
|
||||
switch (button) {
|
||||
case Button.LEFT:
|
||||
case Button.RIGHT:
|
||||
case Button.RIGHT: {
|
||||
// Toggle between action and cancel options.
|
||||
const cursor = this.cursor ? 0 : 1;
|
||||
success = this.setCursor(cursor);
|
||||
success = this.setCursor(this.cursor ? 0 : 1);
|
||||
break;
|
||||
}
|
||||
case Button.ACTION:
|
||||
// Process actions based on current cursor position.
|
||||
if (this.cursor === 0) {
|
||||
this.cancelFn && this.cancelFn();
|
||||
this.cancelFn?.();
|
||||
} else {
|
||||
success = this.swapAction();
|
||||
NavigationManager.getInstance().updateIcons();
|
||||
this.cancelFn && this.cancelFn(success);
|
||||
this.cancelFn?.(success);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default class GamepadBindingUiHandler extends AbstractBindingUiHandler {
|
||||
return globalScene.inputController?.selectedDevice[Device.GAMEPAD];
|
||||
}
|
||||
|
||||
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, value: number): void {
|
||||
gamepadButtonDown(pad: Phaser.Input.Gamepad.Gamepad, button: Phaser.Input.Gamepad.Button, _value: number): void {
|
||||
const blacklist = [12, 13, 14, 15]; // d-pad buttons are blacklisted.
|
||||
// Check conditions before processing the button press.
|
||||
if (
|
||||
|
@ -53,7 +53,7 @@ export default class MoveTouchControlsHandler {
|
||||
this.touchControls = touchControls;
|
||||
this.inConfigurationMode = false;
|
||||
this.setPositions(this.getSavedPositionsOfCurrentOrientation() ?? []);
|
||||
window.addEventListener("resize", event => {
|
||||
window.addEventListener("resize", _event => {
|
||||
const screenSize = this.getScreenSize();
|
||||
if (screenSize.width > screenSize.height !== this.isLandscapeMode) {
|
||||
this.changeOrientation(screenSize.width > screenSize.height);
|
||||
|
@ -43,8 +43,8 @@ export default class SettingsKeyboardUiHandler extends AbstractControlSettingsUi
|
||||
|
||||
const deleteEvent = globalScene.input.keyboard?.addKey(Phaser.Input.Keyboard.KeyCodes.DELETE);
|
||||
const restoreDefaultEvent = globalScene.input.keyboard?.addKey(Phaser.Input.Keyboard.KeyCodes.HOME);
|
||||
deleteEvent && deleteEvent.on("up", this.onDeleteDown, this);
|
||||
restoreDefaultEvent && restoreDefaultEvent.on("up", this.onHomeDown, this);
|
||||
deleteEvent?.on("up", this.onDeleteDown, this);
|
||||
restoreDefaultEvent?.on("up", this.onHomeDown, this);
|
||||
}
|
||||
|
||||
setSetting = setSettingKeyboard;
|
||||
|
@ -30,7 +30,7 @@ import type {
|
||||
StarterAttributes,
|
||||
StarterPreferences,
|
||||
} from "#app/system/game-data";
|
||||
import { AbilityAttr, DexAttr, StarterPrefs } from "#app/system/game-data";
|
||||
import { AbilityAttr, DexAttr, loadStarterPreferences, saveStarterPreferences } from "#app/system/game-data";
|
||||
import { Tutorial, handleTutorial } from "#app/tutorial";
|
||||
import type { OptionSelectItem } from "#app/ui/abstact-option-select-ui-handler";
|
||||
import MessageUiHandler from "#app/ui/message-ui-handler";
|
||||
@ -79,6 +79,7 @@ import type { Nature } from "#enums/nature";
|
||||
import { PLAYER_PARTY_MAX_SIZE } from "#app/constants";
|
||||
import { achvs } from "#app/system/achv";
|
||||
import * as Utils from "../utils";
|
||||
import type { GameObjects } from "phaser";
|
||||
|
||||
export type StarterSelectCallback = (starters: Starter[]) => void;
|
||||
|
||||
@ -1174,7 +1175,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
show(args: any[]): boolean {
|
||||
if (!this.starterPreferences) {
|
||||
// starterPreferences haven't been loaded yet
|
||||
this.starterPreferences = StarterPrefs.load();
|
||||
this.starterPreferences = loadStarterPreferences();
|
||||
}
|
||||
this.moveInfoOverlay.clear(); // clear this when removing a menu; the cancel button doesn't seem to trigger this automatically on controllers
|
||||
this.pokerusSpecies = getPokerusStarters();
|
||||
@ -1241,11 +1242,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
const hasNonShiny = caughtAttr & DexAttr.NON_SHINY;
|
||||
if (starterAttributes.shiny && !hasShiny) {
|
||||
// shiny form wasn't unlocked, purging shiny and variant setting
|
||||
delete starterAttributes.shiny;
|
||||
delete starterAttributes.variant;
|
||||
starterAttributes.shiny = undefined;
|
||||
starterAttributes.variant = undefined;
|
||||
} else if (starterAttributes.shiny === false && !hasNonShiny) {
|
||||
// non shiny form wasn't unlocked, purging shiny setting
|
||||
delete starterAttributes.shiny;
|
||||
starterAttributes.shiny = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.variant !== undefined) {
|
||||
@ -1260,14 +1261,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
!unlockedVariants[starterAttributes.variant]
|
||||
) {
|
||||
// variant value is invalid or requested variant wasn't unlocked, purging setting
|
||||
delete starterAttributes.variant;
|
||||
starterAttributes.variant = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (starterAttributes.female !== undefined) {
|
||||
if (!(starterAttributes.female ? caughtAttr & DexAttr.FEMALE : caughtAttr & DexAttr.MALE)) {
|
||||
// requested gender wasn't unlocked, purging setting
|
||||
delete starterAttributes.female;
|
||||
starterAttributes.female = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1286,7 +1287,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
];
|
||||
if (!unlockedAbilities[starterAttributes.ability]) {
|
||||
// requested ability wasn't unlocked, purging setting
|
||||
delete starterAttributes.ability;
|
||||
starterAttributes.ability = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1297,14 +1298,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
!(caughtAttr & globalScene.gameData.getFormAttr(selectedForm)))
|
||||
) {
|
||||
// requested form wasn't unlocked/isn't a starter form, purging setting
|
||||
delete starterAttributes.form;
|
||||
starterAttributes.form = undefined;
|
||||
}
|
||||
|
||||
if (starterAttributes.nature !== undefined) {
|
||||
const unlockedNatures = globalScene.gameData.getNaturesForAttr(dexEntry.natureAttr);
|
||||
if (unlockedNatures.indexOf(starterAttributes.nature as unknown as Nature) < 0) {
|
||||
// requested nature wasn't unlocked, purging setting
|
||||
delete starterAttributes.nature;
|
||||
starterAttributes.nature = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,7 +1837,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
let starterContainer;
|
||||
let starterContainer: StarterContainer;
|
||||
const starterData = globalScene.gameData.starterData[this.lastSpecies.speciesId];
|
||||
// prepare persistent starter data to store changes
|
||||
let starterAttributes = this.starterPreferences[this.lastSpecies.speciesId];
|
||||
@ -2806,8 +2807,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
updateButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||
let iconPath;
|
||||
updateButtonIcon(
|
||||
iconSetting: SettingKeyboard,
|
||||
gamepadType: string,
|
||||
iconElement: GameObjects.Sprite,
|
||||
controlLabel: GameObjects.Text,
|
||||
): void {
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let iconPath: string;
|
||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||
if (gamepadType === "touch") {
|
||||
@ -2840,6 +2847,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
} else {
|
||||
iconPath = globalScene.inputController?.getIconForLatestInputRecorded(iconSetting);
|
||||
}
|
||||
// @ts-ignore: TODO can iconPath actually be undefined?
|
||||
iconElement.setTexture(gamepadType, iconPath);
|
||||
iconElement.setPosition(this.instructionRowX, this.instructionRowY);
|
||||
controlLabel.setPosition(this.instructionRowX + this.instructionRowTextOffset, this.instructionRowY);
|
||||
@ -2853,8 +2861,13 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
updateFilterButtonIcon(iconSetting, gamepadType, iconElement, controlLabel): void {
|
||||
let iconPath;
|
||||
updateFilterButtonIcon(
|
||||
iconSetting: SettingKeyboard,
|
||||
gamepadType: string,
|
||||
iconElement: GameObjects.Sprite,
|
||||
controlLabel: GameObjects.Text,
|
||||
): void {
|
||||
let iconPath: string;
|
||||
// touch controls cannot be rebound as is, and are just emulating a keyboard event.
|
||||
// Additionally, since keyboard controls can be rebound (and will be displayed when they are), we need to have special handling for the touch controls
|
||||
if (gamepadType === "touch") {
|
||||
@ -2884,7 +2897,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
this.hideInstructions();
|
||||
this.instructionsContainer.removeAll();
|
||||
this.filterInstructionsContainer.removeAll();
|
||||
let gamepadType;
|
||||
let gamepadType: string;
|
||||
if (globalScene.inputMethod === "gamepad") {
|
||||
gamepadType = globalScene.inputController.getConfig(
|
||||
globalScene.inputController.selectedDevice[Device.GAMEPAD],
|
||||
@ -3216,17 +3229,16 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
const sort = this.filterBar.getVals(DropDownColumn.SORT)[0];
|
||||
this.filteredStarterContainers.sort((a, b) => {
|
||||
switch (sort.val) {
|
||||
default:
|
||||
break;
|
||||
case SortCriteria.NUMBER:
|
||||
return (a.species.speciesId - b.species.speciesId) * -sort.dir;
|
||||
case SortCriteria.COST:
|
||||
return (a.cost - b.cost) * -sort.dir;
|
||||
case SortCriteria.CANDY:
|
||||
case SortCriteria.CANDY: {
|
||||
const candyCountA = globalScene.gameData.starterData[a.species.speciesId].candyCount;
|
||||
const candyCountB = globalScene.gameData.starterData[b.species.speciesId].candyCount;
|
||||
return (candyCountA - candyCountB) * -sort.dir;
|
||||
case SortCriteria.IV:
|
||||
}
|
||||
case SortCriteria.IV: {
|
||||
const avgIVsA =
|
||||
globalScene.gameData.dexData[a.species.speciesId].ivs.reduce((a, b) => a + b, 0) /
|
||||
globalScene.gameData.dexData[a.species.speciesId].ivs.length;
|
||||
@ -3234,6 +3246,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
globalScene.gameData.dexData[b.species.speciesId].ivs.reduce((a, b) => a + b, 0) /
|
||||
globalScene.gameData.dexData[b.species.speciesId].ivs.length;
|
||||
return (avgIVsA - avgIVsB) * -sort.dir;
|
||||
}
|
||||
case SortCriteria.NAME:
|
||||
return a.species.name.localeCompare(b.species.name) * -sort.dir;
|
||||
case SortCriteria.CAUGHT:
|
||||
@ -3893,7 +3906,8 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
.filter(f => f).length > 1;
|
||||
this.canCycleNature = globalScene.gameData.getNaturesForAttr(dexEntry.natureAttr).length > 1;
|
||||
this.canCycleTera =
|
||||
!this.statsMode && globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
|
||||
!this.statsMode &&
|
||||
globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
|
||||
!Utils.isNullOrUndefined(getPokemonSpeciesForm(species.speciesId, formIndex ?? 0).type2);
|
||||
}
|
||||
|
||||
@ -4015,7 +4029,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
const availableStarterMoves = this.speciesStarterMoves.concat(
|
||||
speciesEggMoves.hasOwnProperty(species.speciesId)
|
||||
? speciesEggMoves[species.speciesId].filter(
|
||||
(_, em: number) => globalScene.gameData.starterData[species.speciesId].eggMoves & (1 << em),
|
||||
(_: any, em: number) => globalScene.gameData.starterData[species.speciesId].eggMoves & (1 << em),
|
||||
)
|
||||
: [],
|
||||
);
|
||||
@ -4081,7 +4095,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
for (let em = 0; em < 4; em++) {
|
||||
const eggMove = hasEggMoves ? allMoves[speciesEggMoves[species.speciesId][em]] : null;
|
||||
const eggMoveUnlocked = eggMove && globalScene.gameData.starterData[species.speciesId].eggMoves & (1 << em);
|
||||
this.pokemonEggMoveBgs[em].setFrame(PokemonType[eggMove ? eggMove.type : PokemonType.UNKNOWN].toString().toLowerCase());
|
||||
this.pokemonEggMoveBgs[em].setFrame(
|
||||
PokemonType[eggMove ? eggMove.type : PokemonType.UNKNOWN].toString().toLowerCase(),
|
||||
);
|
||||
this.pokemonEggMoveLabels[em].setText(eggMove && eggMoveUnlocked ? eggMove.name : "???");
|
||||
}
|
||||
|
||||
@ -4354,26 +4370,25 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
const thisObj = this;
|
||||
const originalStarterSelectCallback = this.starterSelectCallback;
|
||||
this.starterSelectCallback = null;
|
||||
originalStarterSelectCallback &&
|
||||
originalStarterSelectCallback(
|
||||
new Array(this.starterSpecies.length).fill(0).map((_, i) => {
|
||||
const starterSpecies = thisObj.starterSpecies[i];
|
||||
return {
|
||||
species: starterSpecies,
|
||||
dexAttr: thisObj.starterAttr[i],
|
||||
abilityIndex: thisObj.starterAbilityIndexes[i],
|
||||
passive: !(
|
||||
globalScene.gameData.starterData[starterSpecies.speciesId].passiveAttr ^
|
||||
(PassiveAttr.ENABLED | PassiveAttr.UNLOCKED)
|
||||
),
|
||||
nature: thisObj.starterNatures[i] as Nature,
|
||||
teraType: thisObj.starterTeras[i] as PokemonType,
|
||||
moveset: thisObj.starterMovesets[i],
|
||||
pokerus: thisObj.pokerusSpecies.includes(starterSpecies),
|
||||
nickname: thisObj.starterPreferences[starterSpecies.speciesId]?.nickname,
|
||||
};
|
||||
}),
|
||||
);
|
||||
originalStarterSelectCallback?.(
|
||||
new Array(this.starterSpecies.length).fill(0).map((_, i) => {
|
||||
const starterSpecies = thisObj.starterSpecies[i];
|
||||
return {
|
||||
species: starterSpecies,
|
||||
dexAttr: thisObj.starterAttr[i],
|
||||
abilityIndex: thisObj.starterAbilityIndexes[i],
|
||||
passive: !(
|
||||
globalScene.gameData.starterData[starterSpecies.speciesId].passiveAttr ^
|
||||
(PassiveAttr.ENABLED | PassiveAttr.UNLOCKED)
|
||||
),
|
||||
nature: thisObj.starterNatures[i] as Nature,
|
||||
teraType: thisObj.starterTeras[i] as PokemonType,
|
||||
moveset: thisObj.starterMovesets[i],
|
||||
pokerus: thisObj.pokerusSpecies.includes(starterSpecies),
|
||||
nickname: thisObj.starterPreferences[starterSpecies.speciesId]?.nickname,
|
||||
};
|
||||
}),
|
||||
);
|
||||
};
|
||||
startRun();
|
||||
},
|
||||
@ -4495,9 +4510,15 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
//@ts-ignore
|
||||
this.statsContainer.updateIvs(null); // TODO: resolve ts-ignore. !?!?
|
||||
this.teraIcon.setVisible(globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id));
|
||||
const props = globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId));
|
||||
const props = globalScene.gameData.getSpeciesDexAttrProps(
|
||||
this.lastSpecies,
|
||||
this.getCurrentDexProps(this.lastSpecies.speciesId),
|
||||
);
|
||||
const formIndex = props.formIndex;
|
||||
this.canCycleTera = !this.statsMode && globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) && !Utils.isNullOrUndefined(getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2);
|
||||
this.canCycleTera =
|
||||
!this.statsMode &&
|
||||
globalScene.gameData.achvUnlocks.hasOwnProperty(achvs.TERASTALLIZE.id) &&
|
||||
!Utils.isNullOrUndefined(getPokemonSpeciesForm(this.lastSpecies.speciesId, formIndex ?? 0).type2);
|
||||
this.updateInstructions();
|
||||
}
|
||||
}
|
||||
@ -4537,7 +4558,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler {
|
||||
clear(): void {
|
||||
super.clear();
|
||||
|
||||
StarterPrefs.save(this.starterPreferences);
|
||||
saveStarterPreferences(this.starterPreferences);
|
||||
this.cursor = -1;
|
||||
this.hideInstructions();
|
||||
this.activeTooltip = undefined;
|
||||
|
@ -456,7 +456,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
this.genderText.setShadowColor(getGenderColor(this.pokemon.getGender(true), true));
|
||||
|
||||
switch (this.summaryUiMode) {
|
||||
case SummaryUiMode.DEFAULT:
|
||||
case SummaryUiMode.DEFAULT: {
|
||||
const page = args.length < 2 ? Page.PROFILE : (args[2] as Page);
|
||||
this.hideMoveEffect(true);
|
||||
this.setCursor(page);
|
||||
@ -464,6 +464,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
this.selectCallback = args[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SummaryUiMode.LEARN_MOVE:
|
||||
this.newMove = args[2] as Move;
|
||||
this.moveSelectFunction = args[3] as Function;
|
||||
@ -500,7 +501,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
if (button === Button.ACTION) {
|
||||
if (this.pokemon && this.moveCursor < this.pokemon.moveset.length) {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.moveSelectFunction && this.moveSelectFunction(this.moveCursor);
|
||||
this.moveSelectFunction?.(this.moveCursor);
|
||||
} else {
|
||||
if (this.selectedMoveIndex === -1) {
|
||||
this.selectedMoveIndex = this.moveCursor;
|
||||
@ -602,7 +603,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
const pages = Utils.getEnumValues(Page);
|
||||
switch (button) {
|
||||
case Button.UP:
|
||||
case Button.DOWN:
|
||||
case Button.DOWN: {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
break;
|
||||
}
|
||||
@ -618,6 +619,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
this.show([party[partyMemberIndex + (isDown ? 1 : -1)], this.summaryUiMode, page]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Button.LEFT:
|
||||
if (this.cursor) {
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
@ -786,7 +788,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
}
|
||||
|
||||
switch (page) {
|
||||
case Page.PROFILE:
|
||||
case Page.PROFILE: {
|
||||
const profileContainer = globalScene.add.container(0, -pageBg.height);
|
||||
pageContainer.add(profileContainer);
|
||||
|
||||
@ -956,7 +958,8 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
memoText.setOrigin(0, 0);
|
||||
profileContainer.add(memoText);
|
||||
break;
|
||||
case Page.STATS:
|
||||
}
|
||||
case Page.STATS: {
|
||||
this.statsContainer = globalScene.add.container(0, -pageBg.height);
|
||||
pageContainer.add(this.statsContainer);
|
||||
this.permStatsContainer = globalScene.add.container(27, 56);
|
||||
@ -1075,7 +1078,8 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
this.abilityPrompt.setOrigin(0, 0);
|
||||
this.statsContainer.add(this.abilityPrompt);
|
||||
break;
|
||||
case Page.MOVES:
|
||||
}
|
||||
case Page.MOVES: {
|
||||
this.movesContainer = globalScene.add.container(5, -pageBg.height + 26);
|
||||
pageContainer.add(this.movesContainer);
|
||||
|
||||
@ -1168,6 +1172,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
|
||||
this.moveDescriptionText.setMask(moveDescriptionTextMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1221,7 +1226,7 @@ export default class SummaryUiHandler extends UiHandler {
|
||||
|
||||
hideMoveSelect() {
|
||||
if (this.summaryUiMode === SummaryUiMode.LEARN_MOVE) {
|
||||
this.moveSelectFunction && this.moveSelectFunction(4);
|
||||
this.moveSelectFunction?.(4);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ export default class TargetSelectUiHandler extends UiHandler {
|
||||
if (this.targetFlashTween) {
|
||||
this.targetFlashTween.stop();
|
||||
for (const pokemon of multipleTargets) {
|
||||
pokemon.setAlpha(!!pokemon.getTag(SubstituteTag) ? 0.5 : 1);
|
||||
pokemon.setAlpha(pokemon.getTag(SubstituteTag) ? 0.5 : 1);
|
||||
this.highlightItems(pokemon.id, 1);
|
||||
}
|
||||
}
|
||||
@ -194,7 +194,7 @@ export default class TargetSelectUiHandler extends UiHandler {
|
||||
}
|
||||
|
||||
for (const pokemon of this.targetsHighlighted) {
|
||||
pokemon.setAlpha(!!pokemon.getTag(SubstituteTag) ? 0.5 : 1);
|
||||
pokemon.setAlpha(pokemon.getTag(SubstituteTag) ? 0.5 : 1);
|
||||
this.highlightItems(pokemon.id, 1);
|
||||
}
|
||||
|
||||
|
@ -48,19 +48,19 @@ export default class TestDialogueUiHandler extends FormModalUiHandler {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
||||
getModalTitle(config?: ModalConfig): string {
|
||||
getModalTitle(_config?: ModalConfig): string {
|
||||
return "Test Dialogue";
|
||||
}
|
||||
|
||||
getWidth(config?: ModalConfig): number {
|
||||
getWidth(_config?: ModalConfig): number {
|
||||
return 300;
|
||||
}
|
||||
|
||||
getMargin(config?: ModalConfig): [number, number, number, number] {
|
||||
getMargin(_config?: ModalConfig): [number, number, number, number] {
|
||||
return [0, 0, 48, 0];
|
||||
}
|
||||
|
||||
getButtonLabels(config?: ModalConfig): string[] {
|
||||
getButtonLabels(_config?: ModalConfig): string[] {
|
||||
return ["Check", "Cancel"];
|
||||
}
|
||||
|
||||
|
@ -330,6 +330,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
): void {
|
||||
if (prompt && text.indexOf("$") > -1) {
|
||||
const messagePages = text.split(/\$/g).map(m => m.trim());
|
||||
// biome-ignore lint/complexity/useOptionalChain: optional chain would change this to be null instead of undefined.
|
||||
let showMessageAndCallback = () => callback && callback();
|
||||
for (let p = messagePages.length - 1; p >= 0; p--) {
|
||||
const originalFunc = showMessageAndCallback;
|
||||
|
@ -117,27 +117,35 @@ describe("Moves - Aurora Veil", () => {
|
||||
});
|
||||
|
||||
it("does not affect physical critical hits", async () => {
|
||||
game.override.moveset([ Moves.WICKED_BLOW ]);
|
||||
game.override.moveset([Moves.WICKED_BLOW]);
|
||||
const moveToUse = Moves.WICKED_BLOW;
|
||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||
await game.classicMode.startBattle([Species.SHUCKLE]);
|
||||
|
||||
game.move.select(moveToUse);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
|
||||
it("does not affect critical hits", async () => {
|
||||
game.override.moveset([ Moves.FROST_BREATH ]);
|
||||
game.override.moveset([Moves.FROST_BREATH]);
|
||||
const moveToUse = Moves.FROST_BREATH;
|
||||
vi.spyOn(allMoves[Moves.FROST_BREATH], "accuracy", "get").mockReturnValue(100);
|
||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||
await game.classicMode.startBattle([Species.SHUCKLE]);
|
||||
|
||||
game.move.select(moveToUse);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
});
|
||||
@ -158,13 +166,13 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.AURORA_VEIL, side)) {
|
||||
if (move.getAttrs(CritOnlyAttr).length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.AURORA_VEIL,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
ArenaTagType.AURORA_VEIL,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,27 +199,27 @@ describe("Moves - Instruct", () => {
|
||||
const [karp1, karp2] = game.scene.getEnemyField()!;
|
||||
expect(karp1.isFainted()).toBe(true);
|
||||
expect(karp2.isFainted()).toBe(true);
|
||||
}),
|
||||
it("should allow for dancer copying of instructed dance move", async () => {
|
||||
game.override.battleType("double").enemyMoveset([Moves.INSTRUCT, Moves.SPLASH]).enemyLevel(1000);
|
||||
await game.classicMode.startBattle([Species.ORICORIO, Species.VOLCARONA]);
|
||||
});
|
||||
it("should allow for dancer copying of instructed dance move", async () => {
|
||||
game.override.battleType("double").enemyMoveset([Moves.INSTRUCT, Moves.SPLASH]).enemyLevel(1000);
|
||||
await game.classicMode.startBattle([Species.ORICORIO, Species.VOLCARONA]);
|
||||
|
||||
const [oricorio, volcarona] = game.scene.getPlayerField();
|
||||
game.move.changeMoveset(oricorio, Moves.SPLASH);
|
||||
game.move.changeMoveset(volcarona, Moves.FIERY_DANCE);
|
||||
const [oricorio, volcarona] = game.scene.getPlayerField();
|
||||
game.move.changeMoveset(oricorio, Moves.SPLASH);
|
||||
game.move.changeMoveset(volcarona, Moves.FIERY_DANCE);
|
||||
|
||||
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||
await game.forceEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER_2);
|
||||
await game.forceEnemyMove(Moves.SPLASH);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
game.move.select(Moves.SPLASH, BattlerIndex.PLAYER);
|
||||
game.move.select(Moves.FIERY_DANCE, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY);
|
||||
await game.forceEnemyMove(Moves.INSTRUCT, BattlerIndex.PLAYER_2);
|
||||
await game.forceEnemyMove(Moves.SPLASH);
|
||||
await game.setTurnOrder([BattlerIndex.PLAYER, BattlerIndex.PLAYER_2, BattlerIndex.ENEMY, BattlerIndex.ENEMY_2]);
|
||||
await game.phaseInterceptor.to("BerryPhase");
|
||||
|
||||
// fiery dance triggered dancer successfully for a total of 4 hits
|
||||
// Enemy level is set to a high value so that it does not faint even after all 4 hits
|
||||
instructSuccess(volcarona, Moves.FIERY_DANCE);
|
||||
expect(game.scene.getEnemyField()[0].turnData.attacksReceived.length).toBe(4);
|
||||
});
|
||||
// fiery dance triggered dancer successfully for a total of 4 hits
|
||||
// Enemy level is set to a high value so that it does not faint even after all 4 hits
|
||||
instructSuccess(volcarona, Moves.FIERY_DANCE);
|
||||
expect(game.scene.getEnemyField()[0].turnData.attacksReceived.length).toBe(4);
|
||||
});
|
||||
|
||||
it("should not repeat move when switching out", async () => {
|
||||
game.override.enemyMoveset(Moves.INSTRUCT).enemySpecies(Species.UNOWN);
|
||||
|
@ -86,21 +86,29 @@ describe("Moves - Light Screen", () => {
|
||||
game.move.select(moveToUse);
|
||||
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
|
||||
it("does not affect critical hits", async () => {
|
||||
game.override.moveset([ Moves.FROST_BREATH ]);
|
||||
game.override.moveset([Moves.FROST_BREATH]);
|
||||
const moveToUse = Moves.FROST_BREATH;
|
||||
vi.spyOn(allMoves[Moves.FROST_BREATH], "accuracy", "get").mockReturnValue(100);
|
||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||
await game.classicMode.startBattle([Species.SHUCKLE]);
|
||||
|
||||
game.move.select(moveToUse);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
});
|
||||
@ -121,13 +129,13 @@ const getMockedMoveDamage = (defender: Pokemon, attacker: Pokemon, move: Move) =
|
||||
if (globalScene.arena.getTagOnSide(ArenaTagType.LIGHT_SCREEN, side)) {
|
||||
if (move.getAttrs(CritOnlyAttr).length === 0) {
|
||||
globalScene.arena.applyTagsForSide(
|
||||
ArenaTagType.LIGHT_SCREEN,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
ArenaTagType.LIGHT_SCREEN,
|
||||
side,
|
||||
false,
|
||||
attacker,
|
||||
move.category,
|
||||
multiplierHolder,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,27 +96,35 @@ describe("Moves - Reflect", () => {
|
||||
});
|
||||
|
||||
it("does not affect critical hits", async () => {
|
||||
game.override.moveset([ Moves.WICKED_BLOW ]);
|
||||
game.override.moveset([Moves.WICKED_BLOW]);
|
||||
const moveToUse = Moves.WICKED_BLOW;
|
||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||
await game.classicMode.startBattle([Species.SHUCKLE]);
|
||||
|
||||
game.move.select(moveToUse);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
|
||||
it("does not affect critical hits", async () => {
|
||||
game.override.moveset([ Moves.WICKED_BLOW ]);
|
||||
game.override.moveset([Moves.WICKED_BLOW]);
|
||||
const moveToUse = Moves.WICKED_BLOW;
|
||||
await game.classicMode.startBattle([ Species.SHUCKLE ]);
|
||||
await game.classicMode.startBattle([Species.SHUCKLE]);
|
||||
|
||||
game.move.select(moveToUse);
|
||||
await game.phaseInterceptor.to(TurnEndPhase);
|
||||
|
||||
const mockedDmg = getMockedMoveDamage(game.scene.getEnemyPokemon()!, game.scene.getPlayerPokemon()!, allMoves[moveToUse]);
|
||||
const mockedDmg = getMockedMoveDamage(
|
||||
game.scene.getEnemyPokemon()!,
|
||||
game.scene.getPlayerPokemon()!,
|
||||
allMoves[moveToUse],
|
||||
);
|
||||
expect(mockedDmg).toBe(allMoves[moveToUse].power);
|
||||
});
|
||||
});
|
||||
|
@ -142,9 +142,6 @@ export async function runSelectMysteryEncounterOption(
|
||||
uiHandler.unblockInput(); // input are blocked by 1s to prevent accidental input. Tests need to handle that
|
||||
|
||||
switch (optionNo) {
|
||||
default:
|
||||
// no movement needed. Default cursor position
|
||||
break;
|
||||
case 2:
|
||||
uiHandler.processInput(Button.RIGHT);
|
||||
break;
|
||||
@ -155,6 +152,9 @@ export async function runSelectMysteryEncounterOption(
|
||||
uiHandler.processInput(Button.RIGHT);
|
||||
uiHandler.processInput(Button.DOWN);
|
||||
break;
|
||||
default:
|
||||
// no movement needed. Default cursor position
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isNullOrUndefined(secondaryOptionSelect?.pokemonNo)) {
|
||||
|
@ -218,8 +218,12 @@ describe("Fiery Fallout - Mystery Encounter", () => {
|
||||
|
||||
await runMysteryEncounterToEnd(game, 2);
|
||||
|
||||
const burnablePokemon = party.filter(pkm => pkm.isAllowedInBattle() && !pkm.getTypes().includes(PokemonType.FIRE));
|
||||
const notBurnablePokemon = party.filter(pkm => !pkm.isAllowedInBattle() || pkm.getTypes().includes(PokemonType.FIRE));
|
||||
const burnablePokemon = party.filter(
|
||||
pkm => pkm.isAllowedInBattle() && !pkm.getTypes().includes(PokemonType.FIRE),
|
||||
);
|
||||
const notBurnablePokemon = party.filter(
|
||||
pkm => !pkm.isAllowedInBattle() || pkm.getTypes().includes(PokemonType.FIRE),
|
||||
);
|
||||
expect(scene.currentBattle.mysteryEncounter?.dialogueTokens["burnedPokemon"]).toBe(i18next.t("pokemon:gengar"));
|
||||
burnablePokemon.forEach(pkm => {
|
||||
expect(pkm.hp, `${pkm.name} should have received 20% damage: ${pkm.hp} / ${pkm.getMaxHp()} HP`).toBe(
|
||||
|
@ -10,8 +10,11 @@ import { MenuManip } from "#test/settingMenu/helpers/menuManip";
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
describe("Test Rebinding", () => {
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let config;
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let inGame;
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let inTheSettingMenu;
|
||||
const configs: Map<string, InterfaceConfig> = new Map();
|
||||
const selectedDevice = {
|
||||
|
@ -224,6 +224,7 @@ export default class GameWrapper {
|
||||
return new Promise(resolve => {
|
||||
// need to remove that if later we want to test battle-anims
|
||||
const newUrl = url.includes("./battle-anims/") ? prependPath("./battle-anims/tackle.json") : prependPath(url);
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let raw;
|
||||
try {
|
||||
raw = fs.readFileSync(newUrl, { encoding: "utf8", flag: "r" });
|
||||
|
@ -1,7 +1,9 @@
|
||||
export const MockFetch = (input, _init) => {
|
||||
const url = typeof input === "string" ? input : input.url;
|
||||
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let responseHandler;
|
||||
// biome-ignore lint/suspicious/noImplicitAnyLet: TODO
|
||||
let responseText;
|
||||
|
||||
const handlers = {
|
||||
|
@ -24,11 +24,5 @@
|
||||
"exclude": "**/*+.test.ts",
|
||||
"out": "typedoc"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts",
|
||||
"vitest.workspace.ts"
|
||||
]
|
||||
"exclude": ["node_modules", "dist", "vite.config.ts", "vitest.config.ts", "vitest.workspace.ts"]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user