Update to ESLint 9 (#10926)

ESLint has a whole new config format, so I figure it's a good time to
make the config system saner.

- First, we no longer have separate eslint-no-types configs. Lint
  performance shouldn't be enough of a problem to justify the
  relevant maintenance complexity.

- Second, our base config should work out-of-the-box now. `npx eslint`
  will work as expected, without any CLI flags. You should still use
  `npm run lint` which adds the `--cached` flag for performance.

- Third, whatever updates I did fixed style linting, which apparently
  has been bugged for quite some time, considering all the obvious
  mixed-tabs-and-spaces issues I found in the upgrade.

Also here are some changes to our style rules. In particular:

- Curly brackets (for objects etc) now have spaces inside them. Sorry
  for the huge change. ESLint doesn't support our old style, and most
  projects use Prettier style, so we might as well match them in this way.
  See https://github.com/eslint-stylistic/eslint-stylistic/issues/415

- String + number concatenation is no longer allowed. We now
  consistently use template strings for this.
This commit is contained in:
Guangcong Luo 2025-02-25 20:03:46 -08:00 committed by GitHub
parent 44a9e287fc
commit 78439b4a02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
637 changed files with 21544 additions and 21441 deletions

View File

@ -1,359 +0,0 @@
{
"root": true,
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "script",
"ecmaFeatures": {
"globalReturn": true
}
},
"ignorePatterns": [
"logs/",
"node_modules/",
"dist/",
"data/**/learnsets.ts",
"tools/set-import/importer.js",
"tools/set-import/sets",
"tools/modlog/converter.js",
"server/global-variables.d.ts"
],
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"rules": {
// TODO: add/revisit
// "spaced-comment": ["error", "always", {"exceptions": ["*"]}],
// "no-use-before-define": "off",
// test only (should never be committed, but useful when testing)
"no-debugger": "warn",
"no-unused-vars": ["warn", {"args": "none"}],
"no-warning-comments": "off",
"prefer-const": ["warn", {"destructuring": "all"}],
// PS code (code specific to PS)
"consistent-return": "off", // sim event handlers mix them for ergonomics
"func-style": "off", // used to type event handlers
"no-console": "off",
"no-control-regex": "off", // used to find invalid data in chat messages
"no-invalid-this": "off", // `this` is used to pass context to sim event handlers, chat commands, etc
"no-loop-func": "off", // synchronous
"no-restricted-modules": ["error", "moment", "request", "sugar"],
"no-sync": "off",
"no-void": "off", // used for spawning Promises only
"strict": ["error", "global"],
// bad code, modern (new code patterns we don't like because they're less readable or performant)
"no-restricted-globals": ["error", "Proxy", "Reflect", "Symbol", "WeakSet"],
// bad code, deprecated (deprecated/bad patterns that should be written a different way)
"eqeqeq": "error",
"func-names": "off", // has minor advantages but way too verbose, hurting readability
"guard-for-in": "off", // guarding is a deprecated pattern, we just use no-extend-native instead
"init-declarations": "off", // TypeScript lets us delay initialization safely
"no-caller": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-implied-eval": "error",
"no-inner-declarations": ["error", "functions"],
"no-iterator": "error",
"no-labels": ["error", {"allowLoop": true, "allowSwitch": true}],
"no-multi-str": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-path-concat": "off", // Windows supports `/` as a path separator; concat is more readable
"no-proto": "error",
"no-restricted-syntax": ["error", "WithStatement"],
"no-sparse-arrays": "error",
"no-var": "error",
"no-with": "error",
// probably bugs (code with no reason to exist, probably typoes)
"array-callback-return": "error",
"block-scoped-var": "error", // not actually used; precluded by no-var
"callback-return": [2, ["callback", "cb", "done"]],
"consistent-this": "off", // we use arrow functions instead
"constructor-super": "error",
"default-case": "off", // hopefully TypeScript will let us skip `default` for things that are exhaustive
"no-bitwise": "off", // used in Dashycode
"no-case-declarations": "off", // meh, we have no-shadow
"no-duplicate-case": "error",
"no-empty": ["error", {"allowEmptyCatch": true}],
"no-extra-bind": "error",
"no-extra-label": "error",
"no-fallthrough": "error",
"no-label-var": "error",
"no-new-require": "error",
"no-new": "error",
"no-redeclare": "error",
"no-return-await": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow-restricted-names": "error",
"no-shadow": "off",
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-undef": "off",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "error",
"no-unsafe-finally": "error",
"no-unused-labels": "error",
"use-isnan": "error",
"valid-typeof": "error",
// style choices
"no-constant-condition": ["error", {"checkLoops": false}],
"no-lonely-if": "off",
"radix": ["error", "as-needed"],
// naming style
"camelcase": "off", // mostly only so we can import `child_process`
"id-length": "off",
"id-match": "off",
"new-cap": ["error", {"newIsCap": true, "capIsNew": false}],
"no-underscore-dangle": "off",
// syntax style (local syntactical, usually autofixable formatting decisions)
"arrow-parens": "off",
"arrow-body-style": "error",
"brace-style": ["error", "1tbs", {"allowSingleLine": true}],
"comma-dangle": ["error", {"arrays": "always-multiline", "objects": "always-multiline", "imports": "always-multiline", "exports": "always-multiline", "functions": "ignore"}],
"comma-style": ["error", "last"],
"curly": ["error", "multi-line", "consistent"],
"dot-notation": "off",
"new-parens": "error",
"no-array-constructor": "error",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-extra-parens": "off",
"no-floating-decimal": "error",
"no-mixed-requires": "error",
"no-multi-spaces": "error",
"no-new-object": "error",
"no-octal-escape": "error",
"no-return-assign": ["error", "except-parens"],
"no-undef-init": "off",
"no-unneeded-ternary": "error",
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "off",
"no-useless-rename": "error",
"object-shorthand": ["error", "methods"],
"one-var": "off",
"operator-assignment": "off",
"prefer-arrow-callback": "off",
"quote-props": "off",
"quotes": "off",
"semi": ["error", "always"],
"sort-vars": "off",
"vars-on-top": "off",
"wrap-iife": ["error", "inside"],
"wrap-regex": "off",
"yoda": ["error", "never", { "exceptRange": true }],
// whitespace
"array-bracket-spacing": ["error", "never"],
"arrow-spacing": ["error", {"before": true, "after": true}],
"block-spacing": ["error", "always"],
"comma-spacing": ["error", {"before": false, "after": true}],
"computed-property-spacing": ["error", "never"],
"dot-location": ["error", "property"],
"eol-last": ["error", "always"],
"func-call-spacing": "error",
"function-paren-newline": ["error", "consistent"],
"indent": ["error", "tab", {"flatTernaryExpressions": true}],
"key-spacing": "error",
"keyword-spacing": ["error", {"before": true, "after": true}],
"lines-around-comment": "off",
"no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
"no-multiple-empty-lines": ["error", {"max": 2, "maxEOF": 1}],
"no-trailing-spaces": ["error", {"ignoreComments": false}],
"object-curly-spacing": ["error", "never"],
"operator-linebreak": ["error", "after"],
"padded-blocks": ["error", "never"],
"padding-line-between-statements": "off",
"rest-spread-spacing": ["error", "never"],
"semi-spacing": ["error", {"before": false, "after": true}],
"space-before-blocks": ["error", "always"],
"space-before-function-paren": ["error", {"anonymous": "always", "named": "never"}],
"space-in-parens": ["error", "never"],
"space-infix-ops": "error",
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
"template-curly-spacing": ["error", "never"]
},
"overrides": [
{
"files": [
"./config/*.ts", "./data/**/*.ts", "./lib/*.ts", "./server/**/*.ts", "./server/**/*.tsx", "./sim/**/*.ts",
"./tools/set-import/*.ts", "./tools/modlog/*.ts", "./translations/**/*.ts"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module",
"tsconfigRootDir": ".",
"project": ["./tsconfig.json"]
},
"extends": [
"plugin:@typescript-eslint/recommended"
],
"rules": {
// TODO revisit
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/member-ordering": "off",
// "@typescript-eslint/no-extraneous-class": "error",
// "@typescript-eslint/no-type-alias": "error",
"@typescript-eslint/prefer-optional-chain": "off",
// "@typescript-eslint/consistent-type-imports": "error", // TODO after no-duplicate-imports fix
// test only (should never be committed, but useful when testing)
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["warn", {"args": "none"}],
"max-len": ["warn", {
"code": 120, "tabWidth": 0,
// see bottom of file for source
"ignorePattern": "^\\s*(?:\\/\\/ \\s*)?(?:(?:export )?(?:let |const |readonly )?[a-zA-Z0-9_$.]+(?: \\+?=>? )|[a-zA-Z0-9$]+: \\[?|(?:return |throw )?(?:new )?(?:[a-zA-Z0-9$.]+\\()?)?(?:Utils\\.html|(?:this\\.)?(?:room\\.)?tr|\\$\\()?['\"`/]"
}],
"prefer-const": ["warn", {"destructuring": "all"}], // typescript-eslint/recommended forces this so we need to re-override
// PS code (code specific to PS)
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/unbound-method": "off", // used for sim event handlers, command handlers, etc
"new-parens": "off", // used for the `new class {...}` pattern
"no-prototype-builtins": "off",
"no-shadow": "off",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/no-var-requires": "off",
// typescript-eslint defaults too strict
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-unsafe-argument": "off",
// probably bugs
"@typescript-eslint/ban-types": ["error", {
"extendDefaults": true,
"types": {
"object": false
}
}],
"@typescript-eslint/no-dupe-class-members": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-extra-non-null-assertion": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
"no-dupe-class-members": "off",
"no-unused-expressions": "off", // ternary is used to convert callbacks to Promises
"@typescript-eslint/no-unused-expressions": ["error", {"allowTernary": true}], // ternary is used to convert callbacks to Promises
// naming style
"@typescript-eslint/naming-convention": ["error", {
"selector": ["class", "interface", "typeAlias"],
"format": ["PascalCase"]
}],
// syntax style (local syntactical, usually autofixable formatting decisions)
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/consistent-type-assertions": ["error", {"assertionStyle": "as"}],
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
"@typescript-eslint/member-delimiter-style": ["error", {"overrides": {"typeLiteral": {
"multiline": {"delimiter": "comma", "requireLast": true},
"singleline": {"delimiter": "comma", "requireLast": false}
}}}],
"@typescript-eslint/no-parameter-properties": "error",
// `source` and `target` are frequently used as variables that may point to `this`
// or to another `Pokemon` object, depending on how the given method is invoked
"@typescript-eslint/no-this-alias": ["error", {"allowedNames": ["source", "target"]}],
"@typescript-eslint/prefer-as-const": "error",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"prefer-object-spread": "error",
"@typescript-eslint/triple-slash-reference": "error",
"@typescript-eslint/unified-signatures": "error",
// syntax style, overriding base
"quotes": "off",
"@typescript-eslint/quotes": "off",
"semi": "off",
"@typescript-eslint/semi": ["error", "always"],
"func-call-spacing": "off",
"@typescript-eslint/func-call-spacing": "error",
// whitespace
"@typescript-eslint/type-annotation-spacing": "error",
"spaced-comment": ["error", "always", {"exceptions": ["*", "/"]}],
// whitespace, overriding base
"indent": "off",
"@typescript-eslint/indent": ["error", "tab", {"flatTernaryExpressions": true}]
}
},
{
"files": ["./translations/**/*.ts"],
"rules": {
"no-template-curly-in-string": "off"
}
},
{
"env": {
"mocha": true
},
"files": ["test/**/*.js"]
},
{
"files": ["build"],
"rules": {
"no-var": "off"
}
},
{
"files": ["server/chat-plugins/private/*"],
"parserOptions": {
"ecmaVersion": 2021
}
}
]
}
/*
REGEXFREE SOURCE FOR IGNOREPATTERN: https://zarel.github.io/regexfree/
# indentation
^\s*
# possibly commented out
(\/\/\ \s*)?
(
# define a variable, append to a variable, or define a single-arg arrow function
(export\ )? (let\ |const\ |readonly\ )? [a-zA-Z0-9_$.]+ (\ \+?=>?\ )
|
# define a property (oversize arrays are only allowed in properties)
[a-zA-Z0-9$]+:\ \[?
|
# optionally return or throw
(return\ |throw\ )?
# call a function or constructor
(new\ )?([a-zA-Z0-9$.]+\()?
)?
(
Utils\.html
|
(this\.)?(room\.)?tr
|
\$\(
)?
# start of string or regex
['"`\/]
*/

View File

@ -1,51 +0,0 @@
{
"extends": "./.eslintrc-no-types.json",
"overrides": [
{
"files": ["./config/*.ts", "./data/**/*.ts", "./lib/*.ts", "./server/**/*.ts", "./server/**/*.tsx", "./sim/**/*.ts", "./tools/set-import/*.ts"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module",
"tsconfigRootDir": ".",
"project": ["./tsconfig.json"]
},
"extends": [
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"./.eslintrc-no-types.json"
],
"rules": {
// TODO investigate
"@typescript-eslint/restrict-plus-operands": "off",
// "@typescript-eslint/restrict-plus-operands": ["error", {"checkCompoundAssignments": true}],
// "@typescript-eslint/switch-exhaustiveness-check": "error",
// typescript-eslint defaults too strict
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/restrict-template-expressions": "off",
// probably bugs
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-for-in-array": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/no-throw-literal": "error",
"@typescript-eslint/no-unnecessary-condition": "off", // sadly, we use not-null assertions so commonly that these are often necessary
// syntax style (local syntactical, usually autofixable formatting decisions)
"@typescript-eslint/no-unnecessary-qualifier": "off",
// Disabled because of a bug in typescript-eslint.
// See https://github.com/typescript-eslint/typescript-eslint/issues/4554
"@typescript-eslint/no-unnecessary-type-arguments": "off",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/prefer-regexp-exec": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error"
}
}
]
}

View File

@ -17,7 +17,7 @@ jobs:
strategy: strategy:
matrix: matrix:
node-version: [16.x] node-version: [18.x]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3

View File

@ -1,10 +1,6 @@
{ {
"editor.insertSpaces": false, "editor.insertSpaces": false,
"editor.formatOnSave": false,
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false, "javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
"typescript.format.semicolons": "insert", "typescript.format.semicolons": "insert"
"eslint.options": {
"configFile": ".eslintrc.json"
}
} }

6
build
View File

@ -2,10 +2,10 @@
"use strict"; "use strict";
try { try {
// technically this was introduced in Node 15, but we'll ask for the most recent LTS with it to be safe // technically this was introduced in Node 17, but we'll ask for the most recent LTS with it to be safe
Promise.any([null]); structuredClone({});
} catch (e) { } catch (e) {
console.log("We require Node.js version 16 or later; you're using " + process.version); console.log("We require Node.js version 18 or later; you're using " + process.version);
process.exit(1); process.exit(1);
} }

View File

@ -154,7 +154,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen9', mod: 'gen9',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -230,7 +230,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen9', mod: 'gen9',
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
debug: true, debug: true,
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
@ -531,12 +531,12 @@ export const Formats: import('../sim/dex-formats').FormatList = [
], ],
battle: { battle: {
endTurn() { endTurn() {
// @ts-ignore Hack // @ts-expect-error Hack
for (const pokemon of this.getAllActive(false, true)) { for (const pokemon of this.getAllActive(false, true)) {
// turn counter hasn't been incremented yet // turn counter hasn't been incremented yet
if (this.turn & 1 && pokemon.position === (this.turn & 2 ? 0 : 1) && pokemon.hp && pokemon.allies().length) { if (this.turn & 1 && pokemon.position === (this.turn & 2 ? 0 : 1) && pokemon.hp && pokemon.allies().length) {
pokemon.volatiles['commanding'] = this.initEffectState({id: 'commanding', name: 'Commanding', target: pokemon}); pokemon.volatiles['commanding'] = this.initEffectState({ id: 'commanding', name: 'Commanding', target: pokemon });
pokemon.volatiles['gastroacid'] = this.initEffectState({id: 'gastroacid', name: 'Gastro Acid', target: pokemon}); pokemon.volatiles['gastroacid'] = this.initEffectState({ id: 'gastroacid', name: 'Gastro Acid', target: pokemon });
this.add('-message', `${pokemon.side.name}'s ${pokemon.name !== pokemon.species.name ? `${pokemon.name} (${pokemon.species.name})` : pokemon.name} will be skipped next turn.`); this.add('-message', `${pokemon.side.name}'s ${pokemon.name !== pokemon.species.name ? `${pokemon.name} (${pokemon.species.name})` : pokemon.name} will be skipped next turn.`);
} else { } else {
pokemon.removeVolatile('commanding'); pokemon.removeVolatile('commanding');
@ -734,7 +734,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
if (!format.getSharedPower) format = this.dex.formats.get('gen9sharedpower'); if (!format.getSharedPower) format = this.dex.formats.get('gen9sharedpower');
for (const ability of format.getSharedPower!(pokemon)) { for (const ability of format.getSharedPower!(pokemon)) {
const effect = 'ability:' + ability; const effect = 'ability:' + ability;
pokemon.volatiles[effect] = this.initEffectState({id: this.toID(effect), target: pokemon}); pokemon.volatiles[effect] = this.initEffectState({ id: this.toID(effect), target: pokemon });
if (!pokemon.m.abils) pokemon.m.abils = []; if (!pokemon.m.abils) pokemon.m.abils = [];
if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect); if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect);
} }
@ -1007,8 +1007,8 @@ export const Formats: import('../sim/dex-formats').FormatList = [
Object.assign(t.side.slotConditions[t.position]['futuremove'], { Object.assign(t.side.slotConditions[t.position]['futuremove'], {
duration: 3, duration: 3,
move: moveData.id, move: moveData.id,
source: source, source,
moveData: moveData, moveData,
}); });
this.add('-message', `${source.name} foresaw an attack!`); this.add('-message', `${source.name} foresaw an attack!`);
return this.NOT_FAIL; return this.NOT_FAIL;
@ -1075,10 +1075,12 @@ export const Formats: import('../sim/dex-formats').FormatList = [
move.secondaries?.some(secondary => secondary.boosts?.accuracy && secondary.boosts?.accuracy < 0); move.secondaries?.some(secondary => secondary.boosts?.accuracy && secondary.boosts?.accuracy < 0);
const flinchMove = move.secondaries?.some(secondary => secondary.volatileStatus === 'flinch'); const flinchMove = move.secondaries?.some(secondary => secondary.volatileStatus === 'flinch');
const freezeMove = move.secondaries?.some(secondary => secondary.status === 'frz') || move.id === 'triattack'; const freezeMove = move.secondaries?.some(secondary => secondary.status === 'frz') || move.id === 'triattack';
if (this.ruleTable.isRestricted(`move:${move.id}`) || if (
this.ruleTable.isRestricted(`move:${move.id}`) ||
((accuracyLoweringMove || move.ohko || move.multihit || move.id === 'beatup' || move.flags['charge'] || ((accuracyLoweringMove || move.ohko || move.multihit || move.id === 'beatup' || move.flags['charge'] ||
move.priority > 0 || move.damageCallback || flinchMove || freezeMove) && move.priority > 0 || move.damageCallback || flinchMove || freezeMove) &&
!this.ruleTable.has(`+move:${move.id}`))) { !this.ruleTable.has(`+move:${move.id}`))
) {
problems.push(`The move ${move.name} can't be used as an item.`); problems.push(`The move ${move.name} can't be used as an item.`);
} }
return problems.length ? problems : null; return problems.length ? problems : null;
@ -1096,7 +1098,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
onModifyMove(move, pokemon, target) { onModifyMove(move, pokemon, target) {
const forte: ActiveMove = pokemon.m.forte; const forte: ActiveMove = pokemon.m.forte;
if (move.category !== 'Status' && forte) { if (move.category !== 'Status' && forte) {
move.flags = {...move.flags, ...forte.flags}; move.flags = { ...move.flags, ...forte.flags };
if (forte.self) { if (forte.self) {
if (forte.self.onHit && move.self?.onHit) { if (forte.self.onHit && move.self?.onHit) {
for (const i in forte.self) { for (const i in forte.self) {
@ -1104,11 +1106,11 @@ export const Formats: import('../sim/dex-formats').FormatList = [
(move.self as any)[i] = (forte.self as any)[i]; (move.self as any)[i] = (forte.self as any)[i];
} }
} else { } else {
move.self = {...(move.self || {}), ...forte.self}; move.self = { ...(move.self || {}), ...forte.self };
} }
} }
if (forte.selfBoost?.boosts) { if (forte.selfBoost?.boosts) {
if (!move.selfBoost?.boosts) move.selfBoost = {boosts: {}}; if (!move.selfBoost?.boosts) move.selfBoost = { boosts: {} };
let boostid: BoostID; let boostid: BoostID;
for (boostid in forte.selfBoost.boosts) { for (boostid in forte.selfBoost.boosts) {
if (!move.selfBoost.boosts![boostid]) move.selfBoost.boosts![boostid] = 0; if (!move.selfBoost.boosts![boostid]) move.selfBoost.boosts![boostid] = 0;
@ -1340,7 +1342,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
onValidateTeam(team, f, teamHas) { onValidateTeam(team, f, teamHas) {
if (this.ruleTable.has('abilityclause')) { if (this.ruleTable.has('abilityclause')) {
const abilityTable = new this.dex.Multiset<string>(); const abilityTable = new this.dex.Multiset<string>();
const base: {[k: string]: string} = { const base: { [k: string]: string } = {
airlock: 'cloudnine', airlock: 'cloudnine',
armortail: 'queenlymajesty', armortail: 'queenlymajesty',
battlearmor: 'shellarmor', battlearmor: 'shellarmor',
@ -1454,7 +1456,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
}, },
battle: { battle: {
spreadModify(baseStats, set) { spreadModify(baseStats, set) {
const modStats: SparseStatsTable = {atk: 10, def: 10, spa: 10, spd: 10, spe: 10}; const modStats: SparseStatsTable = { atk: 10, def: 10, spa: 10, spd: 10, spe: 10 };
const tr = this.trunc; const tr = this.trunc;
const nature = this.dex.natures.get(set.nature); const nature = this.dex.natures.get(set.nature);
let statName: keyof StatsTable; let statName: keyof StatsTable;
@ -1524,13 +1526,13 @@ export const Formats: import('../sim/dex-formats').FormatList = [
if (!pokemon.m.innate && !BAD_ABILITIES.includes(this.toID(ally.ability))) { if (!pokemon.m.innate && !BAD_ABILITIES.includes(this.toID(ally.ability))) {
pokemon.m.innate = 'ability:' + ally.ability; pokemon.m.innate = 'ability:' + ally.ability;
if (!ngas || ally.getAbility().flags['cantsuppress'] || pokemon.hasItem('Ability Shield')) { if (!ngas || ally.getAbility().flags['cantsuppress'] || pokemon.hasItem('Ability Shield')) {
pokemon.volatiles[pokemon.m.innate] = this.initEffectState({id: pokemon.m.innate, target: pokemon, pic: ally}); pokemon.volatiles[pokemon.m.innate] = this.initEffectState({ id: pokemon.m.innate, target: pokemon, pic: ally });
} }
} }
if (!ally.m.innate && !BAD_ABILITIES.includes(this.toID(pokemon.ability))) { if (!ally.m.innate && !BAD_ABILITIES.includes(this.toID(pokemon.ability))) {
ally.m.innate = 'ability:' + pokemon.ability; ally.m.innate = 'ability:' + pokemon.ability;
if (!ngas || pokemon.getAbility().flags['cantsuppress'] || ally.hasItem('Ability Shield')) { if (!ngas || pokemon.getAbility().flags['cantsuppress'] || ally.hasItem('Ability Shield')) {
ally.volatiles[ally.m.innate] = this.initEffectState({id: ally.m.innate, target: ally, pic: pokemon}); ally.volatiles[ally.m.innate] = this.initEffectState({ id: ally.m.innate, target: ally, pic: pokemon });
} }
} }
} }
@ -1542,7 +1544,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
delete pokemon.m.innate; delete pokemon.m.innate;
} }
const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted);
if (ally && ally.m.innate) { if (ally?.m.innate) {
ally.removeVolatile(ally.m.innate); ally.removeVolatile(ally.m.innate);
delete ally.m.innate; delete ally.m.innate;
} }
@ -1553,7 +1555,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
delete pokemon.m.innate; delete pokemon.m.innate;
} }
const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted); const ally = pokemon.side.active.find(mon => mon && mon !== pokemon && !mon.fainted);
if (ally && ally.m.innate) { if (ally?.m.innate) {
ally.removeVolatile(ally.m.innate); ally.removeVolatile(ally.m.innate);
delete ally.m.innate; delete ally.m.innate;
} }
@ -1618,7 +1620,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
for (const innate of pokemon.m.innates) { for (const innate of pokemon.m.innates) {
if (pokemon.hasAbility(innate)) continue; if (pokemon.hasAbility(innate)) continue;
const effect = 'ability:' + innate; const effect = 'ability:' + innate;
pokemon.volatiles[effect] = this.initEffectState({id: this.toID(effect), target: pokemon}); pokemon.volatiles[effect] = this.initEffectState({ id: this.toID(effect), target: pokemon });
} }
} }
}, },
@ -1688,11 +1690,11 @@ export const Formats: import('../sim/dex-formats').FormatList = [
set.moves.splice(i, 1); set.moves.splice(i, 1);
} }
} }
const allowedPokemoves = this.ruleTable.valueRules.get('allowedpokemoves') || 1; const allowedPokemoves = Number(this.ruleTable.valueRules.get('allowedpokemoves') || '1');
if (pokemoves > Number(allowedPokemoves)) { if (pokemoves > allowedPokemoves) {
problems.push( problems.push(
`${set.species} has ${pokemoves} Pokemoves.`, `${set.species} has ${pokemoves} Pokemoves.`,
`(Pok\u00e9mon can only have ${allowedPokemoves} Pokemove${allowedPokemoves + '' === '1' ? '' : 's'} each.)` `(Pok\u00e9mon can only have ${allowedPokemoves} Pokemove${allowedPokemoves === 1 ? '' : 's'} each.)`
); );
} }
if (this.validateSet(set, teamHas)) { if (this.validateSet(set, teamHas)) {
@ -1812,7 +1814,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
for (const item of format.getSharedItems!(pokemon)) { for (const item of format.getSharedItems!(pokemon)) {
if (pokemon.m.sharedItemsUsed.includes(item)) continue; if (pokemon.m.sharedItemsUsed.includes(item)) continue;
const effect = 'item:' + item; const effect = 'item:' + item;
pokemon.volatiles[effect] = this.initEffectState({id: this.toID(effect), target: pokemon}); pokemon.volatiles[effect] = this.initEffectState({ id: this.toID(effect), target: pokemon });
} }
}, },
}, },
@ -1861,7 +1863,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
move.category = 'Physical'; move.category = 'Physical';
} }
if (teraType === "Stellar") { if (teraType === "Stellar") {
move.self = {boosts: {atk: -1, spa: -1}}; move.self = { boosts: { atk: -1, spa: -1 } };
} }
} }
} }
@ -1890,7 +1892,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
if (move.spreadHit) { if (move.spreadHit) {
// multi-target modifier (doubles only) // multi-target modifier (doubles only)
const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75); const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75);
this.battle.debug('Spread modifier: ' + spreadModifier); this.battle.debug(`Spread modifier: ${spreadModifier}`);
baseDamage = this.battle.modify(baseDamage, spreadModifier); baseDamage = this.battle.modify(baseDamage, spreadModifier);
} else if (move.multihitType === 'parentalbond' && move.hit > 1) { } else if (move.multihitType === 'parentalbond' && move.hit > 1) {
// Parental Bond modifier // Parental Bond modifier
@ -2575,7 +2577,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
// that a pokemon is on a team through the onStart even triggering // that a pokemon is on a team through the onStart even triggering
// at the start of a match, users with pokemon names will need their // at the start of a match, users with pokemon names will need their
// statuses to end in "user". // statuses to end in "user".
name = name + 'user'; name = `${name}user`;
} }
// Add the mon's status effect to it as a volatile. // Add the mon's status effect to it as a volatile.
const status = this.dex.conditions.get(name); const status = this.dex.conditions.get(name);
@ -2617,7 +2619,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
if (!format.getSharedPower) format = this.dex.formats.get('gen9sharedpower'); if (!format.getSharedPower) format = this.dex.formats.get('gen9sharedpower');
for (const ability of format.getSharedPower!(pokemon)) { for (const ability of format.getSharedPower!(pokemon)) {
const effect = 'ability:' + ability; const effect = 'ability:' + ability;
pokemon.volatiles[effect] = this.initEffectState({id: this.toID(effect), target: pokemon}); pokemon.volatiles[effect] = this.initEffectState({ id: this.toID(effect), target: pokemon });
if (!pokemon.m.abils) pokemon.m.abils = []; if (!pokemon.m.abils) pokemon.m.abils = [];
if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect); if (!pokemon.m.abils.includes(effect)) pokemon.m.abils.push(effect);
} }
@ -3075,7 +3077,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
banlist: ['Nonexistent'], banlist: ['Nonexistent'],
onModifySpecies(species, target, source, effect) { onModifySpecies(species, target, source, effect) {
if (!target) return; if (!target) return;
return {...species, ...(target.set as any).hc}; return { ...species, ...(target.set as any).hc };
}, },
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]'); this.add('-start', pokemon, 'typechange', pokemon.getTypes(true).join('/'), '[silent]');
@ -3360,7 +3362,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen8', mod: 'gen8',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -3433,7 +3435,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen8', mod: 'gen8',
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
debug: true, debug: true,
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
@ -3557,7 +3559,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen7', mod: 'gen7',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -3630,7 +3632,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen7', mod: 'gen7',
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
debug: true, debug: true,
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
@ -3751,7 +3753,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen6', mod: 'gen6',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -3804,7 +3806,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen6', mod: 'gen6',
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
debug: true, debug: true,
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
@ -3821,7 +3823,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen6', mod: 'gen6',
gameType: 'triples', gameType: 'triples',
searchShow: false, searchShow: false,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
debug: true, debug: true,
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
@ -3950,7 +3952,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen5', mod: 'gen5',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -3995,7 +3997,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Team Preview', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -4005,7 +4007,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
gameType: 'triples', gameType: 'triples',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions, for serious (other than team preview) // no restrictions, for serious (other than team preview)
ruleset: ['Team Preview', 'Cancel Mod'], ruleset: ['Team Preview', 'Cancel Mod'],
}, },
@ -4111,7 +4113,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen4', mod: 'gen4',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions // no restrictions
ruleset: ['Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -4146,7 +4148,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
gameType: 'doubles', gameType: 'doubles',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
// no restrictions // no restrictions
ruleset: ['Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
@ -4227,7 +4229,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen3', mod: 'gen3',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
{ {
@ -4312,7 +4314,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen2', mod: 'gen2',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
{ {
@ -4393,7 +4395,7 @@ export const Formats: import('../sim/dex-formats').FormatList = [
mod: 'gen1', mod: 'gen1',
searchShow: false, searchShow: false,
debug: true, debug: true,
battle: {trunc: Math.trunc}, battle: { trunc: Math.trunc },
ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Desync Clause Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'], ruleset: ['HP Percentage Mod', 'Cancel Mod', 'Desync Clause Mod', 'Max Team Size = 24', 'Max Move Count = 24', 'Max Level = 9999', 'Default Level = 100'],
}, },
]; ];

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,37 @@
// Data for computer-generated teams // Data for computer-generated teams
export const MOVE_PAIRINGS: {[moveID: IDEntry]: IDEntry} = { export const MOVE_PAIRINGS: { [moveID: IDEntry]: IDEntry } = {
rest: 'sleeptalk', rest: 'sleeptalk',
sleeptalk: 'rest', sleeptalk: 'rest',
}; };
// Bonuses to move ratings by ability // Bonuses to move ratings by ability
export const ABILITY_MOVE_BONUSES: {[abilityID: IDEntry]: {[moveID: IDEntry]: number}} = { export const ABILITY_MOVE_BONUSES: { [abilityID: IDEntry]: { [moveID: IDEntry]: number } } = {
drought: {sunnyday: 0.2, solarbeam: 2}, drought: { sunnyday: 0.2, solarbeam: 2 },
contrary: {terablast: 2}, contrary: { terablast: 2 },
}; };
// Bonuses to move ratings by move type // Bonuses to move ratings by move type
export const ABILITY_MOVE_TYPE_BONUSES: {[abilityID: IDEntry]: {[typeName: string]: number}} = { export const ABILITY_MOVE_TYPE_BONUSES: { [abilityID: IDEntry]: { [typeName: string]: number } } = {
darkaura: {Dark: 1.33}, darkaura: { Dark: 1.33 },
dragonsmaw: {Dragon: 1.5}, dragonsmaw: { Dragon: 1.5 },
fairyaura: {Fairy: 1.33}, fairyaura: { Fairy: 1.33 },
steelworker: {Steel: 1.5}, steelworker: { Steel: 1.5 },
steelyspirit: {Steel: 1.5}, steelyspirit: { Steel: 1.5 },
transistor: {Electric: 1.3}, transistor: { Electric: 1.3 },
// -ate moves // -ate moves
pixilate: {Normal: 1.5 * 1.2}, pixilate: { Normal: 1.5 * 1.2 },
refrigerate: {Normal: 1.5 * 1.2}, refrigerate: { Normal: 1.5 * 1.2 },
aerilate: {Normal: 1.5 * 1.2}, aerilate: { Normal: 1.5 * 1.2 },
normalize: {Normal: 1.2}, normalize: { Normal: 1.2 },
// weather // weather
drizzle: {Water: 1.4, Fire: 0.6}, drizzle: { Water: 1.4, Fire: 0.6 },
drought: {Fire: 1.4, Water: 0.6}, drought: { Fire: 1.4, Water: 0.6 },
}; };
// For moves whose quality isn't obvious from data // For moves whose quality isn't obvious from data
// USE SPARINGLY! // USE SPARINGLY!
export const HARDCODED_MOVE_WEIGHTS: {[moveID: IDEntry]: number} = { export const HARDCODED_MOVE_WEIGHTS: { [moveID: IDEntry]: number } = {
// Fails unless user is asleep // Fails unless user is asleep
snore: 0, snore: 0,
// Hard to use // Hard to use

View File

@ -33,8 +33,8 @@
* - Tracking type coverage to make it more likely that a moveset can hit every type * - Tracking type coverage to make it more likely that a moveset can hit every type
*/ */
import {Dex, PRNG, SQL} from '../sim'; import { Dex, PRNG, SQL } from '../sim';
import {EventMethods} from '../sim/dex-conditions'; import type { EventMethods } from '../sim/dex-conditions';
import { import {
ABILITY_MOVE_BONUSES, ABILITY_MOVE_BONUSES,
ABILITY_MOVE_TYPE_BONUSES, ABILITY_MOVE_TYPE_BONUSES,
@ -45,13 +45,13 @@ import {
} from './cg-team-data'; } from './cg-team-data';
interface TeamStats { interface TeamStats {
hazardSetters: {[moveid: string]: number}; hazardSetters: { [moveid: string]: number };
typeWeaknesses: {[type: string]: number}; typeWeaknesses: { [type: string]: number };
hazardRemovers: number; hazardRemovers: number;
} }
interface MovesStats { interface MovesStats {
attackTypes: {[type: string]: number}; attackTypes: { [type: string]: number };
setup: {atk: number, def: number, spa: number, spd: number, spe: number}; setup: { atk: number, def: number, spa: number, spd: number, spe: number };
noSleepTalk: number; noSleepTalk: number;
hazards: number; hazards: number;
stallingMoves: number; stallingMoves: number;
@ -64,7 +64,7 @@ const MAX_WEAK_TO_SAME_TYPE = 3;
/** An estimate of the highest raw speed in the metagame */ /** An estimate of the highest raw speed in the metagame */
const TOP_SPEED = 300; const TOP_SPEED = 300;
const levelOverride: {[speciesID: string]: number} = {}; const levelOverride: { [speciesID: string]: number } = {};
export let levelUpdateInterval: NodeJS.Timeout | null = null; export let levelUpdateInterval: NodeJS.Timeout | null = null;
// can't import the function cg-teams-leveling.ts uses to this context for some reason // can't import the function cg-teams-leveling.ts uses to this context for some reason
@ -95,7 +95,7 @@ async function updateLevels(database: SQL.DatabaseManager) {
`INSERT INTO gen9_historical_levels (level, species_id, timestamp) VALUES (?, ?, ${Date.now()})` `INSERT INTO gen9_historical_levels (level, species_id, timestamp) VALUES (?, ?, ${Date.now()})`
); );
const data = await database.all('SELECT species_id, wins, losses, level FROM gen9computergeneratedteams'); const data = await database.all('SELECT species_id, wins, losses, level FROM gen9computergeneratedteams');
for (let {species_id, wins, losses, level} of data) { for (let { species_id, wins, losses, level } of data) {
const total = wins + losses; const total = wins + losses;
if (total > 10) { if (total > 10) {
@ -111,7 +111,7 @@ async function updateLevels(database: SQL.DatabaseManager) {
} }
if (global.Config && Config.usesqlite && Config.usesqliteleveling) { if (global.Config && Config.usesqlite && Config.usesqliteleveling) {
const database = SQL(module, {file: './databases/battlestats.db'}); const database = SQL(module, { file: './databases/battlestats.db' });
// update every 2 hours // update every 2 hours
void updateLevels(database); void updateLevels(database);
@ -125,7 +125,7 @@ export default class TeamGenerator {
forceLevel?: number; forceLevel?: number;
prng: PRNG; prng: PRNG;
itemPool: Item[]; itemPool: Item[];
specialItems: {[pokemon: string]: string}; specialItems: { [pokemon: string]: string };
constructor(format: Format | string, seed: PRNG | PRNGSeed | null) { constructor(format: Format | string, seed: PRNG | PRNGSeed | null) {
this.dex = Dex.forFormat(format); this.dex = Dex.forFormat(format);
@ -184,7 +184,7 @@ export default class TeamGenerator {
const moves: Move[] = []; const moves: Move[] = [];
let movesStats: MovesStats = { let movesStats: MovesStats = {
setup: {atk: 0, def: 0, spa: 0, spd: 0, spe: 0}, setup: { atk: 0, def: 0, spa: 0, spd: 0, spe: 0 },
attackTypes: {}, attackTypes: {},
noSleepTalk: 0, noSleepTalk: 0,
hazards: 0, hazards: 0,
@ -210,7 +210,7 @@ export default class TeamGenerator {
// this is just a second reference the array because movePool gets set to point to a new array before the old one // this is just a second reference the array because movePool gets set to point to a new array before the old one
// gets mutated // gets mutated
const movePoolCopy = movePool; const movePoolCopy = movePool;
let interimMovePool: {move: IDEntry, weight: number}[] = []; let interimMovePool: { move: IDEntry, weight: number }[] = [];
while (moves.length < 4 && movePool.length) { while (moves.length < 4 && movePool.length) {
let weights; let weights;
if (!movePoolIsTrimmed) { if (!movePoolIsTrimmed) {
@ -218,7 +218,7 @@ export default class TeamGenerator {
for (const moveID of movePool) { for (const moveID of movePool) {
const move = this.dex.moves.get(moveID); const move = this.dex.moves.get(moveID);
const weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level); const weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level);
interimMovePool.push({move: moveID, weight}); interimMovePool.push({ move: moveID, weight });
} }
interimMovePool.sort((a, b) => b.weight - a.weight); interimMovePool.sort((a, b) => b.weight - a.weight);
@ -233,13 +233,13 @@ export default class TeamGenerator {
const move = this.dex.moves.get(moveID); const move = this.dex.moves.get(moveID);
if (moves.includes(move)) continue; if (moves.includes(move)) continue;
const weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level); const weight = this.getMoveWeight(move, teamStats, species, moves, movesStats, ability, level);
interimMovePool.push({move: moveID, weight}); interimMovePool.push({ move: moveID, weight });
} }
interimMovePool.sort((a, b) => b.weight - a.weight); interimMovePool.sort((a, b) => b.weight - a.weight);
moves.splice(0); moves.splice(0);
movesStats = { movesStats = {
setup: {atk: 0, def: 0, spa: 0, spd: 0, spe: 0}, setup: { atk: 0, def: 0, spa: 0, spd: 0, spe: 0 },
attackTypes: {}, attackTypes: {},
noSleepTalk: 0, noSleepTalk: 0,
hazards: 0, hazards: 0,
@ -262,7 +262,7 @@ export default class TeamGenerator {
); );
} }
const moveID = this.weightedRandomPick(movePool, weights, {remove: true}); const moveID = this.weightedRandomPick(movePool, weights, { remove: true });
const move = this.dex.moves.get(moveID); const move = this.dex.moves.get(moveID);
moves.push(move); moves.push(move);
@ -392,7 +392,7 @@ export default class TeamGenerator {
moves: moves.map(m => m.name), moves: moves.map(m => m.name),
nature: 'Quirky', nature: 'Quirky',
gender: species.gender, gender: species.gender,
evs: {hp: 84, atk: 84, def: 84, spa: 84, spd: 84, spe: 84}, evs: { hp: 84, atk: 84, def: 84, spa: 84, spd: 84, spe: 84 },
ivs, ivs,
level, level,
teraType, teraType,
@ -493,7 +493,7 @@ export default class TeamGenerator {
weight *= 32; weight *= 32;
// these moves can also lessen the effectiveness of the user's team's own hazards // these moves can also lessen the effectiveness of the user's team's own hazards
weight *= Math.pow(0.8, Object.values(teamStats.hazardSetters).reduce((total, num) => total + num, 0)); weight *= 0.8 ** Object.values(teamStats.hazardSetters).reduce((total, num) => total + num, 0);
} }
// boosts // boosts
@ -639,8 +639,8 @@ export default class TeamGenerator {
if (move.category === 'Special') powerEstimate *= Math.max(0.5, 1 + specialSetup) / Math.max(0.5, 1 + physicalSetup); if (move.category === 'Special') powerEstimate *= Math.max(0.5, 1 + specialSetup) / Math.max(0.5, 1 + physicalSetup);
const abilityBonus = ( const abilityBonus = (
((ABILITY_MOVE_BONUSES[this.dex.toID(ability)] || {})[move.id] || 1) * (ABILITY_MOVE_BONUSES[this.dex.toID(ability)]?.[move.id] || 1) *
((ABILITY_MOVE_TYPE_BONUSES[this.dex.toID(ability)] || {})[moveType] || 1) (ABILITY_MOVE_TYPE_BONUSES[this.dex.toID(ability)]?.[moveType] || 1)
); );
let weight = powerEstimate * abilityBonus; let weight = powerEstimate * abilityBonus;
@ -664,7 +664,7 @@ export default class TeamGenerator {
if (move.flags.contact) { if (move.flags.contact) {
if (ability === 'Tough Claws') weight *= 1.3; if (ability === 'Tough Claws') weight *= 1.3;
if (ability === 'Unseen Fist') weight *= 1.1; if (ability === 'Unseen Fist') weight *= 1.1;
if (ability === 'Poison Touch') weight *= TeamGenerator.statusWeight('psn', 1 - Math.pow(0.7, numberOfHits)); if (ability === 'Poison Touch') weight *= TeamGenerator.statusWeight('psn', 1 - (0.7 ** numberOfHits));
} }
if (move.flags.bite && ability === 'Strong Jaw') weight *= 1.5; if (move.flags.bite && ability === 'Strong Jaw') weight *= 1.5;
// 5% boost for ability to break subs // 5% boost for ability to break subs
@ -697,7 +697,7 @@ export default class TeamGenerator {
} }
} }
} }
if (ability === 'Toxic Chain') weight *= TeamGenerator.statusWeight('tox', 1 - Math.pow(0.7, numberOfHits)); if (ability === 'Toxic Chain') weight *= TeamGenerator.statusWeight('tox', 1 - (0.7 ** numberOfHits));
// Special effect if something special happened earlier in the turn // Special effect if something special happened earlier in the turn
// More useful on slower Pokemon // More useful on slower Pokemon
@ -734,7 +734,7 @@ export default class TeamGenerator {
// these two hazard removers don't clear hazards on the opponent's field, but can be blocked by type immunities // these two hazard removers don't clear hazards on the opponent's field, but can be blocked by type immunities
if (['rapidspin', 'mortalspin'].includes(move.id)) { if (['rapidspin', 'mortalspin'].includes(move.id)) {
weight *= 1 + 20 * Math.pow(0.25, teamStats.hazardRemovers); weight *= 1 + 20 * (0.25 ** teamStats.hazardRemovers);
} }
// these moves have a hard-coded 16x bonus // these moves have a hard-coded 16x bonus
@ -845,10 +845,10 @@ export default class TeamGenerator {
const abilityMod = ability === 'Simple' ? 2 : ability === 'Contrary' ? -1 : 1; const abilityMod = ability === 'Simple' ? 2 : ability === 'Contrary' ? -1 : 1;
const bodyPressMod = movesSoFar.some(m => m.id === 'bodyPress') ? 2 : 1; const bodyPressMod = movesSoFar.some(m => m.id === 'bodyPress') ? 2 : 1;
const electroBallMod = movesSoFar.some(m => m.id === 'electroball') ? 2 : 1; const electroBallMod = movesSoFar.some(m => m.id === 'electroball') ? 2 : 1;
for (const {chance, boosts} of [ for (const { chance, boosts } of [
{chance: 1, boosts: move.boosts}, { chance: 1, boosts: move.boosts },
{chance: 1, boosts: move.self?.boosts}, { chance: 1, boosts: move.self?.boosts },
{chance: 1, boosts: move.selfBoost?.boosts}, { chance: 1, boosts: move.selfBoost?.boosts },
{ {
chance: secondaryChance, chance: secondaryChance,
boosts: move.secondary?.self?.boosts, boosts: move.secondary?.self?.boosts,
@ -883,8 +883,8 @@ export default class TeamGenerator {
if (!['allAdjacentFoes', 'allAdjacent', 'foeSide', 'normal'].includes(move.target)) return 1; if (!['allAdjacentFoes', 'allAdjacent', 'foeSide', 'normal'].includes(move.target)) return 1;
let averageNumberOfDebuffs = 0; let averageNumberOfDebuffs = 0;
for (const {chance, boosts} of [ for (const { chance, boosts } of [
{chance: 1, boosts: move.boosts}, { chance: 1, boosts: move.boosts },
{ {
chance: move.secondary ? ((move.secondary.chance || 100) / 100) : 0, chance: move.secondary ? ((move.secondary.chance || 100) / 100) : 0,
boosts: move.secondary?.boosts, boosts: move.secondary?.boosts,
@ -1046,7 +1046,7 @@ export default class TeamGenerator {
weightedRandomPick<T>( weightedRandomPick<T>(
choices: T[], choices: T[],
weights: number[], weights: number[],
options?: {remove?: boolean} options?: { remove?: boolean }
) { ) {
if (!choices.length) throw new Error(`Can't pick from an empty list`); if (!choices.length) throw new Error(`Can't pick from an empty list`);
if (choices.length !== weights.length) throw new Error(`Choices and weights must be the same length`); if (choices.length !== weights.length) throw new Error(`Choices and weights must be the same length`);

View File

@ -6,7 +6,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
if (sourceEffect && sourceEffect.id === 'flameorb') { if (sourceEffect && sourceEffect.id === 'flameorb') {
this.add('-status', target, 'brn', '[from] item: Flame Orb'); this.add('-status', target, 'brn', '[from] item: Flame Orb');
} else if (sourceEffect && sourceEffect.effectType === 'Ability') { } else if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'brn', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'brn', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-status', target, 'brn'); this.add('-status', target, 'brn');
} }
@ -22,7 +22,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Ability') { if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'par', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'par', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-status', target, 'par'); this.add('-status', target, 'par');
} }
@ -49,9 +49,9 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Ability') { if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else if (sourceEffect && sourceEffect.effectType === 'Move') { } else if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }
@ -85,7 +85,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Ability') { if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'frz', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'frz', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-status', target, 'frz'); this.add('-status', target, 'frz');
} }
@ -106,7 +106,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
}, },
onModifyMove(move, pokemon) { onModifyMove(move, pokemon) {
if (move.flags['defrost']) { if (move.flags['defrost']) {
this.add('-curestatus', pokemon, 'frz', '[from] move: ' + move); this.add('-curestatus', pokemon, 'frz', `[from] move: ${move}`);
pokemon.clearStatus(); pokemon.clearStatus();
} }
}, },
@ -126,7 +126,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Ability') { if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'psn', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'psn', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-status', target, 'psn'); this.add('-status', target, 'psn');
} }
@ -144,7 +144,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
if (sourceEffect && sourceEffect.id === 'toxicorb') { if (sourceEffect && sourceEffect.id === 'toxicorb') {
this.add('-status', target, 'tox', '[from] item: Toxic Orb'); this.add('-status', target, 'tox', '[from] item: Toxic Orb');
} else if (sourceEffect && sourceEffect.effectType === 'Ability') { } else if (sourceEffect && sourceEffect.effectType === 'Ability') {
this.add('-status', target, 'tox', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-status', target, 'tox', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-status', target, 'tox'); this.add('-status', target, 'tox');
} }
@ -167,7 +167,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
if (sourceEffect?.id === 'lockedmove') { if (sourceEffect?.id === 'lockedmove') {
this.add('-start', target, 'confusion', '[fatigue]'); this.add('-start', target, 'confusion', '[fatigue]');
} else if (sourceEffect?.effectType === 'Ability') { } else if (sourceEffect?.effectType === 'Ability') {
this.add('-start', target, 'confusion', '[from] ability: ' + sourceEffect.name, '[of] ' + source); this.add('-start', target, 'confusion', '[from] ability: ' + sourceEffect.name, `[of] ${source}`);
} else { } else {
this.add('-start', target, 'confusion'); this.add('-start', target, 'confusion');
} }
@ -191,7 +191,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
this.activeTarget = pokemon; this.activeTarget = pokemon;
const damage = this.actions.getConfusionDamage(pokemon, 40); const damage = this.actions.getConfusionDamage(pokemon, 40);
if (typeof damage !== 'number') throw new Error("Confusion damage not dealt"); if (typeof damage !== 'number') throw new Error("Confusion damage not dealt");
const activeMove = {id: this.toID('confused'), effectType: 'Move', type: '???'}; const activeMove = { id: this.toID('confused'), effectType: 'Move', type: '???' };
this.damage(damage, pokemon, pokemon, activeMove as ActiveMove); this.damage(damage, pokemon, pokemon, activeMove as ActiveMove);
return false; return false;
}, },
@ -228,7 +228,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
return this.random(5, 7); return this.random(5, 7);
}, },
onStart(pokemon, source) { onStart(pokemon, source) {
this.add('-activate', pokemon, 'move: ' + this.effectState.sourceEffect, '[of] ' + source); this.add('-activate', pokemon, 'move: ' + this.effectState.sourceEffect, `[of] ${source}`);
this.effectState.boundDivisor = source.hasItem('bindingband') ? 6 : 8; this.effectState.boundDivisor = source.hasItem('bindingband') ? 6 : 8;
}, },
onResidualOrder: 13, onResidualOrder: 13,
@ -444,7 +444,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
// this.effectState.counter should never be undefined here. // this.effectState.counter should never be undefined here.
// However, just in case, use 1 if it is undefined. // However, just in case, use 1 if it is undefined.
const counter = this.effectState.counter || 1; const counter = this.effectState.counter || 1;
this.debug("Success chance: " + Math.round(100 / counter) + "%"); this.debug(`Success chance: ${Math.round(100 / counter)}%`);
const success = this.randomChance(1, counter); const success = this.randomChance(1, counter);
if (!success) delete pokemon.volatiles['stall']; if (!success) delete pokemon.volatiles['stall'];
return success; return success;
@ -493,7 +493,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'RainDance', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'RainDance', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'RainDance'); this.add('-weather', 'RainDance');
} }
@ -528,7 +528,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
} }
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
this.add('-weather', 'PrimordialSea', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'PrimordialSea', '[from] ability: ' + effect.name, `[of] ${source}`);
}, },
onFieldResidualOrder: 1, onFieldResidualOrder: 1,
onFieldResidual() { onFieldResidual() {
@ -567,7 +567,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
onFieldStart(battle, source, effect) { onFieldStart(battle, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'SunnyDay', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'SunnyDay', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'SunnyDay'); this.add('-weather', 'SunnyDay');
} }
@ -606,7 +606,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
} }
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
this.add('-weather', 'DesolateLand', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'DesolateLand', '[from] ability: ' + effect.name, `[of] ${source}`);
}, },
onImmunity(type, pokemon) { onImmunity(type, pokemon) {
if (pokemon.hasItem('utilityumbrella')) return; if (pokemon.hasItem('utilityumbrella')) return;
@ -642,7 +642,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'Sandstorm', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'Sandstorm', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'Sandstorm'); this.add('-weather', 'Sandstorm');
} }
@ -672,7 +672,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'Hail', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'Hail', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'Hail'); this.add('-weather', 'Hail');
} }
@ -708,7 +708,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'Snowscape', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'Snowscape', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'Snowscape'); this.add('-weather', 'Snowscape');
} }
@ -734,7 +734,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
} }
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
this.add('-weather', 'DeltaStream', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'DeltaStream', '[from] ability: ' + effect.name, `[of] ${source}`);
}, },
onFieldResidualOrder: 1, onFieldResidualOrder: 1,
onFieldResidual() { onFieldResidual() {
@ -806,7 +806,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
name: "Commanded", name: "Commanded",
noCopy: true, noCopy: true,
onStart(pokemon) { onStart(pokemon) {
this.boost({atk: 2, spa: 2, spe: 2, def: 2, spd: 2}, pokemon); this.boost({ atk: 2, spa: 2, spe: 2, def: 2, spd: 2 }, pokemon);
}, },
onDragOutPriority: 2, onDragOutPriority: 2,
onDragOut() { onDragOut() {
@ -880,7 +880,7 @@ export const Conditions: import('../sim/dex-conditions').ConditionDataTable = {
duration: 2, duration: 2,
onBasePower(relayVar, source, target, move) { onBasePower(relayVar, source, target, move) {
let bp = Math.max(1, move.basePower); let bp = Math.max(1, move.basePower);
bp *= Math.pow(2, source.volatiles['rolloutstorage'].contactHitCount); bp *= 2 ** source.volatiles['rolloutstorage'].contactHitCount;
if (source.volatiles['defensecurl']) { if (source.volatiles['defensecurl']) {
bp *= 2; bp *= 2;
} }

View File

@ -276,7 +276,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({spd: 1}); this.boost({ spd: 1 });
}, },
num: 205, num: 205,
gen: 3, gen: 3,
@ -922,7 +922,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
}, },
onStart(pokemon) { onStart(pokemon) {
if (pokemon.volatiles['choicelock']) { if (pokemon.volatiles['choicelock']) {
this.debug('removing choicelock: ' + pokemon.volatiles['choicelock']); this.debug('removing choicelock');
} }
pokemon.removeVolatile('choicelock'); pokemon.removeVolatile('choicelock');
}, },
@ -946,7 +946,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
}, },
onStart(pokemon) { onStart(pokemon) {
if (pokemon.volatiles['choicelock']) { if (pokemon.volatiles['choicelock']) {
this.debug('removing choicelock: ' + pokemon.volatiles['choicelock']); this.debug('removing choicelock');
} }
pokemon.removeVolatile('choicelock'); pokemon.removeVolatile('choicelock');
}, },
@ -969,7 +969,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
}, },
onStart(pokemon) { onStart(pokemon) {
if (pokemon.volatiles['choicelock']) { if (pokemon.volatiles['choicelock']) {
this.debug('removing choicelock: ' + pokemon.volatiles['choicelock']); this.debug('removing choicelock');
} }
pokemon.removeVolatile('choicelock'); pokemon.removeVolatile('choicelock');
}, },
@ -1037,7 +1037,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
} }
if (showMsg && !(effect as ActiveMove).secondaries && effect.id !== 'octolock') { if (showMsg && !(effect as ActiveMove).secondaries && effect.id !== 'octolock') {
this.add('-fail', target, 'unboost', '[from] item: Clear Amulet', '[of] ' + target); this.add('-fail', target, 'unboost', '[from] item: Clear Amulet', `[of] ${target}`);
} }
}, },
num: 1882, num: 1882,
@ -1304,7 +1304,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
}, },
onAttractPriority: -100, onAttractPriority: -100,
onAttract(target, source) { onAttract(target, source) {
this.debug('attract intercepted: ' + target + ' from ' + source); this.debug(`attract intercepted: ${target} from ${source}`);
if (!source || source === target) return; if (!source || source === target) return;
if (!source.volatiles['attract']) source.addVolatile('attract', target); if (!source.volatiles['attract']) source.addVolatile('attract', target);
}, },
@ -2164,7 +2164,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({def: 1}); this.boost({ def: 1 });
}, },
num: 202, num: 202,
gen: 3, gen: 3,
@ -2872,7 +2872,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({def: 1}); this.boost({ def: 1 });
}, },
num: 687, num: 687,
gen: 6, gen: 6,
@ -3097,7 +3097,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({atk: 1}); this.boost({ atk: 1 });
}, },
num: 201, num: 201,
gen: 3, gen: 3,
@ -3465,7 +3465,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({spd: 1}); this.boost({ spd: 1 });
}, },
num: 688, num: 688,
gen: 6, gen: 6,
@ -3809,7 +3809,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
let i: BoostID; let i: BoostID;
for (i in boost) { for (i in boost) {
if (boost[i]! > 0) { if (boost[i]! > 0) {
boostPlus[i] = (boostPlus[i] || 0) + boost[i]; boostPlus[i] = (boostPlus[i] || 0) + boost[i]!;
this.effectState.ready = true; this.effectState.ready = true;
} }
} }
@ -4190,7 +4190,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({spa: 1}); this.boost({ spa: 1 });
}, },
num: 204, num: 204,
gen: 3, gen: 3,
@ -5100,7 +5100,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
} }
}, },
onEat(pokemon) { onEat(pokemon) {
this.boost({spe: 1}); this.boost({ spe: 1 });
}, },
num: 203, num: 203,
gen: 3, gen: 3,

View File

@ -80,7 +80,7 @@ export const Scripts: ModdedBattleScriptsData = {
const isPhysical = move.category === 'Physical'; const isPhysical = move.category === 'Physical';
const defenseStat: StatIDExceptHP = move.overrideDefensiveStat || (isPhysical ? 'def' : 'spd'); const defenseStat: StatIDExceptHP = move.overrideDefensiveStat || (isPhysical ? 'def' : 'spd');
const statTable: {[k in StatIDExceptHP]: string} = {atk: 'Atk', def: 'Def', spa: 'SpA', spd: 'SpD', spe: 'Spe'}; const statTable: { [k in StatIDExceptHP]: string } = { atk: 'Atk', def: 'Def', spa: 'SpA', spd: 'SpD', spe: 'Spe' };
let maxAttack = 0; let maxAttack = 0;

View File

@ -55,7 +55,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }
@ -155,7 +155,6 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
pokemon.removeVolatile('lockedmove'); pokemon.removeVolatile('lockedmove');
return false; return false;
} }
return;
}, },
}, },
flinch: { flinch: {
@ -234,7 +233,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
const move = this.dex.moves.get(this.effectState.move); const move = this.dex.moves.get(this.effectState.move);
if (move.id) { if (move.id) {
this.debug('Forcing into ' + move.id); this.debug('Forcing into ' + move.id);
this.queue.changeAction(pokemon, {choice: 'move', moveid: move.id}); this.queue.changeAction(pokemon, { choice: 'move', moveid: move.id });
} }
}, },
}, },

View File

@ -53,7 +53,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return false; return false;
} }
const target = this.getRandomTarget(pokemon, 'Pound'); const target = this.getRandomTarget(pokemon, 'Pound');
this.actions.moveHit(target, pokemon, currentMove, {damage: this.effectState.damage * 2} as ActiveMove); this.actions.moveHit(target, pokemon, currentMove, { damage: this.effectState.damage * 2 } as ActiveMove);
pokemon.removeVolatile('bide'); pokemon.removeVolatile('bide');
return false; return false;
} }
@ -175,7 +175,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target: "normal", target: "normal",
onHit(target, source) { onHit(target, source) {
source.setType(target.getTypes(true)); source.setType(target.getTypes(true));
this.add('-start', source, 'typechange', source.types.join('/'), '[from] move: Conversion', '[of] ' + target); this.add('-start', source, 'typechange', source.types.join('/'), '[from] move: Conversion', `[of] ${target}`);
}, },
}, },
counter: { counter: {
@ -217,7 +217,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return 2 * this.lastDamage; return 2 * this.lastDamage;
}, },
flags: {contact: 1, protect: 1, metronome: 1}, flags: { contact: 1, protect: 1, metronome: 1 },
}, },
crabhammer: { crabhammer: {
inherit: true, inherit: true,
@ -246,7 +246,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Disable", name: "Disable",
pp: 20, pp: 20,
priority: 0, priority: 0,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
volatileStatus: 'disable', volatileStatus: 'disable',
onTryHit(target) { onTryHit(target) {
// This function should not return if the checks are met. Adding && undefined ensures this happens. // This function should not return if the checks are met. Adding && undefined ensures this happens.
@ -402,7 +402,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// in-game, so it is equivalent to just clear it. // in-game, so it is equivalent to just clear it.
const silentHack = '|[silent]'; const silentHack = '|[silent]';
const silentHackVolatiles = ['disable', 'confusion']; const silentHackVolatiles = ['disable', 'confusion'];
const hazeVolatiles: {[key: string]: string} = { const hazeVolatiles: { [key: string]: string } = {
'disable': '', 'disable': '',
'confusion': '', 'confusion': '',
'mist': 'Mist', 'mist': 'Mist',
@ -485,7 +485,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Light Screen", name: "Light Screen",
pp: 30, pp: 30,
priority: 0, priority: 0,
flags: {metronome: 1}, flags: { metronome: 1 },
volatileStatus: 'lightscreen', volatileStatus: 'lightscreen',
onTryHit(pokemon) { onTryHit(pokemon) {
if (pokemon.volatiles['lightscreen']) { if (pokemon.volatiles['lightscreen']) {
@ -502,7 +502,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mimic: { mimic: {
inherit: true, inherit: true,
flags: {protect: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, bypasssub: 1, metronome: 1 },
onHit(target, source) { onHit(target, source) {
const moveslot = source.moves.indexOf('mimic'); const moveslot = source.moves.indexOf('mimic');
if (moveslot < 0) return false; if (moveslot < 0) return false;
@ -611,7 +611,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onHit(target, source, move) { onHit(target, source, move) {
// Disable and exploding moves boost Rage even if they miss/fail, so they are dealt with separately. // Disable and exploding moves boost Rage even if they miss/fail, so they are dealt with separately.
if (target.boosts.atk < 6 && (move.category !== 'Status' && !move.selfdestruct)) { if (target.boosts.atk < 6 && (move.category !== 'Status' && !move.selfdestruct)) {
this.boost({atk: 1}); this.boost({ atk: 1 });
} }
}, },
}, },
@ -662,7 +662,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Reflect", name: "Reflect",
pp: 20, pp: 20,
priority: 0, priority: 0,
flags: {metronome: 1}, flags: { metronome: 1 },
volatileStatus: 'reflect', volatileStatus: 'reflect',
onTryHit(pokemon) { onTryHit(pokemon) {
if (pokemon.volatiles['reflect']) { if (pokemon.volatiles['reflect']) {
@ -815,7 +815,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Substitute", name: "Substitute",
pp: 10, pp: 10,
priority: 0, priority: 0,
flags: {metronome: 1}, flags: { metronome: 1 },
volatileStatus: 'substitute', volatileStatus: 'substitute',
onTryHit(target) { onTryHit(target) {
if (target.volatiles['substitute']) { if (target.volatiles['substitute']) {
@ -876,8 +876,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// Drain/recoil/secondary effect confusion do not happen if the substitute breaks // Drain/recoil/secondary effect confusion do not happen if the substitute breaks
if (target.volatiles['substitute']) { if (target.volatiles['substitute']) {
if (move.recoil) { if (move.recoil) {
this.damage(this.clampIntRange(Math.floor(uncappedDamage * move.recoil[0] / move.recoil[1]), 1) this.damage(this.clampIntRange(Math.floor(uncappedDamage * move.recoil[0] / move.recoil[1]), 1),
, source, target, 'recoil'); source, target, 'recoil');
} }
if (move.drain) { if (move.drain) {
const amount = this.clampIntRange(Math.floor(uncappedDamage * move.drain[0] / move.drain[1]), 1); const amount = this.clampIntRange(Math.floor(uncappedDamage * move.drain[0] / move.drain[1]), 1);
@ -899,7 +899,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// Add here counter damage // Add here counter damage
const lastAttackedBy = target.getLastAttackedBy(); const lastAttackedBy = target.getLastAttackedBy();
if (!lastAttackedBy) { if (!lastAttackedBy) {
target.attackedBy.push({source: source, move: move.id, damage: uncappedDamage, slot: source.getSlot(), thisTurn: true}); target.attackedBy.push({ source, move: move.id, damage: uncappedDamage, slot: source.getSlot(), thisTurn: true });
} else { } else {
lastAttackedBy.move = move.id; lastAttackedBy.move = move.id;
lastAttackedBy.damage = uncappedDamage; lastAttackedBy.damage = uncappedDamage;

View File

@ -1,612 +1,612 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
missingno: { missingno: {
inherit: true, inherit: true,
baseStats: {hp: 33, atk: 136, def: 0, spa: 6, spd: 6, spe: 29}, baseStats: { hp: 33, atk: 136, def: 0, spa: 6, spd: 6, spe: 29 },
}, },
bulbasaur: { bulbasaur: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 49, def: 49, spa: 65, spd: 65, spe: 45}, baseStats: { hp: 45, atk: 49, def: 49, spa: 65, spd: 65, spe: 45 },
}, },
ivysaur: { ivysaur: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 62, def: 63, spa: 80, spd: 80, spe: 60}, baseStats: { hp: 60, atk: 62, def: 63, spa: 80, spd: 80, spe: 60 },
}, },
venusaur: { venusaur: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 82, def: 83, spa: 100, spd: 100, spe: 80}, baseStats: { hp: 80, atk: 82, def: 83, spa: 100, spd: 100, spe: 80 },
}, },
charmander: { charmander: {
inherit: true, inherit: true,
baseStats: {hp: 39, atk: 52, def: 43, spa: 50, spd: 50, spe: 65}, baseStats: { hp: 39, atk: 52, def: 43, spa: 50, spd: 50, spe: 65 },
}, },
charmeleon: { charmeleon: {
inherit: true, inherit: true,
baseStats: {hp: 58, atk: 64, def: 58, spa: 65, spd: 65, spe: 80}, baseStats: { hp: 58, atk: 64, def: 58, spa: 65, spd: 65, spe: 80 },
}, },
charizard: { charizard: {
inherit: true, inherit: true,
baseStats: {hp: 78, atk: 84, def: 78, spa: 85, spd: 85, spe: 100}, baseStats: { hp: 78, atk: 84, def: 78, spa: 85, spd: 85, spe: 100 },
}, },
squirtle: { squirtle: {
inherit: true, inherit: true,
baseStats: {hp: 44, atk: 48, def: 65, spa: 50, spd: 50, spe: 43}, baseStats: { hp: 44, atk: 48, def: 65, spa: 50, spd: 50, spe: 43 },
}, },
wartortle: { wartortle: {
inherit: true, inherit: true,
baseStats: {hp: 59, atk: 63, def: 80, spa: 65, spd: 65, spe: 58}, baseStats: { hp: 59, atk: 63, def: 80, spa: 65, spd: 65, spe: 58 },
}, },
blastoise: { blastoise: {
inherit: true, inherit: true,
baseStats: {hp: 79, atk: 83, def: 100, spa: 85, spd: 85, spe: 78}, baseStats: { hp: 79, atk: 83, def: 100, spa: 85, spd: 85, spe: 78 },
}, },
caterpie: { caterpie: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 30, def: 35, spa: 20, spd: 20, spe: 45}, baseStats: { hp: 45, atk: 30, def: 35, spa: 20, spd: 20, spe: 45 },
}, },
metapod: { metapod: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 20, def: 55, spa: 25, spd: 25, spe: 30}, baseStats: { hp: 50, atk: 20, def: 55, spa: 25, spd: 25, spe: 30 },
}, },
butterfree: { butterfree: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 45, def: 50, spa: 80, spd: 80, spe: 70}, baseStats: { hp: 60, atk: 45, def: 50, spa: 80, spd: 80, spe: 70 },
}, },
weedle: { weedle: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 35, def: 30, spa: 20, spd: 20, spe: 50}, baseStats: { hp: 40, atk: 35, def: 30, spa: 20, spd: 20, spe: 50 },
}, },
kakuna: { kakuna: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 25, def: 50, spa: 25, spd: 25, spe: 35}, baseStats: { hp: 45, atk: 25, def: 50, spa: 25, spd: 25, spe: 35 },
}, },
beedrill: { beedrill: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 80, def: 40, spa: 45, spd: 45, spe: 75}, baseStats: { hp: 65, atk: 80, def: 40, spa: 45, spd: 45, spe: 75 },
}, },
pidgey: { pidgey: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 45, def: 40, spa: 35, spd: 35, spe: 56}, baseStats: { hp: 40, atk: 45, def: 40, spa: 35, spd: 35, spe: 56 },
}, },
pidgeotto: { pidgeotto: {
inherit: true, inherit: true,
baseStats: {hp: 63, atk: 60, def: 55, spa: 50, spd: 50, spe: 71}, baseStats: { hp: 63, atk: 60, def: 55, spa: 50, spd: 50, spe: 71 },
}, },
pidgeot: { pidgeot: {
inherit: true, inherit: true,
baseStats: {hp: 83, atk: 80, def: 75, spa: 70, spd: 70, spe: 91}, baseStats: { hp: 83, atk: 80, def: 75, spa: 70, spd: 70, spe: 91 },
}, },
rattata: { rattata: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 56, def: 35, spa: 25, spd: 25, spe: 72}, baseStats: { hp: 30, atk: 56, def: 35, spa: 25, spd: 25, spe: 72 },
}, },
raticate: { raticate: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 81, def: 60, spa: 50, spd: 50, spe: 97}, baseStats: { hp: 55, atk: 81, def: 60, spa: 50, spd: 50, spe: 97 },
}, },
spearow: { spearow: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 60, def: 30, spa: 31, spd: 31, spe: 70}, baseStats: { hp: 40, atk: 60, def: 30, spa: 31, spd: 31, spe: 70 },
}, },
fearow: { fearow: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 90, def: 65, spa: 61, spd: 61, spe: 100}, baseStats: { hp: 65, atk: 90, def: 65, spa: 61, spd: 61, spe: 100 },
}, },
ekans: { ekans: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 60, def: 44, spa: 40, spd: 40, spe: 55}, baseStats: { hp: 35, atk: 60, def: 44, spa: 40, spd: 40, spe: 55 },
}, },
arbok: { arbok: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 85, def: 69, spa: 65, spd: 65, spe: 80}, baseStats: { hp: 60, atk: 85, def: 69, spa: 65, spd: 65, spe: 80 },
}, },
pikachu: { pikachu: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 55, def: 30, spa: 50, spd: 50, spe: 90}, baseStats: { hp: 35, atk: 55, def: 30, spa: 50, spd: 50, spe: 90 },
}, },
raichu: { raichu: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 90, def: 55, spa: 90, spd: 90, spe: 100}, baseStats: { hp: 60, atk: 90, def: 55, spa: 90, spd: 90, spe: 100 },
}, },
sandshrew: { sandshrew: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 75, def: 85, spa: 30, spd: 30, spe: 40}, baseStats: { hp: 50, atk: 75, def: 85, spa: 30, spd: 30, spe: 40 },
}, },
sandslash: { sandslash: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 100, def: 110, spa: 55, spd: 55, spe: 65}, baseStats: { hp: 75, atk: 100, def: 110, spa: 55, spd: 55, spe: 65 },
}, },
nidoranf: { nidoranf: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 47, def: 52, spa: 40, spd: 40, spe: 41}, baseStats: { hp: 55, atk: 47, def: 52, spa: 40, spd: 40, spe: 41 },
}, },
nidorina: { nidorina: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 62, def: 67, spa: 55, spd: 55, spe: 56}, baseStats: { hp: 70, atk: 62, def: 67, spa: 55, spd: 55, spe: 56 },
}, },
nidoqueen: { nidoqueen: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 82, def: 87, spa: 75, spd: 75, spe: 76}, baseStats: { hp: 90, atk: 82, def: 87, spa: 75, spd: 75, spe: 76 },
}, },
nidoranm: { nidoranm: {
inherit: true, inherit: true,
baseStats: {hp: 46, atk: 57, def: 40, spa: 40, spd: 40, spe: 50}, baseStats: { hp: 46, atk: 57, def: 40, spa: 40, spd: 40, spe: 50 },
}, },
nidorino: { nidorino: {
inherit: true, inherit: true,
baseStats: {hp: 61, atk: 72, def: 57, spa: 55, spd: 55, spe: 65}, baseStats: { hp: 61, atk: 72, def: 57, spa: 55, spd: 55, spe: 65 },
}, },
nidoking: { nidoking: {
inherit: true, inherit: true,
baseStats: {hp: 81, atk: 92, def: 77, spa: 75, spd: 75, spe: 85}, baseStats: { hp: 81, atk: 92, def: 77, spa: 75, spd: 75, spe: 85 },
}, },
clefairy: { clefairy: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 45, def: 48, spa: 60, spd: 60, spe: 35}, baseStats: { hp: 70, atk: 45, def: 48, spa: 60, spd: 60, spe: 35 },
}, },
clefable: { clefable: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 70, def: 73, spa: 85, spd: 85, spe: 60}, baseStats: { hp: 95, atk: 70, def: 73, spa: 85, spd: 85, spe: 60 },
}, },
vulpix: { vulpix: {
inherit: true, inherit: true,
baseStats: {hp: 38, atk: 41, def: 40, spa: 65, spd: 65, spe: 65}, baseStats: { hp: 38, atk: 41, def: 40, spa: 65, spd: 65, spe: 65 },
}, },
ninetales: { ninetales: {
inherit: true, inherit: true,
baseStats: {hp: 73, atk: 76, def: 75, spa: 100, spd: 100, spe: 100}, baseStats: { hp: 73, atk: 76, def: 75, spa: 100, spd: 100, spe: 100 },
}, },
jigglypuff: { jigglypuff: {
inherit: true, inherit: true,
baseStats: {hp: 115, atk: 45, def: 20, spa: 25, spd: 25, spe: 20}, baseStats: { hp: 115, atk: 45, def: 20, spa: 25, spd: 25, spe: 20 },
}, },
wigglytuff: { wigglytuff: {
inherit: true, inherit: true,
baseStats: {hp: 140, atk: 70, def: 45, spa: 50, spd: 50, spe: 45}, baseStats: { hp: 140, atk: 70, def: 45, spa: 50, spd: 50, spe: 45 },
}, },
zubat: { zubat: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 45, def: 35, spa: 40, spd: 40, spe: 55}, baseStats: { hp: 40, atk: 45, def: 35, spa: 40, spd: 40, spe: 55 },
}, },
golbat: { golbat: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 80, def: 70, spa: 75, spd: 75, spe: 90}, baseStats: { hp: 75, atk: 80, def: 70, spa: 75, spd: 75, spe: 90 },
}, },
oddish: { oddish: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 50, def: 55, spa: 75, spd: 75, spe: 30}, baseStats: { hp: 45, atk: 50, def: 55, spa: 75, spd: 75, spe: 30 },
}, },
gloom: { gloom: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 65, def: 70, spa: 85, spd: 85, spe: 40}, baseStats: { hp: 60, atk: 65, def: 70, spa: 85, spd: 85, spe: 40 },
}, },
vileplume: { vileplume: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 80, def: 85, spa: 100, spd: 100, spe: 50}, baseStats: { hp: 75, atk: 80, def: 85, spa: 100, spd: 100, spe: 50 },
}, },
paras: { paras: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 70, def: 55, spa: 55, spd: 55, spe: 25}, baseStats: { hp: 35, atk: 70, def: 55, spa: 55, spd: 55, spe: 25 },
}, },
parasect: { parasect: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 95, def: 80, spa: 80, spd: 80, spe: 30}, baseStats: { hp: 60, atk: 95, def: 80, spa: 80, spd: 80, spe: 30 },
}, },
venonat: { venonat: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 55, def: 50, spa: 40, spd: 40, spe: 45}, baseStats: { hp: 60, atk: 55, def: 50, spa: 40, spd: 40, spe: 45 },
}, },
venomoth: { venomoth: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 65, def: 60, spa: 90, spd: 90, spe: 90}, baseStats: { hp: 70, atk: 65, def: 60, spa: 90, spd: 90, spe: 90 },
}, },
diglett: { diglett: {
inherit: true, inherit: true,
baseStats: {hp: 10, atk: 55, def: 25, spa: 45, spd: 45, spe: 95}, baseStats: { hp: 10, atk: 55, def: 25, spa: 45, spd: 45, spe: 95 },
}, },
dugtrio: { dugtrio: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 80, def: 50, spa: 70, spd: 70, spe: 120}, baseStats: { hp: 35, atk: 80, def: 50, spa: 70, spd: 70, spe: 120 },
}, },
meowth: { meowth: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 45, def: 35, spa: 40, spd: 40, spe: 90}, baseStats: { hp: 40, atk: 45, def: 35, spa: 40, spd: 40, spe: 90 },
}, },
persian: { persian: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 70, def: 60, spa: 65, spd: 65, spe: 115}, baseStats: { hp: 65, atk: 70, def: 60, spa: 65, spd: 65, spe: 115 },
}, },
psyduck: { psyduck: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 52, def: 48, spa: 50, spd: 50, spe: 55}, baseStats: { hp: 50, atk: 52, def: 48, spa: 50, spd: 50, spe: 55 },
}, },
golduck: { golduck: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 82, def: 78, spa: 80, spd: 80, spe: 85}, baseStats: { hp: 80, atk: 82, def: 78, spa: 80, spd: 80, spe: 85 },
}, },
mankey: { mankey: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 80, def: 35, spa: 35, spd: 35, spe: 70}, baseStats: { hp: 40, atk: 80, def: 35, spa: 35, spd: 35, spe: 70 },
}, },
primeape: { primeape: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 105, def: 60, spa: 60, spd: 60, spe: 95}, baseStats: { hp: 65, atk: 105, def: 60, spa: 60, spd: 60, spe: 95 },
}, },
growlithe: { growlithe: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 70, def: 45, spa: 50, spd: 50, spe: 60}, baseStats: { hp: 55, atk: 70, def: 45, spa: 50, spd: 50, spe: 60 },
}, },
arcanine: { arcanine: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 110, def: 80, spa: 80, spd: 80, spe: 95}, baseStats: { hp: 90, atk: 110, def: 80, spa: 80, spd: 80, spe: 95 },
}, },
poliwag: { poliwag: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 50, def: 40, spa: 40, spd: 40, spe: 90}, baseStats: { hp: 40, atk: 50, def: 40, spa: 40, spd: 40, spe: 90 },
}, },
poliwhirl: { poliwhirl: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 65, def: 65, spa: 50, spd: 50, spe: 90}, baseStats: { hp: 65, atk: 65, def: 65, spa: 50, spd: 50, spe: 90 },
}, },
poliwrath: { poliwrath: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 85, def: 95, spa: 70, spd: 70, spe: 70}, baseStats: { hp: 90, atk: 85, def: 95, spa: 70, spd: 70, spe: 70 },
}, },
abra: { abra: {
inherit: true, inherit: true,
baseStats: {hp: 25, atk: 20, def: 15, spa: 105, spd: 105, spe: 90}, baseStats: { hp: 25, atk: 20, def: 15, spa: 105, spd: 105, spe: 90 },
}, },
kadabra: { kadabra: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 35, def: 30, spa: 120, spd: 120, spe: 105}, baseStats: { hp: 40, atk: 35, def: 30, spa: 120, spd: 120, spe: 105 },
}, },
alakazam: { alakazam: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 50, def: 45, spa: 135, spd: 135, spe: 120}, baseStats: { hp: 55, atk: 50, def: 45, spa: 135, spd: 135, spe: 120 },
}, },
machop: { machop: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 80, def: 50, spa: 35, spd: 35, spe: 35}, baseStats: { hp: 70, atk: 80, def: 50, spa: 35, spd: 35, spe: 35 },
}, },
machoke: { machoke: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 100, def: 70, spa: 50, spd: 50, spe: 45}, baseStats: { hp: 80, atk: 100, def: 70, spa: 50, spd: 50, spe: 45 },
}, },
machamp: { machamp: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 130, def: 80, spa: 65, spd: 65, spe: 55}, baseStats: { hp: 90, atk: 130, def: 80, spa: 65, spd: 65, spe: 55 },
}, },
bellsprout: { bellsprout: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 75, def: 35, spa: 70, spd: 70, spe: 40}, baseStats: { hp: 50, atk: 75, def: 35, spa: 70, spd: 70, spe: 40 },
}, },
weepinbell: { weepinbell: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 90, def: 50, spa: 85, spd: 85, spe: 55}, baseStats: { hp: 65, atk: 90, def: 50, spa: 85, spd: 85, spe: 55 },
}, },
victreebel: { victreebel: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 105, def: 65, spa: 100, spd: 100, spe: 70}, baseStats: { hp: 80, atk: 105, def: 65, spa: 100, spd: 100, spe: 70 },
}, },
tentacool: { tentacool: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 40, def: 35, spa: 100, spd: 100, spe: 70}, baseStats: { hp: 40, atk: 40, def: 35, spa: 100, spd: 100, spe: 70 },
}, },
tentacruel: { tentacruel: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 70, def: 65, spa: 120, spd: 120, spe: 100}, baseStats: { hp: 80, atk: 70, def: 65, spa: 120, spd: 120, spe: 100 },
}, },
geodude: { geodude: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 80, def: 100, spa: 30, spd: 30, spe: 20}, baseStats: { hp: 40, atk: 80, def: 100, spa: 30, spd: 30, spe: 20 },
}, },
graveler: { graveler: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 95, def: 115, spa: 45, spd: 45, spe: 35}, baseStats: { hp: 55, atk: 95, def: 115, spa: 45, spd: 45, spe: 35 },
}, },
golem: { golem: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 110, def: 130, spa: 55, spd: 55, spe: 45}, baseStats: { hp: 80, atk: 110, def: 130, spa: 55, spd: 55, spe: 45 },
}, },
ponyta: { ponyta: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 85, def: 55, spa: 65, spd: 65, spe: 90}, baseStats: { hp: 50, atk: 85, def: 55, spa: 65, spd: 65, spe: 90 },
}, },
rapidash: { rapidash: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 100, def: 70, spa: 80, spd: 80, spe: 105}, baseStats: { hp: 65, atk: 100, def: 70, spa: 80, spd: 80, spe: 105 },
}, },
slowpoke: { slowpoke: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 65, def: 65, spa: 40, spd: 40, spe: 15}, baseStats: { hp: 90, atk: 65, def: 65, spa: 40, spd: 40, spe: 15 },
}, },
slowbro: { slowbro: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 75, def: 110, spa: 80, spd: 80, spe: 30}, baseStats: { hp: 95, atk: 75, def: 110, spa: 80, spd: 80, spe: 30 },
}, },
magnemite: { magnemite: {
inherit: true, inherit: true,
types: ["Electric"], types: ["Electric"],
baseStats: {hp: 25, atk: 35, def: 70, spa: 95, spd: 95, spe: 45}, baseStats: { hp: 25, atk: 35, def: 70, spa: 95, spd: 95, spe: 45 },
}, },
magneton: { magneton: {
inherit: true, inherit: true,
types: ["Electric"], types: ["Electric"],
baseStats: {hp: 50, atk: 60, def: 95, spa: 120, spd: 120, spe: 70}, baseStats: { hp: 50, atk: 60, def: 95, spa: 120, spd: 120, spe: 70 },
}, },
farfetchd: { farfetchd: {
inherit: true, inherit: true,
baseStats: {hp: 52, atk: 65, def: 55, spa: 58, spd: 58, spe: 60}, baseStats: { hp: 52, atk: 65, def: 55, spa: 58, spd: 58, spe: 60 },
}, },
doduo: { doduo: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 85, def: 45, spa: 35, spd: 35, spe: 75}, baseStats: { hp: 35, atk: 85, def: 45, spa: 35, spd: 35, spe: 75 },
}, },
dodrio: { dodrio: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 110, def: 70, spa: 60, spd: 60, spe: 100}, baseStats: { hp: 60, atk: 110, def: 70, spa: 60, spd: 60, spe: 100 },
}, },
seel: { seel: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 45, def: 55, spa: 70, spd: 70, spe: 45}, baseStats: { hp: 65, atk: 45, def: 55, spa: 70, spd: 70, spe: 45 },
}, },
dewgong: { dewgong: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 70, def: 80, spa: 95, spd: 95, spe: 70}, baseStats: { hp: 90, atk: 70, def: 80, spa: 95, spd: 95, spe: 70 },
}, },
grimer: { grimer: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 80, def: 50, spa: 40, spd: 40, spe: 25}, baseStats: { hp: 80, atk: 80, def: 50, spa: 40, spd: 40, spe: 25 },
}, },
muk: { muk: {
inherit: true, inherit: true,
baseStats: {hp: 105, atk: 105, def: 75, spa: 65, spd: 65, spe: 50}, baseStats: { hp: 105, atk: 105, def: 75, spa: 65, spd: 65, spe: 50 },
}, },
shellder: { shellder: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 65, def: 100, spa: 45, spd: 45, spe: 40}, baseStats: { hp: 30, atk: 65, def: 100, spa: 45, spd: 45, spe: 40 },
}, },
cloyster: { cloyster: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 95, def: 180, spa: 85, spd: 85, spe: 70}, baseStats: { hp: 50, atk: 95, def: 180, spa: 85, spd: 85, spe: 70 },
}, },
gastly: { gastly: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 35, def: 30, spa: 100, spd: 100, spe: 80}, baseStats: { hp: 30, atk: 35, def: 30, spa: 100, spd: 100, spe: 80 },
}, },
haunter: { haunter: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 50, def: 45, spa: 115, spd: 115, spe: 95}, baseStats: { hp: 45, atk: 50, def: 45, spa: 115, spd: 115, spe: 95 },
}, },
gengar: { gengar: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 65, def: 60, spa: 130, spd: 130, spe: 110}, baseStats: { hp: 60, atk: 65, def: 60, spa: 130, spd: 130, spe: 110 },
}, },
onix: { onix: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 45, def: 160, spa: 30, spd: 30, spe: 70}, baseStats: { hp: 35, atk: 45, def: 160, spa: 30, spd: 30, spe: 70 },
}, },
drowzee: { drowzee: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 48, def: 45, spa: 90, spd: 90, spe: 42}, baseStats: { hp: 60, atk: 48, def: 45, spa: 90, spd: 90, spe: 42 },
}, },
hypno: { hypno: {
inherit: true, inherit: true,
baseStats: {hp: 85, atk: 73, def: 70, spa: 115, spd: 115, spe: 67}, baseStats: { hp: 85, atk: 73, def: 70, spa: 115, spd: 115, spe: 67 },
}, },
krabby: { krabby: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 105, def: 90, spa: 25, spd: 25, spe: 50}, baseStats: { hp: 30, atk: 105, def: 90, spa: 25, spd: 25, spe: 50 },
}, },
kingler: { kingler: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 130, def: 115, spa: 50, spd: 50, spe: 75}, baseStats: { hp: 55, atk: 130, def: 115, spa: 50, spd: 50, spe: 75 },
}, },
voltorb: { voltorb: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 30, def: 50, spa: 55, spd: 55, spe: 100}, baseStats: { hp: 40, atk: 30, def: 50, spa: 55, spd: 55, spe: 100 },
}, },
electrode: { electrode: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 50, def: 70, spa: 80, spd: 80, spe: 140}, baseStats: { hp: 60, atk: 50, def: 70, spa: 80, spd: 80, spe: 140 },
}, },
exeggcute: { exeggcute: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 40, def: 80, spa: 60, spd: 60, spe: 40}, baseStats: { hp: 60, atk: 40, def: 80, spa: 60, spd: 60, spe: 40 },
}, },
exeggutor: { exeggutor: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 95, def: 85, spa: 125, spd: 125, spe: 55}, baseStats: { hp: 95, atk: 95, def: 85, spa: 125, spd: 125, spe: 55 },
}, },
cubone: { cubone: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 50, def: 95, spa: 40, spd: 40, spe: 35}, baseStats: { hp: 50, atk: 50, def: 95, spa: 40, spd: 40, spe: 35 },
}, },
marowak: { marowak: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 80, def: 110, spa: 50, spd: 50, spe: 45}, baseStats: { hp: 60, atk: 80, def: 110, spa: 50, spd: 50, spe: 45 },
}, },
hitmonlee: { hitmonlee: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 120, def: 53, spa: 35, spd: 35, spe: 87}, baseStats: { hp: 50, atk: 120, def: 53, spa: 35, spd: 35, spe: 87 },
}, },
hitmonchan: { hitmonchan: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 105, def: 79, spa: 35, spd: 35, spe: 76}, baseStats: { hp: 50, atk: 105, def: 79, spa: 35, spd: 35, spe: 76 },
}, },
lickitung: { lickitung: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 55, def: 75, spa: 60, spd: 60, spe: 30}, baseStats: { hp: 90, atk: 55, def: 75, spa: 60, spd: 60, spe: 30 },
}, },
koffing: { koffing: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 65, def: 95, spa: 60, spd: 60, spe: 35}, baseStats: { hp: 40, atk: 65, def: 95, spa: 60, spd: 60, spe: 35 },
}, },
weezing: { weezing: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 90, def: 120, spa: 85, spd: 85, spe: 60}, baseStats: { hp: 65, atk: 90, def: 120, spa: 85, spd: 85, spe: 60 },
}, },
rhyhorn: { rhyhorn: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 85, def: 95, spa: 30, spd: 30, spe: 25}, baseStats: { hp: 80, atk: 85, def: 95, spa: 30, spd: 30, spe: 25 },
}, },
rhydon: { rhydon: {
inherit: true, inherit: true,
baseStats: {hp: 105, atk: 130, def: 120, spa: 45, spd: 45, spe: 40}, baseStats: { hp: 105, atk: 130, def: 120, spa: 45, spd: 45, spe: 40 },
}, },
chansey: { chansey: {
inherit: true, inherit: true,
baseStats: {hp: 250, atk: 5, def: 5, spa: 105, spd: 105, spe: 50}, baseStats: { hp: 250, atk: 5, def: 5, spa: 105, spd: 105, spe: 50 },
}, },
tangela: { tangela: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 55, def: 115, spa: 100, spd: 100, spe: 60}, baseStats: { hp: 65, atk: 55, def: 115, spa: 100, spd: 100, spe: 60 },
}, },
kangaskhan: { kangaskhan: {
inherit: true, inherit: true,
baseStats: {hp: 105, atk: 95, def: 80, spa: 40, spd: 40, spe: 90}, baseStats: { hp: 105, atk: 95, def: 80, spa: 40, spd: 40, spe: 90 },
}, },
horsea: { horsea: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 40, def: 70, spa: 70, spd: 70, spe: 60}, baseStats: { hp: 30, atk: 40, def: 70, spa: 70, spd: 70, spe: 60 },
}, },
seadra: { seadra: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 65, def: 95, spa: 95, spd: 95, spe: 85}, baseStats: { hp: 55, atk: 65, def: 95, spa: 95, spd: 95, spe: 85 },
}, },
goldeen: { goldeen: {
inherit: true, inherit: true,
baseStats: {hp: 45, atk: 67, def: 60, spa: 50, spd: 50, spe: 63}, baseStats: { hp: 45, atk: 67, def: 60, spa: 50, spd: 50, spe: 63 },
}, },
seaking: { seaking: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 92, def: 65, spa: 80, spd: 80, spe: 68}, baseStats: { hp: 80, atk: 92, def: 65, spa: 80, spd: 80, spe: 68 },
}, },
staryu: { staryu: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 45, def: 55, spa: 70, spd: 70, spe: 85}, baseStats: { hp: 30, atk: 45, def: 55, spa: 70, spd: 70, spe: 85 },
}, },
starmie: { starmie: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 75, def: 85, spa: 100, spd: 100, spe: 115}, baseStats: { hp: 60, atk: 75, def: 85, spa: 100, spd: 100, spe: 115 },
}, },
mrmime: { mrmime: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 45, def: 65, spa: 100, spd: 100, spe: 90}, baseStats: { hp: 40, atk: 45, def: 65, spa: 100, spd: 100, spe: 90 },
}, },
scyther: { scyther: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 110, def: 80, spa: 55, spd: 55, spe: 105}, baseStats: { hp: 70, atk: 110, def: 80, spa: 55, spd: 55, spe: 105 },
}, },
jynx: { jynx: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 50, def: 35, spa: 95, spd: 95, spe: 95}, baseStats: { hp: 65, atk: 50, def: 35, spa: 95, spd: 95, spe: 95 },
}, },
electabuzz: { electabuzz: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 83, def: 57, spa: 85, spd: 85, spe: 105}, baseStats: { hp: 65, atk: 83, def: 57, spa: 85, spd: 85, spe: 105 },
}, },
magmar: { magmar: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 95, def: 57, spa: 85, spd: 85, spe: 93}, baseStats: { hp: 65, atk: 95, def: 57, spa: 85, spd: 85, spe: 93 },
}, },
pinsir: { pinsir: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 125, def: 100, spa: 55, spd: 55, spe: 85}, baseStats: { hp: 65, atk: 125, def: 100, spa: 55, spd: 55, spe: 85 },
}, },
tauros: { tauros: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 100, def: 95, spa: 70, spd: 70, spe: 110}, baseStats: { hp: 75, atk: 100, def: 95, spa: 70, spd: 70, spe: 110 },
}, },
magikarp: { magikarp: {
inherit: true, inherit: true,
baseStats: {hp: 20, atk: 10, def: 55, spa: 20, spd: 20, spe: 80}, baseStats: { hp: 20, atk: 10, def: 55, spa: 20, spd: 20, spe: 80 },
}, },
gyarados: { gyarados: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 125, def: 79, spa: 100, spd: 100, spe: 81}, baseStats: { hp: 95, atk: 125, def: 79, spa: 100, spd: 100, spe: 81 },
}, },
lapras: { lapras: {
inherit: true, inherit: true,
baseStats: {hp: 130, atk: 85, def: 80, spa: 95, spd: 95, spe: 60}, baseStats: { hp: 130, atk: 85, def: 80, spa: 95, spd: 95, spe: 60 },
}, },
ditto: { ditto: {
inherit: true, inherit: true,
baseStats: {hp: 48, atk: 48, def: 48, spa: 48, spd: 48, spe: 48}, baseStats: { hp: 48, atk: 48, def: 48, spa: 48, spd: 48, spe: 48 },
}, },
eevee: { eevee: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 55, def: 50, spa: 65, spd: 65, spe: 55}, baseStats: { hp: 55, atk: 55, def: 50, spa: 65, spd: 65, spe: 55 },
}, },
vaporeon: { vaporeon: {
inherit: true, inherit: true,
baseStats: {hp: 130, atk: 65, def: 60, spa: 110, spd: 110, spe: 65}, baseStats: { hp: 130, atk: 65, def: 60, spa: 110, spd: 110, spe: 65 },
}, },
jolteon: { jolteon: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 65, def: 60, spa: 110, spd: 110, spe: 130}, baseStats: { hp: 65, atk: 65, def: 60, spa: 110, spd: 110, spe: 130 },
}, },
flareon: { flareon: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 130, def: 60, spa: 110, spd: 110, spe: 65}, baseStats: { hp: 65, atk: 130, def: 60, spa: 110, spd: 110, spe: 65 },
}, },
porygon: { porygon: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 60, def: 70, spa: 75, spd: 75, spe: 40}, baseStats: { hp: 65, atk: 60, def: 70, spa: 75, spd: 75, spe: 40 },
}, },
omanyte: { omanyte: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 40, def: 100, spa: 90, spd: 90, spe: 35}, baseStats: { hp: 35, atk: 40, def: 100, spa: 90, spd: 90, spe: 35 },
}, },
omastar: { omastar: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 60, def: 125, spa: 115, spd: 115, spe: 55}, baseStats: { hp: 70, atk: 60, def: 125, spa: 115, spd: 115, spe: 55 },
}, },
kabuto: { kabuto: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 80, def: 90, spa: 45, spd: 45, spe: 55}, baseStats: { hp: 30, atk: 80, def: 90, spa: 45, spd: 45, spe: 55 },
}, },
kabutops: { kabutops: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 115, def: 105, spa: 70, spd: 70, spe: 80}, baseStats: { hp: 60, atk: 115, def: 105, spa: 70, spd: 70, spe: 80 },
}, },
aerodactyl: { aerodactyl: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 105, def: 65, spa: 60, spd: 60, spe: 130}, baseStats: { hp: 80, atk: 105, def: 65, spa: 60, spd: 60, spe: 130 },
}, },
snorlax: { snorlax: {
inherit: true, inherit: true,
baseStats: {hp: 160, atk: 110, def: 65, spa: 65, spd: 65, spe: 30}, baseStats: { hp: 160, atk: 110, def: 65, spa: 65, spd: 65, spe: 30 },
}, },
articuno: { articuno: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 85, def: 100, spa: 125, spd: 125, spe: 85}, baseStats: { hp: 90, atk: 85, def: 100, spa: 125, spd: 125, spe: 85 },
}, },
zapdos: { zapdos: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 90, def: 85, spa: 125, spd: 125, spe: 100}, baseStats: { hp: 90, atk: 90, def: 85, spa: 125, spd: 125, spe: 100 },
}, },
moltres: { moltres: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 100, def: 90, spa: 125, spd: 125, spe: 90}, baseStats: { hp: 90, atk: 100, def: 90, spa: 125, spd: 125, spe: 90 },
}, },
dratini: { dratini: {
inherit: true, inherit: true,
baseStats: {hp: 41, atk: 64, def: 45, spa: 50, spd: 50, spe: 50}, baseStats: { hp: 41, atk: 64, def: 45, spa: 50, spd: 50, spe: 50 },
}, },
dragonair: { dragonair: {
inherit: true, inherit: true,
baseStats: {hp: 61, atk: 84, def: 65, spa: 70, spd: 70, spe: 70}, baseStats: { hp: 61, atk: 84, def: 65, spa: 70, spd: 70, spe: 70 },
}, },
dragonite: { dragonite: {
inherit: true, inherit: true,
baseStats: {hp: 91, atk: 134, def: 95, spa: 100, spd: 100, spe: 80}, baseStats: { hp: 91, atk: 134, def: 95, spa: 100, spd: 100, spe: 80 },
}, },
mewtwo: { mewtwo: {
inherit: true, inherit: true,
baseStats: {hp: 106, atk: 110, def: 90, spa: 154, spd: 154, spe: 130}, baseStats: { hp: 106, atk: 110, def: 90, spa: 154, spd: 154, spe: 130 },
}, },
mew: { mew: {
inherit: true, inherit: true,
baseStats: {hp: 100, atk: 100, def: 100, spa: 100, spd: 100, spe: 100}, baseStats: { hp: 100, atk: 100, def: 100, spa: 100, spd: 100, spe: 100 },
}, },
}; };

View File

@ -36,7 +36,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
}, },
onModifySpecies(species) { onModifySpecies(species) {
const newSpecies = this.dex.deepClone(species); const newSpecies = this.dex.deepClone(species);
const stats: {[k: string]: number} = { const stats: { [k: string]: number } = {
hp: newSpecies.baseStats.spe, hp: newSpecies.baseStats.spe,
atk: newSpecies.baseStats.spa, atk: newSpecies.baseStats.spa,
def: newSpecies.baseStats.def, def: newSpecies.baseStats.def,

View File

@ -26,7 +26,7 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon: { pokemon: {
inherit: true, inherit: true,
getStat(statName, unmodified) { getStat(statName, unmodified) {
// @ts-ignore - type checking prevents 'hp' from being passed, but we're paranoid // @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly"); if (statName === 'hp') throw new Error("Please read `maxhp` directly");
if (unmodified) return this.baseStoredStats[statName]; if (unmodified) return this.baseStoredStats[statName];
return this.modifiedStats![statName]; return this.modifiedStats![statName];
@ -160,8 +160,8 @@ export const Scripts: ModdedBattleScriptsData = {
let lockedMove = this.battle.runEvent('LockMove', pokemon); let lockedMove = this.battle.runEvent('LockMove', pokemon);
if (lockedMove === true) lockedMove = false; if (lockedMove === true) lockedMove = false;
if ( if (
(!lockedMove && !lockedMove &&
(!pokemon.volatiles['partialtrappinglock'] || pokemon.volatiles['partialtrappinglock'].locked !== target)) (!pokemon.volatiles['partialtrappinglock'] || pokemon.volatiles['partialtrappinglock'].locked !== target)
) { ) {
pokemon.deductPP(move, null, target); pokemon.deductPP(move, null, target);
} else { } else {
@ -181,7 +181,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.hint("In Gen 1, if a player is forced to use a move with 0 PP, the move will underflow to have 63 PP."); this.battle.hint("In Gen 1, if a player is forced to use a move with 0 PP, the move will underflow to have 63 PP.");
} }
} }
this.useMove(move, pokemon, {target, sourceEffect}); this.useMove(move, pokemon, { target, sourceEffect });
// Restore PP if the move is the first turn of a charging move. Save the move from which PP should be deducted if the move succeeds. // Restore PP if the move is the first turn of a charging move. Save the move from which PP should be deducted if the move succeeds.
if (pokemon.volatiles['twoturnmove']) { if (pokemon.volatiles['twoturnmove']) {
pokemon.deductPP(move, -1, target); pokemon.deductPP(move, -1, target);
@ -215,7 +215,7 @@ export const Scripts: ModdedBattleScriptsData = {
// The charging turn of a two-turn move does not update pokemon.lastMove // The charging turn of a two-turn move does not update pokemon.lastMove
if (!TWO_TURN_MOVES.includes(move.id) || pokemon.volatiles['twoturnmove']) pokemon.lastMove = move; if (!TWO_TURN_MOVES.includes(move.id) || pokemon.volatiles['twoturnmove']) pokemon.lastMove = move;
const moveResult = this.useMoveInner(moveOrMoveName, pokemon, {target, sourceEffect}); const moveResult = this.useMoveInner(moveOrMoveName, pokemon, { target, sourceEffect });
if (move.id !== 'metronome') { if (move.id !== 'metronome') {
if (move.id !== 'mirrormove' || if (move.id !== 'mirrormove' ||
@ -293,8 +293,8 @@ export const Scripts: ModdedBattleScriptsData = {
return false; return false;
} }
if (sourceEffect) attrs += '|[from]' + this.battle.dex.conditions.get(sourceEffect); if (sourceEffect) attrs += `|[from]${this.battle.dex.conditions.get(sourceEffect)}`;
this.battle.addMove('move', pokemon, move.name, target + attrs); this.battle.addMove('move', pokemon, move.name, `${target}${attrs}`);
if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) { if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) {
return true; return true;
@ -321,7 +321,7 @@ export const Scripts: ModdedBattleScriptsData = {
// Disable and Selfdestruct/Explosion boost rage, regardless of whether they miss/fail. // Disable and Selfdestruct/Explosion boost rage, regardless of whether they miss/fail.
if (target.boosts.atk < 6 && (move.selfdestruct || move.id === 'disable') && target.volatiles['rage']) { if (target.boosts.atk < 6 && (move.selfdestruct || move.id === 'disable') && target.volatiles['rage']) {
this.battle.boost({atk: 1}, target, pokemon, this.dex.conditions.get('rage')); this.battle.boost({ atk: 1 }, target, pokemon, this.dex.conditions.get('rage'));
this.battle.hint(`In Gen 1, using ${move.name} causes the target to build Rage, ` + this.battle.hint(`In Gen 1, using ${move.name} causes the target to build Rage, ` +
`even if it misses or fails`, true); `even if it misses or fails`, true);
} }
@ -394,7 +394,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
// If a sleep inducing move is used while the user is recharging, the accuracy is true. // If a sleep inducing move is used while the user is recharging, the accuracy is true.
if (move.status === 'slp' && target && target.volatiles['mustrecharge']) { if (move.status === 'slp' && target?.volatiles['mustrecharge']) {
accuracy = true; accuracy = true;
} }
@ -971,7 +971,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (typeof effect === 'string') effect = this.dex.conditions.get(effect); if (typeof effect === 'string') effect = this.dex.conditions.get(effect);
if (!target?.hp) return 0; if (!target?.hp) return 0;
let success = null; let success = null;
boost = this.runEvent('TryBoost', target, source, effect, {...boost}); boost = this.runEvent('TryBoost', target, source, effect, { ...boost });
let i: BoostID; let i: BoostID;
for (i in boost) { for (i in boost) {
const currentBoost: SparseBoostsTable = {}; const currentBoost: SparseBoostsTable = {};

View File

@ -65,7 +65,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// Add here counter damage // Add here counter damage
const lastAttackedBy = target.getLastAttackedBy(); const lastAttackedBy = target.getLastAttackedBy();
if (!lastAttackedBy) { if (!lastAttackedBy) {
target.attackedBy.push({source: source, move: move.id, damage: uncappedDamage, thisTurn: true, slot: source.getSlot()}); target.attackedBy.push({ source, move: move.id, damage: uncappedDamage, thisTurn: true, slot: source.getSlot() });
} else { } else {
lastAttackedBy.move = move.id; lastAttackedBy.move = move.id;
lastAttackedBy.damage = uncappedDamage; lastAttackedBy.damage = uncappedDamage;

View File

@ -22,40 +22,40 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
'Flareon + Tackle + Growl', 'Flareon + Focus Energy + Ember', 'Flareon + Tackle + Growl', 'Flareon + Focus Energy + Ember',
], ],
onValidateSet(set) { onValidateSet(set) {
const rgb97Legality: {[speciesid: string]: {[moveid: string]: 'illegal' | number}} = { const rgb97Legality: { [speciesid: string]: { [moveid: string]: 'illegal' | number } } = {
charizard: {fly: 'illegal'}, charizard: { fly: 'illegal' },
butterfree: { butterfree: {
confusion: 12, poisonpowder: 15, stunspore: 16, sleeppowder: 17, supersonic: 21, confusion: 12, poisonpowder: 15, stunspore: 16, sleeppowder: 17, supersonic: 21,
psybeam: 34, flash: 'illegal', gust: 'illegal', psybeam: 34, flash: 'illegal', gust: 'illegal',
}, },
fearow: {payday: 'illegal'}, fearow: { payday: 'illegal' },
pikachu: {quickattack: 16, tailwhip: 'illegal', slam: 'illegal', lightscreen: 'illegal'}, pikachu: { quickattack: 16, tailwhip: 'illegal', slam: 'illegal', lightscreen: 'illegal' },
raichu: {quickattack: 16, tailwhip: 'illegal', slam: 'illegal', lightscreen: 'illegal'}, raichu: { quickattack: 16, tailwhip: 'illegal', slam: 'illegal', lightscreen: 'illegal' },
nidoranf: {doublekick: 43}, nidoranf: { doublekick: 43 },
nidorina: {doublekick: 43}, nidorina: { doublekick: 43 },
nidoqueen: {doublekick: 43}, nidoqueen: { doublekick: 43 },
nidoranm: {doublekick: 43}, nidoranm: { doublekick: 43 },
nidorino: {doublekick: 43}, nidorino: { doublekick: 43 },
nidoking: {doublekick: 43}, nidoking: { doublekick: 43 },
venonat: {poisonpowder: 24, supersonic: 'illegal', confusion: 'illegal'}, venonat: { poisonpowder: 24, supersonic: 'illegal', confusion: 'illegal' },
venomoth: {poisonpowder: 24, supersonic: 'illegal'}, venomoth: { poisonpowder: 24, supersonic: 'illegal' },
diglett: {cut: 'illegal'}, diglett: { cut: 'illegal' },
dugtrio: {cut: 'illegal'}, dugtrio: { cut: 'illegal' },
psyduck: {amnesia: 'illegal'}, psyduck: { amnesia: 'illegal' },
golduck: {amnesia: 'illegal'}, golduck: { amnesia: 'illegal' },
mankey: {lowkick: 'illegal', screech: 'illegal'}, mankey: { lowkick: 'illegal', screech: 'illegal' },
primeape: {lowkick: 'illegal', screech: 'illegal'}, primeape: { lowkick: 'illegal', screech: 'illegal' },
kadabra: {kinesis: 'illegal'}, kadabra: { kinesis: 'illegal' },
alakazam: {kinesis: 'illegal'}, alakazam: { kinesis: 'illegal' },
rapidash: {payday: 'illegal'}, rapidash: { payday: 'illegal' },
cubone: {tailwhip: 'illegal', headbutt: 'illegal'}, cubone: { tailwhip: 'illegal', headbutt: 'illegal' },
marowak: {tailwhip: 'illegal', headbutt: 'illegal'}, marowak: { tailwhip: 'illegal', headbutt: 'illegal' },
chansey: {tailwhip: 'illegal'}, chansey: { tailwhip: 'illegal' },
tangela: {absorb: 29, growth: 49, vinewhip: 'illegal'}, tangela: { absorb: 29, growth: 49, vinewhip: 'illegal' },
scyther: {wingattack: 'illegal'}, scyther: { wingattack: 'illegal' },
pinsir: {bind: 'illegal'}, pinsir: { bind: 'illegal' },
magikarp: {dragonrage: 'illegal'}, magikarp: { dragonrage: 'illegal' },
eevee: {quickattack: 27, tailwhip: 31, bite: 37, growl: 'illegal', focusenergy: 'illegal'}, eevee: { quickattack: 27, tailwhip: 31, bite: 37, growl: 'illegal', focusenergy: 'illegal' },
vaporeon: { vaporeon: {
quickattack: 27, tailwhip: 31, watergun: 31, bite: 37, acidarmor: 42, haze: 44, mist: 48, hydropump: 54, quickattack: 27, tailwhip: 31, watergun: 31, bite: 37, acidarmor: 42, haze: 44, mist: 48, hydropump: 54,
growl: 'illegal', focusenergy: 'illegal', aurorabeam: 'illegal', growl: 'illegal', focusenergy: 'illegal', aurorabeam: 'illegal',

View File

@ -37,7 +37,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }
@ -108,7 +108,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
duration: 2, duration: 2,
onBeforeMovePriority: 1, onBeforeMovePriority: 1,
onStart(target, source, effect) { onStart(target, source, effect) {
this.add('-activate', target, 'move: ' + effect, '[of] ' + source); this.add('-activate', target, `move: ${effect}`, `[of] ${source}`);
}, },
onBeforeMove(pokemon) { onBeforeMove(pokemon) {
if (this.effectState.source && (!this.effectState.source.isActive || this.effectState.source.hp <= 0)) { if (this.effectState.source && (!this.effectState.source.isActive || this.effectState.source.hp <= 0)) {

View File

@ -59,7 +59,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
pokemon.removeVolatile('bide'); pokemon.removeVolatile('bide');
return false; return false;
} }
this.actions.moveHit(target, pokemon, move, {damage: this.effectState.totalDamage * 2} as ActiveMove); this.actions.moveHit(target, pokemon, move, { damage: this.effectState.totalDamage * 2 } as ActiveMove);
pokemon.removeVolatile('bide'); pokemon.removeVolatile('bide');
return false; return false;
} }
@ -167,7 +167,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onLockMove: 'rage', onLockMove: 'rage',
onHit(target, source, move) { onHit(target, source, move) {
if (target.boosts.atk < 6 && (move.category !== 'Status' || move.id === 'disable')) { if (target.boosts.atk < 6 && (move.category !== 'Status' || move.id === 'disable')) {
this.boost({atk: 1}); this.boost({ atk: 1 });
} }
}, },
}, },
@ -270,7 +270,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
// Add here counter damage // Add here counter damage
const lastAttackedBy = target.getLastAttackedBy(); const lastAttackedBy = target.getLastAttackedBy();
if (!lastAttackedBy) { if (!lastAttackedBy) {
target.attackedBy.push({source: source, move: move.id, damage: damage, slot: source.getSlot(), thisTurn: true}); target.attackedBy.push({ source, move: move.id, damage, slot: source.getSlot(), thisTurn: true });
} else { } else {
lastAttackedBy.move = move.id; lastAttackedBy.move = move.id;
lastAttackedBy.damage = damage; lastAttackedBy.damage = damage;
@ -287,7 +287,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
struggle: { struggle: {
inherit: true, inherit: true,
ignoreImmunity: {'Normal': true}, ignoreImmunity: { 'Normal': true },
}, },
wrap: { wrap: {
inherit: true, inherit: true,

View File

@ -81,7 +81,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.setActiveMove(move, pokemon, target); this.battle.setActiveMove(move, pokemon, target);
if (pokemon.moveThisTurn || !this.battle.runEvent('BeforeMove', pokemon, target, move)) { if (pokemon.moveThisTurn || !this.battle.runEvent('BeforeMove', pokemon, target, move)) {
this.battle.debug('' + pokemon.fullname + ' move interrupted; movedThisTurn: ' + pokemon.moveThisTurn); this.battle.debug(`${pokemon.fullname} move interrupted; movedThisTurn: ${pokemon.moveThisTurn}`);
this.battle.clearActiveMove(true); this.battle.clearActiveMove(true);
// This is only run for sleep // This is only run for sleep
this.battle.runEvent('AfterMoveSelf', pokemon, target, move); this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
@ -103,14 +103,14 @@ export const Scripts: ModdedBattleScriptsData = {
} else { } else {
sourceEffect = move; sourceEffect = move;
} }
this.battle.actions.useMove(move, pokemon, {target, sourceEffect}); this.battle.actions.useMove(move, pokemon, { target, sourceEffect });
}, },
// This function deals with AfterMoveSelf events. // This function deals with AfterMoveSelf events.
// This leads with partial trapping moves shenanigans after the move has been used. // This leads with partial trapping moves shenanigans after the move has been used.
useMove(moveOrMoveName, pokemon, options) { useMove(moveOrMoveName, pokemon, options) {
let sourceEffect = options?.sourceEffect; let sourceEffect = options?.sourceEffect;
let target = options?.target; let target = options?.target;
const moveResult = this.useMoveInner(moveOrMoveName, pokemon, {target, sourceEffect}); const moveResult = this.useMoveInner(moveOrMoveName, pokemon, { target, sourceEffect });
if (!sourceEffect && this.battle.effect.id) sourceEffect = this.battle.effect; if (!sourceEffect && this.battle.effect.id) sourceEffect = this.battle.effect;
const baseMove = this.battle.dex.moves.get(moveOrMoveName); const baseMove = this.battle.dex.moves.get(moveOrMoveName);
@ -199,8 +199,8 @@ export const Scripts: ModdedBattleScriptsData = {
return false; return false;
} }
if (sourceEffect) attrs += '|[from]' + this.battle.dex.conditions.get(sourceEffect); if (sourceEffect) attrs += `|[from]${this.battle.dex.conditions.get(sourceEffect)}`;
this.battle.addMove('move', pokemon, move.name, target + attrs); this.battle.addMove('move', pokemon, move.name, `${target}${attrs}`);
if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) { if (!this.battle.singleEvent('Try', move, null, pokemon, target, move)) {
return true; return true;
@ -609,26 +609,26 @@ export const Scripts: ModdedBattleScriptsData = {
let critChance = source.species.baseStats['spe'] + 76; let critChance = source.species.baseStats['spe'] + 76;
// Now we right logical shift it two places, essentially dividing by 4 and flooring it. // Now we right logical shift it two places, essentially dividing by 4 and flooring it.
critChance = critChance >> 2; critChance >>= 2;
// Now we check for focus energy volatile. // Now we check for focus energy volatile.
if (source.volatiles['focusenergy']) { if (source.volatiles['focusenergy']) {
// If it exists, crit chance is multiplied by 4 and floored with a logical left shift. // If it exists, crit chance is multiplied by 4 and floored with a logical left shift.
critChance = critChance << 2; critChance <<= 2;
// Then we add 160. // Then we add 160.
critChance += 160; critChance += 160;
} else { } else {
// If it is not active, we left shift it by 1. // If it is not active, we left shift it by 1.
critChance = critChance << 1; critChance <<= 1;
} }
// Now we check for the move's critical hit ratio. // Now we check for the move's critical hit ratio.
if (move.critRatio === 2) { if (move.critRatio === 2) {
// High crit ratio, we multiply the result so far by 4. // High crit ratio, we multiply the result so far by 4.
critChance = critChance << 2; critChance <<= 2;
} else if (move.critRatio === 1) { } else if (move.critRatio === 1) {
// Normal hit ratio, we divide the crit chance by 2 and floor the result again. // Normal hit ratio, we divide the crit chance by 2 and floor the result again.
critChance = critChance >> 1; critChance >>= 1;
} }
// Now we make sure it's a number between 1 and 255. // Now we make sure it's a number between 1 and 255.

View File

@ -29,7 +29,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }
@ -192,7 +192,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
const move = this.dex.moves.get(this.effectState.move); const move = this.dex.moves.get(this.effectState.move);
if (move.id) { if (move.id) {
this.debug('Forcing into ' + move.id); this.debug('Forcing into ' + move.id);
this.queue.changeAction(pokemon, {choice: 'move', moveid: move.id}); this.queue.changeAction(pokemon, { choice: 'move', moveid: move.id });
} }
}, },
}, },
@ -223,7 +223,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
}, },
onStallMove() { onStallMove() {
const counter = Math.floor(this.effectState.counter) || 127; const counter = Math.floor(this.effectState.counter) || 127;
this.debug("Success chance: " + Math.round(counter * 1000 / 255) / 10 + "% (" + counter + "/255)"); this.debug(`Success chance: ${Math.round(counter * 1000 / 255) / 10}% (${counter}/255)`);
return this.randomChance(counter, 255); return this.randomChance(counter, 255);
}, },
onRestart() { onRestart() {

View File

@ -23,7 +23,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return false; return false;
} }
if (target.hp <= target.maxhp / 2) { if (target.hp <= target.maxhp / 2) {
this.boost({atk: 2}, null, null, this.dex.conditions.get('bellydrum2')); this.boost({ atk: 2 }, null, null, this.dex.conditions.get('bellydrum2'));
return false; return false;
} }
this.directDamage(target.maxhp / 2); this.directDamage(target.maxhp / 2);
@ -45,7 +45,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} }
boosts = target.boosts.atk - originalStage; boosts = target.boosts.atk - originalStage;
target.boosts.atk = originalStage; target.boosts.atk = originalStage;
this.boost({atk: boosts}); this.boost({ atk: boosts });
}, },
}, },
bide: { bide: {
@ -93,7 +93,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
damage: this.effectState.totalDamage * 2, damage: this.effectState.totalDamage * 2,
category: "Physical", category: "Physical",
priority: 0, priority: 0,
flags: {contact: 1, protect: 1}, flags: { contact: 1, protect: 1 },
effectType: 'Move', effectType: 'Move',
type: 'Normal', type: 'Normal',
} as unknown as ActiveMove; } as unknown as ActiveMove;
@ -140,7 +140,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
condition: { condition: {
onStart(pokemon, source) { onStart(pokemon, source) {
this.add('-start', pokemon, 'Curse', '[of] ' + source); this.add('-start', pokemon, 'Curse', `[of] ${source}`);
}, },
onAfterMoveSelf(pokemon) { onAfterMoveSelf(pokemon) {
this.damage(pokemon.baseMaxhp / 4); this.damage(pokemon.baseMaxhp / 4);
@ -231,7 +231,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
explosion: { explosion: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1, noparentalbond: 1, nosketch: 1}, flags: { protect: 1, mirror: 1, metronome: 1, noparentalbond: 1, nosketch: 1 },
}, },
flail: { flail: {
inherit: true, inherit: true,
@ -398,16 +398,16 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
meanlook: { meanlook: {
inherit: true, inherit: true,
flags: {reflectable: 1, mirror: 1, metronome: 1}, flags: { reflectable: 1, mirror: 1, metronome: 1 },
}, },
metronome: { metronome: {
inherit: true, inherit: true,
flags: {failencore: 1, nosketch: 1}, flags: { failencore: 1, nosketch: 1 },
}, },
mimic: { mimic: {
inherit: true, inherit: true,
accuracy: 100, accuracy: 100,
flags: {protect: 1, bypasssub: 1, allyanim: 1, failencore: 1, noassist: 1, nosketch: 1}, flags: { protect: 1, bypasssub: 1, allyanim: 1, failencore: 1, noassist: 1, nosketch: 1 },
}, },
mindreader: { mindreader: {
inherit: true, inherit: true,
@ -434,7 +434,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mirrormove: { mirrormove: {
inherit: true, inherit: true,
flags: {metronome: 1, failencore: 1, nosketch: 1}, flags: { metronome: 1, failencore: 1, nosketch: 1 },
onHit(pokemon) { onHit(pokemon) {
const noMirror = ['metronome', 'mimic', 'mirrormove', 'sketch', 'sleeptalk', 'transform']; const noMirror = ['metronome', 'mimic', 'mirrormove', 'sketch', 'sleeptalk', 'transform'];
const target = pokemon.side.foe.active[0]; const target = pokemon.side.foe.active[0];
@ -456,7 +456,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Mist", name: "Mist",
pp: 30, pp: 30,
priority: 0, priority: 0,
flags: {metronome: 1}, flags: { metronome: 1 },
volatileStatus: 'mist', volatileStatus: 'mist',
condition: { condition: {
onStart(pokemon) { onStart(pokemon) {
@ -548,7 +548,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onResidualOrder: 4, onResidualOrder: 4,
onResidual(pokemon) { onResidual(pokemon) {
const duration = pokemon.volatiles['perishsong'].duration; const duration = pokemon.volatiles['perishsong'].duration;
this.add('-start', pokemon, 'perish' + duration); this.add('-start', pokemon, `perish${duration}`);
}, },
}, },
}, },
@ -724,11 +724,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
selfdestruct: { selfdestruct: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1, noparentalbond: 1, nosketch: 1}, flags: { protect: 1, mirror: 1, metronome: 1, noparentalbond: 1, nosketch: 1 },
}, },
sketch: { sketch: {
inherit: true, inherit: true,
flags: {bypasssub: 1, failencore: 1, noassist: 1, nosketch: 1}, flags: { bypasssub: 1, failencore: 1, noassist: 1, nosketch: 1 },
onHit() { onHit() {
// Sketch always fails in Link Battles // Sketch always fails in Link Battles
this.add('-nothing'); this.add('-nothing');
@ -754,7 +754,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
sleeptalk: { sleeptalk: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, nosketch: 1}, flags: { failencore: 1, nosleeptalk: 1, nosketch: 1 },
onHit(pokemon) { onHit(pokemon) {
const moves = []; const moves = [];
for (const moveSlot of pokemon.moveSlots) { for (const moveSlot of pokemon.moveSlots) {
@ -780,7 +780,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
spiderweb: { spiderweb: {
inherit: true, inherit: true,
flags: {reflectable: 1, mirror: 1, metronome: 1}, flags: { reflectable: 1, mirror: 1, metronome: 1 },
}, },
spikes: { spikes: {
inherit: true, inherit: true,
@ -909,7 +909,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
return; return;
} }
this.add('-item', source, yourItem, '[from] move: Thief', '[of] ' + target); this.add('-item', source, yourItem, '[from] move: Thief', `[of] ${target}`);
}, },
}, },
}, },
@ -930,7 +930,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
transform: { transform: {
inherit: true, inherit: true,
flags: {bypasssub: 1, metronome: 1, failencore: 1, nosketch: 1}, flags: { bypasssub: 1, metronome: 1, failencore: 1, nosketch: 1 },
}, },
triattack: { triattack: {
inherit: true, inherit: true,

View File

@ -1,4 +1,4 @@
import type {Learnset} from "../../../sim/dex-species"; import type { Learnset } from "../../../sim/dex-species";
export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = { export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable = {
obtainablemoves: { obtainablemoves: {
@ -47,34 +47,34 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
name: 'NC 2000 Move Legality', name: 'NC 2000 Move Legality',
desc: "Prevents Pok\u00e9mon from having moves that would only be obtainable in Pok\u00e9mon Crystal.", desc: "Prevents Pok\u00e9mon from having moves that would only be obtainable in Pok\u00e9mon Crystal.",
onValidateSet(set) { onValidateSet(set) {
const illegalCombos: {[speciesid: string]: {[moveid: string]: 'E' | 'L' | 'S'}} = { const illegalCombos: { [speciesid: string]: { [moveid: string]: 'E' | 'L' | 'S' } } = {
arbok: {crunch: 'E'}, arbok: { crunch: 'E' },
sandslash: {metalclaw: 'E'}, sandslash: { metalclaw: 'E' },
golduck: {crosschop: 'E'}, golduck: { crosschop: 'E' },
marowak: {swordsdance: 'E'}, marowak: { swordsdance: 'E' },
electabuzz: {crosschop: 'E'}, electabuzz: { crosschop: 'E' },
magmar: {crosschop: 'E'}, magmar: { crosschop: 'E' },
jolteon: {batonpass: 'L'}, jolteon: { batonpass: 'L' },
vaporeon: {batonpass: 'L'}, vaporeon: { batonpass: 'L' },
flareon: {batonpass: 'L'}, flareon: { batonpass: 'L' },
espeon: {batonpass: 'L'}, espeon: { batonpass: 'L' },
umbreon: {batonpass: 'L'}, umbreon: { batonpass: 'L' },
dragonite: {extremespeed: 'S'}, dragonite: { extremespeed: 'S' },
meganium: {swordsdance: 'E'}, meganium: { swordsdance: 'E' },
typhlosion: {submission: 'E'}, typhlosion: { submission: 'E' },
ariados: {agility: 'L'}, ariados: { agility: 'L' },
yanma: {wingattack: 'L'}, yanma: { wingattack: 'L' },
murkrow: {skyattack: 'E'}, murkrow: { skyattack: 'E' },
qwilfish: {spikes: 'L'}, qwilfish: { spikes: 'L' },
sneasel: {metalclaw: 'L'}, sneasel: { metalclaw: 'L' },
ursaring: {metalclaw: 'E'}, ursaring: { metalclaw: 'E' },
piloswine: {amnesia: 'L'}, piloswine: { amnesia: 'L' },
skarmory: {skyattack: 'E'}, skarmory: { skyattack: 'E' },
donphan: {watergun: 'E'}, donphan: { watergun: 'E' },
suicune: {aurorabeam: 'L'}, suicune: { aurorabeam: 'L' },
dugtrio: {triattack: 'L'}, dugtrio: { triattack: 'L' },
magneton: {triattack: 'L'}, magneton: { triattack: 'L' },
cloyster: {spikes: 'L'}, cloyster: { spikes: 'L' },
}; };
const moveSources: NonNullable<Learnset['learnset']> = Object.fromEntries( const moveSources: NonNullable<Learnset['learnset']> = Object.fromEntries(
@ -82,7 +82,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
); );
const species = this.dex.species.get(set.species); const species = this.dex.species.get(set.species);
for (const {learnset} of this.dex.species.getFullLearnset(species.id)) { for (const { learnset } of this.dex.species.getFullLearnset(species.id)) {
for (const moveid in moveSources) { for (const moveid in moveSources) {
moveSources[moveid].push(...(learnset[moveid] || [])); moveSources[moveid].push(...(learnset[moveid] || []));
} }

View File

@ -8,7 +8,7 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon: { pokemon: {
inherit: true, inherit: true,
getStat(statName, unboosted, unmodified, fastReturn) { getStat(statName, unboosted, unmodified, fastReturn) {
// @ts-ignore - type checking prevents 'hp' from being passed, but we're paranoid // @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly"); if (statName === 'hp') throw new Error("Please read `maxhp` directly");
// base stat // base stat
@ -107,7 +107,7 @@ export const Scripts: ModdedBattleScriptsData = {
// THIS IS PURELY A SANITY CHECK // THIS IS PURELY A SANITY CHECK
// DO NOT TAKE ADVANTAGE OF THIS TO PREVENT A POKEMON FROM MOVING; // DO NOT TAKE ADVANTAGE OF THIS TO PREVENT A POKEMON FROM MOVING;
// USE this.battle.queue.cancelMove INSTEAD // USE this.battle.queue.cancelMove INSTEAD
this.battle.debug('' + pokemon.fullname + ' INCONSISTENT STATE, ALREADY MOVED: ' + pokemon.moveThisTurn); this.battle.debug(`${pokemon.fullname} INCONSISTENT STATE, ALREADY MOVED: ${pokemon.moveThisTurn}`);
this.battle.clearActiveMove(true); this.battle.clearActiveMove(true);
return; return;
} }
@ -135,7 +135,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
pokemon.moveUsed(move); pokemon.moveUsed(move);
this.battle.actions.useMove(move, pokemon, {target, sourceEffect: options?.sourceEffect}); this.battle.actions.useMove(move, pokemon, { target, sourceEffect: options?.sourceEffect });
this.battle.singleEvent('AfterMove', move, null, pokemon, target, move); this.battle.singleEvent('AfterMove', move, null, pokemon, target, move);
if (!move.selfSwitch && pokemon.side.foe.active[0].hp) this.battle.runEvent('AfterMoveSelf', pokemon, target, move); if (!move.selfSwitch && pokemon.side.foe.active[0].hp) this.battle.runEvent('AfterMoveSelf', pokemon, target, move);
}, },
@ -626,7 +626,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
if (move.id === 'present') { if (move.id === 'present') {
const typeIndexes: {[k: string]: number} = { const typeIndexes: { [k: string]: number } = {
Normal: 0, Fighting: 1, Flying: 2, Poison: 3, Ground: 4, Rock: 5, Bug: 7, Ghost: 8, Steel: 9, Normal: 0, Fighting: 1, Flying: 2, Poison: 3, Ground: 4, Rock: 5, Bug: 7, Ghost: 8, Steel: 9,
Fire: 20, Water: 21, Grass: 22, Electric: 23, Psychic: 24, Ice: 25, Dragon: 26, Dark: 27, Fire: 20, Water: 21, Grass: 22, Electric: 23, Psychic: 24, Ice: 25, Dragon: 26, Dark: 27,
}; };

View File

@ -4,7 +4,7 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon: { pokemon: {
inherit: true, inherit: true,
getStat(statName, unboosted, unmodified, fastReturn) { getStat(statName, unboosted, unmodified, fastReturn) {
// @ts-ignore - type checking prevents 'hp' from being passed, but we're paranoid // @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly"); if (statName === 'hp') throw new Error("Please read `maxhp` directly");
// base stat // base stat
@ -212,7 +212,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
if (move.id === 'present') { if (move.id === 'present') {
const typeIndexes: {[k: string]: number} = { const typeIndexes: { [k: string]: number } = {
Normal: 0, Fighting: 1, Flying: 2, Poison: 3, Ground: 4, Rock: 5, Bug: 7, Ghost: 8, Steel: 9, Normal: 0, Fighting: 1, Flying: 2, Poison: 3, Ground: 4, Rock: 5, Bug: 7, Ghost: 8, Steel: 9,
Fire: 20, Water: 21, Grass: 22, Electric: 23, Psychic: 24, Ice: 25, Dragon: 26, Dark: 27, Fire: 20, Water: 21, Grass: 22, Electric: 23, Psychic: 24, Ice: 25, Dragon: 26, Dark: 27,
}; };
@ -293,11 +293,11 @@ export const Scripts: ModdedBattleScriptsData = {
} }
// Attempting to add correct spread damage nerf // Attempting to add correct spread damage nerf
const {targets} = source.getMoveTargets(move, target); const { targets } = source.getMoveTargets(move, target);
if (targets.length > 1) move.spreadHit = true; if (targets.length > 1) move.spreadHit = true;
if (move.spreadHit && move.target === 'allAdjacentFoes') { if (move.spreadHit && move.target === 'allAdjacentFoes') {
const spreadModifier = move.spreadModifier || 0.5; const spreadModifier = move.spreadModifier || 0.5;
this.battle.debug('Spread modifier: ' + spreadModifier); this.battle.debug(`Spread modifier: ${spreadModifier}`);
damage = this.battle.modify(damage, spreadModifier); damage = this.battle.modify(damage, spreadModifier);
} }

View File

@ -46,7 +46,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }

View File

@ -25,7 +25,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} }
boosts = target.boosts.atk - originalStage; boosts = target.boosts.atk - originalStage;
target.boosts.atk = originalStage; target.boosts.atk = originalStage;
this.boost({atk: boosts}); this.boost({ atk: boosts });
}, },
}, },
destinybond: { destinybond: {

View File

@ -7,7 +7,7 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon: { pokemon: {
inherit: true, inherit: true,
getStat(statName, unboosted, unmodified, fastReturn) { getStat(statName, unboosted, unmodified, fastReturn) {
// @ts-ignore - type checking prevents 'hp' from being passed, but we're paranoid // @ts-expect-error type checking prevents 'hp' from being passed, but we're paranoid
if (statName === 'hp') throw new Error("Please read `maxhp` directly"); if (statName === 'hp') throw new Error("Please read `maxhp` directly");
// base stat // base stat
@ -478,7 +478,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (typeof effect === 'string') effect = this.dex.conditions.get(effect); if (typeof effect === 'string') effect = this.dex.conditions.get(effect);
if (!target?.hp) return 0; if (!target?.hp) return 0;
let success = null; let success = null;
boost = this.runEvent('TryBoost', target, source, effect, {...boost}); boost = this.runEvent('TryBoost', target, source, effect, { ...boost });
let i: BoostID; let i: BoostID;
for (i in boost) { for (i in boost) {
const currentBoost: SparseBoostsTable = {}; const currentBoost: SparseBoostsTable = {};
@ -547,7 +547,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.queue.clear(); this.queue.clear();
// Fainting clears accumulated Bide damage // Fainting clears accumulated Bide damage
for (const pokemon of this.getAllActive()) { for (const pokemon of this.getAllActive()) {
if (pokemon.volatiles['bide'] && pokemon.volatiles['bide'].damage) { if (pokemon.volatiles['bide']?.damage) {
pokemon.volatiles['bide'].damage = 0; pokemon.volatiles['bide'].damage = 0;
this.hint("Desync Clause Mod activated!"); this.hint("Desync Clause Mod activated!");
this.hint("In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints."); this.hint("In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints.");

View File

@ -85,7 +85,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (target.volatiles['substitute']) { if (target.volatiles['substitute']) {
this.add('-immune', target); this.add('-immune', target);
} else { } else {
this.boost({atk: -1}, target, pokemon, null, true); this.boost({ atk: -1 }, target, pokemon, null, true);
} }
} }
}, },
@ -98,7 +98,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.effectState.target; return this.effectState.target;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
name: "Lightning Rod", name: "Lightning Rod",
rating: 0, rating: 0,
num: 32, num: 32,
@ -182,7 +182,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (!target || target.fainted) return; if (!target || target.fainted) return;
const ability = target.getAbility(); const ability = target.getAbility();
if (pokemon.setAbility(ability)) { if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
}, },
flags: {}, flags: {},

View File

@ -4,7 +4,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }

View File

@ -18,11 +18,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
ancientpower: { ancientpower: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
assist: { assist: {
inherit: true, inherit: true,
flags: {metronome: 1, noassist: 1, nosleeptalk: 1}, flags: { metronome: 1, noassist: 1, nosleeptalk: 1 },
}, },
astonish: { astonish: {
inherit: true, inherit: true,
@ -100,7 +100,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
damage: this.effectState.totalDamage * 2, damage: this.effectState.totalDamage * 2,
category: "Physical", category: "Physical",
priority: 0, priority: 0,
flags: {contact: 1, protect: 1}, flags: { contact: 1, protect: 1 },
effectType: 'Move', effectType: 'Move',
type: 'Normal', type: 'Normal',
} as unknown as ActiveMove; } as unknown as ActiveMove;
@ -182,7 +182,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
covet: { covet: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, noassist: 1}, flags: { protect: 1, mirror: 1, noassist: 1 },
}, },
crunch: { crunch: {
inherit: true, inherit: true,
@ -200,7 +200,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
disable: { disable: {
inherit: true, inherit: true,
accuracy: 55, accuracy: 55,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
volatileStatus: 'disable', volatileStatus: 'disable',
condition: { condition: {
durationCallback() { durationCallback() {
@ -257,7 +257,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Doom Desire", name: "Doom Desire",
basePower: 120, basePower: 120,
category: "Physical", category: "Physical",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
willCrit: false, willCrit: false,
type: '???', type: '???',
} as unknown as ActiveMove; } as unknown as ActiveMove;
@ -265,15 +265,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
Object.assign(target.side.slotConditions[target.position]['futuremove'], { Object.assign(target.side.slotConditions[target.position]['futuremove'], {
duration: 3, duration: 3,
move: 'doomdesire', move: 'doomdesire',
source: source, source,
moveData: { moveData: {
id: 'doomdesire', id: 'doomdesire',
name: "Doom Desire", name: "Doom Desire",
accuracy: 85, accuracy: 85,
basePower: 0, basePower: 0,
damage: damage, damage,
category: "Physical", category: "Physical",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
effectType: 'Move', effectType: 'Move',
type: '???', type: '???',
}, },
@ -339,11 +339,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
fakeout: { fakeout: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
feintattack: { feintattack: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
flail: { flail: {
inherit: true, inherit: true,
@ -363,7 +363,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} else { } else {
bp = 20; bp = 20;
} }
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -469,7 +469,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mimic: { mimic: {
inherit: true, inherit: true,
flags: {protect: 1, bypasssub: 1, allyanim: 1, failencore: 1, noassist: 1, failmimic: 1}, flags: { protect: 1, bypasssub: 1, allyanim: 1, failencore: 1, noassist: 1, failmimic: 1 },
}, },
mirrorcoat: { mirrorcoat: {
inherit: true, inherit: true,
@ -499,7 +499,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mirrormove: { mirrormove: {
inherit: true, inherit: true,
flags: {metronome: 1, failencore: 1, nosleeptalk: 1, noassist: 1}, flags: { metronome: 1, failencore: 1, nosleeptalk: 1, noassist: 1 },
onTryHit() { }, onTryHit() { },
onHit(pokemon) { onHit(pokemon) {
const noMirror = [ const noMirror = [
@ -544,7 +544,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
overheat: { overheat: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
petaldance: { petaldance: {
inherit: true, inherit: true,
@ -572,7 +572,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} else { } else {
bp = 20; bp = 20;
} }
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -582,7 +582,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
sketch: { sketch: {
inherit: true, inherit: true,
flags: {bypasssub: 1, failencore: 1, noassist: 1, failmimic: 1, nosketch: 1}, flags: { bypasssub: 1, failencore: 1, noassist: 1, failmimic: 1, nosketch: 1 },
}, },
sleeptalk: { sleeptalk: {
inherit: true, inherit: true,
@ -593,7 +593,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const pp = moveSlot.pp; const pp = moveSlot.pp;
const move = this.dex.moves.get(moveid); const move = this.dex.moves.get(moveid);
if (moveid && !move.flags['nosleeptalk'] && !move.flags['charge']) { if (moveid && !move.flags['nosleeptalk'] && !move.flags['charge']) {
moves.push({move: moveid, pp: pp}); moves.push({ move: moveid, pp });
} }
} }
if (!moves.length) { if (!moves.length) {
@ -640,7 +640,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
struggle: { struggle: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, noassist: 1, failencore: 1, failmimic: 1, nosketch: 1}, flags: { contact: 1, protect: 1, noassist: 1, failencore: 1, failmimic: 1, nosketch: 1 },
accuracy: 100, accuracy: 100,
recoil: [1, 4], recoil: [1, 4],
struggleRecoil: false, struggleRecoil: false,
@ -651,7 +651,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
taunt: { taunt: {
inherit: true, inherit: true,
flags: {protect: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, bypasssub: 1, metronome: 1 },
condition: { condition: {
duration: 2, duration: 2,
onStart(target) { onStart(target) {
@ -679,11 +679,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
teeterdance: { teeterdance: {
inherit: true, inherit: true,
flags: {protect: 1, metronome: 1}, flags: { protect: 1, metronome: 1 },
}, },
tickle: { tickle: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
uproar: { uproar: {
inherit: true, inherit: true,

View File

@ -50,7 +50,7 @@ export const Scripts: ModdedBattleScriptsData = {
// and the user's ally, like Earthquake and Explosion, don't get affected by spread modifiers // and the user's ally, like Earthquake and Explosion, don't get affected by spread modifiers
if (move.spreadHit && move.target === 'allAdjacentFoes') { if (move.spreadHit && move.target === 'allAdjacentFoes') {
const spreadModifier = move.spreadModifier || 0.5; const spreadModifier = move.spreadModifier || 0.5;
this.battle.debug('Spread modifier: ' + spreadModifier); this.battle.debug(`Spread modifier: ${spreadModifier}`);
baseDamage = this.battle.modify(baseDamage, spreadModifier); baseDamage = this.battle.modify(baseDamage, spreadModifier);
} }
@ -163,7 +163,7 @@ export const Scripts: ModdedBattleScriptsData = {
let movename = move.name; let movename = move.name;
if (move.id === 'hiddenpower') movename = 'Hidden Power'; if (move.id === 'hiddenpower') movename = 'Hidden Power';
if (sourceEffect) attrs += `|[from]${this.dex.conditions.get(sourceEffect)}`; if (sourceEffect) attrs += `|[from]${this.dex.conditions.get(sourceEffect)}`;
this.battle.addMove('move', pokemon, movename, target + attrs); this.battle.addMove('move', pokemon, movename, `${target}${attrs}`);
if (!target) { if (!target) {
this.battle.attrLastMove('[notarget]'); this.battle.attrLastMove('[notarget]');
@ -171,7 +171,7 @@ export const Scripts: ModdedBattleScriptsData = {
return false; return false;
} }
const {targets, pressureTargets} = pokemon.getMoveTargets(move, target); const { targets, pressureTargets } = pokemon.getMoveTargets(move, target);
if (!sourceEffect || sourceEffect.id === 'pursuit') { if (!sourceEffect || sourceEffect.id === 'pursuit') {
let extraPP = 0; let extraPP = 0;
@ -328,7 +328,7 @@ export const Scripts: ModdedBattleScriptsData = {
let boost: number; let boost: number;
if (accuracy !== true) { if (accuracy !== true) {
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy *= boostTable[boost]; accuracy *= boostTable[boost];
@ -337,7 +337,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
boost = this.battle.clampIntRange(boosts['evasion'], -6, 6); boost = this.battle.clampIntRange(boosts['evasion'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy /= boostTable[boost]; accuracy /= boostTable[boost];
@ -417,7 +417,7 @@ export const Scripts: ModdedBattleScriptsData = {
accuracy = move.accuracy; accuracy = move.accuracy;
if (accuracy !== true) { if (accuracy !== true) {
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy *= boostTable[boost]; accuracy *= boostTable[boost];
@ -426,7 +426,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
boost = this.battle.clampIntRange(boosts['evasion'], -6, 6); boost = this.battle.clampIntRange(boosts['evasion'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy /= boostTable[boost]; accuracy /= boostTable[boost];

View File

@ -11,7 +11,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onAfterSubDamage(damage, target, source, move) { onAfterSubDamage(damage, target, source, move) {
if (!target.hp) return; if (!target.hp) return;
if (move && move.effectType === 'Move' && target.getMoveHitData(move).crit) { if (move && move.effectType === 'Move' && target.getMoveHitData(move).crit) {
target.setBoost({atk: 6}); target.setBoost({ atk: 6 });
this.add('-setboost', target, 'atk', 12, '[from] ability: Anger Point'); this.add('-setboost', target, 'atk', 12, '[from] ability: Anger Point');
} }
}, },
@ -83,9 +83,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
totalspd += target.getStat('spd', false, true); totalspd += target.getStat('spd', false, true);
} }
if (totaldef && totaldef >= totalspd) { if (totaldef && totaldef >= totalspd) {
this.boost({spa: 1}); this.boost({ spa: 1 });
} else if (totalspd) { } else if (totalspd) {
this.boost({atk: 1}); this.boost({ atk: 1 });
} }
}, },
}, },
@ -155,11 +155,11 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(1.5); return this.chainModify(1.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
forecast: { forecast: {
inherit: true, inherit: true,
flags: {notrace: 1}, flags: { notrace: 1 },
}, },
forewarn: { forewarn: {
inherit: true, inherit: true,
@ -191,7 +191,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onStart(pokemon) { onStart(pokemon) {
const target = pokemon.side.randomFoe(); const target = pokemon.side.randomFoe();
if (target?.item && !target.itemState.knockedOff) { if (target?.item && !target.itemState.knockedOff) {
this.add('-item', '', target.getItem().name, '[from] ability: Frisk', '[of] ' + pokemon); this.add('-item', '', target.getItem().name, '[from] ability: Frisk', `[of] ${pokemon}`);
} }
}, },
}, },
@ -238,7 +238,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} else if (target.volatiles['substitutebroken']?.move === 'uturn') { } else if (target.volatiles['substitutebroken']?.move === 'uturn') {
this.hint("In Gen 4, if U-turn breaks Substitute the incoming Intimidate does nothing."); this.hint("In Gen 4, if U-turn breaks Substitute the incoming Intimidate does nothing.");
} else { } else {
this.boost({atk: -1}, target, pokemon, null, true); this.boost({ atk: -1 }, target, pokemon, null, true);
} }
} }
}, },
@ -247,7 +247,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
inherit: true, inherit: true,
onSetStatus(status, target, source, effect) { onSetStatus(status, target, source, effect) {
if (effect && effect.id === 'rest') { if (effect && effect.id === 'rest') {
return; // do nothing
} else if (this.field.isWeather('sunnyday')) { } else if (this.field.isWeather('sunnyday')) {
return false; return false;
} }
@ -261,7 +261,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
liquidooze: { liquidooze: {
inherit: true, inherit: true,
onSourceTryHeal(damage, target, source, effect) { onSourceTryHeal(damage, target, source, effect) {
this.debug("Heal is occurring: " + target + " <- " + source + " :: " + effect.id); this.debug(`Heal is occurring: ${target} <- ${source} :: ${effect.id}`);
const canOoze = ['drain', 'leechseed']; const canOoze = ['drain', 'leechseed'];
if (canOoze.includes(effect.id) && this.activeMove?.id !== 'dreameater') { if (canOoze.includes(effect.id) && this.activeMove?.id !== 'dreameater') {
this.damage(damage, null, null, null, true); this.damage(damage, null, null, null, true);
@ -410,7 +410,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
boosts[key]! *= 2; boosts[key]! *= 2;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
name: "Simple", name: "Simple",
rating: 4, rating: 4,
num: 86, num: 86,
@ -506,7 +506,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
name: "Thick Fat", name: "Thick Fat",
rating: 3.5, rating: 3.5,
num: 47, num: 47,
@ -535,10 +535,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return; return;
} }
if (pokemon.setAbility(ability)) { if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
}, },
flags: {notrace: 1}, flags: { notrace: 1 },
}, },
unburden: { unburden: {
inherit: true, inherit: true,

View File

@ -24,7 +24,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
effectType: 'Status', effectType: 'Status',
onStart(target, source, sourceEffect) { onStart(target, source, sourceEffect) {
if (sourceEffect && sourceEffect.effectType === 'Move') { if (sourceEffect && sourceEffect.effectType === 'Move') {
this.add('-status', target, 'slp', '[from] move: ' + sourceEffect.name); this.add('-status', target, 'slp', `[from] move: ${sourceEffect.name}`);
} else { } else {
this.add('-status', target, 'slp'); this.add('-status', target, 'slp');
} }

View File

@ -89,7 +89,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
}, },
onCustap(pokemon) { onCustap(pokemon) {
const action = this.queue.willMove(pokemon); const action = this.queue.willMove(pokemon);
this.debug('custap action: ' + action); this.debug(`custap action: ${action?.moveid}`);
if (action && pokemon.eatItem()) { if (action && pokemon.eatItem()) {
this.queue.cancelAction(pokemon); this.queue.cancelAction(pokemon);
this.add('-message', "Custap Berry activated."); this.add('-message', "Custap Berry activated.");
@ -241,7 +241,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
condition: { condition: {
duration: 1, duration: 1,
onAfterMoveSecondarySelf(source, target, move) { onAfterMoveSecondarySelf(source, target, move) {
if (move && move.effectType === 'Move' && source && source.volatiles['lifeorb']) { if (move && move.effectType === 'Move' && source?.volatiles['lifeorb']) {
this.damage(source.baseMaxhp / 10, source, source, this.dex.items.get('lifeorb')); this.damage(source.baseMaxhp / 10, source, source, this.dex.items.get('lifeorb'));
source.removeVolatile('lifeorb'); source.removeVolatile('lifeorb');
} }

View File

@ -1,7 +1,7 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
acupressure: { acupressure: {
inherit: true, inherit: true,
flags: {snatch: 1, metronome: 1}, flags: { snatch: 1, metronome: 1 },
onHit(target) { onHit(target) {
if (target.volatiles['substitute']) { if (target.volatiles['substitute']) {
return false; return false;
@ -35,7 +35,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
aquaring: { aquaring: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
condition: { condition: {
onStart(pokemon) { onStart(pokemon) {
this.add('-start', pokemon, 'Aqua Ring'); this.add('-start', pokemon, 'Aqua Ring');
@ -151,7 +151,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
damage: this.effectState.totalDamage * 2, damage: this.effectState.totalDamage * 2,
category: "Physical", category: "Physical",
priority: 1, priority: 1,
flags: {contact: 1, protect: 1}, flags: { contact: 1, protect: 1 },
ignoreImmunity: true, ignoreImmunity: true,
effectType: 'Move', effectType: 'Move',
type: 'Normal', type: 'Normal',
@ -207,7 +207,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
conversion: { conversion: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
onHit(target) { onHit(target) {
const possibleTypes = target.moveSlots.map(moveSlot => { const possibleTypes = target.moveSlots.map(moveSlot => {
const move = this.dex.moves.get(moveSlot.id); const move = this.dex.moves.get(moveSlot.id);
@ -257,19 +257,19 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
basePowerCallback(pokemon, target) { basePowerCallback(pokemon, target) {
const bp = Math.floor(target.hp * 120 / target.maxhp) + 1; const bp = Math.floor(target.hp * 120 / target.maxhp) + 1;
this.debug('BP for ' + target.hp + '/' + target.maxhp + " HP: " + bp); this.debug(`BP for ${target.hp}/${target.maxhp} HP: ${bp}`);
return bp; return bp;
}, },
}, },
curse: { curse: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
onModifyMove(move, source, target) { onModifyMove(move, source, target) {
if (!source.hasType('Ghost')) { if (!source.hasType('Ghost')) {
delete move.volatileStatus; delete move.volatileStatus;
delete move.onHit; delete move.onHit;
move.self = {boosts: {atk: 1, def: 1, spe: -1}}; move.self = { boosts: { atk: 1, def: 1, spe: -1 } };
move.target = move.nonGhostTarget as MoveTarget; move.target = move.nonGhostTarget!;
} else if (target?.volatiles['substitute']) { } else if (target?.volatiles['substitute']) {
delete move.volatileStatus; delete move.volatileStatus;
delete move.onHit; delete move.onHit;
@ -277,7 +277,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
condition: { condition: {
onStart(pokemon, source) { onStart(pokemon, source) {
this.add('-start', pokemon, 'Curse', '[of] ' + source); this.add('-start', pokemon, 'Curse', `[of] ${source}`);
}, },
onResidualOrder: 10, onResidualOrder: 10,
onResidualSubOrder: 8, onResidualSubOrder: 8,
@ -289,7 +289,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
defog: { defog: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
detect: { detect: {
inherit: true, inherit: true,
@ -317,7 +317,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
disable: { disable: {
inherit: true, inherit: true,
accuracy: 80, accuracy: 80,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
volatileStatus: 'disable', volatileStatus: 'disable',
condition: { condition: {
durationCallback() { durationCallback() {
@ -375,7 +375,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Doom Desire", name: "Doom Desire",
basePower: 120, basePower: 120,
category: "Special", category: "Special",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
willCrit: false, willCrit: false,
type: '???', type: '???',
} as unknown as ActiveMove; } as unknown as ActiveMove;
@ -383,15 +383,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
Object.assign(target.side.slotConditions[target.position]['futuremove'], { Object.assign(target.side.slotConditions[target.position]['futuremove'], {
duration: 3, duration: 3,
move: 'doomdesire', move: 'doomdesire',
source: source, source,
moveData: { moveData: {
id: 'doomdesire', id: 'doomdesire',
name: "Doom Desire", name: "Doom Desire",
accuracy: 85, accuracy: 85,
basePower: 0, basePower: 0,
damage: damage, damage,
category: "Special", category: "Special",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
effectType: 'Move', effectType: 'Move',
type: '???', type: '???',
}, },
@ -417,7 +417,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
embargo: { embargo: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
onTryHit(pokemon) { onTryHit(pokemon) {
if (pokemon.ability === 'multitype' || pokemon.item === 'griseousorb') { if (pokemon.ability === 'multitype' || pokemon.item === 'griseousorb') {
return false; return false;
@ -438,7 +438,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
encore: { encore: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1, failencore: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1, failencore: 1 },
volatileStatus: 'encore', volatileStatus: 'encore',
condition: { condition: {
durationCallback() { durationCallback() {
@ -535,7 +535,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} else { } else {
bp = 20; bp = 20;
} }
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -552,7 +552,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (!this.singleEvent('TakeItem', item, source.itemState, source, source, move, item)) return false; if (!this.singleEvent('TakeItem', item, source.itemState, source, source, move, item)) return false;
if (!item.fling) return false; if (!item.fling) return false;
move.basePower = item.fling.basePower; move.basePower = item.fling.basePower;
this.debug('BP: ' + move.basePower); this.debug(`BP: ${move.basePower}`);
if (item.isBerry) { if (item.isBerry) {
move.onHit = function (foe) { move.onHit = function (foe) {
if (this.singleEvent('Eat', item, null, foe, null, null)) { if (this.singleEvent('Eat', item, null, foe, null, null)) {
@ -566,9 +566,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} else { } else {
if (!move.secondaries) move.secondaries = []; if (!move.secondaries) move.secondaries = [];
if (item.fling.status) { if (item.fling.status) {
move.secondaries.push({status: item.fling.status}); move.secondaries.push({ status: item.fling.status });
} else if (item.fling.volatileStatus) { } else if (item.fling.volatileStatus) {
move.secondaries.push({volatileStatus: item.fling.volatileStatus}); move.secondaries.push({ volatileStatus: item.fling.volatileStatus });
} }
} }
source.addVolatile('fling'); source.addVolatile('fling');
@ -591,7 +591,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
foresight: { foresight: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
furycutter: { furycutter: {
inherit: true, inherit: true,
@ -620,7 +620,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Future Sight", name: "Future Sight",
basePower: 80, basePower: 80,
category: "Special", category: "Special",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
willCrit: false, willCrit: false,
type: '???', type: '???',
} as unknown as ActiveMove; } as unknown as ActiveMove;
@ -628,15 +628,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
Object.assign(target.side.slotConditions[target.position]['futuremove'], { Object.assign(target.side.slotConditions[target.position]['futuremove'], {
duration: 3, duration: 3,
move: 'futuresight', move: 'futuresight',
source: source, source,
moveData: { moveData: {
id: 'futuresight', id: 'futuresight',
name: "Future Sight", name: "Future Sight",
accuracy: 90, accuracy: 90,
basePower: 0, basePower: 0,
damage: damage, damage,
category: "Special", category: "Special",
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
effectType: 'Move', effectType: 'Move',
type: '???', type: '???',
}, },
@ -752,7 +752,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
healblock: { healblock: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
condition: { condition: {
duration: 5, duration: 5,
durationCallback(target, source, effect) { durationCallback(target, source, effect) {
@ -793,7 +793,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
healingwish: { healingwish: {
inherit: true, inherit: true,
flags: {heal: 1, metronome: 1}, flags: { heal: 1, metronome: 1 },
onAfterMove(pokemon) { onAfterMove(pokemon) {
pokemon.switchFlag = true; pokemon.switchFlag = true;
}, },
@ -830,7 +830,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
imprison: { imprison: {
inherit: true, inherit: true,
flags: {bypasssub: 1, metronome: 1}, flags: { bypasssub: 1, metronome: 1 },
onTryHit(pokemon) { onTryHit(pokemon) {
for (const target of pokemon.foes()) { for (const target of pokemon.foes()) {
for (const move of pokemon.moves) { for (const move of pokemon.moves) {
@ -880,7 +880,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const item = target.getItem(); const item = target.getItem();
if (this.runEvent('TakeItem', target, source, move, item)) { if (this.runEvent('TakeItem', target, source, move, item)) {
target.itemState.knockedOff = true; target.itemState.knockedOff = true;
this.add('-enditem', target, item.name, '[from] move: Knock Off', '[of] ' + source); this.add('-enditem', target, item.name, '[from] move: Knock Off', `[of] ${source}`);
this.hint("In Gens 3-4, Knock Off only makes the target's item unusable; it cannot obtain a new item.", true); this.hint("In Gens 3-4, Knock Off only makes the target's item unusable; it cannot obtain a new item.", true);
} }
}, },
@ -953,7 +953,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
luckychant: { luckychant: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
condition: { condition: {
duration: 5, duration: 5,
onSideStart(side) { onSideStart(side) {
@ -968,7 +968,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
lunardance: { lunardance: {
inherit: true, inherit: true,
flags: {heal: 1, metronome: 1}, flags: { heal: 1, metronome: 1 },
onAfterMove(pokemon) { onAfterMove(pokemon) {
pokemon.switchFlag = true; pokemon.switchFlag = true;
}, },
@ -1009,7 +1009,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
target.removeVolatile('magiccoat'); target.removeVolatile('magiccoat');
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
this.actions.useMove(newMove, target, {target: source}); this.actions.useMove(newMove, target, { target: source });
return null; return null;
}, },
}, },
@ -1020,7 +1020,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
magnetrise: { magnetrise: {
inherit: true, inherit: true,
flags: {gravity: 1, metronome: 1}, flags: { gravity: 1, metronome: 1 },
volatileStatus: 'magnetrise', volatileStatus: 'magnetrise',
condition: { condition: {
duration: 5, duration: 5,
@ -1049,11 +1049,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
metalburst: { metalburst: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
metronome: { metronome: {
inherit: true, inherit: true,
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1}, flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1, failmimic: 1 },
onHit(pokemon) { onHit(pokemon) {
const moves = this.dex.moves.all().filter(move => ( const moves = this.dex.moves.all().filter(move => (
(![2, 4].includes(this.gen) || !pokemon.moves.includes(move.id)) && (![2, 4].includes(this.gen) || !pokemon.moves.includes(move.id)) &&
@ -1107,7 +1107,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
miracleeye: { miracleeye: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
mirrormove: { mirrormove: {
inherit: true, inherit: true,
@ -1197,7 +1197,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
naturepower: { naturepower: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
onHit(pokemon) { onHit(pokemon) {
this.actions.useMove('triattack', pokemon); this.actions.useMove('triattack', pokemon);
}, },
@ -1221,7 +1221,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
odorsleuth: { odorsleuth: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
outrage: { outrage: {
inherit: true, inherit: true,
@ -1255,7 +1255,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onResidualOrder: 12, onResidualOrder: 12,
onResidual(pokemon) { onResidual(pokemon) {
const duration = pokemon.volatiles['perishsong'].duration; const duration = pokemon.volatiles['perishsong'].duration;
this.add('-start', pokemon, 'perish' + duration); this.add('-start', pokemon, `perish${duration}`);
}, },
}, },
}, },
@ -1272,7 +1272,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
powertrick: { powertrick: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
}, },
protect: { protect: {
inherit: true, inherit: true,
@ -1299,7 +1299,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
psychup: { psychup: {
inherit: true, inherit: true,
flags: {snatch: 1, bypasssub: 1, metronome: 1}, flags: { snatch: 1, bypasssub: 1, metronome: 1 },
}, },
pursuit: { pursuit: {
inherit: true, inherit: true,
@ -1335,12 +1335,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
self: { self: {
onHit(pokemon) { onHit(pokemon) {
if (pokemon.removeVolatile('leechseed')) { if (pokemon.removeVolatile('leechseed')) {
this.add('-end', pokemon, 'Leech Seed', '[from] move: Rapid Spin', '[of] ' + pokemon); this.add('-end', pokemon, 'Leech Seed', '[from] move: Rapid Spin', `[of] ${pokemon}`);
} }
const sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb']; const sideConditions = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb'];
for (const condition of sideConditions) { for (const condition of sideConditions) {
if (pokemon.side.removeSideCondition(condition)) { if (pokemon.side.removeSideCondition(condition)) {
this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Rapid Spin', '[of] ' + pokemon); this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Rapid Spin', `[of] ${pokemon}`);
} }
} }
if (pokemon.volatiles['partiallytrapped']) { if (pokemon.volatiles['partiallytrapped']) {
@ -1351,7 +1351,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
recycle: { recycle: {
inherit: true, inherit: true,
flags: {metronome: 1}, flags: { metronome: 1 },
}, },
reflect: { reflect: {
inherit: true, inherit: true,
@ -1399,13 +1399,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} else { } else {
bp = 20; bp = 20;
} }
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
roar: { roar: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 },
}, },
rockblast: { rockblast: {
inherit: true, inherit: true,
@ -1530,7 +1530,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
snatch: { snatch: {
inherit: true, inherit: true,
flags: {bypasssub: 1, noassist: 1, failcopycat: 1}, flags: { bypasssub: 1, noassist: 1, failcopycat: 1 },
condition: { condition: {
duration: 1, duration: 1,
onStart(pokemon) { onStart(pokemon) {
@ -1544,7 +1544,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return; return;
} }
snatchUser.removeVolatile('snatch'); snatchUser.removeVolatile('snatch');
this.add('-activate', snatchUser, 'move: Snatch', '[of] ' + source); this.add('-activate', snatchUser, 'move: Snatch', `[of] ${source}`);
this.actions.useMove(move.id, snatchUser); this.actions.useMove(move.id, snatchUser);
return null; return null;
}, },
@ -1552,11 +1552,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
snore: { snore: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
spikes: { spikes: {
inherit: true, inherit: true,
flags: {metronome: 1, mustpressure: 1}, flags: { metronome: 1, mustpressure: 1 },
condition: { condition: {
// this is a side condition // this is a side condition
onSideStart(side) { onSideStart(side) {
@ -1577,11 +1577,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
spite: { spite: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
stealthrock: { stealthrock: {
inherit: true, inherit: true,
flags: {metronome: 1, mustpressure: 1}, flags: { metronome: 1, mustpressure: 1 },
condition: { condition: {
// this is a side condition // this is a side condition
onSideStart(side) { onSideStart(side) {
@ -1590,7 +1590,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onEntryHazard(pokemon) { onEntryHazard(pokemon) {
if (pokemon.hasItem('heavydutyboots')) return; if (pokemon.hasItem('heavydutyboots')) return;
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6); const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8); this.damage(pokemon.maxhp * 2 ** typeMod / 8);
}, },
}, },
}, },
@ -1728,7 +1728,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
taunt: { taunt: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
condition: { condition: {
durationCallback() { durationCallback() {
return this.random(3, 6); return this.random(3, 6);
@ -1765,7 +1765,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
torment: { torment: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
toxic: { toxic: {
inherit: true, inherit: true,
@ -1773,7 +1773,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
toxicspikes: { toxicspikes: {
inherit: true, inherit: true,
flags: {metronome: 1, mustpressure: 1}, flags: { metronome: 1, mustpressure: 1 },
condition: { condition: {
// this is a side condition // this is a side condition
onSideStart(side) { onSideStart(side) {
@ -1788,10 +1788,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onEntryHazard(pokemon) { onEntryHazard(pokemon) {
if (!pokemon.isGrounded()) return; if (!pokemon.isGrounded()) return;
if (pokemon.hasType('Poison')) { if (pokemon.hasType('Poison')) {
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', '[of] ' + pokemon); this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
pokemon.side.removeSideCondition('toxicspikes'); pokemon.side.removeSideCondition('toxicspikes');
} else if (pokemon.volatiles['substitute'] || pokemon.hasType('Steel')) { } else if (pokemon.volatiles['substitute'] || pokemon.hasType('Steel')) {
return; // do nothing
} else if (this.effectState.layers >= 2) { } else if (this.effectState.layers >= 2) {
pokemon.trySetStatus('tox', pokemon.side.foe.active[0]); pokemon.trySetStatus('tox', pokemon.side.foe.active[0]);
} else { } else {
@ -1802,7 +1802,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
transform: { transform: {
inherit: true, inherit: true,
flags: {bypasssub: 1, metronome: 1, failencore: 1}, flags: { bypasssub: 1, metronome: 1, failencore: 1 },
}, },
trick: { trick: {
inherit: true, inherit: true,
@ -1823,9 +1823,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
onFieldStart(target, source) { onFieldStart(target, source) {
if (source?.hasAbility('persistent')) { if (source?.hasAbility('persistent')) {
this.add('-fieldstart', 'move: Trick Room', '[of] ' + source, '[persistent]'); this.add('-fieldstart', 'move: Trick Room', `[of] ${source}`, '[persistent]');
} else { } else {
this.add('-fieldstart', 'move: Trick Room', '[of] ' + source); this.add('-fieldstart', 'move: Trick Room', `[of] ${source}`);
} }
}, },
onFieldRestart(target, source) { onFieldRestart(target, source) {
@ -1902,11 +1902,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
whirlwind: { whirlwind: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
wish: { wish: {
inherit: true, inherit: true,
flags: {heal: 1, metronome: 1}, flags: { heal: 1, metronome: 1 },
slotCondition: 'Wish', slotCondition: 'Wish',
condition: { condition: {
duration: 2, duration: 2,
@ -1941,7 +1941,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
basePowerCallback(pokemon, target) { basePowerCallback(pokemon, target) {
const bp = Math.floor(target.hp * 120 / target.maxhp) + 1; const bp = Math.floor(target.hp * 120 / target.maxhp) + 1;
this.debug('BP for ' + target.hp + '/' + target.maxhp + " HP: " + bp); this.debug(`BP for ${target.hp}/${target.maxhp} HP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -1951,7 +1951,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
noCopy: true, // doesn't get copied by Baton Pass noCopy: true, // doesn't get copied by Baton Pass
duration: 2, duration: 2,
onStart(target, source) { onStart(target, source) {
this.add('-start', target, 'move: Yawn', '[of] ' + source); this.add('-start', target, 'move: Yawn', `[of] ${source}`);
}, },
onResidualOrder: 10, onResidualOrder: 10,
onResidualSubOrder: 19, onResidualSubOrder: 19,

View File

@ -48,7 +48,7 @@ export const Scripts: ModdedBattleScriptsData = {
// Double battle multi-hit // Double battle multi-hit
if (move.spreadHit) { if (move.spreadHit) {
const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75); const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75);
this.battle.debug('Spread modifier: ' + spreadModifier); this.battle.debug(`Spread modifier: ${spreadModifier}`);
baseDamage = this.battle.modify(baseDamage, spreadModifier); baseDamage = this.battle.modify(baseDamage, spreadModifier);
} }
@ -147,7 +147,7 @@ export const Scripts: ModdedBattleScriptsData = {
let boost!: number; let boost!: number;
if (accuracy !== true) { if (accuracy !== true) {
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy *= boostTable[boost]; accuracy *= boostTable[boost];
@ -156,7 +156,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
boost = this.battle.clampIntRange(boosts['evasion'], -6, 6); boost = this.battle.clampIntRange(boosts['evasion'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy /= boostTable[boost]; accuracy /= boostTable[boost];

View File

@ -21,7 +21,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onStart(pokemon) { onStart(pokemon) {
const target = pokemon.side.randomFoe(); const target = pokemon.side.randomFoe();
if (target?.item) { if (target?.item) {
this.add('-item', '', target.getItem().name, '[from] ability: Frisk', '[of] ' + pokemon); this.add('-item', '', target.getItem().name, '[from] ability: Frisk', `[of] ${pokemon}`);
} }
}, },
}, },
@ -42,7 +42,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
newMove.pranksterBoosted = false; newMove.pranksterBoosted = false;
this.actions.useMove(newMove, this.effectState.target, {target: source}); this.actions.useMove(newMove, this.effectState.target, { target: source });
return null; return null;
}, },
}, },

View File

@ -8,7 +8,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
partiallytrapped: { partiallytrapped: {
inherit: true, inherit: true,
onStart(pokemon, source) { onStart(pokemon, source) {
this.add('-activate', pokemon, 'move: ' + this.effectState.sourceEffect, '[of] ' + source); this.add('-activate', pokemon, 'move: ' + this.effectState.sourceEffect, `[of] ${source}`);
this.effectState.boundDivisor = source.hasItem('bindingband') ? 8 : 16; this.effectState.boundDivisor = source.hasItem('bindingband') ? 8 : 16;
}, },
onResidual(pokemon) { onResidual(pokemon) {
@ -34,7 +34,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
if (counter >= 256) { if (counter >= 256) {
return this.randomChance(1, 2 ** 32); return this.randomChance(1, 2 ** 32);
} }
this.debug("Success chance: " + Math.round(100 / counter) + "%"); this.debug(`Success chance: ${Math.round(100 / counter)}%`);
return this.randomChance(1, counter); return this.randomChance(1, counter);
}, },
onRestart() { onRestart() {

View File

@ -1,7 +1,7 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
absorb: { absorb: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
acidarmor: { acidarmor: {
inherit: true, inherit: true,
@ -68,7 +68,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
bestow: { bestow: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, noassist: 1, failcopycat: 1}, flags: { protect: 1, mirror: 1, noassist: 1, failcopycat: 1 },
}, },
blizzard: { blizzard: {
inherit: true, inherit: true,
@ -76,11 +76,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
block: { block: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 },
}, },
bounce: { bounce: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1}, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1 },
}, },
bubble: { bubble: {
inherit: true, inherit: true,
@ -88,7 +88,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
bugbuzz: { bugbuzz: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
camouflage: { camouflage: {
inherit: true, inherit: true,
@ -160,22 +160,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
defog: { defog: {
inherit: true, inherit: true,
onHit(pokemon) { onHit(pokemon) {
if (!pokemon.volatiles['substitute']) this.boost({evasion: -1}); if (!pokemon.volatiles['substitute']) this.boost({ evasion: -1 });
const sideConditions = ['reflect', 'lightscreen', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock']; const sideConditions = ['reflect', 'lightscreen', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock'];
for (const condition of sideConditions) { for (const condition of sideConditions) {
if (pokemon.side.removeSideCondition(condition)) { if (pokemon.side.removeSideCondition(condition)) {
this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Defog', '[of] ' + pokemon); this.add('-sideend', pokemon.side, this.dex.conditions.get(condition).name, '[from] move: Defog', `[of] ${pokemon}`);
} }
} }
}, },
}, },
dig: { dig: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, nosleeptalk: 1}, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, nosleeptalk: 1 },
}, },
dive: { dive: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, nosleeptalk: 1}, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, nonsky: 1, metronome: 1, nosleeptalk: 1 },
}, },
dracometeor: { dracometeor: {
inherit: true, inherit: true,
@ -187,22 +187,22 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
drainpunch: { drainpunch: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, punch: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, punch: 1, metronome: 1 },
}, },
dreameater: { dreameater: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
echoedvoice: { echoedvoice: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
electroball: { electroball: {
inherit: true, inherit: true,
basePowerCallback(pokemon, target) { basePowerCallback(pokemon, target) {
const ratio = Math.floor(pokemon.getStat('spe') / Math.max(1, target.getStat('spe'))); const ratio = Math.floor(pokemon.getStat('spe') / Math.max(1, target.getStat('spe')));
const bp = [40, 60, 80, 120, 150][Math.min(ratio, 4)]; const bp = [40, 60, 80, 120, 150][Math.min(ratio, 4)];
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -216,11 +216,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
feint: { feint: {
inherit: true, inherit: true,
flags: {noassist: 1, failcopycat: 1}, flags: { noassist: 1, failcopycat: 1 },
}, },
finalgambit: { finalgambit: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, metronome: 1}, flags: { contact: 1, protect: 1, metronome: 1 },
}, },
fireblast: { fireblast: {
inherit: true, inherit: true,
@ -243,7 +243,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
fly: { fly: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1}, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1 },
}, },
followme: { followme: {
inherit: true, inherit: true,
@ -277,7 +277,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
Object.assign(target.side.slotConditions[target.position]['futuremove'], { Object.assign(target.side.slotConditions[target.position]['futuremove'], {
duration: 3, duration: 3,
move: 'futuresight', move: 'futuresight',
source: source, source,
moveData: { moveData: {
id: 'futuresight', id: 'futuresight',
name: "Future Sight", name: "Future Sight",
@ -285,7 +285,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
basePower: 100, basePower: 100,
category: "Special", category: "Special",
priority: 0, priority: 0,
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
ignoreImmunity: false, ignoreImmunity: false,
effectType: 'Move', effectType: 'Move',
type: 'Psychic', type: 'Psychic',
@ -297,7 +297,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
gigadrain: { gigadrain: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
glare: { glare: {
inherit: true, inherit: true,
@ -305,7 +305,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
grasswhistle: { grasswhistle: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
grasspledge: { grasspledge: {
inherit: true, inherit: true,
@ -320,7 +320,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
growl: { growl: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
growth: { growth: {
inherit: true, inherit: true,
@ -335,13 +335,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
basePowerCallback(pokemon, target) { basePowerCallback(pokemon, target) {
let power = Math.floor(25 * target.getStat('spe') / Math.max(1, pokemon.getStat('spe'))) + 1; let power = Math.floor(25 * target.getStat('spe') / Math.max(1, pokemon.getStat('spe'))) + 1;
if (power > 150) power = 150; if (power > 150) power = 150;
this.debug('BP: ' + power); this.debug(`BP: ${power}`);
return power; return power;
}, },
}, },
healbell: { healbell: {
inherit: true, inherit: true,
flags: {snatch: 1, sound: 1, metronome: 1}, flags: { snatch: 1, sound: 1, metronome: 1 },
onHit(target, source) { onHit(target, source) {
this.add('-activate', source, 'move: Heal Bell'); this.add('-activate', source, 'move: Heal Bell');
const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []]; const allies = [...target.side.pokemon, ...target.side.allySide?.pokemon || []];
@ -368,7 +368,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
basePower: 0, basePower: 0,
basePowerCallback(pokemon) { basePowerCallback(pokemon) {
const bp = pokemon.hpPower || 70; const bp = pokemon.hpPower || 70;
this.debug('BP: ' + bp); this.debug(`BP: ${bp}`);
return bp; return bp;
}, },
}, },
@ -438,7 +438,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
hornleech: { hornleech: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
hurricane: { hurricane: {
inherit: true, inherit: true,
@ -450,7 +450,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
hypervoice: { hypervoice: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
icebeam: { icebeam: {
inherit: true, inherit: true,
@ -477,7 +477,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
leechlife: { leechlife: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
lick: { lick: {
inherit: true, inherit: true,
@ -534,7 +534,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
newMove.pranksterBoosted = this.effectState.pranksterBoosted; newMove.pranksterBoosted = this.effectState.pranksterBoosted;
this.actions.useMove(newMove, target, {target: source}); this.actions.useMove(newMove, target, { target: source });
return null; return null;
}, },
onAllyTryHitSide(target, source, move) { onAllyTryHitSide(target, source, move) {
@ -544,7 +544,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
newMove.pranksterBoosted = false; newMove.pranksterBoosted = false;
this.actions.useMove(newMove, this.effectState.target, {target: source}); this.actions.useMove(newMove, this.effectState.target, { target: source });
return null; return null;
}, },
}, },
@ -559,15 +559,15 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
meanlook: { meanlook: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 },
}, },
megadrain: { megadrain: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
metalsound: { metalsound: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
meteormash: { meteormash: {
inherit: true, inherit: true,
@ -626,7 +626,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
perishsong: { perishsong: {
inherit: true, inherit: true,
flags: {sound: 1, distance: 1, metronome: 1}, flags: { sound: 1, distance: 1, metronome: 1 },
}, },
pinmissile: { pinmissile: {
inherit: true, inherit: true,
@ -706,7 +706,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
ragepowder: { ragepowder: {
inherit: true, inherit: true,
priority: 3, priority: 3,
flags: {noassist: 1, failcopycat: 1}, flags: { noassist: 1, failcopycat: 1 },
}, },
reflect: { reflect: {
inherit: true, inherit: true,
@ -739,12 +739,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
relicsong: { relicsong: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1}, flags: { protect: 1, mirror: 1, sound: 1 },
}, },
roar: { roar: {
inherit: true, inherit: true,
accuracy: 100, accuracy: 100,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 },
}, },
rocktomb: { rocktomb: {
inherit: true, inherit: true,
@ -754,7 +754,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
round: { round: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
sacredsword: { sacredsword: {
inherit: true, inherit: true,
@ -766,7 +766,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
screech: { screech: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
secretpower: { secretpower: {
inherit: true, inherit: true,
@ -779,11 +779,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
shadowforce: { shadowforce: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1}, flags: { contact: 1, charge: 1, mirror: 1, metronome: 1, nosleeptalk: 1 },
}, },
sing: { sing: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
skillswap: { skillswap: {
inherit: true, inherit: true,
@ -793,7 +793,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (targetAbility === sourceAbility) { if (targetAbility === sourceAbility) {
return false; return false;
} }
this.add('-activate', source, 'move: Skill Swap', this.dex.abilities.get(targetAbility), this.dex.abilities.get(sourceAbility), '[of] ' + target); this.add('-activate', source, 'move: Skill Swap', this.dex.abilities.get(targetAbility), this.dex.abilities.get(sourceAbility), `[of] ${target}`);
source.setAbility(targetAbility); source.setAbility(targetAbility);
target.setAbility(sourceAbility); target.setAbility(sourceAbility);
}, },
@ -805,7 +805,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
skydrop: { skydrop: {
inherit: true, inherit: true,
flags: {contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1}, flags: { contact: 1, charge: 1, protect: 1, mirror: 1, gravity: 1, distance: 1, metronome: 1, nosleeptalk: 1 },
onTryHit(target, source, move) { onTryHit(target, source, move) {
if (target.fainted) return false; if (target.fainted) return false;
if (source.removeVolatile(move.id)) { if (source.removeVolatile(move.id)) {
@ -841,12 +841,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
snarl: { snarl: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1}, flags: { protect: 1, mirror: 1, sound: 1 },
}, },
snore: { snore: {
inherit: true, inherit: true,
basePower: 40, basePower: 40,
flags: {protect: 1, mirror: 1, sound: 1}, flags: { protect: 1, mirror: 1, sound: 1 },
}, },
soak: { soak: {
inherit: true, inherit: true,
@ -937,7 +937,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
supersonic: { supersonic: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, sound: 1, metronome: 1 },
}, },
surf: { surf: {
inherit: true, inherit: true,
@ -989,7 +989,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
uproar: { uproar: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, sound: 1, metronome: 1, nosleeptalk: 1}, flags: { protect: 1, mirror: 1, sound: 1, metronome: 1, nosleeptalk: 1 },
}, },
vinewhip: { vinewhip: {
inherit: true, inherit: true,
@ -1032,7 +1032,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
whirlwind: { whirlwind: {
inherit: true, inherit: true,
accuracy: 100, accuracy: 100,
flags: {protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, bypasssub: 1, metronome: 1 },
}, },
wideguard: { wideguard: {
inherit: true, inherit: true,

View File

@ -37,31 +37,31 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
butterfree: { butterfree: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 45, def: 50, spa: 80, spd: 80, spe: 70}, baseStats: { hp: 60, atk: 45, def: 50, spa: 80, spd: 80, spe: 70 },
}, },
beedrill: { beedrill: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 80, def: 40, spa: 45, spd: 80, spe: 75}, baseStats: { hp: 65, atk: 80, def: 40, spa: 45, spd: 80, spe: 75 },
}, },
pidgeot: { pidgeot: {
inherit: true, inherit: true,
baseStats: {hp: 83, atk: 80, def: 75, spa: 70, spd: 70, spe: 91}, baseStats: { hp: 83, atk: 80, def: 75, spa: 70, spd: 70, spe: 91 },
}, },
pikachu: { pikachu: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 55, def: 30, spa: 50, spd: 40, spe: 90}, baseStats: { hp: 35, atk: 55, def: 30, spa: 50, spd: 40, spe: 90 },
}, },
raichu: { raichu: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 90, def: 55, spa: 90, spd: 80, spe: 100}, baseStats: { hp: 60, atk: 90, def: 55, spa: 90, spd: 80, spe: 100 },
}, },
nidoqueen: { nidoqueen: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 82, def: 87, spa: 75, spd: 85, spe: 76}, baseStats: { hp: 90, atk: 82, def: 87, spa: 75, spd: 85, spe: 76 },
}, },
nidoking: { nidoking: {
inherit: true, inherit: true,
baseStats: {hp: 81, atk: 92, def: 77, spa: 85, spd: 75, spe: 85}, baseStats: { hp: 81, atk: 92, def: 77, spa: 85, spd: 75, spe: 85 },
}, },
clefairy: { clefairy: {
inherit: true, inherit: true,
@ -70,38 +70,38 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
clefable: { clefable: {
inherit: true, inherit: true,
types: ["Normal"], types: ["Normal"],
baseStats: {hp: 95, atk: 70, def: 73, spa: 85, spd: 90, spe: 60}, baseStats: { hp: 95, atk: 70, def: 73, spa: 85, spd: 90, spe: 60 },
}, },
jigglypuff: { jigglypuff: {
inherit: true, inherit: true,
types: ["Normal"], types: ["Normal"],
abilities: {0: "Cute Charm", H: "Friend Guard"}, abilities: { 0: "Cute Charm", H: "Friend Guard" },
}, },
wigglytuff: { wigglytuff: {
inherit: true, inherit: true,
types: ["Normal"], types: ["Normal"],
baseStats: {hp: 140, atk: 70, def: 45, spa: 75, spd: 50, spe: 45}, baseStats: { hp: 140, atk: 70, def: 45, spa: 75, spd: 50, spe: 45 },
abilities: {0: "Cute Charm", H: "Frisk"}, abilities: { 0: "Cute Charm", H: "Frisk" },
}, },
vileplume: { vileplume: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 80, def: 85, spa: 100, spd: 90, spe: 50}, baseStats: { hp: 75, atk: 80, def: 85, spa: 100, spd: 90, spe: 50 },
}, },
poliwrath: { poliwrath: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 85, def: 95, spa: 70, spd: 90, spe: 70}, baseStats: { hp: 90, atk: 85, def: 95, spa: 70, spd: 90, spe: 70 },
}, },
alakazam: { alakazam: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 50, def: 45, spa: 135, spd: 85, spe: 120}, baseStats: { hp: 55, atk: 50, def: 45, spa: 135, spd: 85, spe: 120 },
}, },
victreebel: { victreebel: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 105, def: 65, spa: 100, spd: 60, spe: 70}, baseStats: { hp: 80, atk: 105, def: 65, spa: 100, spd: 60, spe: 70 },
}, },
golem: { golem: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 110, def: 130, spa: 55, spd: 65, spe: 45}, baseStats: { hp: 80, atk: 110, def: 130, spa: 55, spd: 65, spe: 45 },
}, },
mrmime: { mrmime: {
inherit: true, inherit: true,
@ -113,7 +113,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
zapdos: { zapdos: {
inherit: true, inherit: true,
abilities: {0: "Pressure", H: "Lightning Rod"}, abilities: { 0: "Pressure", H: "Lightning Rod" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
moltres: { moltres: {
@ -159,7 +159,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
igglybuff: { igglybuff: {
inherit: true, inherit: true,
types: ["Normal"], types: ["Normal"],
abilities: {0: "Cute Charm", H: "Friend Guard"}, abilities: { 0: "Cute Charm", H: "Friend Guard" },
}, },
togepi: { togepi: {
inherit: true, inherit: true,
@ -175,11 +175,11 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
ampharos: { ampharos: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 75, def: 75, spa: 115, spd: 90, spe: 55}, baseStats: { hp: 90, atk: 75, def: 75, spa: 115, spd: 90, spe: 55 },
}, },
bellossom: { bellossom: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 80, def: 85, spa: 90, spd: 100, spe: 50}, baseStats: { hp: 75, atk: 80, def: 85, spa: 90, spd: 100, spe: 50 },
}, },
marill: { marill: {
inherit: true, inherit: true,
@ -188,11 +188,11 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
azumarill: { azumarill: {
inherit: true, inherit: true,
types: ["Water"], types: ["Water"],
baseStats: {hp: 100, atk: 50, def: 80, spa: 50, spd: 80, spe: 50}, baseStats: { hp: 100, atk: 50, def: 80, spa: 50, spd: 80, spe: 50 },
}, },
jumpluff: { jumpluff: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 55, def: 70, spa: 55, spd: 85, spe: 110}, baseStats: { hp: 75, atk: 55, def: 70, spa: 55, spd: 85, spe: 110 },
}, },
snubbull: { snubbull: {
inherit: true, inherit: true,
@ -256,7 +256,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
beautifly: { beautifly: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 70, def: 50, spa: 90, spd: 50, spe: 65}, baseStats: { hp: 60, atk: 70, def: 50, spa: 90, spd: 50, spe: 65 },
}, },
ralts: { ralts: {
inherit: true, inherit: true,
@ -272,7 +272,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
exploud: { exploud: {
inherit: true, inherit: true,
baseStats: {hp: 104, atk: 91, def: 63, spa: 91, spd: 63, spe: 68}, baseStats: { hp: 104, atk: 91, def: 63, spa: 91, spd: 63, spe: 68 },
}, },
azurill: { azurill: {
inherit: true, inherit: true,
@ -284,31 +284,31 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
plusle: { plusle: {
inherit: true, inherit: true,
abilities: {0: "Plus"}, abilities: { 0: "Plus" },
}, },
minun: { minun: {
inherit: true, inherit: true,
abilities: {0: "Minus"}, abilities: { 0: "Minus" },
}, },
kecleon: { kecleon: {
inherit: true, inherit: true,
abilities: {0: "Color Change"}, abilities: { 0: "Color Change" },
}, },
feebas: { feebas: {
inherit: true, inherit: true,
abilities: {0: "Swift Swim", H: "Adaptability"}, abilities: { 0: "Swift Swim", H: "Adaptability" },
}, },
milotic: { milotic: {
inherit: true, inherit: true,
abilities: {0: "Marvel Scale", H: "Cute Charm"}, abilities: { 0: "Marvel Scale", H: "Cute Charm" },
}, },
duskull: { duskull: {
inherit: true, inherit: true,
abilities: {0: "Levitate"}, abilities: { 0: "Levitate" },
}, },
dusclops: { dusclops: {
inherit: true, inherit: true,
abilities: {0: "Pressure"}, abilities: { 0: "Pressure" },
}, },
regirock: { regirock: {
inherit: true, inherit: true,
@ -360,15 +360,15 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
starly: { starly: {
inherit: true, inherit: true,
abilities: {0: "Keen Eye"}, abilities: { 0: "Keen Eye" },
}, },
staraptor: { staraptor: {
inherit: true, inherit: true,
baseStats: {hp: 85, atk: 120, def: 70, spa: 50, spd: 50, spe: 100}, baseStats: { hp: 85, atk: 120, def: 70, spa: 50, spd: 50, spe: 100 },
}, },
roserade: { roserade: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 70, def: 55, spa: 125, spd: 105, spe: 90}, baseStats: { hp: 60, atk: 70, def: 55, spa: 125, spd: 105, spe: 90 },
}, },
mimejr: { mimejr: {
inherit: true, inherit: true,
@ -380,7 +380,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
dusknoir: { dusknoir: {
inherit: true, inherit: true,
abilities: {0: "Pressure"}, abilities: { 0: "Pressure" },
}, },
snivy: { snivy: {
inherit: true, inherit: true,
@ -420,7 +420,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
stoutland: { stoutland: {
inherit: true, inherit: true,
baseStats: {hp: 85, atk: 100, def: 90, spa: 45, spd: 90, spe: 80}, baseStats: { hp: 85, atk: 100, def: 90, spa: 45, spd: 90, spe: 80 },
}, },
pansage: { pansage: {
inherit: true, inherit: true,
@ -448,32 +448,32 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
unfezant: { unfezant: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 105, def: 80, spa: 65, spd: 55, spe: 93}, baseStats: { hp: 80, atk: 105, def: 80, spa: 65, spd: 55, spe: 93 },
}, },
gigalith: { gigalith: {
inherit: true, inherit: true,
baseStats: {hp: 85, atk: 135, def: 130, spa: 60, spd: 70, spe: 25}, baseStats: { hp: 85, atk: 135, def: 130, spa: 60, spd: 70, spe: 25 },
}, },
seismitoad: { seismitoad: {
inherit: true, inherit: true,
baseStats: {hp: 105, atk: 85, def: 75, spa: 85, spd: 75, spe: 74}, baseStats: { hp: 105, atk: 85, def: 75, spa: 85, spd: 75, spe: 74 },
}, },
leavanny: { leavanny: {
inherit: true, inherit: true,
baseStats: {hp: 75, atk: 103, def: 80, spa: 70, spd: 70, spe: 92}, baseStats: { hp: 75, atk: 103, def: 80, spa: 70, spd: 70, spe: 92 },
}, },
venipede: { venipede: {
inherit: true, inherit: true,
abilities: {0: "Poison Point", 1: "Swarm", H: "Quick Feet"}, abilities: { 0: "Poison Point", 1: "Swarm", H: "Quick Feet" },
}, },
whirlipede: { whirlipede: {
inherit: true, inherit: true,
abilities: {0: "Poison Point", 1: "Swarm", H: "Quick Feet"}, abilities: { 0: "Poison Point", 1: "Swarm", H: "Quick Feet" },
}, },
scolipede: { scolipede: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 90, def: 89, spa: 55, spd: 69, spe: 112}, baseStats: { hp: 60, atk: 90, def: 89, spa: 55, spd: 69, spe: 112 },
abilities: {0: "Poison Point", 1: "Swarm", H: "Quick Feet"}, abilities: { 0: "Poison Point", 1: "Swarm", H: "Quick Feet" },
}, },
cottonee: { cottonee: {
inherit: true, inherit: true,
@ -485,11 +485,11 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
basculinbluestriped: { basculinbluestriped: {
inherit: true, inherit: true,
abilities: {0: "Rock Head", 1: "Adaptability", H: "Mold Breaker", S: "Reckless"}, abilities: { 0: "Rock Head", 1: "Adaptability", H: "Mold Breaker", S: "Reckless" },
}, },
krookodile: { krookodile: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 117, def: 70, spa: 65, spd: 70, spe: 92}, baseStats: { hp: 95, atk: 117, def: 70, spa: 65, spd: 70, spe: 92 },
}, },
gothita: { gothita: {
inherit: true, inherit: true,
@ -497,17 +497,17 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
gothorita: { gothorita: {
inherit: true, inherit: true,
abilities: {0: "Frisk", H: "Shadow Tag"}, abilities: { 0: "Frisk", H: "Shadow Tag" },
maleOnlyHidden: true, maleOnlyHidden: true,
}, },
gothitelle: { gothitelle: {
inherit: true, inherit: true,
abilities: {0: "Frisk", H: "Shadow Tag"}, abilities: { 0: "Frisk", H: "Shadow Tag" },
maleOnlyHidden: true, maleOnlyHidden: true,
}, },
ferrothorn: { ferrothorn: {
inherit: true, inherit: true,
abilities: {0: "Iron Barbs"}, abilities: { 0: "Iron Barbs" },
}, },
klink: { klink: {
inherit: true, inherit: true,
@ -515,17 +515,17 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
litwick: { litwick: {
inherit: true, inherit: true,
abilities: {0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag"}, abilities: { 0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
lampent: { lampent: {
inherit: true, inherit: true,
abilities: {0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag"}, abilities: { 0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
chandelure: { chandelure: {
inherit: true, inherit: true,
abilities: {0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag"}, abilities: { 0: "Flash Fire", 1: "Flame Body", H: "Shadow Tag" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
rufflet: { rufflet: {

View File

@ -32,7 +32,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
liquidooze: { liquidooze: {
inherit: true, inherit: true,
onSourceTryHeal(damage, target, source, effect) { onSourceTryHeal(damage, target, source, effect) {
this.debug("Heal is occurring: " + target + " <- " + source + " :: " + effect.id); this.debug(`Heal is occurring: ${target} <- ${source} :: ${effect.id}`);
const canOoze = ['drain', 'leechseed']; const canOoze = ['drain', 'leechseed'];
if (canOoze.includes(effect.id)) { if (canOoze.includes(effect.id)) {
this.damage(damage, null, null, null, true); this.damage(damage, null, null, null, true);
@ -108,20 +108,20 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
source.item = myItem.id; source.item = myItem.id;
return; return;
} }
this.add('-activate', source, 'ability: Symbiosis', myItem, '[of] ' + pokemon); this.add('-activate', source, 'ability: Symbiosis', myItem, `[of] ${pokemon}`);
}, },
}, },
weakarmor: { weakarmor: {
inherit: true, inherit: true,
onDamagingHit(damage, target, source, move) { onDamagingHit(damage, target, source, move) {
if (move.category === 'Physical') { if (move.category === 'Physical') {
this.boost({def: -1, spe: 1}, target, target); this.boost({ def: -1, spe: 1 }, target, target);
} }
}, },
rating: 0.5, rating: 0.5,
}, },
zenmode: { zenmode: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noentrain: 1, notrace: 1}, flags: { failroleplay: 1, noentrain: 1, notrace: 1 },
}, },
}; };

View File

@ -5,11 +5,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
assist: { assist: {
inherit: true, inherit: true,
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1}, flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1 },
}, },
copycat: { copycat: {
inherit: true, inherit: true,
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1}, flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1 },
}, },
darkvoid: { darkvoid: {
inherit: true, inherit: true,
@ -83,7 +83,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
basePower: 30, basePower: 30,
onAfterMoveSecondarySelf(pokemon, target, move) { onAfterMoveSecondarySelf(pokemon, target, move) {
if (!target || target.fainted || target.hp <= 0) this.boost({atk: 2}, pokemon, pokemon, move); if (!target || target.fainted || target.hp <= 0) this.boost({ atk: 2 }, pokemon, pokemon, move);
}, },
}, },
flyingpress: { flyingpress: {
@ -97,7 +97,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mefirst: { mefirst: {
inherit: true, inherit: true,
flags: {protect: 1, bypasssub: 1, noassist: 1, failcopycat: 1, failmefirst: 1, nosleeptalk: 1}, flags: { protect: 1, bypasssub: 1, noassist: 1, failcopycat: 1, failmefirst: 1, nosleeptalk: 1 },
}, },
minimize: { minimize: {
inherit: true, inherit: true,
@ -124,7 +124,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
metronome: { metronome: {
inherit: true, inherit: true,
flags: {noassist: 1, failcopycat: 1, nosleeptalk: 1}, flags: { noassist: 1, failcopycat: 1, nosleeptalk: 1 },
}, },
mistyterrain: { mistyterrain: {
inherit: true, inherit: true,
@ -151,7 +151,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
this.add('-fieldstart', 'move: Misty Terrain', '[from] ability: ' + effect, '[of] ' + source); this.add('-fieldstart', 'move: Misty Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
} else { } else {
this.add('-fieldstart', 'move: Misty Terrain'); this.add('-fieldstart', 'move: Misty Terrain');
} }
@ -169,7 +169,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
naturepower: { naturepower: {
inherit: true, inherit: true,
flags: {nosleeptalk: 1, noassist: 1, failcopycat: 1}, flags: { nosleeptalk: 1, noassist: 1, failcopycat: 1 },
}, },
paraboliccharge: { paraboliccharge: {
inherit: true, inherit: true,
@ -178,7 +178,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
partingshot: { partingshot: {
inherit: true, inherit: true,
onHit(target, source) { onHit(target, source) {
this.boost({atk: -1, spa: -1}, target, source); this.boost({ atk: -1, spa: -1 }, target, source);
}, },
}, },
powder: { powder: {
@ -201,7 +201,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
rockblast: { rockblast: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
sheercold: { sheercold: {
inherit: true, inherit: true,
@ -209,7 +209,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
sleeptalk: { sleeptalk: {
inherit: true, inherit: true,
flags: {nosleeptalk: 1, noassist: 1, failcopycat: 1}, flags: { nosleeptalk: 1, noassist: 1, failcopycat: 1 },
}, },
stockpile: { stockpile: {
inherit: true, inherit: true,
@ -218,18 +218,18 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onStart(target) { onStart(target) {
this.effectState.layers = 1; this.effectState.layers = 1;
this.add('-start', target, 'stockpile' + this.effectState.layers); this.add('-start', target, 'stockpile' + this.effectState.layers);
this.boost({def: 1, spd: 1}, target, target); this.boost({ def: 1, spd: 1 }, target, target);
}, },
onRestart(target) { onRestart(target) {
if (this.effectState.layers >= 3) return false; if (this.effectState.layers >= 3) return false;
this.effectState.layers++; this.effectState.layers++;
this.add('-start', target, 'stockpile' + this.effectState.layers); this.add('-start', target, 'stockpile' + this.effectState.layers);
this.boost({def: 1, spd: 1}, target, target); this.boost({ def: 1, spd: 1 }, target, target);
}, },
onEnd(target) { onEnd(target) {
const layers = this.effectState.layers * -1; const layers = this.effectState.layers * -1;
this.effectState.layers = 0; this.effectState.layers = 0;
this.boost({def: layers, spd: layers}, target, target); this.boost({ def: layers, spd: layers }, target, target);
this.add('-end', target, 'Stockpile'); this.add('-end', target, 'Stockpile');
}, },
}, },

View File

@ -5,7 +5,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
arbok: { arbok: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 85, def: 69, spa: 65, spd: 79, spe: 80}, baseStats: { hp: 60, atk: 85, def: 69, spa: 65, spd: 79, spe: 80 },
}, },
pikachu: { pikachu: {
inherit: true, inherit: true,
@ -13,112 +13,112 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
dugtrio: { dugtrio: {
inherit: true, inherit: true,
baseStats: {hp: 35, atk: 80, def: 50, spa: 50, spd: 70, spe: 120}, baseStats: { hp: 35, atk: 80, def: 50, spa: 50, spd: 70, spe: 120 },
}, },
alakazammega: { alakazammega: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 50, def: 65, spa: 175, spd: 95, spe: 150}, baseStats: { hp: 55, atk: 50, def: 65, spa: 175, spd: 95, spe: 150 },
}, },
farfetchd: { farfetchd: {
inherit: true, inherit: true,
baseStats: {hp: 52, atk: 65, def: 55, spa: 58, spd: 62, spe: 60}, baseStats: { hp: 52, atk: 65, def: 55, spa: 58, spd: 62, spe: 60 },
}, },
dodrio: { dodrio: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 110, def: 70, spa: 60, spd: 60, spe: 100}, baseStats: { hp: 60, atk: 110, def: 70, spa: 60, spd: 60, spe: 100 },
}, },
gengar: { gengar: {
inherit: true, inherit: true,
abilities: {0: "Levitate"}, abilities: { 0: "Levitate" },
}, },
electrode: { electrode: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 50, def: 70, spa: 80, spd: 80, spe: 140}, baseStats: { hp: 60, atk: 50, def: 70, spa: 80, spd: 80, spe: 140 },
}, },
exeggutor: { exeggutor: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 95, def: 85, spa: 125, spd: 65, spe: 55}, baseStats: { hp: 95, atk: 95, def: 85, spa: 125, spd: 65, spe: 55 },
}, },
noctowl: { noctowl: {
inherit: true, inherit: true,
baseStats: {hp: 100, atk: 50, def: 50, spa: 76, spd: 96, spe: 70}, baseStats: { hp: 100, atk: 50, def: 50, spa: 76, spd: 96, spe: 70 },
}, },
ariados: { ariados: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 90, def: 70, spa: 60, spd: 60, spe: 40}, baseStats: { hp: 70, atk: 90, def: 70, spa: 60, spd: 60, spe: 40 },
}, },
qwilfish: { qwilfish: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 95, def: 75, spa: 55, spd: 55, spe: 85}, baseStats: { hp: 65, atk: 95, def: 75, spa: 55, spd: 55, spe: 85 },
}, },
magcargo: { magcargo: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 50, def: 120, spa: 80, spd: 80, spe: 30}, baseStats: { hp: 50, atk: 50, def: 120, spa: 80, spd: 80, spe: 30 },
}, },
corsola: { corsola: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 55, def: 85, spa: 65, spd: 85, spe: 35}, baseStats: { hp: 55, atk: 55, def: 85, spa: 65, spd: 85, spe: 35 },
}, },
mantine: { mantine: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 40, def: 70, spa: 80, spd: 140, spe: 70}, baseStats: { hp: 65, atk: 40, def: 70, spa: 80, spd: 140, spe: 70 },
}, },
raikou: { raikou: {
inherit: true, inherit: true,
abilities: {0: "Pressure", H: "Volt Absorb"}, abilities: { 0: "Pressure", H: "Volt Absorb" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
entei: { entei: {
inherit: true, inherit: true,
abilities: {0: "Pressure", H: "Flash Fire"}, abilities: { 0: "Pressure", H: "Flash Fire" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
suicune: { suicune: {
inherit: true, inherit: true,
abilities: {0: "Pressure", H: "Water Absorb"}, abilities: { 0: "Pressure", H: "Water Absorb" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
swellow: { swellow: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 85, def: 60, spa: 50, spd: 50, spe: 125}, baseStats: { hp: 60, atk: 85, def: 60, spa: 50, spd: 50, spe: 125 },
}, },
wingull: { wingull: {
inherit: true, inherit: true,
abilities: {0: "Keen Eye", H: "Rain Dish"}, abilities: { 0: "Keen Eye", H: "Rain Dish" },
}, },
pelipper: { pelipper: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 50, def: 100, spa: 85, spd: 70, spe: 65}, baseStats: { hp: 60, atk: 50, def: 100, spa: 85, spd: 70, spe: 65 },
abilities: {0: "Keen Eye", H: "Rain Dish"}, abilities: { 0: "Keen Eye", H: "Rain Dish" },
}, },
masquerain: { masquerain: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 60, def: 62, spa: 80, spd: 82, spe: 60}, baseStats: { hp: 70, atk: 60, def: 62, spa: 80, spd: 82, spe: 60 },
}, },
delcatty: { delcatty: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 65, def: 65, spa: 55, spd: 55, spe: 70}, baseStats: { hp: 70, atk: 65, def: 65, spa: 55, spd: 55, spe: 70 },
}, },
volbeat: { volbeat: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 73, def: 55, spa: 47, spd: 75, spe: 85}, baseStats: { hp: 65, atk: 73, def: 55, spa: 47, spd: 75, spe: 85 },
abilities: {0: "Illuminate", 1: "Swarm", H: "Prankster"}, abilities: { 0: "Illuminate", 1: "Swarm", H: "Prankster" },
}, },
illumise: { illumise: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 47, def: 55, spa: 73, spd: 75, spe: 85}, baseStats: { hp: 65, atk: 47, def: 55, spa: 73, spd: 75, spe: 85 },
}, },
torkoal: { torkoal: {
inherit: true, inherit: true,
abilities: {0: "White Smoke", H: "Shell Armor"}, abilities: { 0: "White Smoke", H: "Shell Armor" },
}, },
lunatone: { lunatone: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 55, def: 65, spa: 95, spd: 85, spe: 70}, baseStats: { hp: 70, atk: 55, def: 65, spa: 95, spd: 85, spe: 70 },
}, },
solrock: { solrock: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 95, def: 85, spa: 55, spd: 65, spe: 70}, baseStats: { hp: 70, atk: 95, def: 85, spa: 55, spd: 65, spe: 70 },
}, },
castform: { castform: {
inherit: true, inherit: true,
@ -134,7 +134,7 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
chimecho: { chimecho: {
inherit: true, inherit: true,
baseStats: {hp: 65, atk: 50, def: 70, spa: 95, spd: 80, spe: 65}, baseStats: { hp: 65, atk: 50, def: 70, spa: 95, spd: 80, spe: 65 },
}, },
latiasmega: { latiasmega: {
inherit: true, inherit: true,
@ -255,19 +255,19 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
roggenrola: { roggenrola: {
inherit: true, inherit: true,
abilities: {0: "Sturdy", H: "Sand Force"}, abilities: { 0: "Sturdy", H: "Sand Force" },
}, },
boldore: { boldore: {
inherit: true, inherit: true,
abilities: {0: "Sturdy", H: "Sand Force"}, abilities: { 0: "Sturdy", H: "Sand Force" },
}, },
gigalith: { gigalith: {
inherit: true, inherit: true,
abilities: {0: "Sturdy", H: "Sand Force"}, abilities: { 0: "Sturdy", H: "Sand Force" },
}, },
woobat: { woobat: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 45, def: 43, spa: 55, spd: 43, spe: 72}, baseStats: { hp: 55, atk: 45, def: 43, spa: 55, spd: 43, spe: 72 },
}, },
audinomega: { audinomega: {
inherit: true, inherit: true,
@ -279,19 +279,19 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
crustle: { crustle: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 95, def: 125, spa: 65, spd: 75, spe: 45}, baseStats: { hp: 70, atk: 95, def: 125, spa: 65, spd: 75, spe: 45 },
}, },
vanillite: { vanillite: {
inherit: true, inherit: true,
abilities: {0: "Ice Body", H: "Weak Armor"}, abilities: { 0: "Ice Body", H: "Weak Armor" },
}, },
vanillish: { vanillish: {
inherit: true, inherit: true,
abilities: {0: "Ice Body", H: "Weak Armor"}, abilities: { 0: "Ice Body", H: "Weak Armor" },
}, },
vanilluxe: { vanilluxe: {
inherit: true, inherit: true,
abilities: {0: "Ice Body", H: "Weak Armor"}, abilities: { 0: "Ice Body", H: "Weak Armor" },
}, },
deerling: { deerling: {
inherit: true, inherit: true,
@ -299,20 +299,20 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
cubchoo: { cubchoo: {
inherit: true, inherit: true,
abilities: {0: "Snow Cloak", H: "Rattled"}, abilities: { 0: "Snow Cloak", H: "Rattled" },
}, },
beartic: { beartic: {
inherit: true, inherit: true,
baseStats: {hp: 95, atk: 110, def: 80, spa: 70, spd: 80, spe: 50}, baseStats: { hp: 95, atk: 110, def: 80, spa: 70, spd: 80, spe: 50 },
abilities: {0: "Snow Cloak", H: "Swift Swim"}, abilities: { 0: "Snow Cloak", H: "Swift Swim" },
}, },
cryogonal: { cryogonal: {
inherit: true, inherit: true,
baseStats: {hp: 70, atk: 50, def: 30, spa: 95, spd: 135, spe: 105}, baseStats: { hp: 70, atk: 50, def: 30, spa: 95, spd: 135, spe: 105 },
}, },
greninja: { greninja: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Protean"}, abilities: { 0: "Torrent", H: "Protean" },
}, },
vivillon: { vivillon: {
inherit: true, inherit: true,
@ -324,66 +324,66 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
zygarde: { zygarde: {
inherit: true, inherit: true,
abilities: {0: "Aura Break"}, abilities: { 0: "Aura Break" },
}, },
necturna: { necturna: {
inherit: true, inherit: true,
baseStats: {hp: 64, atk: 120, def: 100, spa: 85, spd: 120, spe: 81}, baseStats: { hp: 64, atk: 120, def: 100, spa: 85, spd: 120, spe: 81 },
}, },
malaconda: { malaconda: {
inherit: true, inherit: true,
abilities: {0: "Harvest", 1: "Infiltrator"}, abilities: { 0: "Harvest", 1: "Infiltrator" },
}, },
naviathan: { naviathan: {
inherit: true, inherit: true,
abilities: {0: "Water Veil", 1: "Heatproof", H: "Light Metal"}, abilities: { 0: "Water Veil", 1: "Heatproof", H: "Light Metal" },
}, },
crucibellemega: { crucibellemega: {
inherit: true, inherit: true,
baseStats: {hp: 106, atk: 135, def: 75, spa: 85, spd: 125, spe: 114}, baseStats: { hp: 106, atk: 135, def: 75, spa: 85, spd: 125, spe: 114 },
}, },
syclant: { syclant: {
inherit: true, inherit: true,
abilities: {0: "Compound Eyes", 1: "Mountaineer"}, abilities: { 0: "Compound Eyes", 1: "Mountaineer" },
}, },
revenankh: { revenankh: {
inherit: true, inherit: true,
abilities: {0: "Air Lock", H: "Shed Skin"}, abilities: { 0: "Air Lock", H: "Shed Skin" },
}, },
pyroak: { pyroak: {
inherit: true, inherit: true,
abilities: {0: "Rock Head", 1: "Battle Armor"}, abilities: { 0: "Rock Head", 1: "Battle Armor" },
}, },
fidgit: { fidgit: {
inherit: true, inherit: true,
abilities: {0: "Persistent", 1: "Vital Spirit"}, abilities: { 0: "Persistent", 1: "Vital Spirit" },
}, },
stratagem: { stratagem: {
inherit: true, inherit: true,
abilities: {0: "Levitate", 1: "Technician"}, abilities: { 0: "Levitate", 1: "Technician" },
}, },
arghonaut: { arghonaut: {
inherit: true, inherit: true,
abilities: {0: "Unaware"}, abilities: { 0: "Unaware" },
}, },
kitsunoh: { kitsunoh: {
inherit: true, inherit: true,
abilities: {0: "Frisk", 1: "Limber"}, abilities: { 0: "Frisk", 1: "Limber" },
}, },
cyclohm: { cyclohm: {
inherit: true, inherit: true,
abilities: {0: "Shield Dust", 1: "Static"}, abilities: { 0: "Shield Dust", 1: "Static" },
}, },
colossoil: { colossoil: {
inherit: true, inherit: true,
abilities: {0: "Rebound", 1: "Guts"}, abilities: { 0: "Rebound", 1: "Guts" },
}, },
krilowatt: { krilowatt: {
inherit: true, inherit: true,
abilities: {0: "Trace", 1: "Magic Guard"}, abilities: { 0: "Trace", 1: "Magic Guard" },
}, },
voodoom: { voodoom: {
inherit: true, inherit: true,
abilities: {0: "Volt Absorb", 1: "Lightning Rod"}, abilities: { 0: "Volt Absorb", 1: "Lightning Rod" },
}, },
}; };

View File

@ -24,11 +24,11 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
darkaura: { darkaura: {
inherit: true, inherit: true,
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
fairyaura: { fairyaura: {
inherit: true, inherit: true,
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
innerfocus: { innerfocus: {
inherit: true, inherit: true,
@ -73,7 +73,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
rattled: { rattled: {
onDamagingHit(damage, target, source, move) { onDamagingHit(damage, target, source, move) {
if (['Dark', 'Bug', 'Ghost'].includes(move.type)) { if (['Dark', 'Bug', 'Ghost'].includes(move.type)) {
this.boost({spe: 1}); this.boost({ spe: 1 });
} }
}, },
name: "Rattled", name: "Rattled",

View File

@ -126,7 +126,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
onHit(target, source, move) { onHit(target, source, move) {
let success = false; let success = false;
if (!target.volatiles['substitute'] || move.infiltrates) success = !!this.boost({evasion: -1}); if (!target.volatiles['substitute'] || move.infiltrates) success = !!this.boost({ evasion: -1 });
const removeTarget = [ const removeTarget = [
'reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'reflect', 'lightscreen', 'auroraveil', 'safeguard', 'mist', 'spikes', 'toxicspikes', 'stealthrock', 'stickyweb',
]; ];
@ -134,13 +134,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
for (const targetCondition of removeTarget) { for (const targetCondition of removeTarget) {
if (target.side.removeSideCondition(targetCondition)) { if (target.side.removeSideCondition(targetCondition)) {
if (!removeAll.includes(targetCondition)) continue; if (!removeAll.includes(targetCondition)) continue;
this.add('-sideend', target.side, this.dex.conditions.get(targetCondition).name, '[from] move: Defog', '[of] ' + source); this.add('-sideend', target.side, this.dex.conditions.get(targetCondition).name, '[from] move: Defog', `[of] ${source}`);
success = true; success = true;
} }
} }
for (const sideCondition of removeAll) { for (const sideCondition of removeAll) {
if (source.side.removeSideCondition(sideCondition)) { if (source.side.removeSideCondition(sideCondition)) {
this.add('-sideend', source.side, this.dex.conditions.get(sideCondition).name, '[from] move: Defog', '[of] ' + source); this.add('-sideend', source.side, this.dex.conditions.get(sideCondition).name, '[from] move: Defog', `[of] ${source}`);
success = true; success = true;
} }
} }
@ -171,7 +171,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
dragonhammer: { dragonhammer: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
dragonrage: { dragonrage: {
inherit: true, inherit: true,
@ -214,7 +214,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect && effect.effectType === 'Ability') { if (effect && effect.effectType === 'Ability') {
this.add('-fieldstart', 'move: Electric Terrain', '[from] ability: ' + effect, '[of] ' + source); this.add('-fieldstart', 'move: Electric Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
} else { } else {
this.add('-fieldstart', 'move: Electric Terrain'); this.add('-fieldstart', 'move: Electric Terrain');
} }
@ -337,7 +337,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect && effect.effectType === 'Ability') { if (effect && effect.effectType === 'Ability') {
this.add('-fieldstart', 'move: Grassy Terrain', '[from] ability: ' + effect, '[of] ' + source); this.add('-fieldstart', 'move: Grassy Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
} else { } else {
this.add('-fieldstart', 'move: Grassy Terrain'); this.add('-fieldstart', 'move: Grassy Terrain');
} }
@ -506,7 +506,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
howl: { howl: {
inherit: true, inherit: true,
flags: {snatch: 1, metronome: 1}, flags: { snatch: 1, metronome: 1 },
boosts: { boosts: {
atk: 1, atk: 1,
}, },
@ -578,13 +578,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} }
} }
if (this.checkMoveMakesContact(move, source, target)) { if (this.checkMoveMakesContact(move, source, target)) {
this.boost({atk: -2}, source, target, this.dex.getActiveMove("King's Shield")); this.boost({ atk: -2 }, source, target, this.dex.getActiveMove("King's Shield"));
} }
return this.NOT_FAIL; return this.NOT_FAIL;
}, },
onHit(target, source, move) { onHit(target, source, move) {
if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) { if (move.isZOrMaxPowered && this.checkMoveMakesContact(move, source, target)) {
this.boost({atk: -2}, source, target, this.dex.getActiveMove("King's Shield")); this.boost({ atk: -2 }, source, target, this.dex.getActiveMove("King's Shield"));
} }
}, },
}, },
@ -665,7 +665,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
moongeistbeam: { moongeistbeam: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
moonlight: { moonlight: {
inherit: true, inherit: true,
@ -733,7 +733,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
naturesmadness: { naturesmadness: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1}, flags: { protect: 1, mirror: 1, metronome: 1 },
}, },
needlearm: { needlearm: {
inherit: true, inherit: true,
@ -761,7 +761,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
pollenpuff: { pollenpuff: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, metronome: 1, bullet: 1}, flags: { protect: 1, mirror: 1, metronome: 1, bullet: 1 },
onHit(target, source) { onHit(target, source) {
if (source.isAlly(target)) { if (source.isAlly(target)) {
if (!this.heal(Math.floor(target.baseMaxhp * 0.5))) { if (!this.heal(Math.floor(target.baseMaxhp * 0.5))) {
@ -813,7 +813,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
if (effect && effect.effectType === 'Ability') { if (effect && effect.effectType === 'Ability') {
this.add('-fieldstart', 'move: Psychic Terrain', '[from] ability: ' + effect, '[of] ' + source); this.add('-fieldstart', 'move: Psychic Terrain', `[from] ability: ${effect}`, `[of] ${source}`);
} else { } else {
this.add('-fieldstart', 'move: Psychic Terrain'); this.add('-fieldstart', 'move: Psychic Terrain');
} }
@ -1037,7 +1037,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
sunsteelstrike: { sunsteelstrike: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
supersonicskystrike: { supersonicskystrike: {
inherit: true, inherit: true,
@ -1072,7 +1072,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (myItem) source.item = myItem.id; if (myItem) source.item = myItem.id;
return false; return false;
} }
this.add('-activate', source, 'move: Trick', '[of] ' + target); this.add('-activate', source, 'move: Trick', `[of] ${target}`);
if (myItem) { if (myItem) {
target.setItem(myItem); target.setItem(myItem);
this.add('-item', target, myItem, '[from] move: Switcheroo'); this.add('-item', target, myItem, '[from] move: Switcheroo');
@ -1172,7 +1172,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (myItem) source.item = myItem.id; if (myItem) source.item = myItem.id;
return false; return false;
} }
this.add('-activate', source, 'move: Trick', '[of] ' + target); this.add('-activate', source, 'move: Trick', `[of] ${target}`);
if (myItem) { if (myItem) {
target.setItem(myItem); target.setItem(myItem);
this.add('-item', target, myItem, '[from] move: Trick'); this.add('-item', target, myItem, '[from] move: Trick');

View File

@ -1,39 +1,39 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
pikachuoriginal: { pikachuoriginal: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachuhoenn: { pikachuhoenn: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachusinnoh: { pikachusinnoh: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachuunova: { pikachuunova: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachukalos: { pikachukalos: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachualola: { pikachualola: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
pikachupartner: { pikachupartner: {
inherit: true, inherit: true,
abilities: {0: "Static"}, abilities: { 0: "Static" },
}, },
koffing: { koffing: {
inherit: true, inherit: true,
abilities: {0: "Levitate"}, abilities: { 0: "Levitate" },
}, },
weezing: { weezing: {
inherit: true, inherit: true,
abilities: {0: "Levitate"}, abilities: { 0: "Levitate" },
}, },
ralts: { ralts: {
inherit: true, inherit: true,
@ -80,32 +80,32 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
heatran: { heatran: {
inherit: true, inherit: true,
abilities: {0: "Flash Fire", H: "Flame Body"}, abilities: { 0: "Flash Fire", H: "Flame Body" },
unreleasedHidden: true, unreleasedHidden: true,
}, },
aegislash: { aegislash: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 50, def: 150, spa: 50, spd: 150, spe: 60}, baseStats: { hp: 60, atk: 50, def: 150, spa: 50, spd: 150, spe: 60 },
}, },
aegislashblade: { aegislashblade: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 150, def: 50, spa: 150, spd: 50, spe: 60}, baseStats: { hp: 60, atk: 150, def: 50, spa: 150, spd: 50, spe: 60 },
}, },
pumpkaboosmall: { pumpkaboosmall: {
inherit: true, inherit: true,
abilities: {0: "Pickup", 1: "Frisk"}, abilities: { 0: "Pickup", 1: "Frisk" },
}, },
pumpkaboolarge: { pumpkaboolarge: {
inherit: true, inherit: true,
abilities: {0: "Pickup", 1: "Frisk"}, abilities: { 0: "Pickup", 1: "Frisk" },
}, },
gourgeistsmall: { gourgeistsmall: {
inherit: true, inherit: true,
abilities: {0: "Pickup", 1: "Frisk"}, abilities: { 0: "Pickup", 1: "Frisk" },
}, },
gourgeistlarge: { gourgeistlarge: {
inherit: true, inherit: true,
abilities: {0: "Pickup", 1: "Frisk"}, abilities: { 0: "Pickup", 1: "Frisk" },
}, },
hawlucha: { hawlucha: {
inherit: true, inherit: true,
@ -147,28 +147,28 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
tapukoko: { tapukoko: {
inherit: true, inherit: true,
abilities: {0: "Electric Surge"}, abilities: { 0: "Electric Surge" },
}, },
tapulele: { tapulele: {
inherit: true, inherit: true,
abilities: {0: "Psychic Surge"}, abilities: { 0: "Psychic Surge" },
}, },
tapubulu: { tapubulu: {
inherit: true, inherit: true,
abilities: {0: "Grassy Surge"}, abilities: { 0: "Grassy Surge" },
}, },
tapufini: { tapufini: {
inherit: true, inherit: true,
abilities: {0: "Misty Surge"}, abilities: { 0: "Misty Surge" },
}, },
pyroak: { pyroak: {
inherit: true, inherit: true,
baseStats: {hp: 120, atk: 70, def: 105, spa: 95, spd: 90, spe: 60}, baseStats: { hp: 120, atk: 70, def: 105, spa: 95, spd: 90, spe: 60 },
abilities: {0: "Rock Head", 1: "Battle Armor", H: "White Smoke"}, abilities: { 0: "Rock Head", 1: "Battle Armor", H: "White Smoke" },
}, },
voodoom: { voodoom: {
inherit: true, inherit: true,
baseStats: {hp: 90, atk: 85, def: 80, spa: 105, spd: 80, spe: 110}, baseStats: { hp: 90, atk: 85, def: 80, spa: 105, spd: 80, spe: 110 },
}, },
mumbao: { mumbao: {
inherit: true, inherit: true,

View File

@ -15,7 +15,7 @@ export const Scripts: ModdedBattleScriptsData = {
init() { init() {
this.modData('Abilities', 'noability').isNonstandard = null; this.modData('Abilities', 'noability').isNonstandard = null;
for (const i in this.data.Pokedex) { for (const i in this.data.Pokedex) {
this.modData('Pokedex', i).abilities = {0: 'No Ability'}; this.modData('Pokedex', i).abilities = { 0: 'No Ability' };
delete this.modData('Pokedex', i).requiredItem; delete this.modData('Pokedex', i).requiredItem;
} }
}, },
@ -62,7 +62,7 @@ export const Scripts: ModdedBattleScriptsData = {
* Given a table of base stats and a pokemon set, return the actual stats. * Given a table of base stats and a pokemon set, return the actual stats.
*/ */
spreadModify(baseStats, set) { spreadModify(baseStats, set) {
const modStats: StatsTable = {hp: 10, atk: 10, def: 10, spa: 10, spd: 10, spe: 10}; const modStats: StatsTable = { hp: 10, atk: 10, def: 10, spa: 10, spd: 10, spe: 10 };
let statName: StatID; let statName: StatID;
for (statName in modStats) { for (statName in modStats) {
const stat = baseStats[statName]; const stat = baseStats[statName];

View File

@ -10,7 +10,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) { if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
const oldAbility = source.setAbility('mummy', target); const oldAbility = source.setAbility('mummy', target);
if (oldAbility) { if (oldAbility) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
} }
} }
} else { } else {
@ -22,13 +22,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (abil === source.ability) { if (abil === source.ability) {
const oldAbility = source.setAbility('mummy', target); const oldAbility = source.setAbility('mummy', target);
if (oldAbility) { if (oldAbility) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
} }
} else { } else {
source.removeVolatile('ability:' + abil); source.removeVolatile('ability:' + abil);
source.addVolatile('ability:mummy', source); source.addVolatile('ability:mummy', source);
if (abil) { if (abil) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(abil).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(abil).name, `[of] ${source}`);
} }
} }
} }
@ -48,12 +48,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
.filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val)); .filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val));
if (!possibleAbilities.length) return; if (!possibleAbilities.length) return;
const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]); const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]);
this.add('-ability', pokemon, ability, '[from] ability: Power of Alchemy', '[of] ' + ally); this.add('-ability', pokemon, ability, '[from] ability: Power of Alchemy', `[of] ${ally}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:powerofalchemy"); pokemon.removeVolatile("ability:powerofalchemy");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
}, },
}, },
@ -70,12 +70,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
.filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val)); .filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val));
if (!possibleAbilities.length) return; if (!possibleAbilities.length) return;
const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]); const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]);
this.add('-ability', pokemon, ability, '[from] ability: Receiver', '[of] ' + ally); this.add('-ability', pokemon, ability, '[from] ability: Receiver', `[of] ${ally}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:receiver"); pokemon.removeVolatile("ability:receiver");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
}, },
}, },
@ -103,12 +103,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
continue; continue;
} }
const ability = this.dex.abilities.get(this.sample(possibleAbilities)); const ability = this.dex.abilities.get(this.sample(possibleAbilities));
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:trace"); pokemon.removeVolatile("ability:trace");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
return; return;
} }

View File

@ -187,7 +187,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
} }
if (statsLowered) { if (statsLowered) {
this.boost({spa: 2}, target, target, null, false, true); this.boost({ spa: 2 }, target, target, null, false, true);
} }
}, },
rating: 2.5, rating: 2.5,
@ -235,7 +235,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
dauntlessshield: { dauntlessshield: {
inherit: true, inherit: true,
onStart(pokemon) { onStart(pokemon) {
this.boost({def: 1}, pokemon); this.boost({ def: 1 }, pokemon);
}, },
rating: 3.5, rating: 3.5,
}, },
@ -264,7 +264,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
} }
if (statsLowered) { if (statsLowered) {
this.boost({atk: 2}, target, target, null, false, true); this.boost({ atk: 2 }, target, target, null, false, true);
} }
}, },
rating: 2.5, rating: 2.5,
@ -407,7 +407,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
gulpmissile: { gulpmissile: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
rating: 2.5, rating: 2.5,
}, },
guts: { guts: {
@ -517,7 +517,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
intrepidsword: { intrepidsword: {
inherit: true, inherit: true,
onStart(pokemon) { onStart(pokemon) {
this.boost({atk: 1}, pokemon); this.boost({ atk: 1 }, pokemon);
}, },
rating: 4, rating: 4,
}, },
@ -1198,7 +1198,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
wonderguard: { wonderguard: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, failskillswap: 1, breakable: 1}, flags: { failroleplay: 1, noreceiver: 1, failskillswap: 1, breakable: 1 },
rating: 5, rating: 5,
}, },
wonderskin: { wonderskin: {

View File

@ -14,7 +14,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
assist: { assist: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
auroraveil: { auroraveil: {
inherit: true, inherit: true,
@ -32,7 +32,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
belch: { belch: {
inherit: true, inherit: true,
flags: {protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { protect: 1, failmefirst: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
blizzard: { blizzard: {
inherit: true, inherit: true,
@ -54,7 +54,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
celebrate: { celebrate: {
inherit: true, inherit: true,
flags: {nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
charge: { charge: {
inherit: true, inherit: true,
@ -96,7 +96,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
copycat: { copycat: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
coreenforcer: { coreenforcer: {
inherit: true, inherit: true,
@ -114,7 +114,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
onModifyMove(move, source, target) { onModifyMove(move, source, target) {
if (!source.hasType('Ghost')) { if (!source.hasType('Ghost')) {
move.target = move.nonGhostTarget as MoveTarget; move.target = move.nonGhostTarget!;
} }
}, },
target: "randomNormal", target: "randomNormal",
@ -126,7 +126,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
darkvoid: { darkvoid: {
inherit: true, inherit: true,
isNonstandard: "Past", isNonstandard: "Past",
flags: {protect: 1, reflectable: 1, mirror: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 },
}, },
doubleironbash: { doubleironbash: {
inherit: true, inherit: true,
@ -134,7 +134,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
dragonhammer: { dragonhammer: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1}, flags: { contact: 1, protect: 1, mirror: 1 },
}, },
dualchop: { dualchop: {
inherit: true, inherit: true,
@ -146,7 +146,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
eternabeam: { eternabeam: {
inherit: true, inherit: true,
flags: {recharge: 1, protect: 1, mirror: 1, failinstruct: 1}, flags: { recharge: 1, protect: 1, mirror: 1, failinstruct: 1 },
isNonstandard: null, isNonstandard: null,
}, },
fishiousrend: { fishiousrend: {
@ -184,7 +184,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
futuresight: { futuresight: {
inherit: true, inherit: true,
flags: {metronome: 1, futuremove: 1}, flags: { metronome: 1, futuremove: 1 },
}, },
geargrind: { geargrind: {
inherit: true, inherit: true,
@ -229,12 +229,12 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
holdhands: { holdhands: {
inherit: true, inherit: true,
isNonstandard: null, isNonstandard: null,
flags: {bypasssub: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { bypasssub: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
hyperspacefury: { hyperspacefury: {
inherit: true, inherit: true,
isNonstandard: "Past", isNonstandard: "Past",
flags: {mirror: 1, bypasssub: 1}, flags: { mirror: 1, bypasssub: 1 },
}, },
hyperspacehole: { hyperspacehole: {
inherit: true, inherit: true,
@ -372,7 +372,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
metronome: { metronome: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
milkdrink: { milkdrink: {
inherit: true, inherit: true,
@ -388,11 +388,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
mirrorcoat: { mirrorcoat: {
inherit: true, inherit: true,
flags: {protect: 1, failmefirst: 1, noassist: 1, failcopycat: 1}, flags: { protect: 1, failmefirst: 1, noassist: 1, failcopycat: 1 },
}, },
mirrormove: { mirrormove: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
mistball: { mistball: {
inherit: true, inherit: true,
@ -405,7 +405,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
naturepower: { naturepower: {
inherit: true, inherit: true,
isNonstandard: null, isNonstandard: null,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
naturesmadness: { naturesmadness: {
inherit: true, inherit: true,
@ -509,7 +509,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
sleeptalk: { sleeptalk: {
inherit: true, inherit: true,
flags: {failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1}, flags: { failencore: 1, nosleeptalk: 1, noassist: 1, failcopycat: 1, failinstruct: 1 },
}, },
snaptrap: { snaptrap: {
inherit: true, inherit: true,
@ -532,7 +532,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return; if (!pokemon.isGrounded() || pokemon.hasItem('heavydutyboots')) return;
this.add('-activate', pokemon, 'move: Sticky Web'); this.add('-activate', pokemon, 'move: Sticky Web');
this.boost({spe: -1}, pokemon, this.effectState.source, this.dex.getActiveMove('stickyweb')); this.boost({ spe: -1 }, pokemon, this.effectState.source, this.dex.getActiveMove('stickyweb'));
}, },
}, },
}, },

View File

@ -1,39 +1,39 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
growlithehisui: { growlithehisui: {
inherit: true, inherit: true,
abilities: {0: "Intimidate", 1: "Flash Fire", H: "Justified"}, abilities: { 0: "Intimidate", 1: "Flash Fire", H: "Justified" },
}, },
arcaninehisui: { arcaninehisui: {
inherit: true, inherit: true,
abilities: {0: "Intimidate", 1: "Flash Fire", H: "Justified"}, abilities: { 0: "Intimidate", 1: "Flash Fire", H: "Justified" },
}, },
typhlosionhisui: { typhlosionhisui: {
inherit: true, inherit: true,
abilities: {0: "Blaze", H: "Flash Fire"}, abilities: { 0: "Blaze", H: "Flash Fire" },
}, },
sneaselhisui: { sneaselhisui: {
inherit: true, inherit: true,
abilities: {0: "Inner Focus", 1: "Keen Eye", H: "Poison Touch"}, abilities: { 0: "Inner Focus", 1: "Keen Eye", H: "Poison Touch" },
}, },
shiftry: { shiftry: {
inherit: true, inherit: true,
abilities: {0: "Chlorophyll", 1: "Early Bird", H: "Pickpocket"}, abilities: { 0: "Chlorophyll", 1: "Early Bird", H: "Pickpocket" },
}, },
piplup: { piplup: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
prinplup: { prinplup: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
empoleon: { empoleon: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
gallade: { gallade: {
inherit: true, inherit: true,
abilities: {0: "Steadfast", H: "Justified"}, abilities: { 0: "Steadfast", H: "Justified" },
}, },
giratinaorigin: { giratinaorigin: {
inherit: true, inherit: true,
@ -41,15 +41,15 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
cresselia: { cresselia: {
inherit: true, inherit: true,
baseStats: {hp: 120, atk: 70, def: 120, spa: 75, spd: 130, spe: 85}, baseStats: { hp: 120, atk: 70, def: 120, spa: 75, spd: 130, spe: 85 },
}, },
samurotthisui: { samurotthisui: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Shell Armor"}, abilities: { 0: "Torrent", H: "Shell Armor" },
}, },
braviaryhisui: { braviaryhisui: {
inherit: true, inherit: true,
abilities: {0: "Keen Eye", 1: "Sheer Force", H: "Defiant"}, abilities: { 0: "Keen Eye", 1: "Sheer Force", H: "Defiant" },
}, },
spewpa: { spewpa: {
inherit: true, inherit: true,
@ -57,68 +57,68 @@ export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable
}, },
vivillonfancy: { vivillonfancy: {
inherit: true, inherit: true,
abilities: {0: "Shield Dust", 1: "Compound Eyes"}, abilities: { 0: "Shield Dust", 1: "Compound Eyes" },
prevo: undefined, prevo: undefined,
evoLevel: undefined, evoLevel: undefined,
}, },
vivillonpokeball: { vivillonpokeball: {
inherit: true, inherit: true,
abilities: {0: "Shield Dust", 1: "Compound Eyes"}, abilities: { 0: "Shield Dust", 1: "Compound Eyes" },
}, },
sliggoohisui: { sliggoohisui: {
inherit: true, inherit: true,
abilities: {0: "Sap Sipper", 1: "Overcoat", H: "Gooey"}, abilities: { 0: "Sap Sipper", 1: "Overcoat", H: "Gooey" },
}, },
goodrahisui: { goodrahisui: {
inherit: true, inherit: true,
abilities: {0: "Sap Sipper", 1: "Overcoat", H: "Gooey"}, abilities: { 0: "Sap Sipper", 1: "Overcoat", H: "Gooey" },
}, },
decidueyehisui: { decidueyehisui: {
inherit: true, inherit: true,
abilities: {0: "Overgrow", H: "Long Reach"}, abilities: { 0: "Overgrow", H: "Long Reach" },
}, },
zacian: { zacian: {
inherit: true, inherit: true,
baseStats: {hp: 92, atk: 130, def: 115, spa: 80, spd: 115, spe: 138}, baseStats: { hp: 92, atk: 130, def: 115, spa: 80, spd: 115, spe: 138 },
}, },
zaciancrowned: { zaciancrowned: {
inherit: true, inherit: true,
baseStats: {hp: 92, atk: 170, def: 115, spa: 80, spd: 115, spe: 148}, baseStats: { hp: 92, atk: 170, def: 115, spa: 80, spd: 115, spe: 148 },
}, },
zamazenta: { zamazenta: {
inherit: true, inherit: true,
baseStats: {hp: 92, atk: 130, def: 115, spa: 80, spd: 115, spe: 138}, baseStats: { hp: 92, atk: 130, def: 115, spa: 80, spd: 115, spe: 138 },
}, },
zamazentacrowned: { zamazentacrowned: {
inherit: true, inherit: true,
baseStats: {hp: 92, atk: 130, def: 145, spa: 80, spd: 145, spe: 128}, baseStats: { hp: 92, atk: 130, def: 145, spa: 80, spd: 145, spe: 128 },
}, },
kleavor: { kleavor: {
inherit: true, inherit: true,
abilities: {0: "Swarm", 1: "Sheer Force", H: "Steadfast"}, abilities: { 0: "Swarm", 1: "Sheer Force", H: "Steadfast" },
}, },
basculegion: { basculegion: {
inherit: true, inherit: true,
abilities: {0: "Rattled", 1: "Adaptability", H: "Mold Breaker"}, abilities: { 0: "Rattled", 1: "Adaptability", H: "Mold Breaker" },
}, },
basculegionf: { basculegionf: {
inherit: true, inherit: true,
abilities: {0: "Rattled", 1: "Adaptability", H: "Mold Breaker"}, abilities: { 0: "Rattled", 1: "Adaptability", H: "Mold Breaker" },
}, },
sneasler: { sneasler: {
inherit: true, inherit: true,
abilities: {0: "Pressure", H: "Poison Touch"}, abilities: { 0: "Pressure", H: "Poison Touch" },
evoType: "useItem", evoType: "useItem",
evoItem: "Razor Claw", evoItem: "Razor Claw",
evoCondition: "during the day", evoCondition: "during the day",
}, },
enamorus: { enamorus: {
inherit: true, inherit: true,
abilities: {0: "Healer", H: "Contrary"}, abilities: { 0: "Healer", H: "Contrary" },
}, },
kitsunoh: { kitsunoh: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 103, def: 85, spa: 55, spd: 80, spe: 110}, baseStats: { hp: 80, atk: 103, def: 85, spa: 55, spd: 80, spe: 110 },
abilities: {0: "Frisk", 1: "Limber", H: "Iron Fist"}, abilities: { 0: "Frisk", 1: "Limber", H: "Iron Fist" },
}, },
}; };

View File

@ -35,7 +35,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
desc: `Pok&eacute;mon below OU get their stats, excluding HP, boosted. UU/RUBL get +10, RU/NUBL get +20, NU/PUBL get +30, and PU or lower get +40.`, desc: `Pok&eacute;mon below OU get their stats, excluding HP, boosted. UU/RUBL get +10, RU/NUBL get +20, NU/PUBL get +30, and PU or lower get +40.`,
onModifySpecies(species, target, source, effect) { onModifySpecies(species, target, source, effect) {
if (!species.baseStats) return; if (!species.baseStats) return;
const boosts: {[tier: string]: number} = { const boosts: { [tier: string]: number } = {
uu: 10, uu: 10,
rubl: 10, rubl: 10,
ru: 20, ru: 20,
@ -79,7 +79,7 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
const typesSet = new Set(species.types); const typesSet = new Set(species.types);
const bonusType = this.dex.types.get(target.set.name); const bonusType = this.dex.types.get(target.set.name);
if (bonusType.exists) typesSet.add(bonusType.name); if (bonusType.exists) typesSet.add(bonusType.name);
return {...species, types: [...typesSet]}; return { ...species, types: [...typesSet] };
}, },
}, },
godlygiftmod: { godlygiftmod: {

View File

@ -125,7 +125,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
dragonhammer: { dragonhammer: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1 },
}, },
drumbeating: { drumbeating: {
inherit: true, inherit: true,

View File

@ -2,7 +2,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
pursuit: { pursuit: {
inherit: true, inherit: true,
beforeTurnCallback(pokemon, target) { beforeTurnCallback(pokemon, target) {
// @ts-ignore // @ts-expect-error modded
const linkedMoves: [string, string] = pokemon.getLinkedMoves(); const linkedMoves: [string, string] = pokemon.getLinkedMoves();
if (linkedMoves.length) { if (linkedMoves.length) {
if (linkedMoves[0] !== 'pursuit' && linkedMoves[1] === 'pursuit') return; if (linkedMoves[0] !== 'pursuit' && linkedMoves[1] === 'pursuit') return;
@ -21,11 +21,11 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const action = this.queue.willMove(target); const action = this.queue.willMove(target);
if (action) { if (action) {
// Mod-specific: Me First copies the first move in the link // Mod-specific: Me First copies the first move in the link
// @ts-ignore // @ts-expect-error modded
const move = this.dex.getActiveMove(action.linked?.[0] || action.move); const move = this.dex.getActiveMove(action.linked?.[0] || action.move);
if (move.category !== 'Status' && !move.flags['failmefirst']) { if (move.category !== 'Status' && !move.flags['failmefirst']) {
pokemon.addVolatile('mefirst'); pokemon.addVolatile('mefirst');
this.actions.useMove(move, pokemon, {target}); this.actions.useMove(move, pokemon, { target });
return null; return null;
} }
} }
@ -50,7 +50,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
this.add('-fail', source); this.add('-fail', source);
return null; return null;
} }
// @ts-ignore // @ts-expect-error modded
if (!action.linked) { if (!action.linked) {
if (action.move.category === 'Status' && action.move.id !== 'mefirst') { if (action.move.category === 'Status' && action.move.id !== 'mefirst') {
this.attrLastMove('[still]'); this.attrLastMove('[still]');
@ -58,7 +58,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return null; return null;
} }
} else { } else {
// @ts-ignore // @ts-expect-error modded
for (const linkedMove of action.linked) { for (const linkedMove of action.linked) {
if (linkedMove.category !== 'Status' || linkedMove.id === 'mefirst') return; if (linkedMove.category !== 'Status' || linkedMove.id === 'mefirst') return;
} }
@ -132,7 +132,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
) { ) {
return false; return false;
} }
this.add('-singleturn', target, 'move: Instruct', '[of] ' + source); this.add('-singleturn', target, 'move: Instruct', `[of] ${source}`);
this.actions.runMove(lastMove.id, target, target.lastMoveTargetLoc!); this.actions.runMove(lastMove.id, target, target.lastMoveTargetLoc!);
}, },
}, },
@ -140,10 +140,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
onTryHit(target, pokemon) { onTryHit(target, pokemon) {
const move: Move | ActiveMove | null = target.m.lastMoveAbsolute; const move: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!move || !move.flags['mirror'] || move.isZ || move.isMax) { if (!move?.flags['mirror'] || move.isZ || move.isMax) {
return false; return false;
} }
this.actions.useMove(move.id, pokemon, {target}); this.actions.useMove(move.id, pokemon, { target });
return null; return null;
}, },
}, },
@ -173,7 +173,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
return false; return false;
} else { } else {
if (effect.id === 'cursedbody') { if (effect.id === 'cursedbody') {
this.add('-start', pokemon, 'Disable', moveSlot.move, '[from] ability: Cursed Body', '[of] ' + source); this.add('-start', pokemon, 'Disable', moveSlot.move, '[from] ability: Cursed Body', `[of] ${source}`);
} else { } else {
this.add('-start', pokemon, 'Disable', moveSlot.move); this.add('-start', pokemon, 'Disable', moveSlot.move);
} }
@ -213,7 +213,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
let lastMove: Move | ActiveMove | null = target.m.lastMoveAbsolute; let lastMove: Move | ActiveMove | null = target.m.lastMoveAbsolute;
if (!lastMove || target.volatiles['dynamax']) return false; if (!lastMove || target.volatiles['dynamax']) return false;
if ((lastMove as ActiveMove).isZOrMaxPowered) lastMove = this.dex.moves.get(lastMove.baseMove); if ((lastMove as ActiveMove).isZOrMaxPowered) lastMove = this.dex.moves.get(lastMove.baseMove);
// @ts-ignore // @ts-expect-error modded
const linkedMoves: [string, string] = target.getLinkedMoves(true); const linkedMoves: [string, string] = target.getLinkedMoves(true);
const moveIndex = target.moves.indexOf(lastMove.id); const moveIndex = target.moves.indexOf(lastMove.id);
if (linkedMoves.includes(lastMove.id) && this.dex.moves.get((linkedMoves[0])).flags['failencore'] && if (linkedMoves.includes(lastMove.id) && this.dex.moves.get((linkedMoves[0])).flags['failencore'] &&
@ -273,7 +273,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const index = target.moves.indexOf(lastMove.id); const index = target.moves.indexOf(lastMove.id);
if (index === -1) return; // no last move if (index === -1) return; // no last move
// @ts-ignore // @ts-expect-error modded
if (target.hasLinkedMove(lastMove.id)) { if (target.hasLinkedMove(lastMove.id)) {
// TODO: Check instead whether the last executed move was linked // TODO: Check instead whether the last executed move was linked
if (target.moveSlots[0].pp <= 0 || target.moveSlots[1].pp <= 0) { if (target.moveSlots[0].pp <= 0 || target.moveSlots[1].pp <= 0) {

View File

@ -99,16 +99,16 @@ export const Scripts: ModdedBattleScriptsData = {
if (!action.pokemon.isActive) return false; if (!action.pokemon.isActive) return false;
if (action.pokemon.fainted) return false; if (action.pokemon.fainted) return false;
// Linked moves // Linked moves
// @ts-ignore // @ts-expect-error modded
if (action.linked) { if (action.linked) {
// @ts-ignore // @ts-expect-error modded
const linkedMoves: ActiveMove[] = action.linked; const linkedMoves: ActiveMove[] = action.linked;
for (let i = linkedMoves.length - 1; i >= 0; i--) { for (let i = linkedMoves.length - 1; i >= 0; i--) {
const validTarget = this.validTargetLoc(action.targetLoc, action.pokemon, linkedMoves[i].target); const validTarget = this.validTargetLoc(action.targetLoc, action.pokemon, linkedMoves[i].target);
const targetLoc = validTarget ? action.targetLoc : 0; const targetLoc = validTarget ? action.targetLoc : 0;
const pseudoAction: Action = { const pseudoAction: Action = {
choice: 'move', priority: action.priority, speed: action.speed, pokemon: action.pokemon, choice: 'move', priority: action.priority, speed: action.speed, pokemon: action.pokemon,
targetLoc: targetLoc, moveid: linkedMoves[i].id, move: linkedMoves[i], mega: action.mega, targetLoc, moveid: linkedMoves[i].id, move: linkedMoves[i], mega: action.mega,
order: action.order, fractionalPriority: action.fractionalPriority, originalTarget: action.originalTarget, order: action.order, fractionalPriority: action.fractionalPriority, originalTarget: action.originalTarget,
}; };
this.queue.unshift(pseudoAction); this.queue.unshift(pseudoAction);
@ -389,7 +389,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.add('-zpower', pokemon); this.battle.add('-zpower', pokemon);
pokemon.side.zMoveUsed = true; pokemon.side.zMoveUsed = true;
} }
const moveDidSomething = this.useMove(baseMove, pokemon, {target, sourceEffect, zMove, maxMove}); const moveDidSomething = this.useMove(baseMove, pokemon, { target, sourceEffect, zMove, maxMove });
this.battle.lastSuccessfulMoveThisTurn = moveDidSomething ? this.battle.activeMove && this.battle.activeMove.id : null; this.battle.lastSuccessfulMoveThisTurn = moveDidSomething ? this.battle.activeMove && this.battle.activeMove.id : null;
if (this.battle.activeMove) move = this.battle.activeMove; if (this.battle.activeMove) move = this.battle.activeMove;
this.battle.singleEvent('AfterMove', move, null, pokemon, target, move); this.battle.singleEvent('AfterMove', move, null, pokemon, target, move);
@ -416,7 +416,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.add('-activate', dancer, 'ability: Dancer'); this.battle.add('-activate', dancer, 'ability: Dancer');
const dancersTarget = !target!.isAlly(dancer) && pokemon.isAlly(dancer) ? target! : pokemon; const dancersTarget = !target!.isAlly(dancer) && pokemon.isAlly(dancer) ? target! : pokemon;
this.runMove(move.id, dancer, dancer.getLocOf(dancersTarget), this.runMove(move.id, dancer, dancer.getLocOf(dancersTarget),
{sourceEffect: this.dex.abilities.get('dancer'), externalMove: true}); { sourceEffect: this.dex.abilities.get('dancer'), externalMove: true });
} }
} }
if (noLock && pokemon.volatiles['lockedmove']) delete pokemon.volatiles['lockedmove']; if (noLock && pokemon.volatiles['lockedmove']) delete pokemon.volatiles['lockedmove'];
@ -433,7 +433,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (!action.side && action.pokemon) action.side = action.pokemon.side; if (!action.side && action.pokemon) action.side = action.pokemon.side;
if (!action.move && action.moveid) action.move = this.battle.dex.getActiveMove(action.moveid); if (!action.move && action.moveid) action.move = this.battle.dex.getActiveMove(action.moveid);
if (!action.order) { if (!action.order) {
const orders: {[choice: string]: number} = { const orders: { [choice: string]: number } = {
team: 1, team: 1,
start: 2, start: 2,
instaswitch: 3, instaswitch: 3,
@ -482,9 +482,11 @@ export const Scripts: ModdedBattleScriptsData = {
} }
action.fractionalPriority = this.battle.runEvent('FractionalPriority', action.pokemon, null, action.move, 0); action.fractionalPriority = this.battle.runEvent('FractionalPriority', action.pokemon, null, action.move, 0);
const linkedMoves: [string, string] = action.pokemon.getLinkedMoves(); const linkedMoves: [string, string] = action.pokemon.getLinkedMoves();
if (linkedMoves.length && if (
linkedMoves.length &&
!(action.pokemon.getItem().isChoice || action.pokemon.hasAbility('gorillatactics')) && !(action.pokemon.getItem().isChoice || action.pokemon.hasAbility('gorillatactics')) &&
!action.zmove && !action.maxMove) { !action.zmove && !action.maxMove
) {
const decisionMove = this.battle.toID(action.move); const decisionMove = this.battle.toID(action.move);
if (linkedMoves.includes(decisionMove)) { if (linkedMoves.includes(decisionMove)) {
action.linked = linkedMoves.map(moveid => this.battle.dex.getActiveMove(moveid)); action.linked = linkedMoves.map(moveid => this.battle.dex.getActiveMove(moveid));
@ -543,7 +545,7 @@ export const Scripts: ModdedBattleScriptsData = {
return ret; return ret;
}, },
hasLinkedMove(moveid) { hasLinkedMove(moveid) {
// @ts-ignore // @ts-expect-error modded
const linkedMoves: ID[] = this.getLinkedMoves(true); const linkedMoves: ID[] = this.getLinkedMoves(true);
if (!linkedMoves.length) return false; if (!linkedMoves.length) return false;
return linkedMoves.some(x => x === moveid); return linkedMoves.some(x => x === moveid);

View File

@ -1,11 +1,11 @@
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = { export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
commander: { commander: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
}, },
gulpmissile: { gulpmissile: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
}, },
protosynthesis: { protosynthesis: {
inherit: true, inherit: true,
@ -63,7 +63,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
this.add('-end', pokemon, 'Protosynthesis'); this.add('-end', pokemon, 'Protosynthesis');
}, },
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1, cantsuppress: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1, cantsuppress: 1 },
}, },
quarkdrive: { quarkdrive: {
inherit: true, inherit: true,
@ -112,6 +112,6 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
this.add('-end', pokemon, 'Quark Drive'); this.add('-end', pokemon, 'Quark Drive');
}, },
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1, cantsuppress: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1, cantsuppress: 1 },
}, },
}; };

View File

@ -1,7 +1,7 @@
export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = { export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
aeroblast: { aeroblast: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, distance: 1, metronome: 1}, flags: { protect: 1, mirror: 1, distance: 1, metronome: 1 },
isNonstandard: "Past", isNonstandard: "Past",
}, },
alluringvoice: { alluringvoice: {
@ -14,7 +14,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
bitterblade: { bitterblade: {
inherit: true, inherit: true,
flags: {contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1}, flags: { contact: 1, protect: 1, mirror: 1, metronome: 1, slicing: 1 },
}, },
blueflare: { blueflare: {
inherit: true, inherit: true,
@ -42,7 +42,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
darkvoid: { darkvoid: {
inherit: true, inherit: true,
flags: {protect: 1, reflectable: 1, mirror: 1, metronome: 1}, flags: { protect: 1, reflectable: 1, mirror: 1, metronome: 1 },
}, },
decorate: { decorate: {
inherit: true, inherit: true,
@ -90,7 +90,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
hyperspacefury: { hyperspacefury: {
inherit: true, inherit: true,
flags: {mirror: 1, bypasssub: 1}, flags: { mirror: 1, bypasssub: 1 },
}, },
iceburn: { iceburn: {
inherit: true, inherit: true,
@ -107,7 +107,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
matchagotcha: { matchagotcha: {
inherit: true, inherit: true,
flags: {protect: 1, mirror: 1, defrost: 1, metronome: 1}, flags: { protect: 1, mirror: 1, defrost: 1, metronome: 1 },
}, },
mightycleave: { mightycleave: {
inherit: true, inherit: true,
@ -140,7 +140,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
}, },
revivalblessing: { revivalblessing: {
inherit: true, inherit: true,
flags: {heal: 1}, flags: { heal: 1 },
}, },
rockwrecker: { rockwrecker: {
inherit: true, inherit: true,

View File

@ -1,8 +1,8 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
cresceidon: { cresceidon: {
inherit: true, inherit: true,
baseStats: {hp: 80, atk: 32, def: 111, spa: 88, spd: 99, spe: 125}, baseStats: { hp: 80, atk: 32, def: 111, spa: 88, spd: 99, spe: 125 },
abilities: {0: "Multiscale", 1: "Rough Skin"}, abilities: { 0: "Multiscale", 1: "Rough Skin" },
eggGroups: ["Undiscovered"], eggGroups: ["Undiscovered"],
}, },
}; };

View File

@ -1,15 +1,15 @@
export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = { export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTable = {
commander: { commander: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
}, },
gulpmissile: { gulpmissile: {
inherit: true, inherit: true,
flags: {cantsuppress: 1, notransform: 1}, flags: { cantsuppress: 1, notransform: 1 },
}, },
hadronengine: { hadronengine: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
}, },
illuminate: { illuminate: {
inherit: true, inherit: true,
@ -24,7 +24,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
orichalcumpulse: { orichalcumpulse: {
inherit: true, inherit: true,
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1, notransform: 1 },
}, },
supersweetsyrup: { supersweetsyrup: {
inherit: true, inherit: true,

View File

@ -1,18 +1,18 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
shiftry: { shiftry: {
inherit: true, inherit: true,
abilities: {0: "Chlorophyll", 1: "Early Bird", H: "Pickpocket"}, abilities: { 0: "Chlorophyll", 1: "Early Bird", H: "Pickpocket" },
}, },
piplup: { piplup: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
prinplup: { prinplup: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
empoleon: { empoleon: {
inherit: true, inherit: true,
abilities: {0: "Torrent", H: "Defiant"}, abilities: { 0: "Torrent", H: "Defiant" },
}, },
}; };

View File

@ -1,5 +1,5 @@
import {ssbSets} from "./random-teams"; import { ssbSets } from "./random-teams";
import {changeSet, getName, PSEUDO_WEATHERS} from "./scripts"; import { changeSet, getName, PSEUDO_WEATHERS } from "./scripts";
const STRONG_WEATHERS = ['desolateland', 'primordialsea', 'deltastream', 'deserteddunes', 'millenniumcastle']; const STRONG_WEATHERS = ['desolateland', 'primordialsea', 'deltastream', 'deserteddunes', 'millenniumcastle'];
@ -29,7 +29,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(1.5); return this.chainModify(1.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
gen: 9, gen: 9,
}, },
@ -71,7 +71,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify([powMod[this.effectState.fallen], 20]); return this.chainModify([powMod[this.effectState.fallen], 20]);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Akir // Akir
@ -116,7 +116,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onTryBoost(boost, target, source, effect) { onTryBoost(boost, target, source, effect) {
if (effect.name === 'Intimidate' && boost.atk) { if (effect.name === 'Intimidate' && boost.atk) {
delete boost.atk; delete boost.atk;
this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Paw Prints', '[of] ' + target); this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Paw Prints', `[of] ${target}`);
} }
}, },
onModifyMove(move) { onModifyMove(move) {
@ -124,7 +124,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
move.ignoreAbility = true; move.ignoreAbility = true;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Alexander489 // Alexander489
@ -134,7 +134,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onBasePowerPriority: 30, onBasePowerPriority: 30,
onBasePower(basePower, attacker, defender, move) { onBasePower(basePower, attacker, defender, move) {
const basePowerAfterMultiplier = this.modify(basePower, this.event.modifier); const basePowerAfterMultiplier = this.modify(basePower, this.event.modifier);
this.debug('Base Power: ' + basePowerAfterMultiplier); this.debug(`Base Power: ${basePowerAfterMultiplier}`);
if (basePowerAfterMultiplier <= 60) { if (basePowerAfterMultiplier <= 60) {
this.debug('Confirmed Town boost'); this.debug('Confirmed Town boost');
return this.chainModify(1.5); return this.chainModify(1.5);
@ -184,13 +184,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
name: "Served Cold", name: "Served Cold",
onTryHit(target, source, move) { onTryHit(target, source, move) {
if (target !== source && move.type === 'Ice') { if (target !== source && move.type === 'Ice') {
if (!this.boost({def: 2})) { if (!this.boost({ def: 2 })) {
this.add('-immune', target, '[from] ability: Served Cold'); this.add('-immune', target, '[from] ability: Served Cold');
} }
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// aQrator // aQrator
@ -263,7 +263,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
boosts['accuracy'] = 0; boosts['accuracy'] = 0;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
gen: 9, gen: 9,
}, },
@ -326,7 +326,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
gen: 9, gen: 9,
}, },
@ -360,7 +360,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
} }
if (showMsg && !(effect as ActiveMove).secondaries && effect.id !== 'octolock') { if (showMsg && !(effect as ActiveMove).secondaries && effect.id !== 'octolock') {
this.add("-fail", target, "unboost", "[from] ability: Supervised Learning", "[of] " + target); this.add("-fail", target, "unboost", "[from] ability: Supervised Learning", `[of] ${target}`);
} }
}, },
flags: {}, flags: {},
@ -380,7 +380,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// ausma // ausma
@ -398,7 +398,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
this.heal(pokemon.maxhp / 3); this.heal(pokemon.maxhp / 3);
if (this.field.pseudoWeather['trickroom']) { if (this.field.pseudoWeather['trickroom']) {
this.field.removePseudoWeather('trickroom'); this.field.removePseudoWeather('trickroom');
this.boost({spe: 2}, pokemon, pokemon, this.effect); this.boost({ spe: 2 }, pokemon, pokemon, this.effect);
} }
}, },
flags: {}, flags: {},
@ -415,7 +415,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
move.accuracy = 40; move.accuracy = 40;
const target = pokemon.foes()[0]; const target = pokemon.foes()[0];
if (target && !target.fainted) { if (target && !target.fainted) {
this.actions.useMove(move, pokemon, {target, sourceEffect: effect}); this.actions.useMove(move, pokemon, { target, sourceEffect: effect });
} }
} }
}, },
@ -464,7 +464,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.75); return this.chainModify(0.75);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Breadey // Breadey
@ -564,7 +564,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (target !== source && move.type === 'Fire') { if (target !== source && move.type === 'Fire') {
if (target.setType('Water')) { if (target.setType('Water')) {
this.add('-start', target, 'typechange', 'Water', '[from] ability: Melting Point'); this.add('-start', target, 'typechange', 'Water', '[from] ability: Melting Point');
this.boost({spe: 2}, target, source, this.dex.abilities.get('meltingpoint')); this.boost({ spe: 2 }, target, source, this.dex.abilities.get('meltingpoint'));
} else { } else {
this.add('-immune', target, '[from] ability: Melting Point'); this.add('-immune', target, '[from] ability: Melting Point');
} }
@ -617,11 +617,11 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const speciesid = pokemon.species.id === 'mimikyutotem' ? 'Mimikyu-Busted-Totem' : 'Mimikyu-Busted'; const speciesid = pokemon.species.id === 'mimikyutotem' ? 'Mimikyu-Busted-Totem' : 'Mimikyu-Busted';
pokemon.formeChange(speciesid, this.effect, true); pokemon.formeChange(speciesid, this.effect, true);
this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid)); this.damage(pokemon.baseMaxhp / 8, pokemon, pokemon, this.dex.species.get(speciesid));
this.boost({atk: 1, spe: 1}); this.boost({ atk: 1, spe: 1 });
this.add(`c:|${getName('clerica')}|oop`); this.add(`c:|${getName('clerica')}|oop`);
} }
}, },
flags: {breakable: 1, failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1}, flags: { breakable: 1, failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
}, },
// Clouds // Clouds
@ -651,7 +651,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return false; return false;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Coolcodename // Coolcodename
@ -666,7 +666,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Corthius // Corthius
@ -762,7 +762,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
for (const ally of pokemon.side.pokemon) { for (const ally of pokemon.side.pokemon) {
if (!ally.hp || ally === pokemon) continue; if (!ally.hp || ally === pokemon) continue;
if (ally.heal(this.modify(ally.baseMaxhp, pokemon.hp > pokemon.maxhp / 4 ? 0.05 : 0.1))) { if (ally.heal(this.modify(ally.baseMaxhp, pokemon.hp > pokemon.maxhp / 4 ? 0.05 : 0.1))) {
this.add('-heal', ally, ally.getHealth, '[from] ability: Coalescence', '[of] ' + pokemon); this.add('-heal', ally, ally.getHealth, '[from] ability: Coalescence', `[of] ${pokemon}`);
} }
} }
}, },
@ -832,13 +832,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onTryHitPriority: 1, onTryHitPriority: 1,
onTryHit(target, source, move) { onTryHit(target, source, move) {
if (target !== source && move.type === 'Ice') { if (target !== source && move.type === 'Ice') {
if (!this.boost({atk: 1})) { if (!this.boost({ atk: 1 })) {
this.add('-immune', target, '[from] ability: Snowballer'); this.add('-immune', target, '[from] ability: Snowballer');
} }
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Fame // Fame
@ -873,14 +873,14 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onResidualOrder: 29, onResidualOrder: 29,
onResidual(pokemon) { onResidual(pokemon) {
if (!this.effectState.gamblingAddiction && pokemon.hp && pokemon.hp < pokemon.maxhp / 4) { if (!this.effectState.gamblingAddiction && pokemon.hp && pokemon.hp < pokemon.maxhp / 4) {
this.boost({spe: 1}); this.boost({ spe: 1 });
this.heal(pokemon.maxhp); this.heal(pokemon.maxhp);
const move = this.dex.moves.get('finalgambit'); const move = this.dex.moves.get('finalgambit');
const finalGambit = { const finalGambit = {
move: move.name, move: move.name,
id: move.id, id: move.id,
pp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target, target: move.target,
disabled: false, disabled: false,
used: false, used: false,
@ -996,7 +996,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onTryHit(target, source, move) { onTryHit(target, source, move) {
// Storm Drain // Storm Drain
if (target !== source && move.type === 'Water') { if (target !== source && move.type === 'Water') {
if (!this.boost({spa: 1})) { if (!this.boost({ spa: 1 })) {
this.add('-immune', target, '[from] ability: Hydrostatic Positivity'); this.add('-immune', target, '[from] ability: Hydrostatic Positivity');
} }
return null; return null;
@ -1004,7 +1004,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
// Motor Drive // Motor Drive
if (target !== source && move.type === 'Electric') { if (target !== source && move.type === 'Electric') {
if (!this.boost({spe: 1})) { if (!this.boost({ spe: 1 })) {
this.add('-immune', target, '[from] ability: Hydrostatic Positivity'); this.add('-immune', target, '[from] ability: Hydrostatic Positivity');
} }
return null; return null;
@ -1070,7 +1070,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (pokemon.baseSpecies.baseSpecies !== 'Kyurem' || pokemon.transformed || !pokemon.hp) return; if (pokemon.baseSpecies.baseSpecies !== 'Kyurem' || pokemon.transformed || !pokemon.hp) return;
changeSet(this, pokemon, ssbSets['Imperial']); changeSet(this, pokemon, ssbSets['Imperial']);
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
}, },
// in the hills // in the hills
@ -1084,7 +1084,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Irpachuza // Irpachuza
@ -1164,7 +1164,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
]; ];
for (const sideCondition of remove) { for (const sideCondition of remove) {
if (side.removeSideCondition(sideCondition)) { if (side.removeSideCondition(sideCondition)) {
this.add('-sideend', side, this.dex.conditions.get(sideCondition).name, '[from] ability: Anfield', '[of] ' + target); this.add('-sideend', side, this.dex.conditions.get(sideCondition).name, '[from] ability: Anfield', `[of] ${target}`);
} }
} }
} }
@ -1213,7 +1213,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify([5120, 4096]); return this.chainModify([5120, 4096]);
} }
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, cantsuppress: 1 },
}, },
// kingbaruk // kingbaruk
@ -1273,7 +1273,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Kry // Kry
@ -1307,7 +1307,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.75); return this.chainModify(0.75);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Lasen // Lasen
@ -1321,12 +1321,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const displayText = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge']; const displayText = ['spikes', 'toxicspikes', 'stealthrock', 'stickyweb', 'gmaxsteelsurge'];
for (const targetCondition of Object.keys(target.sideConditions)) { for (const targetCondition of Object.keys(target.sideConditions)) {
if (target.removeSideCondition(targetCondition) && displayText.includes(targetCondition)) { if (target.removeSideCondition(targetCondition) && displayText.includes(targetCondition)) {
this.add('-sideend', target, this.dex.conditions.get(targetCondition).name, '[from] ability: Idealized World', '[of] ' + pokemon); this.add('-sideend', target, this.dex.conditions.get(targetCondition).name, '[from] ability: Idealized World', `[of] ${pokemon}`);
} }
} }
for (const sideCondition of Object.keys(pokemon.side.sideConditions)) { for (const sideCondition of Object.keys(pokemon.side.sideConditions)) {
if (pokemon.side.removeSideCondition(sideCondition) && displayText.includes(sideCondition)) { if (pokemon.side.removeSideCondition(sideCondition) && displayText.includes(sideCondition)) {
this.add('-sideend', pokemon.side, this.dex.conditions.get(sideCondition).name, '[from] ability: Idealized World', '[of] ' + pokemon); this.add('-sideend', pokemon.side, this.dex.conditions.get(sideCondition).name, '[from] ability: Idealized World', `[of] ${pokemon}`);
} }
} }
this.field.clearTerrain(); this.field.clearTerrain();
@ -1377,7 +1377,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
pokemon.maybeTrapped = true; pokemon.maybeTrapped = true;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Lyna // Lyna
@ -1398,7 +1398,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
newMove.pranksterBoosted = false; newMove.pranksterBoosted = false;
this.actions.useMove(newMove, target, {target: source}); this.actions.useMove(newMove, target, { target: source });
return null; return null;
}, },
onAllyTryHitSide(target, source, move) { onAllyTryHitSide(target, source, move) {
@ -1408,13 +1408,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const newMove = this.dex.getActiveMove(move.id); const newMove = this.dex.getActiveMove(move.id);
newMove.hasBounced = true; newMove.hasBounced = true;
newMove.pranksterBoosted = false; newMove.pranksterBoosted = false;
this.actions.useMove(newMove, this.effectState.target, {target: source}); this.actions.useMove(newMove, this.effectState.target, { target: source });
return null; return null;
}, },
condition: { condition: {
duration: 1, duration: 1,
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Maia // Maia
@ -1432,7 +1432,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
source.trySetStatus('brn', target); source.trySetStatus('brn', target);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Mathy // Mathy
@ -1470,7 +1470,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
]; ];
for (const sideCondition of remove) { for (const sideCondition of remove) {
if (side.removeSideCondition(sideCondition)) { if (side.removeSideCondition(sideCondition)) {
this.add('-sideend', side, this.dex.conditions.get(sideCondition).name, '[from] ability: End Round', '[of] ' + pokemon); this.add('-sideend', side, this.dex.conditions.get(sideCondition).name, '[from] ability: End Round', `[of] ${pokemon}`);
} }
} }
} }
@ -1505,10 +1505,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
} }
mon.clearBoosts(); mon.clearBoosts();
this.add('-clearboost', mon, '[from] ability: End Round', '[of] ' + pokemon); this.add('-clearboost', mon, '[from] ability: End Round', `[of] ${pokemon}`);
} }
}, },
flags: {cantsuppress: 1}, flags: { cantsuppress: 1 },
}, },
// Meteordash // Meteordash
@ -1522,7 +1522,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onModifyDef(def) { onModifyDef(def) {
return this.chainModify(2); return this.chainModify(2);
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Mex // Mex
@ -1549,7 +1549,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onSourceHit(target, source, move) { onSourceHit(target, source, move) {
if (move.flags['contact'] && move.category === 'Physical') { if (move.flags['contact'] && move.category === 'Physical') {
this.add('-activate', source, 'ability: The Rolling Spheal'); this.add('-activate', source, 'ability: The Rolling Spheal');
this.boost({spe: 1}, source, source, move); this.boost({ spe: 1 }, source, source, move);
} }
}, },
condition: { condition: {
@ -1641,7 +1641,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Ney // Ney
@ -1697,9 +1697,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const sourceAbility = source.setAbility('drifting', target); const sourceAbility = source.setAbility('drifting', target);
if (!sourceAbility) return; if (!sourceAbility) return;
if (target.isAlly(source)) { if (target.isAlly(source)) {
this.add('-activate', target, 'Skill Swap', '', '', '[of] ' + source); this.add('-activate', target, 'Skill Swap', '', '', `[of] ${source}`);
} else { } else {
this.add('-activate', target, 'ability: Drifting', this.dex.abilities.get(sourceAbility).name, 'Drifting', '[of] ' + source); this.add('-activate', target, 'ability: Drifting', this.dex.abilities.get(sourceAbility).name, 'Drifting', `[of] ${source}`);
} }
target.setAbility(sourceAbility); target.setAbility(sourceAbility);
} }
@ -1738,7 +1738,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
this.add(`c:|${getName('PartMan')}|That's it. Get ready to be rapid-fire hugged.`); this.add(`c:|${getName('PartMan')}|That's it. Get ready to be rapid-fire hugged.`);
target.clearBoosts(); target.clearBoosts();
this.add('-clearboost', target); this.add('-clearboost', target);
this.boost({atk: 1, def: -1, spa: 1, spd: -1, spe: 1}); this.boost({ atk: 1, def: -1, spa: 1, spd: -1, spe: 1 });
const details = target.getUpdatedDetails(); const details = target.getUpdatedDetails();
target.details = details; target.details = details;
this.add('replace', target, details); this.add('replace', target, details);
@ -1750,9 +1750,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
onStart(pokemon) { onStart(pokemon) {
if (!pokemon.set.shiny) { if (!pokemon.set.shiny) {
this.boost({atk: -1, def: 1, spa: -1, spd: 1}); this.boost({ atk: -1, def: 1, spa: -1, spd: 1 });
} else { } else {
this.boost({atk: 1, def: -1, spa: 1, spd: -1, spe: 1}); this.boost({ atk: 1, def: -1, spa: 1, spd: -1, spe: 1 });
} }
}, },
}, },
@ -1890,7 +1890,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
shortDesc: "Boosts Sp. Atk by 2 and sets a 25% Wish upon switch-in.", shortDesc: "Boosts Sp. Atk by 2 and sets a 25% Wish upon switch-in.",
name: "Anti-Pelau", name: "Anti-Pelau",
onStart(target) { onStart(target) {
this.boost({spa: 2}, target); this.boost({ spa: 2 }, target);
const wish = this.dex.getActiveMove('wish'); const wish = this.dex.getActiveMove('wish');
wish.condition = { wish.condition = {
duration: 2, duration: 2,
@ -2010,9 +2010,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
totalspd += target.getStat('spd', false, true); totalspd += target.getStat('spd', false, true);
} }
if (totaldef && totaldef >= totalspd) { if (totaldef && totaldef >= totalspd) {
this.boost({spa: 1}); this.boost({ spa: 1 });
} else if (totalspd) { } else if (totalspd) {
this.boost({atk: 1}); this.boost({ atk: 1 });
} }
// n.b. only affects Hackmons // n.b. only affects Hackmons
@ -2037,10 +2037,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const target = this.sample(possibleTargets); const target = this.sample(possibleTargets);
const ability = target.getAbility(); const ability = target.getAbility();
if (pokemon.setAbility(ability)) { if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Monke See Monke Do', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Monke See Monke Do', `[of] ${target}`);
} }
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1 },
}, },
// Rio Vidal // Rio Vidal
@ -2048,7 +2048,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
shortDesc: "Stamina + Normal-type moves get +1 priority.", shortDesc: "Stamina + Normal-type moves get +1 priority.",
name: "Built Different", name: "Built Different",
onDamagingHit(damage, target, source, effect) { onDamagingHit(damage, target, source, effect) {
this.boost({def: 1}); this.boost({ def: 1 });
}, },
onModifyPriority(priority, pokemon, target, move) { onModifyPriority(priority, pokemon, target, move) {
if (move?.type === 'Normal') return priority + 1; if (move?.type === 'Normal') return priority + 1;
@ -2217,7 +2217,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// skies // skies
@ -2250,7 +2250,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
shortDesc: "Every turn, raises a random stat by 1 stage if the foe has more raised stats.", shortDesc: "Every turn, raises a random stat by 1 stage if the foe has more raised stats.",
name: "Adaptive Engineering", name: "Adaptive Engineering",
onResidual(source) { onResidual(source) {
if (source === undefined || source.foes() === undefined || source.foes()[0] === undefined) return; if (source?.foes()?.[0] === undefined) return;
if (source.positiveBoosts() < source.foes()[0].positiveBoosts()) { if (source.positiveBoosts() < source.foes()[0].positiveBoosts()) {
const stats: BoostID[] = []; const stats: BoostID[] = [];
let stat: BoostID; let stat: BoostID;
@ -2262,7 +2262,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
if (stats.length) { if (stats.length) {
const randomStat = this.sample(stats); const randomStat = this.sample(stats);
this.boost({[randomStat]: 1}, source, source); this.boost({ [randomStat]: 1 }, source, source);
} }
} }
}, },
@ -2311,7 +2311,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
}, },
onSourceAfterFaint(length, target, source, effect) { onSourceAfterFaint(length, target, source, effect) {
if (effect && effect.effectType === 'Move') { if (effect && effect.effectType === 'Move') {
this.boost({atk: -length}, source); this.boost({ atk: -length }, source);
} }
}, },
flags: {}, flags: {},
@ -2338,7 +2338,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (target.lastMove && target.lastMove.id !== 'struggle') { if (target.lastMove && target.lastMove.id !== 'struggle') {
if (move.id === target.lastMove.id) { if (move.id === target.lastMove.id) {
this.attrLastMove('[still]'); this.attrLastMove('[still]');
this.add('cant', target, 'ability: Overasked Clause', move, '[of] ' + source); this.add('cant', target, 'ability: Overasked Clause', move, `[of] ${source}`);
return false; return false;
} }
} }
@ -2356,7 +2356,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
} }
}, },
onDamagingHit(damage, target, source, effect) { onDamagingHit(damage, target, source, effect) {
this.boost({def: 1}); this.boost({ def: 1 });
}, },
}, },
@ -2406,7 +2406,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const dazzlingHolder = this.effectState.target; const dazzlingHolder = this.effectState.target;
if ((source.isAlly(dazzlingHolder) || move.target === 'all') && move.priority > 0.1) { if ((source.isAlly(dazzlingHolder) || move.target === 'all') && move.priority > 0.1) {
this.attrLastMove('[still]'); this.attrLastMove('[still]');
this.add('cant', target, 'ability: Sand Sleuth', move, '[of] ' + source); this.add('cant', target, 'ability: Sand Sleuth', move, `[of] ${source}`);
return false; return false;
} }
} }
@ -2427,7 +2427,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return false; return false;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// TheJesucristoOsAma // TheJesucristoOsAma
@ -2529,7 +2529,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onModifyDef(def) { onModifyDef(def) {
return this.chainModify(2); return this.chainModify(2);
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// umuwo // umuwo
@ -2566,7 +2566,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onTryHit(target, source, move) { onTryHit(target, source, move) {
if (target === source || move.category === 'Status') return; if (target === source || move.category === 'Status') return;
if (target.runEffectiveness(move) > 0) { if (target.runEffectiveness(move) > 0) {
this.boost({def: 1, spd: 1}, target); this.boost({ def: 1, spd: 1 }, target);
} }
}, },
flags: {}, flags: {},
@ -2610,7 +2610,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(1.3); return this.chainModify(1.3);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Vistar // Vistar
@ -2630,7 +2630,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.5); return this.chainModify(0.5);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// vmnunes // vmnunes
@ -2688,7 +2688,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return this.chainModify(0.75); return this.chainModify(0.75);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// xy01 // xy01
@ -2705,7 +2705,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (target.volatiles['substitute']) { if (target.volatiles['substitute']) {
this.add('-immune', target); this.add('-immune', target);
} else { } else {
this.boost({atk: -1, spa: -1}, target, pokemon, null, true); this.boost({ atk: -1, spa: -1 }, target, pokemon, null, true);
} }
} }
}, },
@ -2725,10 +2725,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
didSomething = !!this.heal(target.baseMaxhp / 4); didSomething = !!this.heal(target.baseMaxhp / 4);
break; break;
case 1: case 1:
didSomething = !!this.boost({spa: 1}, target, target); didSomething = !!this.boost({ spa: 1 }, target, target);
break; break;
case 2: case 2:
didSomething = !!this.boost({spe: 1}, target, target); didSomething = !!this.boost({ spe: 1 }, target, target);
break; break;
case 3: case 3:
if (!target.volatiles['charge']) { if (!target.volatiles['charge']) {
@ -2747,7 +2747,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// yeet dab xd // yeet dab xd
@ -2911,7 +2911,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
target.setAbility(this.sample(abilities), target); target.setAbility(this.sample(abilities), target);
this.add('-ability', target, target.getAbility().name); this.add('-ability', target, target.getAbility().name);
}, },
flags: {notrace: 1}, flags: { notrace: 1 },
}, },
// YveltalNL // YveltalNL
@ -2929,7 +2929,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
this.add('-immune', target); this.add('-immune', target);
} else { } else {
if (this.dex.species.get(pokemon.species).heightm > this.dex.species.get(target.species).heightm) { if (this.dex.species.get(pokemon.species).heightm > this.dex.species.get(target.species).heightm) {
this.boost({atk: -1, spa: -1}, target, pokemon, null, true); this.boost({ atk: -1, spa: -1 }, target, pokemon, null, true);
} }
} }
} }
@ -2962,7 +2962,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
changeSet(this, pokemon, ssbSets['Zarel'], true); changeSet(this, pokemon, ssbSets['Zarel'], true);
} }
}, },
flags: {failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1}, flags: { failroleplay: 1, noreceiver: 1, noentrain: 1, notrace: 1, failskillswap: 1, notransform: 1 },
}, },
// zoro // zoro
@ -2990,7 +2990,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
// Yes, this looks very patchwork-y. declaring new persistent global variables seems to be a no-go here // Yes, this looks very patchwork-y. declaring new persistent global variables seems to be a no-go here
// so i repurposed one which should likely not affect anything else - have tested with clerica/zoro on both sides // so i repurposed one which should likely not affect anything else - have tested with clerica/zoro on both sides
// and their disguise/sturdy state is unaffected by modifying anything here. but let wg know if this breaks stuff. // and their disguise/sturdy state is unaffected by modifying anything here. but let wg know if this breaks stuff.
flags: {breakable: 1}, flags: { breakable: 1 },
}, },
// Modified abilities // Modified abilities

View File

@ -1,8 +1,8 @@
import {ssbSets} from "./random-teams"; import { ssbSets } from "./random-teams";
import {changeSet, getName, enemyStaff} from './scripts'; import { changeSet, getName, enemyStaff } from './scripts';
import {ModdedConditionData} from "../../../sim/dex-conditions"; import type { ModdedConditionData } from "../../../sim/dex-conditions";
export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: string}} = { export const Conditions: { [id: IDEntry]: ModdedConditionData & { innateName?: string } } = {
/* /*
// Example: // Example:
userid: { userid: {
@ -496,7 +496,7 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
shortDesc: "This Pokemon's Defense is raised 2 stages if hit by a Fire move; Fire immunity.", shortDesc: "This Pokemon's Defense is raised 2 stages if hit by a Fire move; Fire immunity.",
onTryHit(target, source, move) { onTryHit(target, source, move) {
if (!target.illusion && target !== source && move.type === 'Fire') { if (!target.illusion && target !== source && move.type === 'Fire') {
if (!this.boost({def: 2})) { if (!this.boost({ def: 2 })) {
this.add('-immune', target, '[from] ability: Well-Baked Body'); this.add('-immune', target, '[from] ability: Well-Baked Body');
} }
return null; return null;
@ -619,7 +619,7 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
if (target.illusion) return; if (target.illusion) return;
if (effect.name === 'Intimidate' && boost.atk) { if (effect.name === 'Intimidate' && boost.atk) {
delete boost.atk; delete boost.atk;
this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Oblivious', '[of] ' + target); this.add('-fail', target, 'unboost', 'Attack', '[from] ability: Oblivious', `[of] ${target}`);
} }
}, },
}, },
@ -2667,7 +2667,7 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
if (pokemon.illusion) return; if (pokemon.illusion) return;
pokemon.abilityState.gluttony = true; pokemon.abilityState.gluttony = true;
this.add('-activate', pokemon, 'ability: Nutrient Boost'); this.add('-activate', pokemon, 'ability: Nutrient Boost');
this.boost({def: 1, spd: 1}, pokemon); this.boost({ def: 1, spd: 1 }, pokemon);
}, },
onSwitchOut() { onSwitchOut() {
this.add(`c:|${getName('WarriorGallade')}|amidst this tactical retreat, you didn't think i forgot about the pokeradar, did you? you can bet that my return with even more questions will be __eventful__ :3`); this.add(`c:|${getName('WarriorGallade')}|amidst this tactical retreat, you didn't think i forgot about the pokeradar, did you? you can bet that my return with even more questions will be __eventful__ :3`);
@ -3069,7 +3069,7 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
onFieldStart(battle, source, effect) { onFieldStart(battle, source, effect) {
if (effect?.effectType === 'Ability') { if (effect?.effectType === 'Ability') {
if (this.gen <= 5) this.effectState.duration = 0; if (this.gen <= 5) this.effectState.duration = 0;
this.add('-weather', 'StormSurge', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'StormSurge', '[from] ability: ' + effect.name, `[of] ${source}`);
} else { } else {
this.add('-weather', 'StormSurge'); this.add('-weather', 'StormSurge');
} }
@ -3107,7 +3107,7 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
} }
}, },
onFieldStart(field, source, effect) { onFieldStart(field, source, effect) {
this.add('-weather', 'DesertedDunes', '[from] ability: ' + effect.name, '[of] ' + source); this.add('-weather', 'DesertedDunes', '[from] ability: ' + effect.name, `[of] ${source}`);
}, },
onFieldResidualOrder: 1, onFieldResidualOrder: 1,
onFieldResidual() { onFieldResidual() {
@ -3179,16 +3179,16 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
} }
if (effect.name === 'Cute Charm') { if (effect.name === 'Cute Charm') {
this.add('-start', pokemon, 'Attract', '[from] ability: Cute Charm', '[of] ' + source); this.add('-start', pokemon, 'Attract', '[from] ability: Cute Charm', `[of] ${source}`);
} else if (effect.name === 'Destiny Knot') { } else if (effect.name === 'Destiny Knot') {
this.add('-start', pokemon, 'Attract', '[from] item: Destiny Knot', '[of] ' + source); this.add('-start', pokemon, 'Attract', '[from] item: Destiny Knot', `[of] ${source}`);
} else { } else {
this.add('-start', pokemon, 'Attract'); this.add('-start', pokemon, 'Attract');
} }
}, },
onUpdate(pokemon) { onUpdate(pokemon) {
if (this.effectState.source && !this.effectState.source.isActive && pokemon.volatiles['attract']) { if (this.effectState.source && !this.effectState.source.isActive && pokemon.volatiles['attract']) {
this.debug('Removing Attract volatile on ' + pokemon); this.debug(`Removing Attract volatile on ${pokemon}`);
pokemon.removeVolatile('attract'); pokemon.removeVolatile('attract');
} }
}, },
@ -3329,13 +3329,13 @@ export const Conditions: {[id: IDEntry]: ModdedConditionData & {innateName?: str
this.activeTarget = pokemon; this.activeTarget = pokemon;
const damage = this.actions.getConfusionDamage(pokemon, 40); const damage = this.actions.getConfusionDamage(pokemon, 40);
if (typeof damage !== 'number') throw new Error("Confusion damage not dealt"); if (typeof damage !== 'number') throw new Error("Confusion damage not dealt");
const activeMove = {id: this.toID('confused'), effectType: 'Move', type: '???'}; const activeMove = { id: this.toID('confused'), effectType: 'Move', type: '???' };
this.damage(damage, pokemon, pokemon, activeMove as ActiveMove); this.damage(damage, pokemon, pokemon, activeMove as ActiveMove);
if (this.effectState.sourceEffect?.id === 'cringedadjoke') { if (this.effectState.sourceEffect?.id === 'cringedadjoke') {
for (const target of this.getAllActive()) { for (const target of this.getAllActive()) {
if (target === pokemon) continue; if (target === pokemon) continue;
if (target.volatiles['cringedadjoke']) { if (target.volatiles['cringedadjoke']) {
this.boost({atk: 1, def: 1}, target); this.boost({ atk: 1, def: 1 }, target);
} }
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,13 @@ export const Rulesets: import('../../../sim/dex-formats').ModdedFormatDataTable
sleepclausemod: { sleepclausemod: {
inherit: true, inherit: true,
onSetStatus(status, target, source) { onSetStatus(status, target, source) {
if (source && source.isAlly(target)) { if (source?.isAlly(target)) {
return; return;
} }
if (status.id === 'slp') { if (status.id === 'slp') {
for (const pokemon of target.side.pokemon) { for (const pokemon of target.side.pokemon) {
if (pokemon.hp && pokemon.status === 'slp') { if (pokemon.hp && pokemon.status === 'slp') {
if (!pokemon.statusState.source || !pokemon.statusState.source.isAlly(pokemon)) { if (!pokemon.statusState.source?.isAlly(pokemon)) {
if (source.hasAbility('ididitagain')) { if (source.hasAbility('ididitagain')) {
this.add('-ability', source, 'I Did It Again'); this.add('-ability', source, 'I Did It Again');
return; return;

View File

@ -1,11 +1,12 @@
import {SSBSet} from "./random-teams"; import type { SSBSet } from "./random-teams";
import {ChosenAction} from '../../../sim/side'; import type { ChosenAction } from '../../../sim/side';
import {FS} from '../../../lib'; import { FS } from '../../../lib';
import {toID} from '../../../sim/dex-data'; import { toID } from '../../../sim/dex-data';
import { type SwitchAction } from "../../../sim/battle-queue";
// Similar to User.usergroups. Cannot import here due to users.ts requiring Chat // Similar to User.usergroups. Cannot import here due to users.ts requiring Chat
// This also acts as a cache, meaning ranks will only update when a hotpatch/restart occurs // This also acts as a cache, meaning ranks will only update when a hotpatch/restart occurs
const usergroups: {[userid: string]: string} = {}; const usergroups: { [userid: string]: string } = {};
const usergroupData = FS('config/usergroups.csv').readIfExistsSync().split('\n'); const usergroupData = FS('config/usergroups.csv').readIfExistsSync().split('\n');
for (const row of usergroupData) { for (const row of usergroupData) {
if (!toID(row)) continue; if (!toID(row)) continue;
@ -15,7 +16,7 @@ for (const row of usergroupData) {
usergroups[toID(cells[0])] = cells[1].trim() || ' '; usergroups[toID(cells[0])] = cells[1].trim() || ' ';
} }
const roomauth: {[roomid: string]: {[userid: string]: string}} = {}; const roomauth: { [roomid: string]: { [userid: string]: string } } = {};
/** /**
* Given a username and room, returns the auth they have in that room. Used for some conditional messages/effects. * Given a username and room, returns the auth they have in that room. Used for some conditional messages/effects.
* Each room is cached on the first call until the process is restarted. * Each room is cached on the first call until the process is restarted.
@ -38,7 +39,7 @@ export function getName(name: string): string {
let group = usergroups[userid] || ' '; let group = usergroups[userid] || ' ';
if (name === 'Artemis') group = '@'; if (name === 'Artemis') group = '@';
if (name === 'Jeopard-E' || name === 'Ice Kyubs') group = '*'; if (name === 'Jeopard-E' || name === 'Ice Kyubs') group = '*';
return Math.floor(Date.now() / 1000) + '|' + group + name; return `${Math.floor(Date.now() / 1000)}|${group}${name}`;
} }
export function enemyStaff(pokemon: Pokemon): string { export function enemyStaff(pokemon: Pokemon): string {
@ -76,7 +77,7 @@ export function changeSet(context: Battle, pokemon: Pokemon, newSet: SSBSet, cha
const oldGender = pokemon.set.gender; const oldGender = pokemon.set.gender;
if ((pokemon.set.gender !== newSet.gender) && !Array.isArray(newSet.gender)) { if ((pokemon.set.gender !== newSet.gender) && !Array.isArray(newSet.gender)) {
pokemon.set.gender = newSet.gender; pokemon.set.gender = newSet.gender;
// @ts-ignore Shut up sharp_claw wanted this // @ts-expect-error Shut up sharp_claw wanted this
pokemon.gender = newSet.gender; pokemon.gender = newSet.gender;
} }
const oldShiny = pokemon.set.shiny; const oldShiny = pokemon.set.shiny;
@ -144,9 +145,8 @@ export function changeMoves(context: Battle, pokemon: Pokemon, newMoves: (string
const moveSlot = { const moveSlot = {
move: move.name, move: move.name,
id: move.id, id: move.id,
// eslint-disable-next-line max-len pp: Math.floor((move.noPPBoosts ? move.pp : move.pp * 8 / 5) * carryOver[slot]),
pp: ((move.noPPBoosts || move.isZ) ? Math.floor(move.pp * carryOver[slot]) : Math.floor((move.pp * (8 / 5)) * carryOver[slot])), maxpp: (move.noPPBoosts ? move.pp : move.pp * 8 / 5),
maxpp: ((move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5),
target: move.target, target: move.target,
disabled: false, disabled: false,
disabledSource: '', disabledSource: '',
@ -170,9 +170,9 @@ export const Scripts: ModdedBattleScriptsData = {
if (!target?.hp) return 0; if (!target?.hp) return 0;
if (!target.isActive) return false; if (!target.isActive) return false;
if (this.gen > 5 && !target.side.foePokemonLeft()) return false; if (this.gen > 5 && !target.side.foePokemonLeft()) return false;
boost = this.runEvent('ChangeBoost', target, source, effect, {...boost}); boost = this.runEvent('ChangeBoost', target, source, effect, { ...boost });
boost = target.getCappedBoost(boost); boost = target.getCappedBoost(boost);
boost = this.runEvent('TryBoost', target, source, effect, {...boost}); boost = this.runEvent('TryBoost', target, source, effect, { ...boost });
let success = null; let success = null;
let boosted = isSecondary; let boosted = isSecondary;
let boostName: BoostID; let boostName: BoostID;
@ -323,7 +323,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.queue.clear(); this.queue.clear();
// Fainting clears accumulated Bide damage // Fainting clears accumulated Bide damage
for (const pokemon of this.getAllActive()) { for (const pokemon of this.getAllActive()) {
if (pokemon.volatiles['bide'] && pokemon.volatiles['bide'].damage) { if (pokemon.volatiles['bide']?.damage) {
pokemon.volatiles['bide'].damage = 0; pokemon.volatiles['bide'].damage = 0;
this.hint("Desync Clause Mod activated!"); this.hint("Desync Clause Mod activated!");
this.hint("In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints."); this.hint("In Gen 1, Bide's accumulated damage is reset to 0 when a Pokemon faints.");
@ -389,7 +389,7 @@ export const Scripts: ModdedBattleScriptsData = {
// pokemon.setAbility(species.abilities['0'], null, true); // pokemon.setAbility(species.abilities['0'], null, true);
// pokemon.baseAbility = pokemon.ability; // pokemon.baseAbility = pokemon.ability;
const behemothMove: {[k: string]: string} = { const behemothMove: { [k: string]: string } = {
'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash', 'Zacian-Crowned': 'behemothblade', 'Zamazenta-Crowned': 'behemothbash',
}; };
const ironHead = pokemon.baseMoves.indexOf('ironhead'); const ironHead = pokemon.baseMoves.indexOf('ironhead');
@ -398,8 +398,8 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.baseMoveSlots[ironHead] = { pokemon.baseMoveSlots[ironHead] = {
move: move.name, move: move.name,
id: move.id, id: move.id,
pp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target, target: move.target,
disabled: false, disabled: false,
disabledSource: '', disabledSource: '',
@ -523,28 +523,23 @@ export const Scripts: ModdedBattleScriptsData = {
this.add('-heal', action.target, action.target.getHealth, '[from] move: Revival Blessing'); this.add('-heal', action.target, action.target.getHealth, '[from] move: Revival Blessing');
action.pokemon.side.removeSlotCondition(action.pokemon, 'revivalblessing'); action.pokemon.side.removeSlotCondition(action.pokemon, 'revivalblessing');
break; break;
// @ts-ignore I'm sorry but it takes a lot // @ts-expect-error I'm sorry but it takes a lot
case 'scapegoat': case 'scapegoat':
// @ts-ignore action = action as SwitchAction;
const percent = (action.target.hp / action.target.baseMaxhp) * 100; const percent = (action.target.hp / action.target.baseMaxhp) * 100;
// @ts-ignore TODO: Client support for custom faint // TODO: Client support for custom faint
action.target.faint(); action.target.faint();
if (percent > 66) { if (percent > 66) {
this.add('message', `Your courage will be greatly rewarded.`); this.add('message', `Your courage will be greatly rewarded.`);
// @ts-ignore this.boost({ atk: 3, spa: 3, spe: 3 }, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat') as any);
this.boost({atk: 3, spa: 3, spe: 3}, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat'));
} else if (percent > 33) { } else if (percent > 33) {
this.add('message', `Your offering was accepted.`); this.add('message', `Your offering was accepted.`);
// @ts-ignore this.boost({ atk: 2, spa: 2, spe: 2 }, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat') as any);
this.boost({atk: 2, spa: 2, spe: 2}, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat'));
} else { } else {
this.add('message', `Coward.`); this.add('message', `Coward.`);
// @ts-ignore this.boost({ atk: 1, spa: 1, spe: 1 }, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat') as any);
this.boost({atk: 1, spa: 1, spe: 1}, action.pokemon, action.pokemon, this.dex.moves.get('scapegoat'));
} }
// @ts-ignore
this.add(`c:|${getName((action.pokemon.illusion || action.pokemon).name)}|Don't worry, if this plan fails we can just blame ${action.target.name}`); this.add(`c:|${getName((action.pokemon.illusion || action.pokemon).name)}|Don't worry, if this plan fails we can just blame ${action.target.name}`);
// @ts-ignore
action.pokemon.side.removeSlotCondition(action.pokemon, 'scapegoat'); action.pokemon.side.removeSlotCondition(action.pokemon, 'scapegoat');
break; break;
case 'runSwitch': case 'runSwitch':
@ -633,8 +628,10 @@ export const Scripts: ModdedBattleScriptsData = {
let reviveSwitch = false; // Used to ignore the fake switch for Revival Blessing let reviveSwitch = false; // Used to ignore the fake switch for Revival Blessing
if (switches[i] && !this.canSwitch(this.sides[i])) { if (switches[i] && !this.canSwitch(this.sides[i])) {
for (const pokemon of this.sides[i].active) { for (const pokemon of this.sides[i].active) {
if (this.sides[i].slotConditions[pokemon.position]['revivalblessing'] || if (
this.sides[i].slotConditions[pokemon.position]['scapegoat']) { this.sides[i].slotConditions[pokemon.position]['revivalblessing'] ||
this.sides[i].slotConditions[pokemon.position]['scapegoat']
) {
reviveSwitch = true; reviveSwitch = true;
continue; continue;
} }
@ -721,7 +718,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (move.spreadHit) { if (move.spreadHit) {
// multi-target modifier (doubles only) // multi-target modifier (doubles only)
const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75); const spreadModifier = move.spreadModifier || (this.battle.gameType === 'freeforall' ? 0.5 : 0.75);
this.battle.debug('Spread modifier: ' + spreadModifier); this.battle.debug(`Spread modifier: ${spreadModifier}`);
baseDamage = this.battle.modify(baseDamage, spreadModifier); baseDamage = this.battle.modify(baseDamage, spreadModifier);
} else if (move.multihitType === 'parentalbond' && move.hit > 1) { } else if (move.multihitType === 'parentalbond' && move.hit > 1) {
// Parental Bond modifier // Parental Bond modifier
@ -906,7 +903,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
this.battle.runEvent('BeforeSwitchIn', pokemon); this.battle.runEvent('BeforeSwitchIn', pokemon);
if (sourceEffect) { if (sourceEffect) {
this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails, '[from] ' + sourceEffect); this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails, `[from] ${sourceEffect}`);
} else { } else {
this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails); this.battle.add(isDrag ? 'drag' : 'switch', pokemon, pokemon.getFullDetails);
} }
@ -919,7 +916,7 @@ export const Scripts: ModdedBattleScriptsData = {
// runSwitch happens immediately so that Mold Breaker can make hazards bypass Clear Body and Levitate // runSwitch happens immediately so that Mold Breaker can make hazards bypass Clear Body and Levitate
this.runSwitch(pokemon); this.runSwitch(pokemon);
} else { } else {
this.battle.queue.insertChoice({choice: 'runSwitch', pokemon}); this.battle.queue.insertChoice({ choice: 'runSwitch', pokemon });
} }
return true; return true;
@ -1004,7 +1001,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (zMoveName) { if (zMoveName) {
const zMove = this.dex.moves.get(zMoveName); const zMove = this.dex.moves.get(zMoveName);
if (!zMove.isZ && zMove.category === 'Status') zMoveName = "Z-" + zMoveName; if (!zMove.isZ && zMove.category === 'Status') zMoveName = "Z-" + zMoveName;
zMoves.push({move: zMoveName, target: zMove.target}); zMoves.push({ move: zMoveName, target: zMove.target });
} else { } else {
zMoves.push(null); zMoves.push(null);
} }
@ -1061,11 +1058,11 @@ export const Scripts: ModdedBattleScriptsData = {
if (accuracy !== true) { if (accuracy !== true) {
let boost = 0; let boost = 0;
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
const boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); const boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
boost = this.battle.clampIntRange(boost - boosts['evasion'], -6, 6); boost = this.battle.clampIntRange(boost - boosts['evasion'], -6, 6);
} }
if (boost > 0) { if (boost > 0) {
@ -1103,7 +1100,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ohko && pokemon.hasItem('blunderpolicy') && pokemon.useItem()) { if (!move.ohko && pokemon.hasItem('blunderpolicy') && pokemon.useItem()) {
this.battle.boost({spe: 2}, pokemon); this.battle.boost({ spe: 2 }, pokemon);
} }
hitResults[i] = false; hitResults[i] = false;
continue; continue;
@ -1202,7 +1199,7 @@ export const Scripts: ModdedBattleScriptsData = {
const oldActiveMove = move; const oldActiveMove = move;
const moveDidSomething = this.useMove(baseMove, pokemon, {target, sourceEffect, zMove, maxMove}); const moveDidSomething = this.useMove(baseMove, pokemon, { target, sourceEffect, zMove, maxMove });
this.battle.lastSuccessfulMoveThisTurn = moveDidSomething ? this.battle.activeMove && this.battle.activeMove.id : null; this.battle.lastSuccessfulMoveThisTurn = moveDidSomething ? this.battle.activeMove && this.battle.activeMove.id : null;
if (this.battle.activeMove) move = this.battle.activeMove; if (this.battle.activeMove) move = this.battle.activeMove;
this.battle.singleEvent('AfterMove', move, null, pokemon, target, move); this.battle.singleEvent('AfterMove', move, null, pokemon, target, move);
@ -1233,7 +1230,7 @@ export const Scripts: ModdedBattleScriptsData = {
targetOf1stDance : targetOf1stDance :
pokemon; pokemon;
const dancersTargetLoc = dancer.getLocOf(dancersTarget); const dancersTargetLoc = dancer.getLocOf(dancersTarget);
this.runMove(move.id, dancer, dancersTargetLoc, {sourceEffect: dancer.getAbility(), externalMove: true}); this.runMove(move.id, dancer, dancersTargetLoc, { sourceEffect: dancer.getAbility(), externalMove: true });
} }
} }
if (noLock && pokemon.volatiles['lockedmove']) delete pokemon.volatiles['lockedmove']; if (noLock && pokemon.volatiles['lockedmove']) delete pokemon.volatiles['lockedmove'];
@ -1278,7 +1275,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (!move.hasBounced) move.pranksterBoosted = this.battle.activeMove.pranksterBoosted; if (!move.hasBounced) move.pranksterBoosted = this.battle.activeMove.pranksterBoosted;
} }
const baseTarget = move.target; const baseTarget = move.target;
let targetRelayVar = {target}; let targetRelayVar = { target };
targetRelayVar = this.battle.runEvent('ModifyTarget', pokemon, target, move, targetRelayVar, true); targetRelayVar = this.battle.runEvent('ModifyTarget', pokemon, target, move, targetRelayVar, true);
if (targetRelayVar.target !== undefined) target = targetRelayVar.target; if (targetRelayVar.target !== undefined) target = targetRelayVar.target;
if (target === undefined) target = this.battle.getRandomTarget(pokemon, move); if (target === undefined) target = this.battle.getRandomTarget(pokemon, move);
@ -1320,7 +1317,7 @@ export const Scripts: ModdedBattleScriptsData = {
attrs = '|[anim]' + movename + attrs; attrs = '|[anim]' + movename + attrs;
movename = 'Z-' + movename; movename = 'Z-' + movename;
} }
this.battle.addMove('move', pokemon, movename, target + attrs); this.battle.addMove('move', pokemon, movename, `${target}${attrs}`);
if (zMove) this.runZPower(move, pokemon); if (zMove) this.runZPower(move, pokemon);
@ -1330,7 +1327,7 @@ export const Scripts: ModdedBattleScriptsData = {
return false; return false;
} }
const {targets, pressureTargets} = pokemon.getMoveTargets(move, target); const { targets, pressureTargets } = pokemon.getMoveTargets(move, target);
if (targets.length) { if (targets.length) {
target = targets[targets.length - 1]; // in case of redirection target = targets[targets.length - 1]; // in case of redirection
} }
@ -1469,7 +1466,7 @@ export const Scripts: ModdedBattleScriptsData = {
const boostTable = [1, 4 / 3, 5 / 3, 2, 7 / 3, 8 / 3, 3]; const boostTable = [1, 4 / 3, 5 / 3, 2, 7 / 3, 8 / 3, 3];
if (accuracy !== true) { if (accuracy !== true) {
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
const boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); const boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy *= boostTable[boost]; accuracy *= boostTable[boost];
@ -1478,7 +1475,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
const boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); const boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
const boost = this.battle.clampIntRange(boosts['evasion'], -6, 6); const boost = this.battle.clampIntRange(boosts['evasion'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy /= boostTable[boost]; accuracy /= boostTable[boost];
@ -1517,7 +1514,7 @@ export const Scripts: ModdedBattleScriptsData = {
// purposes of Counter, Metal Burst, and Mirror Coat. // purposes of Counter, Metal Burst, and Mirror Coat.
damage[i] = md === true || !md ? 0 : md; damage[i] = md === true || !md ? 0 : md;
// Total damage dealt is accumulated for the purposes of recoil (Parental Bond). // Total damage dealt is accumulated for the purposes of recoil (Parental Bond).
move.totalDamage += damage[i] as number; move.totalDamage += damage[i];
} }
if (move.mindBlownRecoil) { if (move.mindBlownRecoil) {
const hpBeforeRecoil = pokemon.hp; const hpBeforeRecoil = pokemon.hp;
@ -1557,7 +1554,7 @@ export const Scripts: ModdedBattleScriptsData = {
} else { } else {
recoilDamage = this.battle.clampIntRange(this.battle.trunc(pokemon.maxhp / 4), 1); recoilDamage = this.battle.clampIntRange(this.battle.trunc(pokemon.maxhp / 4), 1);
} }
this.battle.directDamage(recoilDamage, pokemon, pokemon, {id: 'strugglerecoil'} as Condition); this.battle.directDamage(recoilDamage, pokemon, pokemon, { id: 'strugglerecoil' } as Condition);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) { if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.battle.runEvent('EmergencyExit', pokemon, pokemon); this.battle.runEvent('EmergencyExit', pokemon, pokemon);
} }
@ -1583,7 +1580,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.eachEvent('Update'); this.battle.eachEvent('Update');
this.afterMoveSecondaryEvent(targetsCopy.filter(val => !!val) as Pokemon[], pokemon, move); this.afterMoveSecondaryEvent(targetsCopy.filter(val => !!val), pokemon, move);
if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) { if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) {
for (const [i, d] of damage.entries()) { for (const [i, d] of damage.entries()) {
@ -1611,11 +1608,13 @@ export const Scripts: ModdedBattleScriptsData = {
} else if (!this.battle.singleEvent('TryImmunity', move, {}, target, pokemon, move)) { } else if (!this.battle.singleEvent('TryImmunity', move, {}, target, pokemon, move)) {
this.battle.add('-immune', target); this.battle.add('-immune', target);
hitResults[i] = false; hitResults[i] = false;
} else if (this.battle.gen >= 7 && move.pranksterBoosted && } else if (
this.battle.gen >= 7 && move.pranksterBoosted &&
// Prankster Clone immunity // Prankster Clone immunity
(pokemon.hasAbility('prankster') || pokemon.hasAbility('youkaiofthedusk') || (pokemon.hasAbility('prankster') || pokemon.hasAbility('youkaiofthedusk') ||
pokemon.volatiles['irpachuza'] || pokemon.hasAbility('neverendingfhunt')) && pokemon.volatiles['irpachuza'] || pokemon.hasAbility('neverendingfhunt')) &&
!targets[i].isAlly(pokemon) && !this.dex.getImmunity('prankster', target)) { !targets[i].isAlly(pokemon) && !this.dex.getImmunity('prankster', target)
) {
this.battle.debug('natural prankster immunity'); this.battle.debug('natural prankster immunity');
if (!target.illusion) this.battle.hint("Since gen 7, Dark is immune to Prankster moves."); if (!target.illusion) this.battle.hint("Since gen 7, Dark is immune to Prankster moves.");
this.battle.add('-immune', target); this.battle.add('-immune', target);
@ -1636,8 +1635,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
const move = this.dex.getActiveMove(moveOrMoveName); const move = this.dex.getActiveMove(moveOrMoveName);
let hitResult: boolean | number | null = true; let hitResult: boolean | number | null = true;
let moveData = hitEffect as ActiveMove; const moveData = hitEffect || move;
if (!moveData) moveData = move;
if (!moveData.flags) moveData.flags = {}; if (!moveData.flags) moveData.flags = {};
if (move.target === 'all' && !isSelf) { if (move.target === 'all' && !isSelf) {
hitResult = this.battle.singleEvent('TryHitField', moveData, {}, target || null, pokemon, move); hitResult = this.battle.singleEvent('TryHitField', moveData, {}, target || null, pokemon, move);
@ -1796,7 +1794,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (!target || (target.fainted && !target.isAlly(this)) && this.battle.gameType !== 'freeforall') { if (!target || (target.fainted && !target.isAlly(this)) && this.battle.gameType !== 'freeforall') {
// If a targeted foe faints, the move is retargeted // If a targeted foe faints, the move is retargeted
const possibleTarget = this.battle.getRandomTarget(this, move); const possibleTarget = this.battle.getRandomTarget(this, move);
if (!possibleTarget) return {targets: [], pressureTargets: []}; if (!possibleTarget) return { targets: [], pressureTargets: [] };
target = possibleTarget; target = possibleTarget;
} }
if (this.battle.activePerHalf > 1 && !move.tracksTarget) { if (this.battle.activePerHalf > 1 && !move.tracksTarget) {
@ -1817,7 +1815,7 @@ export const Scripts: ModdedBattleScriptsData = {
targets.push(target); targets.push(target);
} }
if (target.fainted && !move.flags['futuremove']) { if (target.fainted && !move.flags['futuremove']) {
return {targets: [], pressureTargets: []}; return { targets: [], pressureTargets: [] };
} }
if (selectedTarget !== target) { if (selectedTarget !== target) {
this.battle.retargetLastMove(target); this.battle.retargetLastMove(target);
@ -1833,7 +1831,7 @@ export const Scripts: ModdedBattleScriptsData = {
pressureTargets = this.foes(); pressureTargets = this.foes();
} }
return {targets, pressureTargets}; return { targets, pressureTargets };
}, },
}, },
side: { side: {
@ -1854,7 +1852,7 @@ export const Scripts: ModdedBattleScriptsData = {
case 'switch': case 'switch':
case 'instaswitch': case 'instaswitch':
case 'revivalblessing': case 'revivalblessing':
// @ts-ignore custom status falls through // @ts-expect-error custom status falls through
case 'scapegoat': case 'scapegoat':
return `switch ${action.target!.position + 1}`; return `switch ${action.target!.position + 1}`;
case 'team': case 'team':
@ -1938,7 +1936,7 @@ export const Scripts: ModdedBattleScriptsData = {
// Should always subtract, but stop at 0 to prevent errors. // Should always subtract, but stop at 0 to prevent errors.
this.choice.forcedSwitchesLeft = this.battle.clampIntRange(this.choice.forcedSwitchesLeft - 1, 0); this.choice.forcedSwitchesLeft = this.battle.clampIntRange(this.choice.forcedSwitchesLeft - 1, 0);
pokemon.switchFlag = false; pokemon.switchFlag = false;
// @ts-ignore custom request // @ts-expect-error custom request
this.choice.actions.push({ this.choice.actions.push({
choice: 'scapegoat', choice: 'scapegoat',
pokemon, pokemon,
@ -1994,7 +1992,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (!action.side && action.pokemon) action.side = action.pokemon.side; if (!action.side && action.pokemon) action.side = action.pokemon.side;
if (!action.move && action.moveid) action.move = this.battle.dex.getActiveMove(action.moveid); if (!action.move && action.moveid) action.move = this.battle.dex.getActiveMove(action.moveid);
if (!action.order) { if (!action.order) {
const orders: {[choice: string]: number} = { const orders: { [choice: string]: number } = {
team: 1, team: 1,
start: 2, start: 2,
instaswitch: 3, instaswitch: 3,

View File

@ -74,10 +74,10 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
return; return;
} }
this.add('-item', source, yourItem, '[from] ability: Magic Resistance', '[of] ' + target); this.add('-item', source, yourItem, '[from] ability: Magic Resistance', `[of] ${target}`);
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
name: "Magic Resistance", name: "Magic Resistance",
rating: 3.5, rating: 3.5,
shortDesc: "This Pokemon steals foe's item after hitting them, and takes 50% damage from Fire/Ice.", shortDesc: "This Pokemon steals foe's item after hitting them, and takes 50% damage from Fire/Ice.",
@ -93,7 +93,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
stall: { stall: {
onBeforeMove(target, source, move) { onBeforeMove(target, source, move) {
if (move.category === 'Status') { if (move.category === 'Status') {
this.actions.useMove(move, target, {target: source}); this.actions.useMove(move, target, { target: source });
} }
}, },
onFractionalPriority: -0.1, onFractionalPriority: -0.1,
@ -127,7 +127,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
return null; return null;
} }
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
shortDesc: "Effects of Unware and Water Absorb.", shortDesc: "Effects of Unware and Water Absorb.",
name: "Go with the Flow", name: "Go with the Flow",
rating: 4, rating: 4,
@ -160,7 +160,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
onDamagingHit(damage, target, source, move) { onDamagingHit(damage, target, source, move) {
target.addVolatile('charge'); target.addVolatile('charge');
}, },
flags: {breakable: 1}, flags: { breakable: 1 },
shortDesc: "Effects of Fluffy and Electromorphosis.", shortDesc: "Effects of Fluffy and Electromorphosis.",
name: "Fluffy Charger", name: "Fluffy Charger",
rating: 4, rating: 4,

View File

@ -7,7 +7,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Surging Lava", name: "Surging Lava",
pp: 20, pp: 20,
priority: 0, priority: 0,
flags: {snatch: 1, metronome: 1}, flags: { snatch: 1, metronome: 1 },
onPrepareHit(target, source, move) { onPrepareHit(target, source, move) {
this.attrLastMove('[still]'); this.attrLastMove('[still]');
this.add('-anim', source, "Morning Sun", target); this.add('-anim', source, "Morning Sun", target);
@ -19,7 +19,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
secondary: null, secondary: null,
target: "self", target: "self",
type: "Fire", type: "Fire",
zMove: {effect: 'clearnegativeboost'}, zMove: { effect: 'clearnegativeboost' },
contestType: "Cool", contestType: "Cool",
}, },
@ -32,7 +32,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Stealth Rock", name: "Stealth Rock",
pp: 20, pp: 20,
priority: 0, priority: 0,
flags: {reflectable: 1, snatch: 1}, flags: { reflectable: 1, snatch: 1 },
sideCondition: 'stealthrock', sideCondition: 'stealthrock',
condition: { condition: {
// this is a side condition // this is a side condition
@ -42,13 +42,13 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
if (pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('magmaticentrance') || pokemon.hasAbility('hover')) return; if (pokemon.hasItem('heavydutyboots') || pokemon.hasAbility('magmaticentrance') || pokemon.hasAbility('hover')) return;
const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6); const typeMod = this.clampIntRange(pokemon.runEffectiveness(this.dex.getActiveMove('stealthrock')), -6, 6);
this.damage(pokemon.maxhp * Math.pow(2, typeMod) / 8); this.damage(pokemon.maxhp * (2 ** typeMod) / 8);
}, },
}, },
secondary: null, secondary: null,
target: "foeSide", target: "foeSide",
type: "Rock", type: "Rock",
zMove: {boost: {def: 1}}, zMove: { boost: { def: 1 } },
contestType: "Cool", contestType: "Cool",
}, },
spikes: { spikes: {
@ -59,7 +59,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
name: "Spikes", name: "Spikes",
pp: 20, pp: 20,
priority: 0, priority: 0,
flags: {reflectable: 1, nonsky: 1, mustpressure: 1, snatch: 1}, flags: { reflectable: 1, nonsky: 1, mustpressure: 1, snatch: 1 },
sideCondition: 'spikes', sideCondition: 'spikes',
condition: { condition: {
// this is a side condition // this is a side condition
@ -82,7 +82,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
secondary: null, secondary: null,
target: "foeSide", target: "foeSide",
type: "Ground", type: "Ground",
zMove: {boost: {def: 1}}, zMove: { boost: { def: 1 } },
contestType: "Clever", contestType: "Clever",
}, },
}; };

View File

@ -1,99 +1,99 @@
export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = { export const Pokedex: import('../../../sim/dex-species').ModdedSpeciesDataTable = {
gastly: { gastly: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 35, def: 30, spa: 70, spd: 35, spe: 60}, baseStats: { hp: 30, atk: 35, def: 30, spa: 70, spd: 35, spe: 60 },
abilities: {0: "Frisk", 1: "Protean", H: "Neutralizing Gas"}, abilities: { 0: "Frisk", 1: "Protean", H: "Neutralizing Gas" },
}, },
swablu: { swablu: {
inherit: true, inherit: true,
types: ["Fairy", "Flying"], types: ["Fairy", "Flying"],
baseStats: {hp: 45, atk: 45, def: 60, spa: 45, spd: 75, spe: 50}, baseStats: { hp: 45, atk: 45, def: 60, spa: 45, spd: 75, spe: 50 },
abilities: {0: "Natural Cure", 1: "Scrappy", H: "Pixilate"}, abilities: { 0: "Natural Cure", 1: "Scrappy", H: "Pixilate" },
}, },
slugma: { slugma: {
inherit: true, inherit: true,
baseStats: {hp: 30, atk: 40, def: 40, spa: 80, spd: 30, spe: 40}, baseStats: { hp: 30, atk: 40, def: 40, spa: 80, spd: 30, spe: 40 },
abilities: {0: "Flame Body", 1: "Weak Armor", H: "Magmatic Entrance"}, abilities: { 0: "Flame Body", 1: "Weak Armor", H: "Magmatic Entrance" },
}, },
sprigatito: { sprigatito: {
inherit: true, inherit: true,
baseStats: {hp: 40, atk: 65, def: 54, spa: 31, spd: 45, spe: 75}, baseStats: { hp: 40, atk: 65, def: 54, spa: 31, spd: 45, spe: 75 },
abilities: {0: "Overgrow", H: "Entertainer"}, abilities: { 0: "Overgrow", H: "Entertainer" },
}, },
dreepy: { dreepy: {
inherit: true, inherit: true,
baseStats: {hp: 41, atk: 60, def: 40, spa: 42, spd: 40, spe: 82}, baseStats: { hp: 41, atk: 60, def: 40, spa: 42, spd: 40, spe: 82 },
}, },
tepig: { tepig: {
inherit: true, inherit: true,
types: ["Fire", "Ground"], types: ["Fire", "Ground"],
baseStats: {hp: 65, atk: 63, def: 50, spa: 35, spd: 50, spe: 45}, baseStats: { hp: 65, atk: 63, def: 50, spa: 35, spd: 50, spe: 45 },
abilities: {0: "Blaze", H: "Sap Sipper"}, abilities: { 0: "Blaze", H: "Sap Sipper" },
}, },
meowthgalar: { meowthgalar: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 65, def: 65, spa: 40, spd: 40, spe: 40}, baseStats: { hp: 60, atk: 65, def: 65, spa: 40, spd: 40, spe: 40 },
abilities: {0: "Tough Claws", H: "Spiked Fur"}, abilities: { 0: "Tough Claws", H: "Spiked Fur" },
}, },
toxel: { toxel: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 48, def: 55, spa: 64, spd: 55, spe: 40}, baseStats: { hp: 60, atk: 48, def: 55, spa: 64, spd: 55, spe: 40 },
abilities: {0: "Rattled", 1: "Static", H: "Pickpocket"}, abilities: { 0: "Rattled", 1: "Static", H: "Pickpocket" },
}, },
fletchling: { fletchling: {
inherit: true, inherit: true,
types: ["Fire", "Flying"], types: ["Fire", "Flying"],
baseStats: {hp: 45, atk: 50, def: 55, spa: 40, spd: 38, spe: 52}, baseStats: { hp: 45, atk: 50, def: 55, spa: 40, spd: 38, spe: 52 },
}, },
spoink: { spoink: {
inherit: true, inherit: true,
types: ["Psychic", "Rock"], types: ["Psychic", "Rock"],
baseStats: {hp: 60, atk: 25, def: 35, spa: 70, spd: 75, spe: 70}, baseStats: { hp: 60, atk: 25, def: 35, spa: 70, spd: 75, spe: 70 },
abilities: {0: "Magic Resistance", 1: "Own Tempo", H: "Gluttony"}, abilities: { 0: "Magic Resistance", 1: "Own Tempo", H: "Gluttony" },
}, },
cutiefly: { cutiefly: {
inherit: true, inherit: true,
baseStats: {hp: 50, atk: 35, def: 50, spa: 50, spd: 50, spe: 25}, baseStats: { hp: 50, atk: 35, def: 50, spa: 50, spd: 50, spe: 25 },
abilities: {0: "Oblivious", 1: "Shield Dust", H: "Hover"}, abilities: { 0: "Oblivious", 1: "Shield Dust", H: "Hover" },
}, },
shieldon: { shieldon: {
inherit: true, inherit: true,
abilities: {0: "Sturdy", 1: "Battle Armor", H: "Stall"}, abilities: { 0: "Sturdy", 1: "Battle Armor", H: "Stall" },
}, },
wooperpaldea: { wooperpaldea: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 65, def: 65, spa: 25, spd: 45, spe: 35}, baseStats: { hp: 55, atk: 65, def: 65, spa: 25, spd: 45, spe: 35 },
}, },
wooper: { wooper: {
inherit: true, inherit: true,
baseStats: {hp: 55, atk: 65, def: 65, spa: 25, spd: 45, spe: 35}, baseStats: { hp: 55, atk: 65, def: 65, spa: 25, spd: 45, spe: 35 },
abilities: {0: "Damp", 1: "Go with the Flow"}, abilities: { 0: "Damp", 1: "Go with the Flow" },
}, },
corphish: { corphish: {
inherit: true, inherit: true,
types: ["Water", "Dark"], types: ["Water", "Dark"],
baseStats: {hp: 50, atk: 80, def: 65, spa: 50, spd: 35, spe: 46}, baseStats: { hp: 50, atk: 80, def: 65, spa: 50, spd: 35, spe: 46 },
abilities: {0: "Adaptability", 1: "Hyper Cutter", H: "Shell Armor"}, abilities: { 0: "Adaptability", 1: "Hyper Cutter", H: "Shell Armor" },
}, },
jangmoo: { jangmoo: {
inherit: true, inherit: true,
types: ["Dragon", "Fairy"], types: ["Dragon", "Fairy"],
baseStats: {hp: 65, atk: 65, def: 65, spa: 55, spd: 55, spe: 55}, baseStats: { hp: 65, atk: 65, def: 65, spa: 55, spd: 55, spe: 55 },
abilities: {0: "Bulletproof", 1: "Overcoat", H: "Marvel Scale"}, abilities: { 0: "Bulletproof", 1: "Overcoat", H: "Marvel Scale" },
}, },
mareep: { mareep: {
inherit: true, inherit: true,
types: ["Electric", "Grass"], types: ["Electric", "Grass"],
baseStats: {hp: 55, atk: 40, def: 40, spa: 65, spd: 60, spe: 35}, baseStats: { hp: 55, atk: 40, def: 40, spa: 65, spd: 60, spe: 35 },
abilities: {0: "Static", H: "Fluffy Charger"}, abilities: { 0: "Static", H: "Fluffy Charger" },
}, },
cetoddle: { cetoddle: {
inherit: true, inherit: true,
abilities: {0: "Thick Fat", 1: "Sheer Force", H: "Sliding Whale"}, abilities: { 0: "Thick Fat", 1: "Sheer Force", H: "Sliding Whale" },
}, },
eevee: { eevee: {
inherit: true, inherit: true,
baseStats: {hp: 60, atk: 55, def: 50, spa: 45, spd: 65, spe: 55}, baseStats: { hp: 60, atk: 55, def: 50, spa: 45, spd: 65, spe: 55 },
abilities: {0: "Run Away", 1: "Supreme Survivor", H: "Anticipation"}, abilities: { 0: "Run Away", 1: "Supreme Survivor", H: "Anticipation" },
}, },
}; };

View File

@ -60,7 +60,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
inherit: true, inherit: true,
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) { if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-ignore // @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Kyogre-Primal', pokemon); const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Kyogre-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Kyogre') { if (pokemon.m.originalSpecies === 'Kyogre') {
pokemon.formeChange(species, this.effect, true); pokemon.formeChange(species, this.effect, true);
@ -211,7 +211,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
inherit: true, inherit: true,
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) { if (pokemon.isActive && !pokemon.species.isPrimal && !pokemon.transformed) {
// @ts-ignore // @ts-expect-error modded
const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Groudon-Primal', pokemon); const species: Species = this.actions.getMixedSpecies(pokemon.m.originalSpecies, 'Groudon-Primal', pokemon);
if (pokemon.m.originalSpecies === 'Groudon') { if (pokemon.m.originalSpecies === 'Groudon') {
pokemon.formeChange(species, this.effect, true); pokemon.formeChange(species, this.effect, true);

View File

@ -88,7 +88,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (subFormat.onTeamPreview) subFormat.onTeamPreview.call(this); if (subFormat.onTeamPreview) subFormat.onTeamPreview.call(this);
} }
this.queue.addChoice({choice: 'start'}); this.queue.addChoice({ choice: 'start' });
this.midTurn = true; this.midTurn = true;
if (!this.requestState) this.turnLoop(); if (!this.requestState) this.turnLoop();
}, },
@ -121,7 +121,7 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.ability = this.toID(species.abilities['0']); pokemon.ability = this.toID(species.abilities['0']);
pokemon.baseAbility = pokemon.ability; pokemon.baseAbility = pokemon.ability;
const behemothMove: {[k: string]: string} = { const behemothMove: { [k: string]: string } = {
'Rusted Sword': 'behemothblade', 'Rusted Shield': 'behemothbash', 'Rusted Sword': 'behemothblade', 'Rusted Shield': 'behemothbash',
}; };
const ironHead = pokemon.baseMoves.indexOf('ironhead'); const ironHead = pokemon.baseMoves.indexOf('ironhead');
@ -130,8 +130,8 @@ export const Scripts: ModdedBattleScriptsData = {
pokemon.baseMoveSlots[ironHead] = { pokemon.baseMoveSlots[ironHead] = {
move: move.name, move: move.name,
id: move.id, id: move.id,
pp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, pp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
maxpp: (move.noPPBoosts || move.isZ) ? move.pp : move.pp * 8 / 5, maxpp: move.noPPBoosts ? move.pp : move.pp * 8 / 5,
target: move.target, target: move.target,
disabled: false, disabled: false,
disabledSource: '', disabledSource: '',
@ -515,7 +515,7 @@ export const Scripts: ModdedBattleScriptsData = {
mutateOriginalSpecies(speciesOrForme, deltas) { mutateOriginalSpecies(speciesOrForme, deltas) {
if (!deltas) throw new TypeError("Must specify deltas!"); if (!deltas) throw new TypeError("Must specify deltas!");
const species = this.dex.deepClone(this.dex.species.get(speciesOrForme)); const species = this.dex.deepClone(this.dex.species.get(speciesOrForme));
species.abilities = {'0': deltas.ability}; species.abilities = { '0': deltas.ability };
if (deltas.formeType === 'Arceus') { if (deltas.formeType === 'Arceus') {
const secondType = species.types[1]; const secondType = species.types[1];
species.types = [deltas.type]; species.types = [deltas.type];

View File

@ -62,7 +62,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const target = this.sample(possibleTargets); const target = this.sample(possibleTargets);
const ability = target.getAbility(); const ability = target.getAbility();
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {

View File

@ -134,9 +134,9 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
const ally = source.side.active.find(mon => mon && mon !== source && !mon.fainted); const ally = source.side.active.find(mon => mon && mon !== source && !mon.fainted);
const foeAlly = target.side.active.find(mon => mon && mon !== target && !mon.fainted); const foeAlly = target.side.active.find(mon => mon && mon !== target && !mon.fainted);
if (target.isAlly(source)) { if (target.isAlly(source)) {
this.add('-activate', source, 'move: Skill Swap', '', '', '[of] ' + target); this.add('-activate', source, 'move: Skill Swap', '', '', `[of] ${target}`);
} else { } else {
this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, '[of] ' + target); this.add('-activate', source, 'move: Skill Swap', targetAbility, sourceAbility, `[of] ${target}`);
} }
this.singleEvent('End', sourceAbility, source.abilityState, source); this.singleEvent('End', sourceAbility, source.abilityState, source);
if (ally?.m.innate) { if (ally?.m.innate) {
@ -151,8 +151,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} }
source.ability = targetAbility.id; source.ability = targetAbility.id;
source.abilityState = this.initEffectState({id: this.toID(source.ability), target: source}); source.abilityState = this.initEffectState({ id: this.toID(source.ability), target: source });
if (source.m.innate && source.m.innate.endsWith(targetAbility.id)) { if (source.m.innate?.endsWith(targetAbility.id)) {
source.removeVolatile(source.m.innate); source.removeVolatile(source.m.innate);
delete source.m.innate; delete source.m.innate;
} }
@ -166,8 +166,8 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
} }
target.ability = sourceAbility.id; target.ability = sourceAbility.id;
target.abilityState = this.initEffectState({id: this.toID(target.ability), target: target}); target.abilityState = this.initEffectState({ id: this.toID(target.ability), target });
if (target.m.innate && target.m.innate.endsWith(sourceAbility.id)) { if (target.m.innate?.endsWith(sourceAbility.id)) {
target.removeVolatile(target.m.innate); target.removeVolatile(target.m.innate);
delete target.m.innate; delete target.m.innate;
} }

View File

@ -24,9 +24,9 @@ export const Scripts: ModdedBattleScriptsData = {
const volatileState = ally.volatiles[ally.m.innate]; const volatileState = ally.volatiles[ally.m.innate];
if (volatileState) { if (volatileState) {
const volatile = this.dex.conditions.getByID(ally.m.innate as ID); const volatile = this.dex.conditions.getByID(ally.m.innate as ID);
// @ts-ignore - dynamic lookup // @ts-expect-error dynamic lookup
let callback = volatile[callbackName]; let callback = volatile[callbackName];
// @ts-ignore - dynamic lookup // @ts-expect-error dynamic lookup
if (this.gen >= 5 && !volatile.onSwitchIn && !volatile.onAnySwitchIn) { if (this.gen >= 5 && !volatile.onSwitchIn && !volatile.onAnySwitchIn) {
callback = volatile.onStart; callback = volatile.onStart;
} }
@ -54,7 +54,7 @@ export const Scripts: ModdedBattleScriptsData = {
handlers.shift(); handlers.shift();
const effect = handler.effect; const effect = handler.effect;
if ((handler.effectHolder as Pokemon).fainted || (handler.state?.pic as Pokemon)?.fainted) continue; if ((handler.effectHolder as Pokemon).fainted || (handler.state?.pic as Pokemon)?.fainted) continue;
if (eventid === 'Residual' && handler.end && handler.state && handler.state.duration) { if (eventid === 'Residual' && handler.end && handler.state?.duration) {
handler.state.duration--; handler.state.duration--;
if (!handler.state.duration) { if (!handler.state.duration) {
const endCallArgs = handler.endCallArgs || [handler.effectHolder, effect.id]; const endCallArgs = handler.endCallArgs || [handler.effectHolder, effect.id];
@ -88,7 +88,7 @@ export const Scripts: ModdedBattleScriptsData = {
const ally = side.active.find(mon => mon && mon !== pokemon && !mon.fainted); const ally = side.active.find(mon => mon && mon !== pokemon && !mon.fainted);
let allyMoves = ally ? this.dex.deepClone(ally.moveSlots) : []; let allyMoves = ally ? this.dex.deepClone(ally.moveSlots) : [];
if (ally) { if (ally) {
// @ts-ignore // @ts-expect-error modded
allyMoves = allyMoves.filter(move => !pokemon.moves.includes(move.id) && ally.m.curMoves.includes(move.id)); allyMoves = allyMoves.filter(move => !pokemon.moves.includes(move.id) && ally.m.curMoves.includes(move.id));
for (const aMove of allyMoves) { for (const aMove of allyMoves) {
aMove.pp = this.clampIntRange(aMove.maxpp - (pokemon.m.trackPP.get(aMove.id) || 0), 0); aMove.pp = this.clampIntRange(aMove.maxpp - (pokemon.m.trackPP.get(aMove.id) || 0), 0);
@ -290,11 +290,11 @@ export const Scripts: ModdedBattleScriptsData = {
delete ally.m.innate; delete ally.m.innate;
} }
if (this.battle.effect && this.battle.effect.effectType === 'Move' && !isFromFormeChange) { if (this.battle.effect && this.battle.effect.effectType === 'Move' && !isFromFormeChange) {
this.battle.add('-endability', this, this.battle.dex.abilities.get(oldAbility), '[from] move: ' + this.battle.add('-endability', this, this.battle.dex.abilities.get(oldAbility),
this.battle.dex.moves.get(this.battle.effect.id)); `[from] move: ${this.battle.dex.moves.get(this.battle.effect.id)}`);
} }
this.ability = ability.id; this.ability = ability.id;
this.abilityState = this.battle.initEffectState({id: ability.id, target: this}); this.abilityState = this.battle.initEffectState({ id: ability.id, target: this });
if (ability.id && this.battle.gen > 3) { if (ability.id && this.battle.gen > 3) {
this.battle.singleEvent('Start', ability, this.abilityState, this, source); this.battle.singleEvent('Start', ability, this.abilityState, this, source);
if (ally && ally.ability !== this.ability) { if (ally && ally.ability !== this.ability) {
@ -309,7 +309,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
// Entrainment // Entrainment
if (this.m.innate && this.m.innate.endsWith(ability.id)) { if (this.m.innate?.endsWith(ability.id)) {
this.removeVolatile(this.m.innate); this.removeVolatile(this.m.innate);
delete this.m.innate; delete this.m.innate;
} }
@ -331,10 +331,12 @@ export const Scripts: ModdedBattleScriptsData = {
}, },
transformInto(pokemon, effect) { transformInto(pokemon, effect) {
const species = pokemon.species; const species = pokemon.species;
if (pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) || if (
pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) ||
(pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) || (pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) ||
species.name === 'Eternatus-Eternamax' || (['Ogerpon', 'Terapagos'].includes(species.baseSpecies) && species.name === 'Eternatus-Eternamax' || (['Ogerpon', 'Terapagos'].includes(species.baseSpecies) &&
(this.terastallized || pokemon.terastallized))) { (this.terastallized || pokemon.terastallized))
) {
return false; return false;
} }

View File

@ -28,7 +28,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const calc = calculate(this, target, source); const calc = calculate(this, target, source);
if (calc) this.damage(calc * source.baseMaxhp / 4, source, target); if (calc) this.damage(calc * source.baseMaxhp / 4, source, target);
if (target.species.id === 'cramorantgulping') { if (target.species.id === 'cramorantgulping') {
this.boost({def: -1}, source, target, null, true); this.boost({ def: -1 }, source, target, null, true);
} else { } else {
source.trySetStatus('par', target, move); source.trySetStatus('par', target, move);
} }
@ -59,7 +59,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) { function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) {
const move = battle.dex.getActiveMove('tackle'); const move = battle.dex.getActiveMove('tackle');
move.type = source.getTypes()[0]; move.type = source.getTypes()[0];
const typeMod = Math.pow(2, battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6)); const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0; if (!pokemon.runImmunity(move.type)) return 0;
return typeMod; return typeMod;
} }

View File

@ -50,7 +50,7 @@ export const Conditions: import('../../../sim/dex-conditions').ModdedConditionDa
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) { function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) {
const move = battle.dex.getActiveMove('tackle'); const move = battle.dex.getActiveMove('tackle');
move.type = source.getTypes()[0]; move.type = source.getTypes()[0];
const typeMod = Math.pow(2, battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6)); const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0; if (!pokemon.runImmunity(move.type)) return 0;
return typeMod; return typeMod;
} }

View File

@ -62,7 +62,7 @@ export const Items: import('../../../sim/dex-items').ModdedItemDataTable = {
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) { function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon) {
const move = battle.dex.getActiveMove('tackle'); const move = battle.dex.getActiveMove('tackle');
move.type = source.getTypes()[0]; move.type = source.getTypes()[0];
const typeMod = Math.pow(2, battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6)); const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0; if (!pokemon.runImmunity(move.type)) return 0;
return typeMod; return typeMod;
} }

View File

@ -59,7 +59,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
inherit: true, inherit: true,
condition: { condition: {
onStart(pokemon, source) { onStart(pokemon, source) {
this.add('-start', pokemon, 'Curse', '[of] ' + source); this.add('-start', pokemon, 'Curse', `[of] ${source}`);
}, },
onResidualOrder: 12, onResidualOrder: 12,
onResidual(pokemon) { onResidual(pokemon) {
@ -282,10 +282,10 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
onSwitchIn(pokemon) { onSwitchIn(pokemon) {
if (!pokemon.isGrounded()) return; if (!pokemon.isGrounded()) return;
if (pokemon.hasType('Poison')) { if (pokemon.hasType('Poison')) {
this.add('-sideend', pokemon.side, 'move: Toxic Spikes', '[of] ' + pokemon); this.add('-sideend', pokemon.side, 'move: Toxic Spikes', `[of] ${pokemon}`);
pokemon.side.removeSideCondition('toxicspikes'); pokemon.side.removeSideCondition('toxicspikes');
} else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots')) { } else if (pokemon.hasType('Steel') || pokemon.hasItem('heavydutyboots')) {
return; // do nothing
} else if (this.effectState.layers >= 2) { } else if (this.effectState.layers >= 2) {
pokemon.trySetStatus('tox', this.effectState.source); pokemon.trySetStatus('tox', this.effectState.source);
} else { } else {
@ -299,7 +299,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon, moveid = 'tackle') { function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon, moveid = 'tackle') {
const move = battle.dex.getActiveMove(moveid); const move = battle.dex.getActiveMove(moveid);
move.type = source.getTypes()[0]; move.type = source.getTypes()[0];
const typeMod = Math.pow(2, battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6)); const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0; if (!pokemon.runImmunity(move.type)) return 0;
return typeMod; return typeMod;
} }

View File

@ -60,7 +60,7 @@ export const Scripts: ModdedBattleScriptsData = {
const boostTable = [1, 4 / 3, 5 / 3, 2, 7 / 3, 8 / 3, 3]; const boostTable = [1, 4 / 3, 5 / 3, 2, 7 / 3, 8 / 3, 3];
if (accuracy !== true) { if (accuracy !== true) {
if (!move.ignoreAccuracy) { if (!move.ignoreAccuracy) {
const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, {...pokemon.boosts}); const boosts = this.battle.runEvent('ModifyBoost', pokemon, null, null, { ...pokemon.boosts });
const boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6); const boost = this.battle.clampIntRange(boosts['accuracy'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy *= boostTable[boost]; accuracy *= boostTable[boost];
@ -69,7 +69,7 @@ export const Scripts: ModdedBattleScriptsData = {
} }
} }
if (!move.ignoreEvasion) { if (!move.ignoreEvasion) {
const boosts = this.battle.runEvent('ModifyBoost', target, null, null, {...target.boosts}); const boosts = this.battle.runEvent('ModifyBoost', target, null, null, { ...target.boosts });
const boost = this.battle.clampIntRange(boosts['evasion'], -6, 6); const boost = this.battle.clampIntRange(boosts['evasion'], -6, 6);
if (boost > 0) { if (boost > 0) {
accuracy /= boostTable[boost]; accuracy /= boostTable[boost];
@ -108,7 +108,7 @@ export const Scripts: ModdedBattleScriptsData = {
// purposes of Counter, Metal Burst, and Mirror Coat. // purposes of Counter, Metal Burst, and Mirror Coat.
damage[i] = md === true || !md ? 0 : md; damage[i] = md === true || !md ? 0 : md;
// Total damage dealt is accumulated for the purposes of recoil (Parental Bond). // Total damage dealt is accumulated for the purposes of recoil (Parental Bond).
move.totalDamage += damage[i] as number; move.totalDamage += damage[i];
} }
if (move.mindBlownRecoil) { if (move.mindBlownRecoil) {
const hpBeforeRecoil = pokemon.hp; const hpBeforeRecoil = pokemon.hp;
@ -150,7 +150,7 @@ export const Scripts: ModdedBattleScriptsData = {
} else { } else {
recoilDamage = this.battle.clampIntRange(this.battle.trunc(pokemon.maxhp / 4), 1); recoilDamage = this.battle.clampIntRange(this.battle.trunc(pokemon.maxhp / 4), 1);
} }
this.battle.directDamage(recoilDamage, pokemon, pokemon, {id: 'strugglerecoil'} as Condition); this.battle.directDamage(recoilDamage, pokemon, pokemon, { id: 'strugglerecoil' } as Condition);
if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) { if (pokemon.hp <= pokemon.maxhp / 2 && hpBeforeRecoil > pokemon.maxhp / 2) {
this.battle.runEvent('EmergencyExit', pokemon, pokemon); this.battle.runEvent('EmergencyExit', pokemon, pokemon);
} }
@ -176,7 +176,7 @@ export const Scripts: ModdedBattleScriptsData = {
this.battle.eachEvent('Update'); this.battle.eachEvent('Update');
this.afterMoveSecondaryEvent(targetsCopy.filter(val => !!val) as Pokemon[], pokemon, move); this.afterMoveSecondaryEvent(targetsCopy.filter(val => !!val), pokemon, move);
if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) { if (!move.negateSecondary && !(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) {
for (const [i, d] of damage.entries()) { for (const [i, d] of damage.entries()) {
@ -207,7 +207,7 @@ export const Scripts: ModdedBattleScriptsData = {
function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon, moveid = 'tackle') { function calculate(battle: Battle, source: Pokemon, pokemon: Pokemon, moveid = 'tackle') {
const move = battle.dex.getActiveMove(moveid); const move = battle.dex.getActiveMove(moveid);
move.type = source.getTypes()[0]; move.type = source.getTypes()[0];
const typeMod = Math.pow(2, battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6)); const typeMod = 2 ** battle.clampIntRange(pokemon.runEffectiveness(move), -6, 6);
if (!pokemon.runImmunity(move.type)) return 0; if (!pokemon.runImmunity(move.type)) return 0;
return typeMod; return typeMod;
} }

View File

@ -10,7 +10,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) { if (this.checkMoveMakesContact(move, source, target, !source.isAlly(target))) {
const oldAbility = source.setAbility('mummy', target); const oldAbility = source.setAbility('mummy', target);
if (oldAbility) { if (oldAbility) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
} }
} }
} else { } else {
@ -22,13 +22,13 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (abil === source.ability) { if (abil === source.ability) {
const oldAbility = source.setAbility('mummy', target); const oldAbility = source.setAbility('mummy', target);
if (oldAbility) { if (oldAbility) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(oldAbility).name, `[of] ${source}`);
} }
} else { } else {
source.removeVolatile('ability:' + abil); source.removeVolatile('ability:' + abil);
source.addVolatile('ability:mummy', source); source.addVolatile('ability:mummy', source);
if (abil) { if (abil) {
this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(abil).name, '[of] ' + source); this.add('-activate', target, 'ability: Mummy', this.dex.abilities.get(abil).name, `[of] ${source}`);
} }
} }
} }
@ -105,12 +105,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
.filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val)); .filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val));
if (!possibleAbilities.length) return; if (!possibleAbilities.length) return;
const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]); const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]);
this.add('-ability', pokemon, ability, '[from] ability: Power of Alchemy', '[of] ' + ally); this.add('-ability', pokemon, ability, '[from] ability: Power of Alchemy', `[of] ${ally}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:powerofalchemy"); pokemon.removeVolatile("ability:powerofalchemy");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
}, },
}, },
@ -127,12 +127,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
.filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val)); .filter(val => !this.dex.abilities.get(val).flags['noreceiver'] && !additionalBannedAbilities.includes(val));
if (!possibleAbilities.length) return; if (!possibleAbilities.length) return;
const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]); const ability = this.dex.abilities.get(possibleAbilities[this.random(possibleAbilities.length)]);
this.add('-ability', pokemon, ability, '[from] ability: Receiver', '[of] ' + ally); this.add('-ability', pokemon, ability, '[from] ability: Receiver', `[of] ${ally}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:receiver"); pokemon.removeVolatile("ability:receiver");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
}, },
}, },
@ -160,12 +160,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
continue; continue;
} }
const ability = this.dex.abilities.get(this.sample(possibleAbilities)); const ability = this.dex.abilities.get(this.sample(possibleAbilities));
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
if (isAbility) { if (isAbility) {
pokemon.setAbility(ability); pokemon.setAbility(ability);
} else { } else {
pokemon.removeVolatile("ability:trace"); pokemon.removeVolatile("ability:trace");
pokemon.addVolatile("ability:" + ability, pokemon); pokemon.addVolatile(`ability:${ability}`, pokemon);
} }
return; return;
} }
@ -182,9 +182,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
const sourceAbility = source.setAbility('wanderingspirit', target); const sourceAbility = source.setAbility('wanderingspirit', target);
if (!sourceAbility) return; if (!sourceAbility) return;
if (target.isAlly(source)) { if (target.isAlly(source)) {
this.add('-activate', target, 'Skill Swap', '', '', '[of] ' + source); this.add('-activate', target, 'Skill Swap', '', '', `[of] ${source}`);
} else { } else {
this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', '[of] ' + source); this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', `[of] ${source}`);
} }
target.setAbility(sourceAbility); target.setAbility(sourceAbility);
} }
@ -202,9 +202,9 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
source.addVolatile('ability:wanderingspirit', source); source.addVolatile('ability:wanderingspirit', source);
} }
if (target.isAlly(source)) { if (target.isAlly(source)) {
this.add('-activate', target, 'Skill Swap', '', '', '[of] ' + source); this.add('-activate', target, 'Skill Swap', '', '', `[of] ${source}`);
} else { } else {
this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', '[of] ' + source); this.add('-activate', target, 'ability: Wandering Spirit', this.dex.abilities.get(sourceAbility).name, 'Wandering Spirit', `[of] ${source}`);
} }
if (sourceAbility === source.ability) { if (sourceAbility === source.ability) {
target.setAbility(sourceAbility); target.setAbility(sourceAbility);

View File

@ -15,12 +15,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (isAbility) { if (isAbility) {
if (pokemon.setAbility(ability)) { if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
} else { } else {
pokemon.removeVolatile('ability:trace'); pokemon.removeVolatile('ability:trace');
pokemon.addVolatile('ability:' + ability.id, pokemon); pokemon.addVolatile('ability:' + ability.id, pokemon);
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
}, },
}, },

View File

@ -1,6 +1,6 @@
import {PRNG} from '../../../sim/prng'; import { PRNG } from '../../../sim/prng';
import {Pokemon} from '../../../sim/pokemon'; import { Pokemon } from '../../../sim/pokemon';
import {Teams} from '../../../sim/teams'; import { Teams } from '../../../sim/teams';
export const Scripts: ModdedBattleScriptsData = { export const Scripts: ModdedBattleScriptsData = {
start() { start() {
@ -114,7 +114,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (subFormat.onTeamPreview) subFormat.onTeamPreview.call(this); if (subFormat.onTeamPreview) subFormat.onTeamPreview.call(this);
} }
this.queue.addChoice({choice: 'start'}); this.queue.addChoice({ choice: 'start' });
this.midTurn = true; this.midTurn = true;
if (!this.requestState) this.turnLoop(); if (!this.requestState) this.turnLoop();
}, },

View File

@ -66,12 +66,12 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
if (isAbility) { if (isAbility) {
if (pokemon.setAbility(ability)) { if (pokemon.setAbility(ability)) {
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
} else { } else {
pokemon.removeVolatile('ability:trace'); pokemon.removeVolatile('ability:trace');
pokemon.addVolatile('ability:' + ability.id, pokemon); pokemon.addVolatile('ability:' + ability.id, pokemon);
this.add('-ability', pokemon, ability, '[from] ability: Trace', '[of] ' + target); this.add('-ability', pokemon, ability, '[from] ability: Trace', `[of] ${target}`);
} }
}, },
}, },

View File

@ -1,4 +1,4 @@
import {RESTORATIVE_BERRIES} from "../../../sim/pokemon"; import { RESTORATIVE_BERRIES } from "../../../sim/pokemon";
export const Scripts: ModdedBattleScriptsData = { export const Scripts: ModdedBattleScriptsData = {
gen: 9, gen: 9,
@ -30,7 +30,7 @@ export const Scripts: ModdedBattleScriptsData = {
const hasAnyItem = !!this.item || Object.keys(this.volatiles).some(v => v.startsWith('item:')); const hasAnyItem = !!this.item || Object.keys(this.volatiles).some(v => v.startsWith('item:'));
// Best to declare everything early because ally might have a gem that needs proccing // Best to declare everything early because ally might have a gem that needs proccing
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; if (!source && this.battle.event?.target) source = this.battle.event.target;
const item = (sourceEffect?.id.startsWith('item:')) ? sourceEffect as Item : this.getItem(); const item = (sourceEffect?.id.startsWith('item:')) ? sourceEffect as Item : this.getItem();
if ((!this.hp && !item.isGem) || !this.isActive) return false; if ((!this.hp && !item.isGem) || !this.isActive) return false;
if (!hasAnyItem) return false; if (!hasAnyItem) return false;
@ -38,7 +38,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (this.battle.runEvent('UseItem', this, null, null, item)) { if (this.battle.runEvent('UseItem', this, null, null, item)) {
switch (item.id.startsWith('item:') ? item.id.slice(5) : item.id) { switch (item.id.startsWith('item:') ? item.id.slice(5) : item.id) {
case 'redcard': case 'redcard':
this.battle.add('-enditem', this, item.fullname, '[of] ' + source); this.battle.add('-enditem', this, item.fullname, `[of] ${source}`);
break; break;
default: default:
if (item.isGem) { if (item.isGem) {
@ -71,7 +71,7 @@ export const Scripts: ModdedBattleScriptsData = {
eatItem(force, source, sourceEffect) { eatItem(force, source, sourceEffect) {
const hasAnyItem = !!this.item || Object.keys(this.volatiles).some(v => v.startsWith('item:')); const hasAnyItem = !!this.item || Object.keys(this.volatiles).some(v => v.startsWith('item:'));
if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect; if (!sourceEffect && this.battle.effect) sourceEffect = this.battle.effect;
if (!source && this.battle.event && this.battle.event.target) source = this.battle.event.target; if (!source && this.battle.event?.target) source = this.battle.event.target;
const item = (sourceEffect?.id.startsWith('item:')) ? sourceEffect as Item : this.getItem(); const item = (sourceEffect?.id.startsWith('item:')) ? sourceEffect as Item : this.getItem();
if (!hasAnyItem) return false; if (!hasAnyItem) return false;
if ((!this.hp && this.battle.toID(item.name) !== 'jabocaberry' && this.battle.toID(item.name) !== 'rowapberry') || if ((!this.hp && this.battle.toID(item.name) !== 'jabocaberry' && this.battle.toID(item.name) !== 'rowapberry') ||
@ -129,13 +129,13 @@ export const Scripts: ModdedBattleScriptsData = {
const oldItem = this.getItem(); const oldItem = this.getItem();
const oldItemState = this.itemState; const oldItemState = this.itemState;
this.item = item.id; this.item = item.id;
this.itemState = this.battle.initEffectState({id: item.id, target: this}); this.itemState = this.battle.initEffectState({ id: item.id, target: this });
if (oldItem.exists) this.battle.singleEvent('End', oldItem, oldItemState, this); if (oldItem.exists) this.battle.singleEvent('End', oldItem, oldItemState, this);
if (item.id) { if (item.id) {
this.battle.singleEvent('Start', item, this.itemState, this, source, effect); this.battle.singleEvent('Start', item, this.itemState, this, source, effect);
for (const ally of this.side.pokemon) { for (const ally of this.side.pokemon) {
if (!ally.m.sharedItemsUsed) continue; if (!ally.m.sharedItemsUsed) continue;
ally.m.sharedItemsUsed = ally.m.sharedItemsUsed.filter((i: ID) => i !== (item as Item).id); ally.m.sharedItemsUsed = ally.m.sharedItemsUsed.filter((i: ID) => i !== item.id);
} }
} }
return true; return true;

View File

@ -98,7 +98,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
inherit: true, inherit: true,
onDamagingHit(damage, target, source, move) { onDamagingHit(damage, target, source, move) {
if (['Dark', 'Grass', 'Psychic'].includes(move.type)) { if (['Dark', 'Grass', 'Psychic'].includes(move.type)) {
this.boost({spe: 1}); this.boost({ spe: 1 });
} }
}, },
}, },

View File

@ -84,7 +84,7 @@ export const Moves: import('../../../sim/dex-moves').ModdedMoveDataTable = {
if (target.hasType('Normal')) return 0; if (target.hasType('Normal')) return 0;
} }
}, },
ignoreImmunity: {'Fighting': true}, ignoreImmunity: { 'Fighting': true },
}, },
trickortreat: { trickortreat: {
inherit: true, inherit: true,

View File

@ -80,7 +80,7 @@ export const Scripts: ModdedBattleScriptsData = {
if (overriddenBerries.includes(id)) { if (overriddenBerries.includes(id)) {
// these berries were already modded in ./items.ts // these berries were already modded in ./items.ts
// so they have inherited references to the base dex naturalGift objects and need new ones // so they have inherited references to the base dex naturalGift objects and need new ones
this.modData('Items', id).naturalGift = {...item.naturalGift, type}; this.modData('Items', id).naturalGift = { ...item.naturalGift, type };
} else { } else {
// these were unmodded, so modData makes deep clones of them which makes this a safe write // these were unmodded, so modData makes deep clones of them which makes this a safe write
this.modData('Items', id).naturalGift.type = type; this.modData('Items', id).naturalGift.type = type;

View File

@ -209,10 +209,12 @@ export const Scripts: ModdedBattleScriptsData = {
}, },
transformInto(pokemon, effect) { transformInto(pokemon, effect) {
const species = pokemon.species; const species = pokemon.species;
if (pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) || if (
pokemon.fainted || this.illusion || pokemon.illusion || (pokemon.volatiles['substitute'] && this.battle.gen >= 5) ||
(pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) || (pokemon.transformed && this.battle.gen >= 2) || (this.transformed && this.battle.gen >= 5) ||
species.name === 'Eternatus-Eternamax' || (['Ogerpon', 'Terapagos'].includes(species.baseSpecies) && species.name === 'Eternatus-Eternamax' || (['Ogerpon', 'Terapagos'].includes(species.baseSpecies) &&
(this.terastallized || pokemon.terastallized)) || this.terastallized === 'Stellar') { (this.terastallized || pokemon.terastallized)) || this.terastallized === 'Stellar'
) {
return false; return false;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import RandomGen2Teams from '../gen2/teams'; import RandomGen2Teams from '../gen2/teams';
import {Utils} from '../../../lib'; import { Utils } from '../../../lib';
interface HackmonsCupEntry { interface HackmonsCupEntry {
types: string[]; types: string[];
@ -15,7 +15,7 @@ interface Gen1RandomBattleSpecies {
} }
export class RandomGen1Teams extends RandomGen2Teams { export class RandomGen1Teams extends RandomGen2Teams {
randomData: {[species: IDEntry]: Gen1RandomBattleSpecies} = require('./data.json'); randomData: { [species: IDEntry]: Gen1RandomBattleSpecies } = require('./data.json');
// Challenge Cup or CC teams are basically fully random teams. // Challenge Cup or CC teams are basically fully random teams.
randomCCTeam() { randomCCTeam() {
@ -77,7 +77,7 @@ export class RandomGen1Teams extends RandomGen2Teams {
ivs["spe"] *= 2; ivs["spe"] *= 2;
// Maxed EVs. // Maxed EVs.
const evs = {hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255}; const evs = { hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255 };
// Four random unique moves from movepool. don't worry about "attacking" or "viable". // Four random unique moves from movepool. don't worry about "attacking" or "viable".
// Since Gens 1 and 2 learnsets are shared, we need to weed out Gen 2 moves. // Since Gens 1 and 2 learnsets are shared, we need to weed out Gen 2 moves.
@ -89,8 +89,8 @@ export class RandomGen1Teams extends RandomGen2Teams {
moves: this.multipleSamplesNoReplace(pool, 4), moves: this.multipleSamplesNoReplace(pool, 4),
gender: false, gender: false,
ability: 'No Ability', ability: 'No Ability',
evs: evs, evs,
ivs: ivs, ivs,
item: '', item: '',
level, level,
happiness: 0, happiness: 0,
@ -120,8 +120,8 @@ export class RandomGen1Teams extends RandomGen2Teams {
const rejectedButNotInvalidPool: string[] = []; const rejectedButNotInvalidPool: string[] = [];
// Now let's store what we are getting. // Now let's store what we are getting.
const typeCount: {[k: string]: number} = {}; const typeCount: { [k: string]: number } = {};
const weaknessCount: {[k: string]: number} = {Electric: 0, Psychic: 0, Water: 0, Ice: 0, Ground: 0, Fire: 0}; const weaknessCount: { [k: string]: number } = { Electric: 0, Psychic: 0, Water: 0, Ice: 0, Ground: 0, Fire: 0 };
let numMaxLevelPokemon = 0; let numMaxLevelPokemon = 0;
const pokemonPool = Object.keys(this.getPokemonPool(type, pokemon, isMonotype, Object.keys(this.randomData))[0]); const pokemonPool = Object.keys(this.getPokemonPool(type, pokemon, isMonotype, Object.keys(this.randomData))[0]);
@ -257,8 +257,8 @@ export class RandomGen1Teams extends RandomGen2Teams {
const level = this.getLevel(species); const level = this.getLevel(species);
const evs = {hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255}; const evs = { hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255 };
const ivs = {hp: 30, atk: 30, def: 30, spa: 30, spd: 30, spe: 30}; const ivs = { hp: 30, atk: 30, def: 30, spa: 30, spd: 30, spe: 30 };
// Should be able to use Substitute four times from full HP without fainting // Should be able to use Substitute four times from full HP without fainting
if (moves.has('substitute')) { if (moves.has('substitute')) {
@ -308,7 +308,7 @@ export class RandomGen1Teams extends RandomGen2Teams {
const typesPool = ['Bird', ...this.dex.types.names()]; const typesPool = ['Bird', ...this.dex.types.names()];
const randomN = this.randomNPokemon(this.maxTeamSize); const randomN = this.randomNPokemon(this.maxTeamSize);
const hackmonsCup: {[k: string]: HackmonsCupEntry} = {}; const hackmonsCup: { [k: string]: HackmonsCupEntry } = {};
for (const forme of randomN) { for (const forme of randomN) {
// Choose forme // Choose forme

View File

@ -1,6 +1,6 @@
import RandomGen3Teams from '../gen3/teams'; import RandomGen3Teams from '../gen3/teams';
import {PRNG, PRNGSeed} from '../../../sim/prng'; import type { PRNG, PRNGSeed } from '../../../sim/prng';
import type {MoveCounter} from '../gen8/teams'; import type { MoveCounter } from '../gen8/teams';
// Moves that restore HP: // Moves that restore HP:
const RECOVERY_MOVES = [ const RECOVERY_MOVES = [
@ -26,7 +26,7 @@ const MOVE_PAIRS = [
]; ];
export class RandomGen2Teams extends RandomGen3Teams { export class RandomGen2Teams extends RandomGen3Teams {
randomSets: {[species: IDEntry]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json'); randomSets: { [species: IDEntry]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) { constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng); super(format, prng);
@ -312,7 +312,7 @@ export class RandomGen2Teams extends RandomGen3Teams {
if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker'].includes(role)) { if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker'].includes(role)) {
if (counter.damagingMoves.size === 1) { if (counter.damagingMoves.size === 1) {
// Find the type of the current attacking move // Find the type of the current attacking move
const currentAttackType = counter.damagingMoves.values().next().value.type; const currentAttackType = counter.damagingMoves.values().next().value!.type;
// Choose an attacking move that is of different type to the current single attack // Choose an attacking move that is of different type to the current single attack
const coverageMoves = []; const coverageMoves = [];
for (const moveid of movePool) { for (const moveid of movePool) {
@ -397,8 +397,8 @@ export class RandomGen2Teams extends RandomGen3Teams {
const ability = ''; const ability = '';
let item = undefined; let item = undefined;
const evs = {hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255}; const evs = { hp: 255, atk: 255, def: 255, spa: 255, spd: 255, spe: 255 };
const ivs = {hp: 30, atk: 30, def: 30, spa: 30, spd: 30, spe: 30}; const ivs = { hp: 30, atk: 30, def: 30, spa: 30, spd: 30, spe: 30 };
const types = species.types; const types = species.types;
const abilities: string[] = []; const abilities: string[] = [];
@ -426,22 +426,22 @@ export class RandomGen2Teams extends RandomGen3Teams {
if (move.startsWith('hiddenpower')) hpType = move.substr(11); if (move.startsWith('hiddenpower')) hpType = move.substr(11);
} }
if (!hpType) throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`); if (!hpType) throw new Error(`hasHiddenPower is true, but no Hidden Power move was found.`);
const hpIVs: {[k: string]: Partial<typeof ivs>} = { const hpIVs: { [k: string]: Partial<typeof ivs> } = {
dragon: {def: 28}, dragon: { def: 28 },
ice: {def: 26}, ice: { def: 26 },
psychic: {def: 24}, psychic: { def: 24 },
electric: {atk: 28}, electric: { atk: 28 },
grass: {atk: 28, def: 28}, grass: { atk: 28, def: 28 },
water: {atk: 28, def: 26}, water: { atk: 28, def: 26 },
fire: {atk: 28, def: 24}, fire: { atk: 28, def: 24 },
steel: {atk: 26}, steel: { atk: 26 },
ghost: {atk: 26, def: 28}, ghost: { atk: 26, def: 28 },
bug: {atk: 26, def: 26}, bug: { atk: 26, def: 26 },
rock: {atk: 26, def: 24}, rock: { atk: 26, def: 24 },
ground: {atk: 24}, ground: { atk: 24 },
poison: {atk: 24, def: 28}, poison: { atk: 24, def: 28 },
flying: {atk: 24, def: 26}, flying: { atk: 24, def: 26 },
fighting: {atk: 24, def: 24}, fighting: { atk: 24, def: 24 },
}; };
let iv: StatID; let iv: StatID;
for (iv in hpIVs[hpType]) { for (iv in hpIVs[hpType]) {

View File

@ -1,6 +1,6 @@
import RandomGen4Teams from '../gen4/teams'; import RandomGen4Teams from '../gen4/teams';
import {PRNG, PRNGSeed} from '../../../sim/prng'; import type { PRNG, PRNGSeed } from '../../../sim/prng';
import type {MoveCounter} from '../gen8/teams'; import type { MoveCounter } from '../gen8/teams';
// Moves that restore HP: // Moves that restore HP:
const RECOVERY_MOVES = [ const RECOVERY_MOVES = [
@ -30,7 +30,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
battleHasDitto: boolean; battleHasDitto: boolean;
battleHasWobbuffet: boolean; battleHasWobbuffet: boolean;
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json'); randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) { constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng); super(format, prng);
@ -349,7 +349,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker', 'Berry Sweeper'].includes(role)) { if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker', 'Berry Sweeper'].includes(role)) {
if (counter.damagingMoves.size === 1) { if (counter.damagingMoves.size === 1) {
// Find the type of the current attacking move // Find the type of the current attacking move
const currentAttackType = counter.damagingMoves.values().next().value.type; const currentAttackType = counter.damagingMoves.values().next().value!.type;
// Choose an attacking move that is of different type to the current single attack // Choose an attacking move that is of different type to the current single attack
const coverageMoves = []; const coverageMoves = [];
for (const moveid of movePool) { for (const moveid of movePool) {
@ -410,7 +410,6 @@ export class RandomGen3Teams extends RandomGen4Teams {
return false; return false;
} }
getAbility( getAbility(
types: Set<string>, types: Set<string>,
moves: Set<string>, moves: Set<string>,
@ -540,8 +539,8 @@ export class RandomGen3Teams extends RandomGen4Teams {
let ability = ''; let ability = '';
let item = undefined; let item = undefined;
const evs = {hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85}; const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
const ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
const types = species.types; const types = species.types;
const abilities = set.abilities!; const abilities = set.abilities!;
@ -648,10 +647,10 @@ export class RandomGen3Teams extends RandomGen4Teams {
const typePool = this.dex.types.names(); const typePool = this.dex.types.names();
const type = this.forceMonotype || this.sample(typePool); const type = this.forceMonotype || this.sample(typePool);
const baseFormes: {[k: string]: number} = {}; const baseFormes: { [k: string]: number } = {};
const typeCount: {[k: string]: number} = {}; const typeCount: { [k: string]: number } = {};
const typeWeaknesses: {[k: string]: number} = {}; const typeWeaknesses: { [k: string]: number } = {};
const typeDoubleWeaknesses: {[k: string]: number} = {}; const typeDoubleWeaknesses: { [k: string]: number } = {};
const teamDetails: RandomTeamsTypes.TeamDetails = {}; const teamDetails: RandomTeamsTypes.TeamDetails = {};
let numMaxLevelPokemon = 0; let numMaxLevelPokemon = 0;
@ -701,7 +700,7 @@ export class RandomGen3Teams extends RandomGen4Teams {
} }
if (this.dex.getEffectiveness(typeName, species) > 1) { if (this.dex.getEffectiveness(typeName, species) > 1) {
if (!typeDoubleWeaknesses[typeName]) typeDoubleWeaknesses[typeName] = 0; if (!typeDoubleWeaknesses[typeName]) typeDoubleWeaknesses[typeName] = 0;
if (typeDoubleWeaknesses[typeName] >= 1 * limitFactor) { if (typeDoubleWeaknesses[typeName] >= limitFactor) {
skip = true; skip = true;
break; break;
} }

View File

@ -1,6 +1,6 @@
import RandomGen5Teams from '../gen5/teams'; import RandomGen5Teams from '../gen5/teams';
import {PRNG} from '../../../sim'; import type { PRNG } from '../../../sim';
import type {MoveCounter} from '../gen8/teams'; import type { MoveCounter } from '../gen8/teams';
// Moves that restore HP: // Moves that restore HP:
const RECOVERY_MOVES = [ const RECOVERY_MOVES = [
@ -42,7 +42,7 @@ const PRIORITY_POKEMON = [
]; ];
export class RandomGen4Teams extends RandomGen5Teams { export class RandomGen4Teams extends RandomGen5Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json'); randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) { constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng); super(format, prng);
@ -427,7 +427,7 @@ export class RandomGen4Teams extends RandomGen5Teams {
if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker'].includes(role)) { if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker'].includes(role)) {
if (counter.damagingMoves.size === 1) { if (counter.damagingMoves.size === 1) {
// Find the type of the current attacking move // Find the type of the current attacking move
const currentAttackType = counter.damagingMoves.values().next().value.type; const currentAttackType = counter.damagingMoves.values().next().value!.type;
// Choose an attacking move that is of different type to the current single attack // Choose an attacking move that is of different type to the current single attack
const coverageMoves = []; const coverageMoves = [];
for (const moveid of movePool) { for (const moveid of movePool) {
@ -490,7 +490,6 @@ export class RandomGen4Teams extends RandomGen5Teams {
return false; return false;
} }
getAbility( getAbility(
types: Set<string>, types: Set<string>,
moves: Set<string>, moves: Set<string>,
@ -677,8 +676,8 @@ export class RandomGen4Teams extends RandomGen5Teams {
let ability = ''; let ability = '';
let item = undefined; let item = undefined;
const evs = {hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85}; const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
const ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
const types = species.types; const types = species.types;
const abilities = set.abilities!; const abilities = set.abilities!;

View File

@ -1,7 +1,7 @@
import RandomGen6Teams from '../gen6/teams'; import RandomGen6Teams from '../gen6/teams';
import {PRNG} from '../../../sim'; import type { PRNG } from '../../../sim';
import {MoveCounter} from '../gen8/teams'; import type { MoveCounter } from '../gen8/teams';
import {toID} from '../../../sim/dex'; import { toID } from '../../../sim/dex';
// Moves that restore HP: // Moves that restore HP:
const RECOVERY_MOVES = [ const RECOVERY_MOVES = [
@ -51,7 +51,7 @@ const PRIORITY_POKEMON = [
]; ];
export class RandomGen5Teams extends RandomGen6Teams { export class RandomGen5Teams extends RandomGen6Teams {
randomSets: {[species: string]: RandomTeamsTypes.RandomSpeciesData} = require('./sets.json'); randomSets: { [species: string]: RandomTeamsTypes.RandomSpeciesData } = require('./sets.json');
constructor(format: string | Format, prng: PRNG | PRNGSeed | null) { constructor(format: string | Format, prng: PRNG | PRNGSeed | null) {
super(format, prng); super(format, prng);
@ -454,7 +454,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker'].includes(role)) { if (['Fast Attacker', 'Setup Sweeper', 'Bulky Attacker', 'Wallbreaker'].includes(role)) {
if (counter.damagingMoves.size === 1) { if (counter.damagingMoves.size === 1) {
// Find the type of the current attacking move // Find the type of the current attacking move
const currentAttackType = counter.damagingMoves.values().next().value.type; const currentAttackType = counter.damagingMoves.values().next().value!.type;
// Choose an attacking move that is of different type to the current single attack // Choose an attacking move that is of different type to the current single attack
const coverageMoves = []; const coverageMoves = [];
for (const moveid of movePool) { for (const moveid of movePool) {
@ -521,7 +521,6 @@ export class RandomGen5Teams extends RandomGen6Teams {
return false; return false;
} }
getAbility( getAbility(
types: Set<string>, types: Set<string>,
moves: Set<string>, moves: Set<string>,
@ -730,8 +729,8 @@ export class RandomGen5Teams extends RandomGen6Teams {
let ability = ''; let ability = '';
let item = undefined; let item = undefined;
const evs = {hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85}; const evs = { hp: 85, atk: 85, def: 85, spa: 85, spd: 85, spe: 85 };
const ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31}; const ivs = { hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31 };
const types = species.types; const types = species.types;
const abilities = set.abilities!; const abilities = set.abilities!;
@ -853,10 +852,10 @@ export class RandomGen5Teams extends RandomGen6Teams {
const typePool = this.dex.types.names(); const typePool = this.dex.types.names();
const type = this.forceMonotype || this.sample(typePool); const type = this.forceMonotype || this.sample(typePool);
const baseFormes: {[k: string]: number} = {}; const baseFormes: { [k: string]: number } = {};
const typeCount: {[k: string]: number} = {}; const typeCount: { [k: string]: number } = {};
const typeWeaknesses: {[k: string]: number} = {}; const typeWeaknesses: { [k: string]: number } = {};
const typeDoubleWeaknesses: {[k: string]: number} = {}; const typeDoubleWeaknesses: { [k: string]: number } = {};
const teamDetails: RandomTeamsTypes.TeamDetails = {}; const teamDetails: RandomTeamsTypes.TeamDetails = {};
let numMaxLevelPokemon = 0; let numMaxLevelPokemon = 0;
@ -905,7 +904,7 @@ export class RandomGen5Teams extends RandomGen6Teams {
} }
if (this.dex.getEffectiveness(typeName, species) > 1) { if (this.dex.getEffectiveness(typeName, species) > 1) {
if (!typeDoubleWeaknesses[typeName]) typeDoubleWeaknesses[typeName] = 0; if (!typeDoubleWeaknesses[typeName]) typeDoubleWeaknesses[typeName] = 0;
if (typeDoubleWeaknesses[typeName] >= 1 * limitFactor) { if (typeDoubleWeaknesses[typeName] >= limitFactor) {
skip = true; skip = true;
break; break;
} }

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