diff --git a/assets/images/pokedex/sprites.png b/assets/images/pokedex/sprites.png new file mode 100644 index 00000000..eb80fbe0 Binary files /dev/null and b/assets/images/pokedex/sprites.png differ diff --git a/commands/pokedex/pokedex-location.js b/commands/pokedex/pokedex-location.js index 8d9e97b1..abfbfbb4 100644 --- a/commands/pokedex/pokedex-location.js +++ b/commands/pokedex/pokedex-location.js @@ -59,10 +59,16 @@ module.exports = class PokedexLocationCommand extends Command { : 'Location Unknown'; const embed = new MessageEmbed() .setColor(0xED1C24) - .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, pokemon.boxImageURL, pokemon.serebiiURL) + .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, 'attachment://box.png', pokemon.serebiiURL) .setDescription(desc) .setThumbnail(pokemon.spriteImageURL); - return msg.embed(embed); + return msg.channel.send({ + embeds: [embed], + files: [{ + attachment: await pokemon.generateBoxImage(), + name: 'box.png' + }] + }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/pokedex/pokedex-moveset.js b/commands/pokedex/pokedex-moveset.js index d37168f6..021fda54 100644 --- a/commands/pokedex/pokedex-moveset.js +++ b/commands/pokedex/pokedex-moveset.js @@ -59,11 +59,17 @@ module.exports = class PokedexMovesetCommand extends Command { if (!pokemon.moveSet.length) return msg.say('This Pokémon\'s moves are not yet documented.'); const embed = new MessageEmbed() .setColor(0xED1C24) - .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, pokemon.boxImageURL, pokemon.serebiiURL) + .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, 'attachment://box.png', pokemon.serebiiURL) .setDescription(pokemon.moveSet.map(move => `**Level ${move.level}:** ${move.move.name}`).join('\n')) .setThumbnail(pokemon.spriteImageURL) .setFooter(`Moveset data taken from ${versions[pokemon.moveSetVersion]}.`); - return msg.embed(embed); + return msg.channel.send({ + embeds: [embed], + files: [{ + attachment: await pokemon.generateBoxImage(), + name: 'box.png' + }] + }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/pokedex/pokedex-stats.js b/commands/pokedex/pokedex-stats.js index f8bfe3a0..30cbb626 100644 --- a/commands/pokedex/pokedex-stats.js +++ b/commands/pokedex/pokedex-stats.js @@ -76,7 +76,7 @@ module.exports = class PokedexCommand extends Command { .setColor(0xED1C24) .setAuthor( `#${pokemon.displayID} - ${pokemon.name}`, - pokemon.formBoxImageURL(variety.id), + 'attachment://box.png', pokemon.serebiiURL ) .setThumbnail(pokemon.formSpriteImageURL(variety.id)) @@ -96,7 +96,13 @@ module.exports = class PokedexCommand extends Command { **Forms Available:** ${displayForms.map(vrity => `\`${vrity.name || 'Normal'}\``).join(', ')} `); - return msg.embed(embed); + return msg.channel.send({ + embeds: [embed], + files: [{ + attachment: await pokemon.generateBoxImage(), + name: 'box.png' + }] + }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/pokedex/pokedex.js b/commands/pokedex/pokedex.js index 4d4b1fea..452bed3d 100644 --- a/commands/pokedex/pokedex.js +++ b/commands/pokedex/pokedex.js @@ -93,7 +93,7 @@ module.exports = class PokedexCommand extends Command { }).join(' -> '); const embed = new MessageEmbed() .setColor(0xED1C24) - .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, pokemon.boxImageURL, pokemon.serebiiURL) + .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, 'attachment://box.png', pokemon.serebiiURL) .setDescription(stripIndents` **${pokemon.genus}** ${pokemon.entries.length ? pokemon.entries[Math.floor(Math.random() * pokemon.entries.length)] : 'No data.'} @@ -120,7 +120,13 @@ module.exports = class PokedexCommand extends Command { await reactIfAble(msg, this.client.user, '🔉'); } } - return msg.embed(embed); + return msg.channel.send({ + embeds: [embed], + files: [{ + attachment: await pokemon.generateBoxImage(), + name: 'box.png' + }] + }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/commands/pokedex/smogon.js b/commands/pokedex/smogon.js index 43c13a20..7f9088a6 100644 --- a/commands/pokedex/smogon.js +++ b/commands/pokedex/smogon.js @@ -60,7 +60,7 @@ module.exports = class SmogonCommand extends Command { if (!pokemon.missingno) await pokemon.fetchSmogonTiers(...fetchGames); const embed = new MessageEmbed() .setColor(0xED1C24) - .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, pokemon.boxImageURL, pokemon.serebiiURL) + .setAuthor(`#${pokemon.displayID} - ${pokemon.name}`, 'attachment://box.png', pokemon.serebiiURL) .setThumbnail(pokemon.spriteImageURL); for (const game of fetchGames) { embed.addField(`❯ ${games[game]}`, @@ -71,7 +71,13 @@ module.exports = class SmogonCommand extends Command { embed.addField('\u200B', '\u200B', true); } } - return msg.embed(embed); + return msg.channel.send({ + embeds: [embed], + files: [{ + attachment: await pokemon.generateBoxImage(), + name: 'box.png' + }] + }); } catch (err) { return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); } diff --git a/structures/pokemon/Pokemon.js b/structures/pokemon/Pokemon.js index 2bad074b..14db45eb 100644 --- a/structures/pokemon/Pokemon.js +++ b/structures/pokemon/Pokemon.js @@ -1,4 +1,5 @@ const request = require('node-superfetch'); +const { createCanvas } = require('canvas'); const path = require('path'); const { removeDuplicates, firstUpperCase, delay } = require('../../util/Util'); const missingno = require('../../assets/json/missingno'); @@ -133,20 +134,6 @@ module.exports = class Pokemon { return `https://serebii.net/pokemon/art/${this.displayID}${name ? `-${name}` : ''}.png`; } - get boxImageURL() { - if (this.missingno) return missingno.box; - return `https://www.serebii.net/pokedex-sv/icon/${this.displayID}.png`; - } - - formBoxImageURL(variety) { - if (this.missingno) return missingno.box; - const found = this.varieties.find(vrity => variety ? vrity.id === variety.toLowerCase() : vrity.default); - const name = found.default ? '' : found.mega - ? found.name.toLowerCase().split(' ').map(n => n.charAt(0)).join('') - : found.name.toLowerCase().charAt(0); - return `https://www.serebii.net/pokedex-sv/icon/${this.displayID}${name ? `-${name}` : ''}.png`; - } - get serebiiURL() { if (this.missingno) return missingno.url; return `https://www.serebii.net/pokedex-sv/${this.displayID}.shtml`; @@ -157,6 +144,16 @@ module.exports = class Pokemon { return `https://www.smogon.com/dex/${gen.toLowerCase()}/pokemon/${this.slug}/`; } + async generateBoxImage() { + if (!this.store.sprites) await this.store.loadSprites(); + const canvas = createCanvas(40, 30); + const ctx = canvas.getContext('2d'); + const x = 40 * (this.id % 12); + const y = Math.floor(this.id / 12) * 30; + ctx.drawImage(this.store.sprites, x, y, 40, 30, 0, 0, 40, 30); + return canvas.toBuffer(); + } + async fetchSmogonTiers(...gens) { for (const gen of gens) { if (!this.store.smogonData[gen.toLowerCase()]) await this.store.fetchSmogonData(gen.toLowerCase()); diff --git a/structures/pokemon/PokemonStore.js b/structures/pokemon/PokemonStore.js index b5d21353..4a2190db 100644 --- a/structures/pokemon/PokemonStore.js +++ b/structures/pokemon/PokemonStore.js @@ -1,5 +1,7 @@ const { Collection } = require('@discordjs/collection'); const request = require('node-superfetch'); +const { loadImage } = require('canvas'); +const path = require('path'); const Pokemon = require('./Pokemon'); const MoveStore = require('./MoveStore'); const AbilityStore = require('./AbilityStore'); @@ -16,6 +18,14 @@ module.exports = class PokemonStore extends Collection { this.moves = new MoveStore(); this.abilities = new AbilityStore(); this.items = new ItemStore(); + this.sprites = null; + } + + async loadSprites() { + if (this.sprites) return this.sprites; + const sprites = await loadImage(path.join(__dirname, '..', '..', 'assets', 'images', 'pokedex', 'sprites.png')); + this.sprites = sprites; + return this.sprites; } async fetch(query) {