Giter Club home page Giter Club logo

showdex's Introduction

showdex-icon

showdex

 Current v1.2.3   Install on Chrome · Opera · Firefox · Safari   Discuss on Smogon · Discord

Showdex is a browser extension for Pokémon Showdown that brings the Damage Calculator you know & love right into your battle! Automatically syncs all Pokémon & field conditions as you play, so you can spend less time shitting brix & more time hitting kicks.


Officially supported on Chrome (+ any native Chromium browser, like Edge & Brave), Opera & Firefox.

  ༼ つ ಥ_ಥ ༽つ  Safari  ...?

Despite Apple requiring us to shell out $100/year for the Apple Developer Program just to distribute a singular free extension on the App Store, thanks to the many generous contributions from the awesome Showdown community over the years, we're now planning on officially supporting Showdex on iOS & macOS in the future!

In the meantime, Enhanced Tooltips for Showdown (Source on GitHub), currently available on the App Store, bundles Showdex along with the Enhanced Tooltips & Randbats Tooltip extensions. Note that the bundled Showdex is not officially supported, so questions regarding Showdex running on Safari should be directed towards the maintainer of the aforementioned App Store app, Christian Brüggemann (Smogon · GitHub).

Would you like to know more?


Navigation

 Planned Features   Known Bugs 
 Suggest a Feature   Report a Bug   Contribute/Translate 


Developer Zone

Warning
You are about to get in the zone, the developer zone.
If you do not wish to get in the zone, the developer zone, please visit the Smogon Forums post instead.


Developer SparkNotes™

Note
This section is a work-in-progress.

This extension is written in TypeScript, which is essentially JavaScript on crack, using:

 How It's Made™ 

Note
More information coming soon!

uhhhhhhhhh



Requirements

Warning Due to the removal of --experimental-specifier-resolution=node starting in node v19, v18 is required (i.e., ^18.0.0) to build this project. Use something like nvm to install v18 (nvm install lts/hydrogen) alongside your current node installation.

  • node LTS Hydrogen v18
  • yarn Classic v1.22.0+
  • bash (Windows WSL, macOS, or Linux)

①  Setup

Note
If your browser is already configured for extension development, you can skip this part. If you're building for 'standalone', don't skip this part.

When building this as an extension (i.e., the BUILD_TARGET env is either 'chrome' or 'firefox'), you'll need to apply some slight tweaks to your browser in order to directly install extensions from your local disk.

 Google Chrome
  1. Navigate to the Chrome extensions page (chrome://extensions).
  2. Enable Developer mode in the top-right corner.
  3. Verify that the Load unpacked option is available.

 Mozilla Firefox
  1. Navigate to the Advanced Preferences page (about:config).
  2. Search for the preference xpinstall.signatures.required.
  3. Set the preference's value to false (typically true by default).
  4. Navigate to the Debugging page (about:debugging).
  5. Select This Firefox on the left-hand panel.
  6. Verify that the Temporary Extensions section and the Load Temporary Add-on... option are available.

 Mozilla Firefox for Android

Note
More information coming soon!
Though instructions aren't currently provided, this project supports developing on Firefox for Android Nightly.

For now, see these instructions from Mozilla for setting up your Android device and Firefox for Android Nightly installation for extension development.


When building in 'standalone' mode (for embedding Showdex into your own pokemon-showdown-client), you'll need to mimic what the content script does in your client's index.html file.

 Standalone

Note
Standalone builds remove all Web Extension API dependencies so that Showdex can be directly embedded into your pokemon-showdown-client. This includes the manifest.json, which will be omitted completely during the build process. That being said, you'll be manually doing what the content script would do to the index.html file in the following steps.

Warning
This is considered to be an experimental feature. In other words, it's untested beyond the build process as I don't have my own pokemon-showdown-client to run this off of (surprising, I know), but in theory, it should work! Essentially Showdex only uses the Web Extension APIs to inject the transpiled main script & some Google Fonts into the client's index.html, but other than that, everything else is good 'ol JavaScript.

  1. Figure out where you'll be storing the built files by setting the STANDALONE_RESOURCE_PROTOCOL & STANDALONE_RESOURCE_PREFIX environment variables accordingly.
  • By default, the protocol is blank & prefix is 'showdex', which means Showdex will expect its resources to be available in a /showdex path relative to your client's root domain.
  • For instance, when it requests 'file.jpg', it will look for /showdex/file.jpg.
  • See the comments for these environment variables for more information.
  1. In your client's index.html, add the following Google Fonts used by Showdex anywhere inside the <head>:
<!-- the "preconnect" one below is optional, but recommended for optimizing loading -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Work+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&display=swap">
  1. Also in the index.html, based on where Showdex will be stored in the first step (e.g., /showdex, by default), add the following inside the <body> after all the js/* & data/* scripts:
<!-- example of what your index.html may contain inside the <body> -->
<script src="data/search-index.js" onerror="loadRemoteData(this.src)"></script>
<script src="data/teambuilder-tables.js" onerror="loadRemoteData(this.src)"></script>
<script src="js/battle-dex-search.js"></script>
<script src="js/search.js"></script>
<script src="data/aliases.js" async="async" onerror="loadRemoteData(this.src)"></script>

<!-- plop this in AFTER all of the <script> tags !! -->
<!-- async, async="true", or async="async" ??? doesn't matter (all truthy), so the choice is yours c: -->
<script src="/showdex/main.js" async="true"></script>


②  Installation

Note
These are instructions for installing the development environment for building Showdex locally from source.

  1. cd into your favorite directory.
  2. git clone [email protected]:doshidak/showdex.git
  3. cd showdex
  4. yarn
 Post-Installation Scripts 

Each time you run yarn (including yarn add & yarn remove), the postinstall script will automatically run afterwards, which itself runs the following:

This project is configured for ES Modules (ESM) (as opposed to ye olde CommonJS [CJS]), while also making use of cz-customizable, which requires cz-customizable-ghooks, which requires ghooks.

Node v18 doesn't allow you to run extensionless files (such as .git/hooks/commit-msg), which ghooks poops out, so patch-ghooks adds .js at the end of each pooped out file (e.g., .git/hooks/commit-msg.js).

Otherwise, Node will complain about running an extensionless file and critically fail when you attempt to make a git commit.

  • yarn patch-package

This runs patch-package, which reads from the patches directory and applies the diff to the corresponding package in your node_modules.

Patch for @babel/plugin-transform-typescript adds a custom option called yeetEmptyImportElisions, which, during the transpilation process from TS/TSX to JS, will completely remove the import statement if there aren't any imported modules left after removing all type modules (e.g., import { type SomeType } from 'some-package'; becomes import {} from 'some-package';, which will be removed if the aforementioned custom option is enabled; however, in the case of import { type SomeType, SomeModule } from 'some-package';, this import won't be removed as SomeModule remains after removing the type's, i.e., import { SomeModule } from 'some-package';). This is to prevent side-effects resulting from simply importing the file, even when no exported module in that file is actually being imported. Path for @babel/preset-typescript simply passes yeetEmptyImportElisions to @babel/plugin-transform-typescript. (Also, the terrible name for the custom option was intentional to indicate that this was a custom option I put in LOL.)

Patch for @smogon/calc incorporates all the changes up to the ad544eb commit. Additionally, some direct modifications such as disabling internal boosts applied to some abilities & moves like Pixiliate & Acrobatics, for instance, since they're handled by the Calcdex, as well as implementing offensive & defensive stat overrides in older gens. Finally, a custom modification interface called ShowdexCalcMods was added to the exported calculate() function, which allows the Calcdex to tap into specific parts of the damage calculation algorithm to implement Beat Up.

Patch for simplebar adds typings for the untyped scrollableNode and contentNode options, which is actually used inside SimpleBar class, but not typed. These two options are required if the internal <div>s are provided outside of SimpleBar (by default, it will create its own <div>s inside the provided container element). For use with React, we must provide these internal <div>s ourselves, as React doesn't like it when a vanilla JS library adds and removes DOM elements that React isn't aware of.




③  Development

Note
yarn dev is an alias of yarn dev:chrome.

Warning
While developing in 'standalone' mode is possible, I don't recommend it as you'll need to manually move the built files to your webserver every time (& they can pile up between hot-reloads!). Skip this step if you're intending on just embedding a production build of Showdex into your Showdown client.

  1. cd showdex
  2. yarn dev:chrome or yarn dev:firefox or yarn dev:standalone (not recommended!)

Warning
Although this project makes use of TypeScript & ESLint, they are only used suggestively. In other words, your code will still compile even if you have errors!

Built contents will be dumped into a build directory in the project root (will be created if it doesn't exist).

 Google Chrome
  1. Navigate to chrome://extensions.
  2. Select Load unpacked.
  3. Point to the chrome sub-directory in build.
  4. Verify the extension appears in the list.
  5. Navigate to Pokémon Showdown.
  6. Play or spectate a battle.

 Mozilla Firefox
  1. Navigate to about:debugging.
  2. Select Load Temporary Add-on.
  3. Point to the showdex-...-dev.firefox.xpi in build.
  4. Verify the extension appears under Temporary Extensions.
  5. Navigate to Pokémon Showdown.
  6. Play or spectate a battle.

 Mozilla Firefox for Android

Note
More information coming soon!
Though instructions aren't currently provided, this project supports developing on Firefox for Android Nightly.

For now, see these instructions from Mozilla for running the extension on your Android's Firefox for Android Nightly installation.



 "Hot" Reloading 

Warning
Hot-reloading is a bit of a mess right now since it requires you to reload the extension and refresh Pokémon Showdown. Will figure out a better system in the future.

While yarn dev:chrome or yarn dev:firefox is running, Webpack will trigger a re-compilation of the bundle when files are changed in the src directory.

  • For Chrome, you'll need to select the reload icon button in the Chrome extensions page (chrome://extensions). Once reloaded, refresh Pokémon Showdown to see your changes.
  • For Firefox, you'll need to Reload the extension in the Debugging page (about:debugging). Once reloaded, refresh Pokémon Showdown to see your changes.

 Environment Variables 

Note
More information coming soon!

uhhhhhh for now, check the .env



④  Building

Note
yarn build is an alias of yarn build:chrome && yarn build:firefox.

  1. cd showdex
  2. yarn build:chrome or yarn build:firefox or yarn build:standalone
 Standalone
  1. Create the directory in your webserver that will house the built Showdex bundle & assets.
  • This should be created relative to where your Showdown client's index.html is, which should be in the root of your webserver.
  • By default, STANDALONE_RESOURCE_PREFIX is 'showdex', so this entails creating a directory called 'showdex', which should be accessible via https://showdown.example.com/showdex.
  1. Move all of the built files in the dist/standalone directory to the one you just created on your webserver.
  • Make sure you don't move the standalone directory itself, but rather, all of its contents.
  • Alternatively, you can just rename standalone to showdex & move that directory to your webserver.
  • In other words, make sure the main.js bundle is accessible via https://showdown.example.com/showdex/main.js.
  • If it's only accessible via https://showdown.example.com/showdex/standalone/main.js, then you did it wrong! (That is unless you set the STANDALONE_RESOURCE_PREFIX to 'showdex/standalone'.)
  1. Start your webserver & you should hopefully see Showdex!


Warning
As mentioned in the Development section, TypeScript & ESLint are configured to be suggestive, so your code will still compile even if you have errors!

Built contents will be dumped into a dist directory in the project root (will be created if it doesn't exist).

There will be an un-zipped directory named after the BUILD_TARGET env (i.e., chrome, firefox or standalone) containing all the bundled files, as well as:

  • For Chrome, a packaged extension under showdex-...chrome.zip in dist, and
  • For Firefox, a packaged extension under showdex-...firefox.xpi in dist.
 What's the HTML file? 

Builds for each target come with their very own bundle size pie chart, showing you exactly which modules in the bundle are too thicc. Particularly useful for finding modules to chunk, especially since AMO enforces a 5 MB size limit per file.

  • Bundle size analysis is written to showdex-...[BUILD_TARGET].html in dist.

Pro-Tip: Don't want to wait the extra 30 seconds for the analysis during builds? You can run the build:fast script instead, e.g., yarn build:fast, yarn build:chrome:fast, etc. Note that the term "fast" used in the aforementioned scripts doesn't imply a more optimal build process as it's the same process minus the analysis & ironically takes longer to type the extra characters to run this build mode.



Contributing

(ノ◕ヮ◕)ノ* :・゚✧  Issues & PRs (Pull Requests) are very welcome!  ✧゚・: *ヽ(◕ヮ◕ヽ)


Issues

Found a bug? · Got a cool idea? · Have suggestions? · Hate these questions & demand answers?

Contributor Covenant

Thanks for your help in making Showdex better for everyone!

I'm not a stickler for how these should be formatted; just make sure you provide enough info for me to work off of. If you're having trouble running Showdex, please make sure you first try turning off your other extensions before opening an issue. This will help me narrow down the problem (e.g., your ad-blocker, productivity enforcer &/or distraction minimizer could potentially block Showdex from downloading sets!).

If possible, including the following would be immensely helpful!

  • Device (e.g., Custom PC, MacBook Pro 14" 2023, eMachines eTower 400i, Samsung Smart Fridge, etc.)
  • OS & Version (e.g., Windows 11, macOS Sonoma 14.1, Ubuntu 22.04.3 LTS, Android 12, etc.)
  • Browser (e.g., Chrome, Firefox, Opera, Netscape Navigator, etc.)
  • Showdex Version (e.g., v1.2.3)
  • Format, if applicable (e.g., Gen 9 VGC 2024 Reg F Bo3)
  • Replay, if applicable

If you would like to be credited for your contribution, please also include your username on Smogon Forums or Pokémon Showdown. Otherwise, your GitHub username will be used, unless you don't want to be credited.

 Create a GitHub Issue 

No GitHub? No problem!

We're also listening for feedback & bug reports on our Showdex thread on Smogon Forums.

 Post on Smogon Forums 

Not on Smogon Forums? All good!

We also created a Discord community with channels where you can report bugs, request features & get help.

 Join Our Discord 

No Discord? Still, no problem!

Feel free to contact me directly via email.

 Slide Into My Inbox 

PRs

Fixed a bug? · Added something cool? · A translation, perchance?

Commitizen friendly

Not a stickler with these either, but at the very least, please:

  • Fork this repo & commit changes to your fork,
  • Style your code according to the ESLint rules,
  • Create a PR from your fork to this repo, and
  • Provide a brief description of your changes in your PR.

Although this project makes use of Commitizen, you don't need to format your commit messages this way. Use whatever you're comfortable with!

Additionally, I don't make use of any fancy automations like CI (Continuous Integration), so each PR will be manually reviewed. Your patience is greatly appreciated!

 Fork Me on GitHub 

Credits

big thank to:


Supporters

big ・゚✧  sparkly thank  ✧゚・ to these fine individuals for their generous support!

Supreme Overlords

 ・゚✧  Dastardlydwarf  ✧゚・   ・゚✧  Ah Ok Got It  ✧゚・   ・゚✧  Swift Mochi  ✧゚・ 
 ・゚✧  Zzodz  ✧゚・ 

Pop Bombers

 ・゚✧  benzyne  ✧゚・ 

Blazikens

 ・゚✧  GabrielPBC  ✧゚・   ・゚✧  BruhMomentMaker  ✧゚・   ・゚✧  TheNexyr  ✧゚・ 
 ・゚✧  Christopher Y  ✧゚・   ・゚✧  PokePastry  ✧゚・   ・゚✧  Kristen G  ✧゚・ 
 ・゚✧  Michael K  ✧゚・   ・゚✧  Wan L  ✧゚・ 

  ༼ つ ͡° ͜ʖ ͡° ༽つ

 ・゚✧  CPL593H  ✧゚・   ・゚✧  Angie L  ✧゚・   ・゚✧  Fubwubs  ✧゚・ 
 ・゚✧  Timothy B  ✧゚・   ・゚✧  PastGenOUFan  ✧゚・   ・゚✧  Luc H  ✧゚・ 
 ・゚✧  Snacky98  ✧゚・   ・゚✧  joshtheking7  ✧゚・   ・゚✧  Michael L  ✧゚・ 
 ・゚✧  Bongphan  ✧゚・   ・゚✧  Pulse_kS  ✧゚・   ・゚✧  Thilo P  ✧゚・ 
 ・゚✧  GenOne  ✧゚・   ・゚✧  Jacek L  ✧゚・   ・゚✧  Lunarvania  ✧゚・ 
 ・゚✧  Leman T  ✧゚・   ・゚✧  Sunny B  ✧゚・   ・゚✧  Peter T  ✧゚・ 
 ・゚✧  Sam P  ✧゚・   ・゚✧  PokePastry  ✧゚・   ・゚✧  DoubleCaret  ✧゚・ 
 ・゚✧  JesskyKhemically  ✧゚・   ・゚✧  Plague von Karma  ✧゚・   ・゚✧  MrMimikry  ✧゚・ 
 ・゚✧  momalaharris  ✧゚・   ・゚✧  FR1E5  ✧゚・   ・゚✧  Tanuj C  ✧゚・ 
 ・゚✧  GoldenGottaGo  ✧゚・ 

  (づ ̄ ³ ̄)づ


Contributors

another big thank to these fine people for helping with development!

SpiffyTheSpaceman malaow3 · GitHub Cureja · GitHub

now that Showdex went mr worldwide, big thank to these fine people for helping with translations!

Sykless · Français Betcheg · Français

also big thank to this fine person for providing us with dank bundled sets!

nerd-of-now · NCP VGC

...and finally, big thank to these fine people who helped improve Showdex!

105C 85percent A_Wild_Noob_Appeared! AhmedA1559
aim alchemistake Alhen AndViet
Baloor Bice BlackCapCoder brokenmotor
Catri cbruegg · GitHub Celestia ChrisPBacon
Clastia Cloyster Chowder coral fan CPL593H
cynicproject DarkPhoenix911 dex Ducky
dyrana Ehmcee Elitemagikarp · GitHub Fitah_
Furret4ssb IHatePasswords Iodyne ITR
jmynes ketchuppainting Kibo kirito_1707
Lazosful Legend-Recalls lighthouse64 MachJacob
madamadam-c Mandibuladel5555 Maxouille · GitHub mdragon13
Mia · GitHub MoltenGluten mpique mnittsch
Nails orangelego21 paolode99 _Pea_
pokeblade101 PokeChess Pulse_kS Runoisch
ry4242 Sabelette SeaSoil Shiox
Shock3600 · GitHub sh0shin ShrikeNW Singiamtel · GitHub
Sorrica Surgent James TheDebatingOne ThornxRose
ThrohKing TJ Timboberino TrainerX493
Tree69420 · GitHub Turtlek zooki2006 zuils · GitHub

  \ (•◡•) /

showdex's People

Contributors

betcheg avatar cureja avatar doshidak avatar malaow3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

showdex's Issues

show possible damage amounts for LC/NFE Pokémon

Requested by: Nails

In LC (Little Cup) formats (and probably any format that uses NFE [Not Fully Evolved] Pokémon), Pokémon don't have much HP, so the damage percentages aren't very helpful.

incorrect Psyshock/Psystrike damage again rip

Also affects Psystrike.

Since in v1.0.3, the passed-in Generation object is now fully supplied by the global Dex object available in Showdown, which is missing some key properties, most notably overrideDefensiveStat, which is responsible for making sure Psyshock and Psystrike hits the defending Pokémon's DEF, not SPD.

Note
This SmogonMove is based off of the latest efa6fe7 commit on @smogon/calc, not its v0.6.0 release on npm, which does not include the overrideDefensiveStat, but rather defensiveCategory. The current v0.6.0 release is known to not properly account for Psyshock, hence why this project includes a patch for @smogon/calc.

import { Move as SmogonMove } from '@smogon/calc';

const move = new SmogonMove(8, 'Psyshock');

SmogonMove {
  ability: undefined,
  bp: 80,
  breaksProtect: false,
  category: 'Special',
  drain: undefined,
  flags: {},
  gen: Generation { num: 8, ... },
  hasCrashDamage: false,
  hits: 1,
  ignoreDefensive: false,
  isCrit: false,
  isMax: false,
  isZ: false,
  item: undefined,
  mindBlownRecoil: false,
  name: 'Psyshock',
  originalName: 'Psyshock',
  overrideDefensivePokemon: undefined,
  overrideDefensiveStat: 'def',
  overrideOffensivePokemon: undefined,
  overrideOffensiveStat: undefined,
  overrides: undefined,
  priority: 0,
  recoil: undefined,
  secondaries: undefined,
  species: undefined,
  struggleRecoil: false,
  target: 'any',
  timesUsed: 1,
  timesUsedWithMetronome: undefined,
  type: 'Psychic',
  useMax: undefined,
  useZ: undefined,
}
Dex.forGen(8).moves.get('Psyshock');

Showdown.Move {
  accuracy: 100,
  basePower: 80,
  category: 'Special',
  critRatio: 1,
  desc: 'Deals damage to the target based on its Defense instead of Special Defense.',
  effectType: 'Move',
  exists: true,
  flags: {
    protect: 1,
    mirror: 1,
  },
  gen: 5,
  hasCrashDamage: false,
  heal: null,
  id: 'psyshock',
  isMax: false,
  isNonstandard: null,
  isZ: '',
  maxMove: {
    basePower: 130,
  },
  multihit: null,
  name: 'Psyshock',
  noPPBoosts: false,
  noSketch: false,
  num: 473,
  ohko: null,
  pp: 10,
  pressureTarget: 'normal',
  priority: 0,
  recoil: null,
  secondaries: null,
  shortDesc: 'Damages target based on Defense, not Sp. Def.',
  target: 'normal',
  type: 'Psychic',
  zMove: {
    basePower: 160,
  },
}

Using the global Dex object results in the following SmogonMove:

SmogonMove {
  ability: null,
  bp: 80,
  breaksProtect: false,
  category: 'Special',
  drain: undefined,
  flags: {
    protect: 1,
    mirror: 1,
  },
  gen: Showdown.Dex { gen: 8, modid: 'gen8', ... },
  hasCrashDamage: false,
  hits: 1,
  ignoreDefensive: false,
  isCrit: false,
  isMax: false,
  isZ: false,
  item: undefined,
  mindBlownRecoil: false,
  name: 'Psyshock',
  originalName: 'Psyshock',
  overrideDefensivePokemon: undefined,
  overrideDefensiveStat: undefined,
  overrideOffensivePokemon: undefined,
  overrideOffensiveStat: undefined,
  overrides: undefined,
  priority: 0,
  recoil: 0,
  secondaries: null,
  species: undefined,
  struggleRecoil: false,
  target: 'normal',
  timesUsed: 1,
  timesUsedWithMetronome: undefined,
  type: 'Psychic',
  useMax: false,
  useZ: false,
}

Since @smogon/calc includes its own Generation data in its own data directory, the fix is to supply these missing properties from @smogon/calc's internal data to the data already supplied by Showdown's global Dex object.

Additionally, unlike @pkmn/dex, passing an invalid name for the constructor parameter of SmogonMove won't return undefined, but rather, an instantiated SmogonMove with invalid properties:

// 'Psyshock' is purposefully mistyped here for demonstration purposes
const move = new SmogonMove(8, 'Psyshck');

SmogonMove {
  ability: undefined,
  bp: undefined,
  breaksProtect: false,
  category: 'Status',
  drain: undefined,
  flags: undefined,
  gen: Generation { num: 8, ... },
  hasCrashDamage: false,
  hits: 1,
  ignoreDefensive: false,
  isCrit: false,
  isMax: false,
  isZ: false,
  item: undefined,
  mindBlownRecoil: false,
  name: 'Psyshck',
  originalName: 'Psyshck',
  overrideDefensivePokemon: undefined,
  overrideDefensiveStat: undefined,
  overrideOffensivePokemon: undefined,
  overrideOffensiveStat: undefined,
  overrides: undefined,
  priority: 0,
  recoil: undefined,
  secondaries: undefined,
  struggleRecoil: false,
  target: 'any',
  timesUsed: 1,
  timesUsedWithMetronome: undefined,
  type: undefined,
  useMax: undefined,
  useZ: undefined,
}

Thankfully, Photon Geyser is still working properly, using the corresponding defensive stat (either DEF or SPD) of the defending Pokémon determined by the higher attacking stat (either ATK or SPA) of the attacking Pokémon.

show item icon for mega-evolved Pokémon in Hackmon formats

Requested by: TrainerX493

Since in Hackmons, you can start with mega-evolved Pokémon, such as Swampert-Mega, and give them an item that's not their mega-evo item, we should still show the item icon.

Additionally, this might be a bug since we don't pass an item to the Pokemon class constructor of @smogon/calc when we detect the Pokémon in its mega forme.

refresh prompt always appears after opening a Calcdex

Still appears even after "closing" (actually hiding) the Calcdex tab. Doesn't matter if only one or many Calcdexes are open since the refresh prompt will appear when any room's requestLeave() returns false, which for Calcdexes, it does.

Not a big deal, but can get annoying for sure, especially if you're developing and refreshing the page constantly.

Wandering Spirit ability causes affected Pokémon's ability to show "???"

Caused by the abilities dropdown not including the Wandering Spirit ability in the list, which in legal-locked formats, wouldn't be there.

Bug was found in a gen8randombattle with a Runerigus.

showdex-wandering-spirit-00

showdex-wandering-spirit-01

Note that in this particular battle, the Runerigus faints on the same turn it obtains the Gluttony ability from the Linoone, so in the battle object, Runerigus still has its ability set to Wandering Spirit for some reason. (May have changed mid-turn, but reverted back once fainted before the next sync tick.)

port the extension to Firefox

Requested by:

Mozilla offers a pretty cool tool called extensiontest.com, which determines extension compatibility with Firefox from the generated CRX file.

Based on just uploading the CRX that was provided to the Chrome Web Store, seems that it's compatible as-is:

Image

According to the report, this just needs some minor tweaking for the extension ID in the manifest.json:

{
  "compat": [],
  "errors": [
    {
      "message": "\"/manifest_version\" must be <= 2",
      "description": "Your JSON file could not be parsed.",
      "locations": [
        {}
      ]
    },
    {
      "message": "The extension ID is required in Manifest Version 3 and above.",
      "description": "See https://mzl.la/3PLZYdo for more information.",
      "locations": [
        {
          "file": "manifest.json"
        }
      ]
    },
    {
      "message": "File is too large to parse.",
      "description": "This file is not binary and is too large to parse. Files larger than 4MB will not be parsed. Consider moving large lists of data out of JavaScript files and into JSON files, or splitting very large files into smaller ones.",
      "locations": [
        {
          "file": "main.js"
        }
      ]
    }
  ],
  "warnings": [
    {
      "message": "\"runtime.onMessageExternal\" can cause issues when loaded temporarily",
      "description": "This API can cause issues when loaded temporarily using about:debugging in Firefox unless you specify applications|browser_specific_settings > gecko > id in the manifest. Please see: https://mzl.la/2hizK4a for more.",
      "locations": [
        {
          "file": "background.js",
          "line": 1
        }
      ]
    }
  ]
}

setting EVs of Dexited Pokémon w/ no set crashes the Calcdex

Reported by:

Setting SPA/SPD EVs of dexited Pokémon without a set crashes the Calcdex in Gen 8 National Dex formats.

As per the follow-up by Runoisch and MachJacob, the following Pokémon are known to crash:

  • Gligar
  • Dewgong
  • Ursaring
  • Smeargle
  • Ambipom
  • Ariados
  • Venomoth
  • Ampharos (possibly mega forme too)
  • Donphan

The following Pokémon are unaffected:

  • Pyroar
  • Muk-Alola (base forme may be affected)
  • Meloetta
  • Zebstrika
  • Servine
  • Staraptor
  • Camerupt-Mega (base forme may be affected)
  • Beedrill-Mega (base forme may be affected)

BDSP formats crash Calcdex

any BDSP format will crash the Calcdex.

seems that the following error is spat out in the console as it crashes:

TypeError: Cannot read properties of undefined (reading 'hp')

basically means that the Pokemon class from @smogon/calc fails to obtain the baseStats for the passed-in speciesForme, since baseStats.hp (where baseStats is undefined) throws this error.

Showdown/browser lags after a couple games

Reported by:

Showdown will start to lag after playing or spectating a couple games. This can occasionally lead to the browser itself crashing if the user's host system does not have enough system resources.

Most likely culprit is the thousands of downloaded sets (potentially across multiple gens and formats) in Redux via RTK Query, but more so the way I'm accessing them in usePresets().

First optimization to try is passing a filter function to the RTK Query hooks in usePresets(), so that it doesn't return ALL of the sets for EVERY Pokémon, which the massive array gets memoized for each Calcdex.

Firefox users get to dual-wield scrollbars

Typo exists in the styling that hides the scrollbars in Firefox, which causes both the system and custom scrollbars to overlay on top of each other.

showdex-dual-scrollbars

Worse on Windows cause the default system scrollbar is still there.

Whoopsie :o

Calcdex theme doesn't apply until end of turn

Update (2022/09/12)
Just thought of a solution to this problem, outlined below.

Note
This also applies to the Hellodex as well, as it includes both light and dark styling.

Best way I thought of to fix this is to store the colorScheme state in Redux instead of the ColorSchemeProvider (via React.Context). There's no clean way to dispatch an update to React once the color scheme is updated, but since we're using Redux, we can simply hook into the client function that updates the color scheme (and makes it available via Dex.prefs()) and dispatch the new value to Redux. (We're able to dispatch to the Redux state via Vanilla JS, despite using react-redux.) This will cause all existing React instances that are hooked into the Redux state to update with the updated color scheme.

Since most components are using the useColorScheme() hook to read the value, we can accomplish a similar functionality to useColorScheme() through Redux, so refactoring should be pretty straightforward (i.e., just need to update the import path of useColorScheme() with no other changes in logic required).

Mr-Mime Galar crashes the extention

If the lead mon of either teams is Mr-Mime G, or they have it in team preview the extention immidiately crashes. If you have in the back and switch it in/click on its icon to check calcs for it it also crashes. When it crashes it goes blank and shows nothing. I have checked it in AG and gen 8 randbats, don't know if it happens anywhere else but I would assume so. (This app is really cool and I wanted to thank you for making it :))

Gen 1 and 2 stats are wrong

Gen 1 and 2 pokemon stats have 252 evs in every stat, the calc does not have that and adding more evs just crashes it for some reason

EDIT: Also, gen 1 and 2 calcs stats with dvs (0-15) and doesn't multiply the base by 2 in the stat formula

add reopen Calcdex buttons in Hellodex

Requested by: Clastia

Show all the Calcdexes in Redux in the Hellodex and allow users to reopen a Calcdex or unload it completely from Redux.

  • This is possible since closing the Calcdex tab doesn't clear it from Redux.
    • This means some slowdowns can occur for lower-end machines when many Calcdexes have been opened in a single client session.
    • Once this is implemented, no need to unload the Calcdex from Redux when the tab is closed.
    • Could be a future setting to automatically unload when the tab is closed though.

set shows as "None" after Pokémon mega-evolves in gen7randombattle

There's a separate set for mega Pokémon in the pkmn API (gen7randombattle.json). When the Pokémon is not-mega'd yet, the non-mega set is loaded in (and set as the Pokémon's preset).

After the Pokémon mega-evolves, the mega set is loaded in, but since the Pokémon's preset is still set to the non-mega set, the dropdown shows "None". However, the user can still manually select the "Randoms" set, which is the mega set.

Just gotta update the preset when the Pokémon's speciesForme changes and the Pokémon's current preset ID no longer exists in the list of sets.

Calc cannot handle multiple battles

When multiple battles are started, the calc will get confused, possibly treating it as the same battle. Can result in one of your pokemon getting repeated in the calc, which is especially an issue since you can't manually change the Pokemon (known for Chrome)

closing a Calcdex with the Teambuilder open moves the Teambuilder to the right panel

If you have a single Calcdex tab and the Teambuilder open (with no other tabs, including a ChatRoom or BattlesRoom), the Teambuilder will move to the right panel once the Calcdex tab is closed.

This is caused by the overwritten close tab handler for Calcdex tabs, which causes the Calcdex to visually close, but is actually hidden in order to preserve the state (this was the easiest and quickest way for me to implement re-opening Calcdex tabs before pushing out v1.0.1).

In that close tab handler, I forgot to check if the room we're refocusing into is a side room by reading the room's isSideRoom property. The Teambuilder tab is not a side room, so its isSideRoom property would be false. Filtering would remove the Teambuilder from the list of focusable side rooms, preventing it from opening on the right panel.

(There is logic already in place to hide the right panel if there are no more focusable side rooms. Clicking on the "+" tab would show the hidden right panel again.)

In other words, this should be a straightforward fix.

Hidden Power Damage Wrong

Not sure the exact scenario that causes this, but hidden power is often calculated incorrectly. An example is hidden power bug on hariyama saying it will OHKO max defensive celebi when this is in fact not the case. (Chrome)
image

burned status (BRN) may not be correctly accounted for in the calculations

in the screenshot below, the Crustle has +2 ATK from Shell Smash, but -2 ATK from the BRN.

I had to manually set the ATK boost stage to 0 (as indicated by the blue-colored value) in order to obtain the correct damage range for X-Scissor.

Image

additionally, not sure how guessServerSpread() obtained the spread for Darmanitan-Galar. since this was randoms, the Hardy nature is prioritized first when guessing, but ended up on Quiet.

boost stages doubled in calculations for some stat-boosting abilities

Reported by: Nails

Stat-boosting abilities like Intrepid Sword (typically on Zacian-Crowned) and Download (typically on Genesect-*) will have the boosted stat automatically applied by the calculator, despite not specifying any boosts for that stat.

For example, Intrepid Sword will boost the ATK by 1 stage (only visible in the result description), without having to actually specify +1 for ATK:

calc-ps-auto-boost

However, the Showdown client will also report +1 for the boosted stat, which the Calcdex will feed into the damage calculator, resulting in +2, i.e., double-boostage.

unallocated EVs warning in Randoms

In v1.0.3, a feature was added that turns the EVs label in the Pokémon's stats table cyan if there are unallocated EVs. However, in Randoms, all EVs are set to 84, which is 4 less than the maximum legal EVs (508), as defined by process.env.CALCDEX_POKEMON_MAX_LEGAL_EVS.

create settings panel

General

Option Type Default
Color scheme 'showdown' | 'light' | 'dark' 'showdown'
Developer mode boolean __DEV__

Hellodex

Option Type Default
Open when Showdown opens boolean true

Calcdex

Option Type Default Requestor
Open when battle starts 'playing' | 'spectating' | 'both' | 'never' 'both' dex
Close when battle ends boolean false --
Destroy when closed boolean false --

Players

Option Type Default
Auto-select to active Pokémon (per side + auth) boolean true (all sides)
Auth player location 'top' | 'bottom' | 'auto' 'top'

Pokémon

Option Dependency Type Default Requestor
Nicknames -- boolean false --
Reverse icon/name functionality -- boolean false (icon opens Smogon page/name switches formes) --
Always show all abilities/items/moves -- boolean false --
Download Smogon sets -- boolean true --
Download Showdown Usage -- boolean true --
Prioritize Showdown Usage set Download Showdown Usage is true boolean true --
Include Teambuilder sets -- boolean true --
Teambuilder export of opponent's team when battle ends -- boolean false --
Auto-set revealed moves (per side) -- boolean false (all sides) --
Show IVs/EVs (per side + auth) -- boolean true (all sides) 85percent

Calculations

Option Dependency Type Default Requestor
NHKO colors -- [1hko: string, 2hko: string, 3hko: string, 4hko: string, after: string] ['#4CAF50', '#FF9800', '#FF9800', '#F44336', '#F44336'] camdawgboi
NHKO labels -- [1hko: string, 2hko: string, 3hko: string, 4hko: string] ['1HKO', '2HKO', '3HKO', '4HKO'] camdawgboi
Move tooltip -- boolean true --
Matchup tooltip -- boolean true Nails
Prettify matchup description Matchup tooltip is true boolean true --
Copy matchup description Matchup tooltip is true boolean true Nails
Possible damage amounts Matchup tooltip is true 'always' | 'nfe' | 'never' 'nfe' Nails

Field

Option Dependency Type Default
Quick edit mode (per auth + spectating) -- boolean true (both auth + spectating)
Show all conditions Quick edit mode is false boolean true

Opera GX Support

The extension that allows you to install chrome extensions on opera gx just doesn't load on showdown. I can install it but the showdex tab doesn't appear.

moves like Psystrike, Psyshock & Photon Geyser report incorrect damage

Moves that use conditional defensive stats like Psystrike & Psyshock and Photon Geyser always calculate against the defending Pokémon's SPD (since all 3 moves are special), which results in incorrect damage ranges.

  • Psystrike & Psyshock are both special moves that hit the defending Pokémon's DEF.
  • Photon Geyser is also a special move that hits the defending Pokémon's DEF only if the attacking Pokémon's ATK is greater than (but not equal!) its SPA (otherwise, the defending Pokémon's SPD is used, as you'd expect).

always critting moves don't crit until crit is toggled

Moves that always result in a critical hit like Frost Breath and Surging Strikes don't calculate as critical hits until the "CRIT" toggle is activated in the Calcdex.

This is how these types of moves work on calc.ps. However, unlike calc.ps, we should not apply the crit when the always critting move is Z/Max'd.

closed Calcdex appears again when closing the last native tab

When closing a native tab (i.e., a tab that's already built into Showdown, like the BattlesRoom) that also happens to be the last visible tab open (on the right panel only), the client's default handler will focus the next room in app.rooms, which includes the hidden (i.e., "closed") Calcdex rooms.

duplicate usernames in the Hellodex

Reported by:

When you are player 2 in the battle state (you can tell if you show up on the bottom side of the Calcdex), the Hellodex will show your opponent's username versing themselves.

allow selection of any ability/moves in OMs

Requested by: Ducky

While AAA and Hackmons allow you to select any move, abilities are still locked to their legal sets.

Instead of just supporting AAA and Hackmons, we should lock abilities/moves to only legal sets for certain formats like Randoms, OU, and Ubers, but allow any ability/move for formats not in that list.

dupe Pokémon due to Illusion ability in Randoms

This is due to the server reporting a new Showdown.Pokemon (client Pokémon) based on one of the existing Showdown.Pokemon[] when the Zoroark activates its Illusion ability on switch-in, causing the Calcdex to show a duplicate Pokémon, if the copied Pokémon was previously revealed in battle.

For example:

CalcdexBattleState {
  battleId: 'battle-gen8randombattle-...',
  gen: 8,
  format: 'gen8randombattle',
  active: true,
  authPlayerKey: 'p1',
  playerKey: 'p1',
  opponentKey: 'p2',
  p1: CalcdexPlayerSide { ... },
  p2: CalcdexPlayerSide {
    ...,
    pokemon: [
      CalcdexPokemon { calcdexId: '0d7cadb6-...', speciesForme: 'Klefki', level: 82, hp: 228, maxhp: 228, ... },
      CalcdexPokemon { calcdexId: 'c01682c0-...', speciesForme: 'Palkia', level: 74, hp: 510, maxhp: 510, ... },
      CalcdexPokemon { calcdexId: '30904a8a-...', speciesForme: 'Orbeetle', level: 86, hp: 243, maxhp: 243, ... },
      CalcdexPokemon { calcdexId: 'deda7a90-...', speciesForme: 'Centiskorch', level: 84, hp: 305, maxhp: 305, ... },
    ],
  },
  field: CalcdexBattleField { ... },
}

If Zoroark came in as another Orbeetle (as its Illusion), the server will report another Showdown.Pokemon:

Showdown.Pokemon {
  ability: '',
  baseAbility: '',
  boosts: {},
  details: 'Orbeetle, L84, M',
  fainted: false,
  gender: 'M',
  hp: 238,
  hpcolor: '',
  ident: 'p2: Orbeetle',
  item: 'Life Orb',
  itemEffect: '',
  lastMove: 'darkpulse',
  level: 84,
  maxhp: 238,
  moveTrack: [
    ['Dark Pulse', 1],
  ],
  moves: [],
  name: 'Orbeetle',
  prevItem: '',
  prevItemEffect: '',
  searchid: 'p2: Orbeetle|Orbettle, L84, M',
  shiny: false,
  side: Showdown.Side { ... },
  slot: 0,
  speciesForme: 'Orbeetle',
  sprite: Showdown.Sprite { sideid: 'p2', ... },
  status: '???',
  statusData: {
    sleepTurns: 0,
    toxicTurns: 0,
  },
  statusStage: 0,
  turnstatuses: {},
  volatiles: {},
}

With the following stepQueue commands:

|t:|...
|switch|p2a: Orbeetle|Orbeetle, L84, M|238/238
|-status|p2a: Orbeetle|psn
|turn|30
|
|t:|...
|move|p2a: Orbeetle|Dark Pulse|p1a: Greedent
|-damage|p1a: Greedent|16/678
|-damage|p2a: Orbeetle|215/238 psn|[from] item: Life Orb
|move|p1a: Greedent|Max Flare|p2a: Orbeetle
|-damage|p2a: Orbeetle|0 fnt
|-weather|SunnyDay
|replace|p2a: Zoroark|Zoroark, L84, M
|-end|p2a: Zoroark|Illusion
|faint|p2a: Zoroark

This one is of an existing CalcdexPokemon, however, is untagged with a calcdexId, so the Calcdex will assume this is a new Pokémon entirely, adding it to the pokemon array of the CalcdexPlayerSide.

Note that there are some dead giveaways that this Pokémon may be an Illusion, particularly the maxhp value, which is 238 (Zoroark's max HP) instead of 243 (Orbeetle's max HP). (Characteristic of Illusion is that it retains the mimicking Pokémon's level and HP, not those of the mimicked Pokémon.) However, we cannot know this during the battle if the HP Percentage Mod is enabled (which is the case for the format in the example, gen8randombattle), which only reports a max HP of 100 or 1000 (if the Showdown.Pokemon is initialized, but unpopulated).

Once the Illusion ends, another Showdown.Pokemon is created for the actual Zoroark, causing the Calcdex to add an additional Pokémon again. This leaves out the Zoroark if the player revealed 5 of 6 Pokémon, or if more space is available, would eventually leave out the last actual Pokémon.

Showdown.Pokemon {
  ability: 'Illusion',
  baseAbility: 'Illusion',
  boosts: {},
  details: 'Zoroark, L84, M',
  fainted: true,
  gender: 'M',
  hp: 0,
  hpcolor: '',
  ident: 'p2: Zoroark',
  item: '',
  itemEffect: '',
  lastMove: 'darkpulse',
  level: 84,
  maxhp: 238,
  moveTrack: [],
  moves: [],
  movestatuses: {},
  name: 'Zoroark',
  prevItem: '',
  prevItemEffect: '',
  searchid: 'p2: Zoroark|Zoroark, L84, M',
  shiny: false,
  side: Showdown.Side { sideid: 'p2', ... },
  slot: 0,
  speciesForme: 'Zoroark',
  sprite: Showdown.Sprite { ... },
  status: 'psn',
  statusData: {
    sleepTurns: 0,
    toxicTurns: 0,
  },
  statusStage: 0,
  turnstatuses: {},
  volatiles: {},
}

Resulting in the following CalcdexPlayerSide for p2:

CalcdexPlayerSide {
  ...,
  pokemon: [
    CalcdexPokemon { calcdexId: '0d7cadb6-...', speciesForme: 'Klefki', level: 82, hp: 228, maxhp: 228, ... },
    CalcdexPokemon { calcdexId: 'c01682c0-...', speciesForme: 'Palkia', level: 74, hp: 510, maxhp: 510, ... },
    CalcdexPokemon { calcdexId: '30904a8a-...', speciesForme: 'Orbeetle', level: 86, hp: 243, maxhp: 243, ... },
    CalcdexPokemon { calcdexId: 'deda7a90-...', speciesForme: 'Centiskorch', level: 84, hp: 305, maxhp: 305, ... },
    CalcdexPokemon { calcdexId: '973bcac1-...', speciesForme: 'Orbeetle', level: 84, hp: 238, maxhp: 238, ... },
    CalcdexPokemon { calcdexId: '34a4a243-...', speciesForme: 'Zoroark', level: 84, hp: 0, maxhp: 238, ... },
  ],
}

Notice that p2.pokemon.length is now 6, which is the defined limit of the process.env.CALCDEX_PLAYER_MAX_POKEMON environment variable. Hence, when the following commands are added to the battle's stepQueue:

|t:|...
|switch|p2a: Gardevoir|Gardevoir, L82, M|246/246
|-status|p2a: Gardevoir|psn
|-ability|p2a: Gardevoir|Cheeck Pouch|[from] ability: Trace|[of] p1a: Greedent
|turn|31
Showdown.Pokemon {
  ability: 'Cheek Pouch',
  baseAbility: 'Trace',
  boosts: {},
  details: 'Gardevoir, L82, M',
  fainted: false,
  gender: 'M',
  hp: 246,
  hpcolor: '',
  ident: 'p2: Gardevoir',
  item: '',
  itemEffect: '',
  lastMove: 'psyshock',
  level: 82,
  maxhp: 246,
  moveTrack: [
    ['Psyshock', 1],
  ],
  moves: [],
  movestatuses: {},
  name: 'Gardevoir',
  prevItem: '',
  prevItemEffect: '',
  searchid: 'p2: Gardevoir|Gardevoir, L82, M',
  shiny: false,
  side: Showdown.Side { sideid: 'p2', ... },
  speciesForme: 'Gardevoir',
  sprite: Showdown.Sprite { ... },
  status: 'psn',
  statusData: {
    sleepTurns: 0,
    toxicTurns: 0,
  },
  statusStage: 0,
  turnstatuses: {},
  volatiles: {},
}

The switched-in Gardevoir is ignored in the Calcdex since we've already reached the maximum limit of Pokémon.

Thankfully, this does not affect the IDing mechanism since a new untagged Showdown.Pokemon is created, which causes syncBattle() to assign it a new ID, despite the copied Pokémon potentially already existing in the array (would have its own unique ID assigned prior).

Note that in the case of Gardevoir the IDing mechanism assigns it a calcdexId to its Showdown.Pokemon, despite not being in the pokemon array of the CalcdexPlayerSide for p2. Additionally, battle.p2.pokemon.length is 7 due to the Illusion, but the client seems to properly handle this case visually, ignoring the mimicked Orbeetle and showing only 6 unique Pokémon in the battle frame, including the Gardevoir.


Possible solution is to show the duplicate Pokémon as usual, but once a Zoroark (or any Pokémon, for that matter) with the Illusion ability switches in, the syncBattle() should detect if we're attempting to add an Illusion Pokémon and look for and remove the duplicate (the L84 238 HP Orbeetle in this case).

In terms of filtering for the duplicates, we can check which ones have the same speciesForme, including ones that end in '-*', since we can't rule unrevealed formes out just yet (such as Urshifu, whose speciesForme will be 'Urshifu-*' until it's actual forme is revealed, unlike Arceus, whose forme is revealed on switch-in, e.g., Arceus-Bug).

Then, we can compare the duplicate Pokémon's level, to see which one matches the Zoroark's. If they're the same (which they could be in a non-Randoms format where every Pokémon is typically level 100), then we can check if the HP Percentage Mod is disabled and then compare the maxhp values. Otherwise, we can check if one of the duplicates has a falsy ability. If we still can't determine which one is the duplicate through all of this, we'll just remove the one that was most recently added, since the mimicked Showdown.Pokemon and the Zoroark's Showdown.Pokemon should be right next to each other in the pokemon array of p2's Showdown.Side.

Actually, we can probably just remove the last added CalcdexPokemon when processing another Pokémon with the Illusion ability, especially since we can't guarantee that the mimicked Pokémon already exists on the field. May also need to keep track of an "ignored" calcdexId list.

gen8nationaldex formats crashes Calcdex

this is caused by mega evo items like Mawilite not existing in the Gen 8 Generation object from @pkmn/dex.

import { Dex } from '@pkmn/dex';
import { Generations } from '@pkmn/data';

const gens = new Generations(Dex);
const dexGen8 = gens.get(8);

dexGen8.items.get('Mawilite');

returns:

undefined

we can either load from a previous gen (e.g., gens.get(6)) if dex.items.get() returns undefined, or use the global Dex object from the Showdown client:

Dex.items.get('Mawilite');

returns:

Item {
  id: 'Mawilite',
  num: 681,
  spritenum: 598,
  name: 'Mawilite',
  desc: 'If held by a Mawile, this item allows it to Mega Evolve in battle.',
  shortDesc: 'If held by a Mawile, this item allows it to Mega Evolve in battle.',
  gen: 6,
  exists: true,
  effectType: 'Item',
  itemUser: [
    'Mawile',
  ],
  fling: null,
  isPokeball: false,
  megaEvolves: 'Mawile',
  megaStone: 'Mawile-Mega',
  naturalGift: null,
  onDrive: '',
  onMemory: '',
  onPlate: '',
  zMove: null,
  zMoveFrom: '',
  zMoveType: '',
  zMoveUser: null,
}

note that the following is the return object of dex.items.get() (from @pkmn/dex):

const dexGen6 = gens.get(6);

dexGen6.items.get('Mawilite');

returns:

Item {
  id: 'mawilite',
  num: 681,
  name: 'Mawilite',
  fullName: 'item: Mawilite',
  desc: 'If held by a Mawile, this item allows it to Mega Evolve in battle.',
  shortDesc: '',
  gen: 6,
  exists: true,
  isNonstandard: null,
  kind: 'Item',
  effectType: 'Item',
  itemUser: [
    'Mawile',
  ],
  duration: undefined,
  fling: {
    basePower: 80,
  },
  megaEvolves: 'Mawile',
  megaStone: 'Mawile-Mega',
}

the objects from Dex.items.get() and dex.items.get() share similar properties, but differ slightly, such as the return object from Dex.items.get() not including the isNonstandard property that the return object from dex.items.get() has.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.