From 322fef7c3c324ba2ecbf6974d77dac54061dab42 Mon Sep 17 00:00:00 2001 From: WubzyGD Date: Sun, 2 Jan 2022 05:33:29 -0700 Subject: [PATCH] chests spawn now yay it's 5:30am going sleep now --- bot.js | 3 ++ commands/leveling/chests.js | 70 ++++++++++++++++++++++++++ commands/leveling/setupleveling.js | 4 +- events/messageCreate.js | 2 + models/char.js | 3 +- models/chests.js | 8 +++ models/localxp.js | 3 +- util/cache.js | 5 ++ util/cache/chest.js | 9 ++++ util/cache/lxp.js | 1 + util/lxp/spawnchest.js | 80 ++++++++++++++++++++++++++++++ 11 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 commands/leveling/chests.js create mode 100644 models/chests.js create mode 100644 util/cache/chest.js create mode 100644 util/lxp/spawnchest.js diff --git a/bot.js b/bot.js index 15ef176..2edc42d 100644 --- a/bot.js +++ b/bot.js @@ -34,6 +34,8 @@ client.misc = { hasLevelRoles: [], disabledChannels: new Map() }, + chests: [], + chestsTimeout: new Map(), monit: {}, monitEnabled: [], inVC: [], @@ -126,6 +128,7 @@ async function init() { client.utils.logch = async () => {return client.guilds.cache.get('762707532417335296').channels.cache.get('762732961753595915');}; client.utils.s = num => num === 1 ? '' : 's'; client.utils.as = (num, text) => `${text}${client.utils.s(num)}`; + client.utils.an = (text, caps) => `${caps ? 'A' : 'a'}${['a', 'e', 'i', 'o'].includes(text.toLowerCase().trim().slice(0, 1)) ? 'n' : ''} ${text}`; client.guildconfig = {}; client.guildconfig.prefixes = new Map(); diff --git a/commands/leveling/chests.js b/commands/leveling/chests.js new file mode 100644 index 0000000..2626b49 --- /dev/null +++ b/commands/leveling/chests.js @@ -0,0 +1,70 @@ +const Discord = require('discord.js'); + +const Chests = require("../../models/chests"); + +const ask = require('../../util/ask'); + +module.exports = { + name: "chests", + aliases: ['setupchests', 'enablechests', 'togglechests', 'tch'], + meta: { + category: 'Leveling', + description: "Enable or disable chests in your server, or set a channel for them to spawn in", + syntax: '`chests [enable|disable|toggle|channel]`', + extra: null, + guildOnly: true + }, + help: new Discord.MessageEmbed() + .setTitle("Help -> Chests") + .setDescription("Enable or disable chests in your server, or set a channel for them to spawn in") + .addField("Notice", "You must have administrator permissions to edit these settings.") + .addField("Syntax", "`chests [enable|disable|channel]`"), + async execute(message, msg, args, cmd, prefix, mention, client) { + if (!message.member.permissions.has("ADMINISTRATOR")) {return message.channel.send("You must have administrator permissions in order to edit these settings.");} + if (!args.length) {args[0] = 'enable';} + + if (['e', 'enable'].includes(args[0].toLowerCase())) { + if (client.misc.cache.chests.includes(message.guild.id)) {return message.channel.send("This server already has chest spawning enabled.")}; + try { + am = await message.channel.send("Would you like to have me send chests to a specific channel?"); + await am.react('👍'); + await am.react('👎'); + } catch {return message.channel.send(":thinking: hmmm... something went wrong there. I might not have permissions to add reactions to messages, and this could be the issue.");} + try { + let rc = am.createReactionCollector({filter: (r, u) => ['👍', '👎'].includes(r.emoji.name) && u.id === message.author.id, max: 1, time: 60000}); + rc.on("collect", async r => { + useCh = r.emoji.name === "👍"; + let chestCh = ''; + if (useCh) { + let chestCh = await ask(message, 'What channel would you like me to send chests to? (Ideally, people should be able to speak in it so they can claim the chests)', 60000, false, true); + if (!chestCh) {return;} + if (!message.guild.channels.cache.has(chestCh) || !message.guild.channels.cache.has(chestCh.slice(2, chestCh.length - 1))) {return message.channel.send("That doesn't seem to be a channel! Try again?");} + if (chestCh.startsWith("<")) {chestCh = chestCh.slice(2, chestCh.length - 1);} + } + let c = new Chests({gid: message.guild.id, channel: chestCh}); + c.save(); + client.misc.cache.chests.push(message.guild.id); + return message.channel.send({embeds: [new Discord.MessageEmbed() + .setTitle("Chest Spawning Enabled!") + .setThumbnail(message.guild.iconURL({size: 2048})) + .setDescription(`Your server now has its chest spawning enabled! Chests will spawn in ${chestCh.length ? `<#${chestCh}>` : 'any channel'}.`) + .setColor("c375f0") + .setFooter({text: "Natsuki", iconURL: client.user.avatarURL()}) + .setTimestamp() + ]}); + }); + rc.on("end", collected => {if (!collected.size) {return message.channel.send("Looks like you ran out of time! Try again?");}}); + } catch {return message.channel.send("Hmm... there was some error problem thingy that happened when I tried to enable chest spawning for your server. If it keeps not working, then go yell at my devs!");} + } + + else if (['d', 'disable'].includes(args[0].toLowerCase())) { + + } + + else if (['c', 'ch', 'setchannel', 'setch ', 'sc', 'sch', 'enable'].includes(args[0].toLowerCase())) { + + } + + else {return message.channel.send(`Invalid arg! Syntax: \`${prefix}chests [enable|disable|channel]\``);} + } +}; \ No newline at end of file diff --git a/commands/leveling/setupleveling.js b/commands/leveling/setupleveling.js index 77f1bcb..0532a31 100644 --- a/commands/leveling/setupleveling.js +++ b/commands/leveling/setupleveling.js @@ -14,7 +14,7 @@ module.exports = { }, help: new Discord.MessageEmbed() .setTitle("Help -> Local Leveling Setup") - .setDescription("Set up your local leveling system to allow your server's members to progress in ranks, which lets you enable leveling roles and shops *features not available at this time*") //TODO remove the "features not available" as soon as they are available + .setDescription("Set up your local leveling system to allow your server's members to progress in ranks, which lets you enable leveling roles") .addField("Syntax", "`setupleveling`") .addField("Important Notice", "You must be a server administrator in order to use this command. Please know that local leveling systems can cost a great deal of our database storage space when used on larger servers, so please only enable this feature **if you will actually make use of it**, not just for fun."), async execute(message, msg, args, cmd, prefix, mention, client) { @@ -36,7 +36,7 @@ module.exports = { return message.channel.send({embeds: [new Discord.MessageEmbed() .setTitle("XP System Enabled!") .setThumbnail(message.guild.iconURL({size: 2048})) - .setDescription(`Your server now has its leveling system enabled! If you enabled level up messages, you can set the channel for that using \`${prefix}levelchannel\`.`) //TODO update this with info on how the shiz works + .setDescription(`Your server now has its leveling system enabled! If you enabled level up messages, you can set the channel for that using \`${prefix}levelchannel\`.\n\nAll members of your server will now gain XP as they talk. I'm a smart cookie, so don't try spamming. It won't work. Every member can gain more XP once per minute, no matter how many messages they send in that one minute.\n\nIf you want to see your level and how much more XP you need to level up, run \`${prefix}stats\`.`) .setColor("c375f0") .setFooter({text: "Natsuki", iconURL: client.user.avatarURL()}) .setTimestamp() diff --git a/events/messageCreate.js b/events/messageCreate.js index f43f499..acf81f1 100644 --- a/events/messageCreate.js +++ b/events/messageCreate.js @@ -78,6 +78,8 @@ module.exports = async (client, message) => { } } + if (message.guild && client.misc.cache.chests.includes(message.guild.id)) {require('../util/lxp/spawnchest')(client, message.member, message.channel, prefix);} + if (!client.misc.cache.monners[message.author.id]) { let tmonners = await Monners.findOne({uid: message.author.id}) || new Monners({uid: message.author.id}); client.misc.cache.monners[message.author.id] = tmonners.currency; diff --git a/models/char.js b/models/char.js index 857c4f5..0b16f1f 100644 --- a/models/char.js +++ b/models/char.js @@ -11,7 +11,8 @@ const char = new mongoose.Schema({ personality: {type: String, defualt: null}, gender: String, loveInterest: {type: String, defualt: null}, - queued: {type: Boolean, default: true} + queued: {type: Boolean, default: true}, + highValue: {type: Boolean} }); module.exports = mongoose.model('char', char); \ No newline at end of file diff --git a/models/chests.js b/models/chests.js new file mode 100644 index 0000000..df298f4 --- /dev/null +++ b/models/chests.js @@ -0,0 +1,8 @@ +const mongoose = require('mongoose'); + +const Chests = new mongoose.Schema({ + gid: {type: String, unique: true}, + channel: {type: String, default: ''} +}); + +module.exports = mongoose.model('chests', Chests); \ No newline at end of file diff --git a/models/localxp.js b/models/localxp.js index 35e4a9d..5827d3d 100644 --- a/models/localxp.js +++ b/models/localxp.js @@ -5,8 +5,7 @@ const lxp = new mongoose.Schema({ msg: {type: Boolean, default: true}, xp: {type: Object, default: {}}, lvch: {type: String, default: ''}, - chests: {type: Object}, - noGains: {type: [String]} + noGains: [String] }); module.exports = mongoose.model('localxp', lxp); \ No newline at end of file diff --git a/util/cache.js b/util/cache.js index 7ab7e47..979ae29 100644 --- a/util/cache.js +++ b/util/cache.js @@ -38,4 +38,9 @@ module.exports = async (client) => { await require('./cache/char')(client); ora_chCache.stop(); ora_chCache.clear(); console.log(`${chalk.gray('[PROC]')} >> ${chalk.blueBright(`Cached`)} ${chalk.white(`${client.misc.cache.charsNum}`)} ${chalk.blueBright(`characters into lookup registry.`)} ${chalk.gray(`(${client.misc.cache.chars.size} // NN)`)}`); + + let ora_ctCache = ora("Caching Chests...").start(); + await require('./cache/chest')(client); + ora_ctCache.stop(); ora_ctCache.clear(); + console.log(`${chalk.gray('[PROC]')} >> ${chalk.blueBright(`Cached`)} ${chalk.white(`${client.misc.cache.chests.length}`)} ${chalk.blueBright("guilds that spawn chests.")}`); }; \ No newline at end of file diff --git a/util/cache/chest.js b/util/cache/chest.js new file mode 100644 index 0000000..8e9ec65 --- /dev/null +++ b/util/cache/chest.js @@ -0,0 +1,9 @@ +const Chests = require('../../models/chests'); + +module.exports = async client => { + client.misc.cache.chests = []; + + for await (const chest of Chests.find()) { + client.misc.cache.chests.push(chest.gid); + } +}; \ No newline at end of file diff --git a/util/cache/lxp.js b/util/cache/lxp.js index 97be344..754d7c2 100644 --- a/util/cache/lxp.js +++ b/util/cache/lxp.js @@ -3,6 +3,7 @@ const LXP = require('../../models/localxp'); module.exports = async client => { client.misc.cache.lxp.enabled = []; client.misc.cache.lxp.disabledChannels = new Map(); + client.misc.cache.chests = new Map(); for await (const xp of LXP.find()) { client.misc.cache.lxp.enabled.push(xp.gid); diff --git a/util/lxp/spawnchest.js b/util/lxp/spawnchest.js new file mode 100644 index 0000000..58680f4 --- /dev/null +++ b/util/lxp/spawnchest.js @@ -0,0 +1,80 @@ +const Monners = require('../../models/monners'); +const Chests = require('../../models/chests'); +const manyitems = require('manyitems'); +const Discord = require('discord.js'); + +module.exports = async (client, member, channel, prefix) => { + if (client.misc.cache.chestsTimeout.has(member.guild.id) && new Date().getTime() - client.misc.cache.chestsTimeout.get(member.guild.id) < (1000 * 60 * 2)) {return;} + //let rand = Math.floor(Math.random() * 100); + //if (rand !== 69) {return;} //decide if it even continues + + let tm = await Monners.findOne({uid: member.id}); + let streak = tm && tm.daily ? tm.daily.streak : 0; //get streak for bonus later + + let rarities = [ //decide rarity + { + rarity: 100, + name: 'Common', + color: '586269', + amount: 40 + }, { + rarity: 40, + name: 'Uncommon', + color: '449e77', + amount: 120 + }, { + rarity: 20, + name: 'Rare', + color: '459dcc', + amount: 300 + }, { + rarity: 10, + name: 'Legendary', + color: '7951bd', + amount: 750 + }, { + rarity: 1, + name: 'Epic', + color: 'c7a756', + amount: 1250 + }, { + rarity: 0.02, + name: 'Godly', + color: 'fa25be', + amount: 20000 + } + ]; + let rareNum = (Math.ceil(Math.random() * 10000)) / 100; + let rarity; + for (let i = 0; i < Object.keys(rarities).length; i++) { //loop that reassigns to a higher rarity until the rarity value is lower than its requirement + if (rareNum < (100 - rarities[i].rarity)) {break;} + else {rarity = rarities[i];} + } + + let ri = new manyitems.Random("bubble", undefined, { + min: rarity.amount - (rarity.amount * .10), + max: rarity.amount + (rarity.amount * .10) + (rarity.amount * .10 * 1.25 * streak) + }); + let streakBonus = streak !== 0 ? Math.floor((Math.floor(Math.random() * (rarity.amount * .10)) * 1.5 * streak)) : 0; + let amount = ri.calc_bubble() + streakBonus; //calculate the amount by allowing a 10% +/- variance, higher potential with higher streak, and adding another random bonus with streak + + let chests = await Chests.findOne({gid: member.guild.id}); + if (!chests) {return;} + let spawnChannel = chests.channel && chests.channel.length ? chests.channel : channel; + + client.misc.cache.chestsTimeout.set(member.guild.id, new Date().getTime()); + + let chestEmbed = new Discord.MessageEmbed() + .setTitle(`${client.utils.an(rarity.name, true)} Chest has spawned!`) + .setDescription(`It has **${amount} Monners<:monners:926736756047495218>**`) + .setFooter({text: `Type \`${prefix}claim\` to claim it!`}) + .setColor(rarity.color) //create the chest message + + if (spawnChannel === channel) {return channel.send({embeds: [chestEmbed]}).catch(() => {});} + else { + member.guild.channels.fetch(spawnChannel) + .then(ch => ch.send({embeds: [chestEmbed]}).catch(() => {})) + .catch(() => {}) + } + return spawnChannel.send({embeds: [chestEmbed]}); //spawn the chest +}; \ No newline at end of file