UNPKG

discord-mini-games-es.js

Version:

Un paquete para implementar minijuegos usando discord.js-v14 en español

137 lines (133 loc) 6.66 kB
const discord = require('discord.js'); const translate = require('node-google-translate-skidz'); const {EmbedBuilder,ButtonBuilder,ButtonStyle,ActionRowBuilder,ComponentType} = require('discord.js') class Trivia{ /** * Initialises a new instance of Trivia Game. * @param {`Message/Interaction`} message The Message Object. * @param {`GameOptions-Object`} gameOptions The game Options Object. * @returns {Trivia} Game instance. */ constructor(message,gameOptions) { if(!message) throw new Error("el mensaje no ha sido proporcionado"); this.message = message; if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions debe de ser un Objeto"); this.isSlash = gameOptions?.isSlash ?? false; if(this.isSlash == true) { if(!(this.message instanceof discord.CommandInteraction)){ throw new TypeError("el mensaje debe ser una instancia de interacción de comandos") }} else { if(!(this.message instanceof discord.Message)) { throw new TypeError("el mensaje debe ser una instancia del mensaje Discord") } } this.player = this.isSlash == true ? this.message?.user : this.message?.author; this.options = gameOptions this.time = gameOptions?.time ?? 30000; this.replied = false; this.edit = async (messageOptions,replyMessage) => { messageOptions.fetchReply = true; if(this.replied == false) { this.replied=true; if(this.isSlash == true) return await replyMessage.editReply(messageOptions) return await this.message.reply(messageOptions);} else return await replyMessage.edit(messageOptions) } this.difficulty = gameOptions?.difficulty ?? 'medium'; if(this.difficulty !== 'easy' && this.difficulty !== 'medium' && this.difficulty !== 'hard') throw new RangeError('la dificultad debe ser fácil, media o difícil'); this.onWin = gameOptions?.onWin ?? null; this.onLose = gameOptions?.onLose ?? null; if(typeof this.isSlash !== 'boolean') throw new TypeError('isSlash debe de ser Boolean'); if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin debe de ser una Función'); if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose debe de ser una Función'); if(typeof this.time !== 'number') throw new TypeError('time debe de ser un Número'); if(this.time < 5000) throw new RangeError('time debe de ser mayor que 5000'); if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title debe de ser un String'); if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes debe de ser un String'); if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes debe de ser un String'); if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes debe de ser un String'); } /** * Starts The Game. */ async run() { if(this.isSlash == true) { await this.message.deferReply().catch(() => {}); } const game = this; async function fetchQuestion() { var res = 1; while(res !== 0){ const data = await fetch(`https://opentdb.com/api.php?amount=1&type=multiple&encode=url3986&difficulty=${game.difficulty}`) const json = await data.json(); res = json.response_code; if(res == 0) return json.results[0]; } } const emojis = ["1️⃣","2️⃣","3️⃣","4️⃣"]; const question = await fetchQuestion(); const result = await translate({ text: decodeURIComponent(question.question), source: "en", target: "es", }); const spanishQuestion = result.translation; const answer = decodeURIComponent(question.correct_answer); question.incorrect_answers[3] = question.correct_answer; const choices = shuffleArray(question.incorrect_answers); function oooEm(text,color) { const embed = new EmbedBuilder() .setTitle(game.options?.title ?? 'Trivia') .setDescription(`**${spanishQuestion}** **Dificultad:** ${decodeURIComponent(question.difficulty)} | **Categoría:** ${decodeURIComponent(question.category)} 1️⃣ ${decodeURIComponent(choices[0])} 2️⃣ ${decodeURIComponent(choices[1])} 3️⃣ ${decodeURIComponent(choices[2])} 4️⃣ ${decodeURIComponent(choices[3])} ${text ? '\n\n' + text : ''}`) .setColor(color) .setThumbnail(game.player.avatarURL()) .setTimestamp() .setFooter({text:`Pedido por ${game.player.username}`}) return embed; } function shuffleArray(lol) { let New = new Array().concat(lol) for (let i = New.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [New[i], New[j]] = [New[j], New[i]]; } return New; } var Row = new ActionRowBuilder().addComponents( new ButtonBuilder().setCustomId('trivia_0').setStyle(ButtonStyle.Secondary).setLabel("1️⃣"), new ButtonBuilder().setCustomId('trivia_1').setStyle(ButtonStyle.Secondary).setLabel("2️⃣"), new ButtonBuilder().setCustomId('trivia_2').setStyle(ButtonStyle.Secondary).setLabel("3️⃣"), new ButtonBuilder().setCustomId('trivia_3').setStyle(ButtonStyle.Secondary).setLabel("4️⃣")) const msg = await this.edit({embeds:[oooEm(null,'Green')],components:[Row]},this.message) const collector = msg.createMessageComponentCollector({ componentType: ComponentType.Button, idle:this.time}) let played = false; collector.on('collect', async (i) => { await i.deferUpdate(); if(i.user.id == this.player.id) { played = true; collector.stop() Row.components.find(x => x.data.custom_id == i.customId).setDisabled(true) if(decodeURIComponent(choices[i.customId[7]]) == answer) { await this.edit({embeds:[oooEm(this.options?.winDes?.replace(/{answer}/g,`"${answer}"`)?.replace(/{user_option}/g,`"${answer}"`) ?? `¡Ganaste! Era "${answer}"`,`Yellow`)],components:[Row]},msg) if(this.onWin) await this.onWin(); } else { await this.edit({embeds:[oooEm(this.options?.loseDes?.replace(/{answer}/g,`"${answer}"`)?.replace(/{user_option}/g,emojis[i.customId[7]]) ?? `¡Perdiste! Era "${answer}"`,`Red`)],components:[Row]},msg) if(this.onLose) await this.onLose(); } } }) collector.on('end', async () => { if(played == false) { Row.components.forEach(x => x.setDisabled(true)) await this.edit({embeds:[oooEm(this.options?.timeUpDes?.replace(/{answer}/g,`"${answer}"`) ?? `Juego terminado: Se acabó el tiempo, era ` + answer,'Red')],components:[Row]},msg); } }) } } module.exports = Trivia;