From 43eb2ffb2a0108d3c348fe31d46ff65f6b78d6a9 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 25 Jul 2017 08:01:00 -0500 Subject: [PATCH 01/15] :ambulance: Hotfix for ban and kick code as well as subscriptions --- src/commands/moderation/ban.js | 6 +----- src/commands/moderation/kick.js | 6 +----- src/modules/stats/Auditor.js | 9 ++++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/commands/moderation/ban.js b/src/commands/moderation/ban.js index d75f03d..6123cbc 100644 --- a/src/commands/moderation/ban.js +++ b/src/commands/moderation/ban.js @@ -42,11 +42,6 @@ class Ban extends Command { return responder.error('{{ban.exit}}') } try { - const channel = await this.bot.getDMChannel(user.id) - await this.send(channel, [ - `🔨 | You have been banned from **\`${guild.name}\`**\n`, - `**Reason**: ${reason}` - ].join('\n')) await msg.channel.guild.banMember(member.id) client.emit('haruMemberBanned', msg.channel.guild, member.user, args.reason) return responder.format('emoji:hammer').reply('{{ban.msg}}', { @@ -54,6 +49,7 @@ class Ban extends Command { deleteDelay: 5000 }) } catch (err) { + logger.error(err) return responder.error('{{ban.exitError}}') } } diff --git a/src/commands/moderation/kick.js b/src/commands/moderation/kick.js index ecbe1b5..e504825 100644 --- a/src/commands/moderation/kick.js +++ b/src/commands/moderation/kick.js @@ -42,11 +42,6 @@ class Kick extends Command { return responder.error('{{kick.exit}}') } try { - const channel = await this.bot.getDMChannel(user.id) - await this.send(channel, [ - `👢 | You have been kicked from **\`${guild.name}\`**\n`, - `**Reason**: ${reason}` - ].join('\n')) await msg.channel.guild.kickMember(member.id) client.emit('haruMemberKicked', msg.channel.guild, member.user, args.reason) return responder.format('emoji:boot').reply('{{kick.msg}}', { @@ -54,6 +49,7 @@ class Kick extends Command { deleteDelay: 5000 }) } catch (err) { + logger.error(err) return responder.error('{{kick.exitError}}') } } diff --git a/src/modules/stats/Auditor.js b/src/modules/stats/Auditor.js index dffd5c7..83ac6ca 100644 --- a/src/modules/stats/Auditor.js +++ b/src/modules/stats/Auditor.js @@ -6,7 +6,7 @@ class Auditor extends Module { super(...args, { name: 'guilds:settings', events: { - haruMemberBanned: 'onBan', + guildBanAdd: 'onBan', haruMemberKicked: 'onKick', guildMemberUpdate: 'memberUpdate', guildMemberAdd: 'onJoin', @@ -47,15 +47,14 @@ class Auditor extends Module { }) } - onBan (guild, user, reason) { + onBan (guild, user) { this.data.Guild.fetch(guild.id).then(settings => { if (typeof settings.events !== 'object') return if (!settings.events.hasOwnProperty('ban')) return for (const id of settings.events['ban']) { this.send(id, '', { embed: { color: this.colours.red, - description: `🔨 **Member Banned**: ${user.username}#${user.discriminator} (ID: ${user.id})` + - (reason ? `\n\n**Reason**: ${reason}` : ''), + description: `🔨 **Member Banned**: ${user.username}#${user.discriminator} (ID: ${user.id})`, footer: { text: moment().locale(settings.lang).tz(settings.tz).format('ddd Do MMM, YYYY [at] hh:mm:ss a') } }}) } @@ -91,7 +90,7 @@ class Auditor extends Module { userUpdate (user, oldUser) { const guilds = this.bot.guilds.find(g => g.members.has(user.id)) - Promise.all(guilds.map(g => + Promise.all(guilds.map(g => this.data.Guild.fetch(g.id).then(settings => { if (user.username !== oldUser.username) { return this.onNameChange(user, oldUser, settings) From a48957cfe8a764e4f94c07b224a686a9945cf163 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 25 Jul 2017 08:05:30 -0500 Subject: [PATCH 02/15] :fire: removes useless client.emit code in ban --- src/commands/moderation/ban.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/commands/moderation/ban.js b/src/commands/moderation/ban.js index 6123cbc..c3b050e 100644 --- a/src/commands/moderation/ban.js +++ b/src/commands/moderation/ban.js @@ -43,7 +43,6 @@ class Ban extends Command { } try { await msg.channel.guild.banMember(member.id) - client.emit('haruMemberBanned', msg.channel.guild, member.user, args.reason) return responder.format('emoji:hammer').reply('{{ban.msg}}', { member: `**${member.user.username}#${member.user.discriminator}**`, deleteDelay: 5000 From 76108cdd8c8745f5c33ba1f08d2ddc8968c0cf76 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 26 Jul 2017 11:08:23 -0500 Subject: [PATCH 03/15] :heavy_plus_sign: :package: :sparkles: Adds botspeak back --- .env.example | 4 ++++ package.json | 1 + src/middleware/cleverbot.js | 4 ++-- src/modules/misc/CleverIO.js | 24 ++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 src/modules/misc/CleverIO.js diff --git a/.env.example b/.env.example index 1d7663a..05601d1 100644 --- a/.env.example +++ b/.env.example @@ -30,6 +30,10 @@ API_ANILIST_CLIENT= API_ANILIST_SECRET= API_SOUNDCLOUD= +#Cleverbot.io API +CLEVERIO_USER= +CLEVERIO_KEY= + # RethinkDB options DB_HOST= DB_PORT= diff --git a/package.json b/package.json index 3091352..6a85551 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "bluebird": "^3.4.6", "bufferutil": "^1.3.0", "chalk": "^1.1.3", + "cleverbot.io": "^1.0.4", "dotenv-safe": "^2.3.2", "entities": "^1.1.1", "eris": "github:abalabahaha/eris#dev", diff --git a/src/middleware/cleverbot.js b/src/middleware/cleverbot.js index 4a5aed7..e7a34dd 100644 --- a/src/middleware/cleverbot.js +++ b/src/middleware/cleverbot.js @@ -18,9 +18,9 @@ module.exports = { return container } - const cleverbot = modules.get('cleverbot') + const cleverbot = modules.get('cleverio') if (!cleverbot) return - // await cleverbot.respond(msg.cleanContent.split(' ').slice(1).join(' '), msg.channel) + await cleverbot.respond(msg.cleanContent.split(' ').slice(1).join(' '), msg.channel) logger.info(`${chalk.bold.magenta( !isPrivate diff --git a/src/modules/misc/CleverIO.js b/src/modules/misc/CleverIO.js new file mode 100644 index 0000000..e20183e --- /dev/null +++ b/src/modules/misc/CleverIO.js @@ -0,0 +1,24 @@ +const cleverbot = require('cleverbot.io') +talk = new cleverbot(process.env.CLEVERIO_USER, process.env.CLEVERIO_KEY) + +const { Module } = require('../../core') + +class CleverIO extends Module { + constructor(...args) { + super(...args, { + name: 'cleverio' + }) + + talk.create(function (err, session) { + }) + } + + async respond (message, channel) { + talk.ask(`${message}`, (err, response) => { + if (err) console.log(err) + if (!response) return + this.send(channel, `💬 | ${response}`) + }) + } +} +module.exports = CleverIO From 214dac94ec4959171c9530584799fc3a3fb456bd Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 27 Jul 2017 10:58:24 -0500 Subject: [PATCH 04/15] Revert ":heavy_plus_sign: :package: :sparkles: Adds botspeak back" Gah y it crash so much when it just worked reeeeee This reverts commit 76108cdd8c8745f5c33ba1f08d2ddc8968c0cf76. --- .env.example | 4 ---- package.json | 1 - src/middleware/cleverbot.js | 4 ++-- src/modules/misc/CleverIO.js | 24 ------------------------ 4 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 src/modules/misc/CleverIO.js diff --git a/.env.example b/.env.example index 05601d1..1d7663a 100644 --- a/.env.example +++ b/.env.example @@ -30,10 +30,6 @@ API_ANILIST_CLIENT= API_ANILIST_SECRET= API_SOUNDCLOUD= -#Cleverbot.io API -CLEVERIO_USER= -CLEVERIO_KEY= - # RethinkDB options DB_HOST= DB_PORT= diff --git a/package.json b/package.json index 6a85551..3091352 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "bluebird": "^3.4.6", "bufferutil": "^1.3.0", "chalk": "^1.1.3", - "cleverbot.io": "^1.0.4", "dotenv-safe": "^2.3.2", "entities": "^1.1.1", "eris": "github:abalabahaha/eris#dev", diff --git a/src/middleware/cleverbot.js b/src/middleware/cleverbot.js index e7a34dd..4a5aed7 100644 --- a/src/middleware/cleverbot.js +++ b/src/middleware/cleverbot.js @@ -18,9 +18,9 @@ module.exports = { return container } - const cleverbot = modules.get('cleverio') + const cleverbot = modules.get('cleverbot') if (!cleverbot) return - await cleverbot.respond(msg.cleanContent.split(' ').slice(1).join(' '), msg.channel) + // await cleverbot.respond(msg.cleanContent.split(' ').slice(1).join(' '), msg.channel) logger.info(`${chalk.bold.magenta( !isPrivate diff --git a/src/modules/misc/CleverIO.js b/src/modules/misc/CleverIO.js deleted file mode 100644 index e20183e..0000000 --- a/src/modules/misc/CleverIO.js +++ /dev/null @@ -1,24 +0,0 @@ -const cleverbot = require('cleverbot.io') -talk = new cleverbot(process.env.CLEVERIO_USER, process.env.CLEVERIO_KEY) - -const { Module } = require('../../core') - -class CleverIO extends Module { - constructor(...args) { - super(...args, { - name: 'cleverio' - }) - - talk.create(function (err, session) { - }) - } - - async respond (message, channel) { - talk.ask(`${message}`, (err, response) => { - if (err) console.log(err) - if (!response) return - this.send(channel, `💬 | ${response}`) - }) - } -} -module.exports = CleverIO From 20d38c351b8286d78890fef0af278ffb8501dbd0 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 28 Jul 2017 11:45:59 -0500 Subject: [PATCH 05/15] :ambulance: desyncs multislots and slots timeouts --- src/commands/games/multislots.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/games/multislots.js b/src/commands/games/multislots.js index d996d13..38b0222 100644 --- a/src/commands/games/multislots.js +++ b/src/commands/games/multislots.js @@ -92,9 +92,9 @@ class Multislots extends Command { } async handle ({ msg, args, data, settings, cache }, responder) { - let dailyWins = await cache.client.getAsync(`slots:${msg.author.id}`) + let dailyWins = await cache.client.getAsync(`multislots:${msg.author.id}`) if (parseInt(dailyWins, 10) >= 750000) { - const res = await cache.client.pttlAsync(`slots:${msg.author.id}`) + const res = await cache.client.pttlAsync(`multislots:${msg.author.id}`) return responder.error('{{dailyLimit}}', { time: `${moment(res + moment()).fromNow(true)}` }) @@ -119,8 +119,8 @@ class Multislots extends Command { } await user.save() await cache.client.multi() - .incrby(`slots:${msg.author.id}`, total) - .expire(`slots:${msg.author.id}`, 86400) + .incrby(`multislots:${msg.author.id}`, total) + .expire(`multislots:${msg.author.id}`, 86400) .execAsync() } catch (err) { return responder.error() From c276a185de4b14a8a16466be63f6e9100dc3d589 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 28 Jul 2017 12:58:22 -0500 Subject: [PATCH 06/15] :ambulance: revert previous commit and unifiy cooldowns --- src/commands/games/multislots.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/games/multislots.js b/src/commands/games/multislots.js index 38b0222..a148516 100644 --- a/src/commands/games/multislots.js +++ b/src/commands/games/multislots.js @@ -92,9 +92,9 @@ class Multislots extends Command { } async handle ({ msg, args, data, settings, cache }, responder) { - let dailyWins = await cache.client.getAsync(`multislots:${msg.author.id}`) - if (parseInt(dailyWins, 10) >= 750000) { - const res = await cache.client.pttlAsync(`multislots:${msg.author.id}`) + let dailyWins = await cache.client.getAsync(`slots:${msg.author.id}`) + if (parseInt(dailyWins, 10) >= 1000000) { + const res = await cache.client.pttlAsync(`slots:${msg.author.id}`) return responder.error('{{dailyLimit}}', { time: `${moment(res + moment()).fromNow(true)}` }) @@ -119,8 +119,8 @@ class Multislots extends Command { } await user.save() await cache.client.multi() - .incrby(`multislots:${msg.author.id}`, total) - .expire(`multislots:${msg.author.id}`, 86400) + .incrby(`slots:${msg.author.id}`, total) + .expire(`slots:${msg.author.id}`, 86400) .execAsync() } catch (err) { return responder.error() From 108bbb452804a035d1dd80d329069a46135c0804 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 3 Aug 2017 10:11:32 -0500 Subject: [PATCH 07/15] :construction: First part of pets enhancements --- src/commands/games/companions.js | 10 ++++++++-- src/models/Companion.js | 3 +++ src/modules/games/Companions.js | 12 ++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/commands/games/companions.js b/src/commands/games/companions.js index 8a8dbc5..a850e2c 100644 --- a/src/commands/games/companions.js +++ b/src/commands/games/companions.js @@ -34,7 +34,10 @@ class Companions extends Command { description: `**\`LVL ${Math.floor(Math.cbrt(companion.xp)) || 0}\`** :${companion.type}: ${companion.name}`, fields: [ { name: responder.t('{{definitions.wins}}'), value: stats.wins || 0, inline: true }, - { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true } + { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true }, + { name: responder.t('{{definitions.stats}}'), value: null, inline: false}, + { name: responder.t('{{definitions.mood}}'), value: stats.mood, inline: true}, + { name: responder.t('{{definitions.hunger}}'), value: stats.food, inline: true} ] }).send() } @@ -55,7 +58,10 @@ class Companions extends Command { description: `**\`LVL ${Math.floor(Math.cbrt(companion.xp)) || 0}\`** :${companion.type}: ${companion.name}`, fields: [ { name: responder.t('{{definitions.wins}}'), value: stats.wins || 0, inline: true }, - { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true } + { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true }, + { name: responder.t('{{definitions.stats}}') }, + { name: responder.t('{{definitions.mood}}'), value: stats.mood, inline: true}, + { name: responder.t('{{definitions.hunger}}'), value: stats.food, inline: true} ] }).send() } diff --git a/src/models/Companion.js b/src/models/Companion.js index a6007b3..8ec5308 100644 --- a/src/models/Companion.js +++ b/src/models/Companion.js @@ -19,6 +19,9 @@ module.exports = function () { hp: number().default(10), crit: number().default(1), atk: number().default(1), + heal: number().default(1), + mood: number().default(10), + hunger: number().default(10), inventory: array().default([]) }, relations: { diff --git a/src/modules/games/Companions.js b/src/modules/games/Companions.js index fe50d37..cbdf517 100644 --- a/src/modules/games/Companions.js +++ b/src/modules/games/Companions.js @@ -151,6 +151,7 @@ class Companions extends Module { hp: p1.hp || 10, crit: p1.crit || 1, atk: p1.atk || 1, + heal: p1.heal || 1, type: p1.type }, p2: { @@ -160,6 +161,7 @@ class Companions extends Module { hp: p2.hp || 10, crit: p2.crit || 1, atk: p2.atk || 1, + heal: p2.heal || 1, type: p2.type } } @@ -188,7 +190,9 @@ class Companions extends Module { battle._turn = turn const crit = stats[attacker].crit - const multiplier = Array(100).fill(2, 0, crit).fill(1, crit)[~~(Math.random() * 100)] + const critmultiplier = Array(100).fill(2, 0, crit).fill(1, crit)[~~(Math.random() * 100)] + const heal = stats[attacker].heal + const healmultiplier = Array(100).fill(2, 0, heal).fill(1, heal)[~~(Math.random() * 100)] const damagenum = Math.floor(Math.random() * (6 - 1 + 1)) + 1; const actionnum = Math.floor(Math.random() * (4 - 1 + 1)) + 1; switch (res) { @@ -197,13 +201,13 @@ class Companions extends Module { break } case 1: { - const dmg = (stats[attacker].atk * multiplier) - battle._actions.push(`${multiplier > 1 ? ':anger:' : ':punch:'} **${responder.t(`{{script.HIT_${damagenum}}}`, {p1: stats[attacker].name, p2: stats[receiver].name, dmg: dmg}) }**`) + const dmg = (stats[attacker].atk * critmultiplier) + battle._actions.push(`${critmultiplier > 1 ? ':anger:' : ':punch:'} **${responder.t(`{{script.HIT_${damagenum}}}`, {p1: stats[attacker].name, p2: stats[receiver].name, dmg: dmg}) }**`) battle._stats[receiver].hp -= dmg break } case 2: { - const heal = (1 * multiplier) + const heal = (1 * healmultiplier) battle._actions.push(`:sparkles: **${responder.t(`{{script.HEAL_${actionnum}}}`, {p1: stats[attacker].name, heal: heal}) }**`) battle._stats[attacker].hp += heal break From 9834972a510fed9612cca86af1c61ed0c3b19ca9 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 3 Aug 2017 16:32:54 -0500 Subject: [PATCH 08/15] :construction: more pets features, including hunger and mood --- resources/i18n/en/companion.json | 4 +++- src/commands/games/battle.js | 15 +++++++++++++++ src/commands/games/companions.js | 10 ++++------ src/modules/games/Companions.js | 6 ++++++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/resources/i18n/en/companion.json b/resources/i18n/en/companion.json index 7cf5438..eb2daea 100644 --- a/resources/i18n/en/companion.json +++ b/resources/i18n/en/companion.json @@ -21,7 +21,9 @@ "wins": "Wins", "losses": "Losses", "info": "Companion Info", - "info2": "{{author}}'s Companion" + "info2": "{{author}}'s Companion", + "mood": "Mood", + "hunger": "Food" }, "errors": { "self": "you can't battle yourself!", diff --git a/src/commands/games/battle.js b/src/commands/games/battle.js index 28d1861..76c21cc 100644 --- a/src/commands/games/battle.js +++ b/src/commands/games/battle.js @@ -47,9 +47,24 @@ class Battle extends Command { balance: `**${userProfile.credits}**` }) } + + if (userProfile.companion.hunger === 0) { + return responder.error('{{errors.hungry}}') + } + + if (userProfile.companion.mood === 0) { + return responder.error('{{errors.moody}}') + } + const oppProfile = await data.User.fetch(opp.id) if (!oppProfile.companion) return responder.error('{{errors.opponentNoCompanion}}') if (oppProfile.credits < this.entryFee) return responder.error('{{errors.cantChallenge}}') + if (oppProfile.companion.hunger === 0) { + return responder.error('{{errors.hungryOpponent}}') + } + if (oppProfile.companion.mood === 0) { + return responder.error('{{errors.moodyOpponent}}') + } try { await companions.initBattle(msg.author, opp, msg.channel, settings, responder, this.respondTime, this.entryFee) diff --git a/src/commands/games/companions.js b/src/commands/games/companions.js index a850e2c..7f20bda 100644 --- a/src/commands/games/companions.js +++ b/src/commands/games/companions.js @@ -35,9 +35,8 @@ class Companions extends Command { fields: [ { name: responder.t('{{definitions.wins}}'), value: stats.wins || 0, inline: true }, { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true }, - { name: responder.t('{{definitions.stats}}'), value: null, inline: false}, - { name: responder.t('{{definitions.mood}}'), value: stats.mood, inline: true}, - { name: responder.t('{{definitions.hunger}}'), value: stats.food, inline: true} + { name: responder.t('{{definitions.mood}}'), value: companion.mood || 10, inline: true}, + { name: responder.t('{{definitions.hunger}}'), value: companion.hunger || 10, inline: true} ] }).send() } @@ -59,9 +58,8 @@ class Companions extends Command { fields: [ { name: responder.t('{{definitions.wins}}'), value: stats.wins || 0, inline: true }, { name: responder.t('{{definitions.losses}}'), value: stats.losses || 0, inline: true }, - { name: responder.t('{{definitions.stats}}') }, - { name: responder.t('{{definitions.mood}}'), value: stats.mood, inline: true}, - { name: responder.t('{{definitions.hunger}}'), value: stats.food, inline: true} + { name: responder.t('{{definitions.mood}}'), value: companion.mood || 10, inline: true}, + { name: responder.t('{{definitions.hunger}}'), value: companion.hunger || 10, inline: true} ] }).send() } diff --git a/src/modules/games/Companions.js b/src/modules/games/Companions.js index cbdf517..d74c91f 100644 --- a/src/modules/games/Companions.js +++ b/src/modules/games/Companions.js @@ -257,10 +257,16 @@ class Companions extends Module { winUser.credits += battle.fee * 2 winUser.companion.xp = (winUser.companion.xp || 0) + ~~(Math.random() * 5) + 2 winUser.companion.stats.wins += 1 + winUser.companion.hunger -= 1 + if (winUser.companion.mood < 10) { + winUser.companion.mood += 1 + } const loseUser = await this.db.User.fetch(battle[loser], { companion: true }) loseUser.companion.xp = (loseUser.companion.xp || 0) + ~~(Math.random() * 3) + 1 loseUser.companion.stats.losses += 1 + loseUser.companion.hunger -= 1 + loseUser.companion.mood -= 1 await loseUser.saveAll({ companion: true }) await this.send(battle.channel, [ From ebfc082c8fedbffd771164cb30a958ad670177f9 Mon Sep 17 00:00:00 2001 From: Mark Date: Sat, 5 Aug 2017 21:45:30 -0500 Subject: [PATCH 09/15] :construction: Fully functional feeding and mood system --- resources/i18n/en/companion.json | 6 ++++ src/commands/games/companions.js | 59 ++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/resources/i18n/en/companion.json b/resources/i18n/en/companion.json index eb2daea..6d0a3f0 100644 --- a/resources/i18n/en/companion.json +++ b/resources/i18n/en/companion.json @@ -9,6 +9,12 @@ "Are you certain you'd like to purchase it for {{amount}} credits?\n", "To confirm, please write {{code}}, or anything else to exit." ], + "food": [ + "{{author}}, are you sure you'd like to feed your {{animal}} for {{amount}} food?\n", + "To confirm, please write {{code}}, or anything else to exit." + ], + "petFed": "{{author}}, you have just fed your {{animal}}, restoring their **hunger** and **mood** by {{amount}}", + "tooHungry": "Your companion is too full to feed it {{amount}} food!", "invalidCode": "you have entered an invalid code! The transaction was cancelled.", "error": "an error has occurred! The transaction was cancelled. Try again later.", "result": [ diff --git a/src/commands/games/companions.js b/src/commands/games/companions.js index 7f20bda..2b2d9ab 100644 --- a/src/commands/games/companions.js +++ b/src/commands/games/companions.js @@ -6,7 +6,7 @@ class Companions extends Command { super(...args, { name: 'companion', description: 'Animal companion system', - usage: [{ name: 'action', displayName: 'buy | rename | peek', type: 'string', optional: true }], + usage: [{ name: 'action', displayName: 'buy | rename | peek | feed', type: 'string', optional: true }], aliases: ['pet'], cooldown: 5, subcommands: { @@ -15,7 +15,10 @@ class Companions extends Command { usage: [{ name: 'user', type: 'member', optional: false }], options: { guildOnly: true } }, - rename: 'rename' + rename: 'rename', + feed: { + usage: [{ name: 'amount', type: 'int', optional: true }] + } }, options: { botPerms: ['embedLinks'] } }) @@ -41,6 +44,43 @@ class Companions extends Command { }).send() } + async feed ({ msg, args, data }, responder) { + const companion = (await data.User.fetchJoin(msg.author.id, { companion: true })).companion + if (!companion) { + responder.error('{{noPet}}', { command: `**\`${settings.prefix}${trigger} buy\`**` }) + return + } + const amount = args.amount || 1 + if ((companion.hunger + amount) > 10) { + responder.error('{{tooHungry}}', {amount: `**${amount}**`}) + return + } + const code = ~~(Math.random() * 8999) + 1000 + const arg = await responder.format('emoji:info').dialog([{ + prompt: '{{food}}', + input: { type: 'string', name: 'code' } + }], { + author: `**${msg.author.username}**`, + animal: `:${companion.type}:`, + amount: `**${amount}**`, + code: `**\`${code}\`**` + }) + if (parseInt(arg.code, 10) !== code) { + return responder.error('{{invalidCode}}') + } + if ((companion.mood + amount) > 10) { + companion.mood = 10 + } else { + companion.mood += amount + } + companion.hunger += amount + responder.format('emoji:success').send('{{petFed}}', { + author: `**${msg.author.username}**`, + animal: `:${companion.type}:`, + amount: `**${amount}**` + }) + } + async peek ({ args, data }, responder) { const [member] = await responder.selection(args.user, { mapFunc: m => `${m.user.username}#${m.user.discriminator}` }) if (!member) return @@ -224,4 +264,17 @@ class PetBuy extends Companions { } } -module.exports = [ Companions, PetBuy ] +class PetFeed extends Companions { + constructor (...args) { + super(...args, { + name: 'feedpet', + description: 'Feeds your personal companion', + options: { localeKey: 'companion' }, + aliases: [], + usage: [{ name: 'amount', type: 'int', optional: true }], + subcommand: 'feed' + }) + } +} + +module.exports = [ Companions, PetBuy, PetFeed ] From fa91e56e72e7bde72483e8656dafa13f9f619942 Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 6 Aug 2017 14:31:36 -0500 Subject: [PATCH 10/15] :construction :boom: Begin work on a basic shop --- resources/i18n/en/companion.json | 1 + src/commands/games/battle.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/i18n/en/companion.json b/resources/i18n/en/companion.json index 6d0a3f0..55d51bc 100644 --- a/resources/i18n/en/companion.json +++ b/resources/i18n/en/companion.json @@ -15,6 +15,7 @@ ], "petFed": "{{author}}, you have just fed your {{animal}}, restoring their **hunger** and **mood** by {{amount}}", "tooHungry": "Your companion is too full to feed it {{amount}} food!", + "noFood": "You have no food in your inventory to feed your {{animal}}!", "invalidCode": "you have entered an invalid code! The transaction was cancelled.", "error": "an error has occurred! The transaction was cancelled. Try again later.", "result": [ diff --git a/src/commands/games/battle.js b/src/commands/games/battle.js index 76c21cc..8e5332a 100644 --- a/src/commands/games/battle.js +++ b/src/commands/games/battle.js @@ -48,11 +48,11 @@ class Battle extends Command { }) } - if (userProfile.companion.hunger === 0) { + if (userProfile.companion.hunger < 1) { return responder.error('{{errors.hungry}}') } - if (userProfile.companion.mood === 0) { + if (userProfile.companion.mood < 1) { return responder.error('{{errors.moody}}') } From 6e0956714b60ca2e4d432e8205b2013d59e004ae Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 10 Aug 2017 13:02:31 -0500 Subject: [PATCH 11/15] :construction: More work on pet feeding system --- resources/i18n/en/shop.json | 11 +++++++ src/commands/games/companions.js | 7 +++++ src/commands/games/shop.js | 51 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 resources/i18n/en/shop.json create mode 100644 src/commands/games/shop.js diff --git a/resources/i18n/en/shop.json b/resources/i18n/en/shop.json new file mode 100644 index 0000000..0f70000 --- /dev/null +++ b/resources/i18n/en/shop.json @@ -0,0 +1,11 @@ +{ + "buyDialog": "Items for purchase", + "sellDialog": "Items for sale", + "menu": { + "food": "Bag of generic pet food. Raises food by 1" + }, + "purchase": [ + "{{author}}, are you sure you'd like to purchase {{selection}}?\n", + "To confirm, please write {{code}}, or anything else to exit." + ] +} diff --git a/src/commands/games/companions.js b/src/commands/games/companions.js index 2b2d9ab..b4d9f6f 100644 --- a/src/commands/games/companions.js +++ b/src/commands/games/companions.js @@ -45,6 +45,7 @@ class Companions extends Command { } async feed ({ msg, args, data }, responder) { + const user = await data.User.fetch(msg.author.id) const companion = (await data.User.fetchJoin(msg.author.id, { companion: true })).companion if (!companion) { responder.error('{{noPet}}', { command: `**\`${settings.prefix}${trigger} buy\`**` }) @@ -55,6 +56,12 @@ class Companions extends Command { responder.error('{{tooHungry}}', {amount: `**${amount}**`}) return } + console.log(user.inventory) + var userInvArray = user.inventory + var userInv = userInvArray.values() + for (let value of userInv) { + console.log(value) + } const code = ~~(Math.random() * 8999) + 1000 const arg = await responder.format('emoji:info').dialog([{ prompt: '{{food}}', diff --git a/src/commands/games/shop.js b/src/commands/games/shop.js new file mode 100644 index 0000000..d7705bb --- /dev/null +++ b/src/commands/games/shop.js @@ -0,0 +1,51 @@ +const logger = require('winston') +const { Command } = require('../../core') + +class Shop extends Command { + constructor (...args) { + super(...args, { + name: 'shop', + description: 'A small shop to buy things with credits', + options: { localeKey: 'shop' } + }) + } + + handle (container, responder) { + const { msg, data, settings } = container + return responder.selection(['food', 'null'], { + title: '{{buyDialog}}', + mapFunc: ch => responder.t(`{{menu.${ch}}}`) + }).then(arg => arg.length ? this[arg[0]](container, responder) : false) + } + + async food ({ msg, data, settings }, responder) { + const user = await data.User.fetch(msg.author.id) + const price = 100 + if (user.credits < price) { + responder.error('{{cannotAfford}}', { + amount: `**${price}**`, + balance: `**${user.credits}**` + }) + return + } + const code = ~~(Math.random() * 8999) + 1000 + const arg = await responder.format('emoji:info').dialog([{ + prompt: '{{purchase}}', + input: { type: 'string', name: 'code' } + }], { + author: `**${msg.author.username}**`, + selection: `food`, + //amount: `**${amount}**`, + code: `**\`${code}\`**` + }) + if (parseInt(arg.code, 10) !== code) { + return responder.error('{{invalidCode}}') + } + console.log(user.inventory) + user.inventory.push('food') + console.log(user.inventory) + responder.success(`Yay`) + } + +} +module.exports = [Shop] From bd575109fae4edb19827716c9c2f45f03afbf85d Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 14 Aug 2017 12:48:12 -0500 Subject: [PATCH 12/15] :sparkles: Fully functional shop and major pets reworks What's happened: -Functional shop -Inventory checker -Pet hunger and mood -Pet feeding command --- resources/i18n/en/companion.json | 10 +++++-- resources/i18n/en/shop.json | 18 ++++++++++-- src/commands/games/battle.js | 8 +++--- src/commands/games/companions.js | 19 +++++++++---- src/commands/games/shop.js | 49 ++++++++++++++++++++++++++------ src/models/User.js | 1 + 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/resources/i18n/en/companion.json b/resources/i18n/en/companion.json index 55d51bc..959d24a 100644 --- a/resources/i18n/en/companion.json +++ b/resources/i18n/en/companion.json @@ -10,12 +10,12 @@ "To confirm, please write {{code}}, or anything else to exit." ], "food": [ - "{{author}}, are you sure you'd like to feed your {{animal}} for {{amount}} food?\n", + "{{author}}, are you sure you'd like to feed your {{animal}} {{amount}} food?\n", "To confirm, please write {{code}}, or anything else to exit." ], "petFed": "{{author}}, you have just fed your {{animal}}, restoring their **hunger** and **mood** by {{amount}}", "tooHungry": "Your companion is too full to feed it {{amount}} food!", - "noFood": "You have no food in your inventory to feed your {{animal}}!", + "notEnoughFood": "You can't feed your {{animal}} {{amount}} food as you only have {{inv}} in your inventory!", "invalidCode": "you have entered an invalid code! The transaction was cancelled.", "error": "an error has occurred! The transaction was cancelled. Try again later.", "result": [ @@ -51,7 +51,11 @@ "plsBetProperly": "you can't bet less than one credit!", "notBetting": "the battle has not entered the betting phase!", "afterBetting": "the betting phase has already concluded for this battle!", - "notOnline": "that user is not online yet!" + "notOnline": "that user is not online yet!", + "hungry": "your companion is too hungry to battle", + "moody": "your companion's mood is too low to battle", + "hungryOpponent": "your opponent's companion is too hungry to battle", + "moodyOpponent": "your opponent's companion's mood is too low to battle" }, "challenge": [ "you have challenged {{mention}} to a pet battle!\n", diff --git a/resources/i18n/en/shop.json b/resources/i18n/en/shop.json index 0f70000..180c102 100644 --- a/resources/i18n/en/shop.json +++ b/resources/i18n/en/shop.json @@ -2,10 +2,22 @@ "buyDialog": "Items for purchase", "sellDialog": "Items for sale", "menu": { - "food": "Bag of generic pet food. Raises food by 1" + "food": "Bag of generic pet food. Raises food by 1", + "checkInv": "Check your current inventory" }, + "howMuch": "{{author}}, how many {{selection}} would you like to buy?", "purchase": [ - "{{author}}, are you sure you'd like to purchase {{selection}}?\n", + "{{author}}, are you sure you'd like to purchase {{amount}} {{selection}}?\n", "To confirm, please write {{code}}, or anything else to exit." - ] + ], + "result": [ + "**Food Purchased**\n", + "{{author}}, you have successfully purchased {{amount}} {{selection}}.", + "__Current Balance__: {{balance}} credits\n" + ], + "error": "an error has occurred! The transaction was cancelled. Try again later.", + "info": "Current Inventory", + "amounts": { + "petFood": "Pet food" + } } diff --git a/src/commands/games/battle.js b/src/commands/games/battle.js index 8e5332a..7a66174 100644 --- a/src/commands/games/battle.js +++ b/src/commands/games/battle.js @@ -48,21 +48,21 @@ class Battle extends Command { }) } - if (userProfile.companion.hunger < 1) { + if (userProfile.companion.hunger <= 1) { return responder.error('{{errors.hungry}}') } - if (userProfile.companion.mood < 1) { + if (userProfile.companion.mood <= 1) { return responder.error('{{errors.moody}}') } const oppProfile = await data.User.fetch(opp.id) if (!oppProfile.companion) return responder.error('{{errors.opponentNoCompanion}}') if (oppProfile.credits < this.entryFee) return responder.error('{{errors.cantChallenge}}') - if (oppProfile.companion.hunger === 0) { + if (oppProfile.companion.hunger === 1) { return responder.error('{{errors.hungryOpponent}}') } - if (oppProfile.companion.mood === 0) { + if (oppProfile.companion.mood === 1) { return responder.error('{{errors.moodyOpponent}}') } diff --git a/src/commands/games/companions.js b/src/commands/games/companions.js index b4d9f6f..97b4c83 100644 --- a/src/commands/games/companions.js +++ b/src/commands/games/companions.js @@ -56,11 +56,13 @@ class Companions extends Command { responder.error('{{tooHungry}}', {amount: `**${amount}**`}) return } - console.log(user.inventory) - var userInvArray = user.inventory - var userInv = userInvArray.values() - for (let value of userInv) { - console.log(value) + if (user.petfood < amount) { + responder.error('{{notEnoughFood}}', { + amount: `**${amount}**`, + inv: `**${user.petfood}**`, + animal: `:${companion.type}:` + }) + return } const code = ~~(Math.random() * 8999) + 1000 const arg = await responder.format('emoji:info').dialog([{ @@ -81,6 +83,13 @@ class Companions extends Command { companion.mood += amount } companion.hunger += amount + try { + await user.saveAll() + await data.User.update(user.id, user) + } catch (err) { + logger.error(`Could not save after companion feeding: ${err}`) + return responder.error('{{error}}') + } responder.format('emoji:success').send('{{petFed}}', { author: `**${msg.author.username}**`, animal: `:${companion.type}:`, diff --git a/src/commands/games/shop.js b/src/commands/games/shop.js index d7705bb..8875a99 100644 --- a/src/commands/games/shop.js +++ b/src/commands/games/shop.js @@ -12,7 +12,7 @@ class Shop extends Command { handle (container, responder) { const { msg, data, settings } = container - return responder.selection(['food', 'null'], { + return responder.selection(['food', 'checkInv'], { title: '{{buyDialog}}', mapFunc: ch => responder.t(`{{menu.${ch}}}`) }).then(arg => arg.length ? this[arg[0]](container, responder) : false) @@ -20,7 +20,15 @@ class Shop extends Command { async food ({ msg, data, settings }, responder) { const user = await data.User.fetch(msg.author.id) - const price = 100 + const arg = await responder.format('emoji:info').dialog([{ + prompt: '{{howMuch}}', + input: { type: 'int', name: 'howMuch' } + }], { + author: `**${msg.author.username}**`, + selection: `food` + }) + const amount = arg.howMuch + const price = (100 * amount) if (user.credits < price) { responder.error('{{cannotAfford}}', { amount: `**${price}**`, @@ -29,22 +37,45 @@ class Shop extends Command { return } const code = ~~(Math.random() * 8999) + 1000 - const arg = await responder.format('emoji:info').dialog([{ + const argCode = await responder.format('emoji:info').dialog([{ prompt: '{{purchase}}', input: { type: 'string', name: 'code' } }], { author: `**${msg.author.username}**`, selection: `food`, - //amount: `**${amount}**`, + amount: `**${amount}**`, code: `**\`${code}\`**` }) - if (parseInt(arg.code, 10) !== code) { + if (parseInt(argCode.code, 10) !== code) { return responder.error('{{invalidCode}}') } - console.log(user.inventory) - user.inventory.push('food') - console.log(user.inventory) - responder.success(`Yay`) + user.petfood += amount + user.credits -= price + try { + await user.saveAll() + await data.User.update(user.id, user) + } catch (err) { + logger.error(`Could not save after food purchase: ${err}`) + return responder.error('{{error}}') + } + responder.format('emoji:success').send('{{result}}', { + author: `**${msg.author.username}**`, + amount: `**${amount}**`, + selection: `food`, + balance: `:credits: **${user.credits}**` + }) + } + + async checkInv ({ msg, data, settings }, responder){ + const user = await data.User.fetch(msg.author.id) + responder.embed({ + color: this.colours.blue, + author: { name: responder.t('{{info}}'), icon_url: msg.author.avatarURL }, + description: `:credit_card: ${user.credits}`, + fields: [ + { name: responder.t('{{amounts.petFood}}'), value: user.petfood || 0, inline: true } + ] + }).send() } } diff --git a/src/models/User.js b/src/models/User.js index f5557b9..9e6ebb2 100644 --- a/src/models/User.js +++ b/src/models/User.js @@ -11,6 +11,7 @@ module.exports = function () { id: string(), credits: number().default(0), exp: number().default(0), + petfood: number().default(0), deleted: bool().default(false), title: string().default('Commoner'), description: string().default('A simple wandering soul'), From a32c2a24e863be9ba5db4a7f6d4a2a9195a37653 Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 14 Aug 2017 15:32:19 -0500 Subject: [PATCH 13/15] Update shop.json --- resources/i18n/en/shop.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/i18n/en/shop.json b/resources/i18n/en/shop.json index 180c102..3bf586b 100644 --- a/resources/i18n/en/shop.json +++ b/resources/i18n/en/shop.json @@ -16,6 +16,7 @@ "__Current Balance__: {{balance}} credits\n" ], "error": "an error has occurred! The transaction was cancelled. Try again later.", + "cannotAfford": "I'm sorry, you need {{ammount}} credits to buy that but you only have {{balance}}", "info": "Current Inventory", "amounts": { "petFood": "Pet food" From 39a61640f95ffb81e3741b7c01cd18cd4e0f17e2 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 24 Aug 2017 08:27:25 -0500 Subject: [PATCH 14/15] Fix start of battle emoji --- src/modules/games/Companions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/games/Companions.js b/src/modules/games/Companions.js index d74c91f..ab57953 100644 --- a/src/modules/games/Companions.js +++ b/src/modules/games/Companions.js @@ -186,7 +186,7 @@ class Companions extends Module { const res = this.outcomes[~~(Math.random() * 100)] if (!stats[attacker] || !stats[receiver]) return - if (battle._turn < 0) battle._actions.push(':info: **Match begins!**') + if (battle._turn < 0) battle._actions.push(':information_source: **Match begins!**') battle._turn = turn const crit = stats[attacker].crit From f213618dee90adc6559fd43258efa41a25b2d88a Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 1 Sep 2017 17:17:39 -0500 Subject: [PATCH 15/15] :art: Update Autorole helptext Added a better usage for autorole --- src/commands/moderation/autorole.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/moderation/autorole.js b/src/commands/moderation/autorole.js index 6498c5c..3fbd519 100644 --- a/src/commands/moderation/autorole.js +++ b/src/commands/moderation/autorole.js @@ -7,7 +7,7 @@ class Autorole extends Command { name: 'autorole', description: 'Add a role to a user on join', usage: [ - { name: 'action', displayName: ' add | remove', type: 'string', optional: true }], + { name: 'action', displayName: ' add <@role> | remove', type: 'string', optional: true }], subcommands: { add: { usage: [