diff --git a/commands/games/battle.js b/commands/games/battle.js index 9f0c6d9c..e7f23f0e 100644 --- a/commands/games/battle.js +++ b/commands/games/battle.js @@ -8,13 +8,14 @@ module.exports = class BattleCommand extends Command { aliases: ['fight', 'death-battle'], group: 'games', memberName: 'battle', - description: 'Engage in a turn-based battle against another user.', + description: 'Engage in a turn-based battle against another user or the AI.', guildOnly: true, args: [ { key: 'opponent', prompt: 'Who would you like to battle?', - type: 'user' + type: 'user', + default: '' } ] }); @@ -22,89 +23,102 @@ module.exports = class BattleCommand extends Command { this.fighting = new Set(); } - async run(msg, args) { - const { opponent } = args; + async run(msg, args) { // eslint-disable-line complexity + const opponent = args.opponent || 'AI'; if (opponent.bot) return msg.say('Bots may not be fought.'); if (opponent.id === msg.author.id) return msg.say('You may not fight yourself.'); if (this.fighting.has(msg.guild.id)) return msg.say('Only one fight may be occurring per server.'); this.fighting.add(msg.guild.id); - await msg.say(`${opponent}, do you accept this challenge? **__Y__es** or **No**?`); - const verify = await msg.channel.awaitMessages((res) => res.author.id === opponent.id, { - max: 1, - time: 30000 - }); - if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { - this.fighting.delete(msg.guild.id); - return msg.say('Looks like they declined...'); - } - let userHP = 500; - let oppoHP = 500; - let userTurn = false; - let guard = false; - const reset = (changeGuard = true) => { - if (userTurn) userTurn = false; - else userTurn = true; - if (changeGuard && guard) guard = false; - }; - const dealDamage = (damage) => { - if (userTurn) oppoHP -= damage; - else userHP -= damage; - }; - const forfeit = () => { - if (userTurn) userHP = 0; - else oppoHP = 0; - }; - while (userHP > 0 && oppoHP > 0) { // eslint-disable-line no-unmodified-loop-condition - const user = userTurn ? msg.author : opponent; - const id = userTurn ? msg.author.id : opponent.id; - await msg.say(stripIndents` - ${user}, do you **fight**, **guard**, **special**, or **run**? - **${msg.author.username}**: ${userHP}HP - **${opponent.username}**: ${oppoHP}HP - `); - const turn = await msg.channel.awaitMessages((res) => res.author.id === id, { - max: 1, - time: 30000 - }); - if (!turn.size) { - await msg.say('Time!'); - forfeit(); - break; + try { + if (opponent !== 'AI') { + await msg.say(`${opponent}, do you accept this challenge? **__Y__es** or **No**?`); + const verify = await msg.channel.awaitMessages((res) => res.author.id === opponent.id, { + max: 1, + time: 30000 + }); + if (!verify.size || !['yes', 'y'].includes(verify.first().content.toLowerCase())) { + this.fighting.delete(msg.guild.id); + return msg.say('Looks like they declined...'); + } } - const choice = turn.first().content.toLowerCase(); - if (choice === 'fight') { - const damage = Math.floor(Math.random() * (guard ? 10 : 100)) + 1; - await msg.say(`${user} deals **${damage}** damage!`); - dealDamage(damage); - reset(); - } else if (choice === 'guard') { - await msg.say(`${user} guards!`); - guard = true; - reset(false); - } else if (choice === 'special') { - const hit = Math.floor(Math.random() * 4) + 1; - if (hit === 1) { - const damage = Math.floor(Math.random() * ((guard ? 300 : 150) - 100 + 1) + 100); + let userHP = 500; + let oppoHP = 500; + let userTurn = false; + let guard = false; + const reset = (changeGuard = true) => { + if (userTurn) userTurn = false; + else userTurn = true; + if (changeGuard && guard) guard = false; + }; + const dealDamage = (damage) => { + if (userTurn) oppoHP -= damage; + else userHP -= damage; + }; + const forfeit = () => { + if (userTurn) userHP = 0; + else oppoHP = 0; + }; + while (userHP > 0 && oppoHP > 0) { // eslint-disable-line no-unmodified-loop-condition + const user = userTurn ? msg.author : opponent; + let choice; + if (opponent !== 'AI' || (opponent === 'AI' && userTurn)) { + const id = userTurn ? msg.author.id : opponent.id; + await msg.say(stripIndents` + ${user}, do you **fight**, **guard**, **special**, or **run**? + **${msg.author.username}**: ${userHP}HP + **${opponent === 'ai' ? 'AI' : opponent.username}**: ${oppoHP}HP + `); + const turn = await msg.channel.awaitMessages((res) => res.author.id === id, { + max: 1, + time: 30000 + }); + if (!turn.size) { + await msg.say('Time!'); + forfeit(); + break; + } + choice = turn.first().content.toLowerCase(); + } else { + const choices = ['fight', 'guard', 'special']; + choice = choices[Math.floor(Math.random() * choices.length)]; + } + if (choice === 'fight') { + const damage = Math.floor(Math.random() * (guard ? 10 : 100)) + 1; await msg.say(`${user} deals **${damage}** damage!`); dealDamage(damage); reset(); + } else if (choice === 'guard') { + await msg.say(`${user} guards!`); + guard = true; + reset(false); + } else if (choice === 'special') { + const hit = Math.floor(Math.random() * 4) + 1; + if (hit === 1) { + const damage = Math.floor(Math.random() * ((guard ? 300 : 150) - 100 + 1) + 100); + await msg.say(`${user} deals **${damage}** damage!`); + dealDamage(damage); + reset(); + } else { + await msg.say(`${user}'s attack missed!`); + reset(); + } + } else if (choice === 'run') { + await msg.say(`${user} flees!`); + forfeit(); + break; } else { - await msg.say(`${user}'s attack missed!`); - reset(); + await msg.say(`${user}, I do not understand what you want to do.`); } - } else if (choice === 'run') { - await msg.say(`${user} flees!`); - forfeit(); - break; - } else { - await msg.say(`${user}, I do not understand what you want to do.`); } + this.fighting.delete(msg.guild.id); + return msg.say(stripIndents` + The match is over! + **Winner:** ${userHP > oppoHP ? `${msg.author} (${userHP}HP)` : `${opponent} (${oppoHP}HP)`} + **Loser:** ${userHP > oppoHP ? `${opponent} (${oppoHP}HP)` : `${msg.author} (${userHP}HP)`} + `); + } catch (err) { + this.fighting.delete(msg.guild.id); + return msg.say(`Oh no, an Error occurred: \`${err.message}\`. Try again later!`); } - this.fighting.delete(msg.guild.id); - return msg.say(stripIndents` - The match is over! - **Winner:** ${userHP > oppoHP ? `${msg.author} (${userHP}HP)` : `${opponent} (${oppoHP}HP)`} - **Loser:** ${userHP > oppoHP ? `${opponent} (${oppoHP}HP)` : `${msg.author} (${userHP}HP)`} - `); } }; diff --git a/commands/search/recipe.js b/commands/search/recipe.js new file mode 100644 index 00000000..77402a89 --- /dev/null +++ b/commands/search/recipe.js @@ -0,0 +1,39 @@ +const Command = require('../../structures/Command'); +const { RichEmbed } = require('discord.js'); +const snekfetch = require('snekfetch'); + +module.exports = class RecipeCommand extends Command { + constructor(client) { + super(client, { + name: 'recipe', + group: 'search', + memberName: 'recipe', + description: 'Searches for recipes that include your query.', + clientPermissions: ['EMBED_LINKS'], + args: [ + { + key: 'query', + prompt: 'What would you like to search for?', + type: 'string' + } + ] + }); + } + + async run(msg, args) { + const { query } = args; + const { text } = await snekfetch + .get('http://www.recipepuppy.com/api/') + .query({ q: query }); + const body = JSON.parse(text); + if (!body.results.length) return msg.say('No Results.'); + const recipe = body.results[Math.floor(Math.random() * body.results.length)]; + const embed = new RichEmbed() + .setColor(0xC20000) + .setURL(recipe.href) + .setTitle(recipe.title) + .setDescription(`**Ingredients:** ${recipe.ingredients}`) + .setThumbnail(recipe.thumbnail); + return msg.embed(embed); + } +}; diff --git a/commands/search/urban.js b/commands/search/urban.js index 1eef114d..49c040ca 100644 --- a/commands/search/urban.js +++ b/commands/search/urban.js @@ -27,7 +27,7 @@ module.exports = class UrbanCommand extends Command { .query({ term: query }); if (!body.list.length) return msg.say('No Results.'); const embed = new RichEmbed() - .setColor(0x32a8f0) + .setColor(0x32A8F0) .setAuthor('Urban Dictionary', 'https://i.imgur.com/fzFuuL7.png') .setURL(body.list[0].permalink) .setTitle(body.list[0].word) diff --git a/html/carbonfeat.html b/html/carbonfeat.html index f54edd98..92bfe2f4 100644 --- a/html/carbonfeat.html +++ b/html/carbonfeat.html @@ -50,6 +50,7 @@
  • Google Maps
  • Neopets
  • osu!
  • +
  • Recipe Puppy
  • Rule34
  • SoundCloud
  • Urban Dictionary
  • diff --git a/html/discordbots.html b/html/discordbots.html index 2eb56560..a623ae2b 100644 --- a/html/discordbots.html +++ b/html/discordbots.html @@ -47,6 +47,7 @@
  • Google Maps
  • Neopets
  • osu!
  • +
  • Recipe Puppy
  • Rule34
  • SoundCloud
  • Urban Dictionary
  • diff --git a/package.json b/package.json index aadf5d73..09d7fdce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaobot", - "version": "26.1.0", + "version": "26.2.0", "description": "Your personal server companion.", "main": "Shard.js", "scripts": {