diff --git a/assets/nuts_box.png b/assets/nuts_box.png new file mode 100644 index 0000000..b57194f Binary files /dev/null and b/assets/nuts_box.png differ diff --git a/commands/nuts/nuts.js b/commands/nuts/nuts.js index 0a49cab..f405f7d 100644 --- a/commands/nuts/nuts.js +++ b/commands/nuts/nuts.js @@ -138,54 +138,70 @@ async function nutsLeaderboard(interaction) { }) } async function nutsStats(interaction) { - const db = mClient.db(process.env.M_DB) - const nStatsColl = db.collection('stats_nuts') - const stats = await nStatsColl.find({}).sort({ amount: 1 }).toArray() - let nutMin = { - count: 0, - amount: 0 + const db = mClient.db(process.env.M_DB); + const nStatsColl = db.collection('stats_nuts'); + + // fetch user stats + const statsDoc = await nStatsColl.findOne({ userID: interaction.user.id }); + const stat = statsDoc?.stat || {}; // fallback to empty object + + // compute totals + const totalCount = Object.values(stat).reduce((a, b) => a + b, 0); + const totalNuts = Object.entries(stat).reduce( + (sum, [num, count]) => sum + Number(num) * count, + 0 + ); + + const rolledNumbers = Object.entries(stat).filter(([_, count]) => count > 0); + + let nutMin = { number: 0, count: 0 }; + let nutMax = { number: 0, count: 0 }; + + if (rolledNumbers.length > 0) { + // initialize to first rolled number + nutMin = nutMax = { number: Number(rolledNumbers[0][0]), count: rolledNumbers[0][1] }; + + for (const [numStr, count] of rolledNumbers) { + const num = Number(numStr); + + // best nut: prefer higher number if counts tie + if (count > nutMax.count || (count === nutMax.count && num > nutMax.number)) { + nutMax = { number: num, count }; + } + + // worst nut: prefer lower number if counts tie + if (count < nutMin.count || (count === nutMin.count && num < nutMin.number)) { + nutMin = { number: num, count }; + } + } } - let nutMax = { - count: 0, - amount: 0 - } - let totalNuts = 0 - let totalCount = 0 - stats.forEach(stat => { - totalCount += stat.count - totalNuts += (stat.count * stat.amount) - if (nutMin.count > stat.count) { nutMin = stat } - if (nutMax.count < stat.count) { nutMax = stat } - }) - let nutAvg = totalNuts / totalCount + + const nutAvg = totalCount ? totalNuts / totalCount : 0; + + // dynamically create fields for numbers 0-9 + const fields = Array.from({ length: 10 }, (_, i) => ({ + name: `[${i}]`, + value: `x${stat[i] ?? 0}`, + inline: true + })); + const embed = new EmbedBuilder() .setTitle("Nut Statistic") .setDescription( - `Total Nut Actions: **${totalCount}**\r\n - Total Nuts nutted: **${totalNuts}**\r\n - Nut Average: **${nutAvg.toFixed(3)}**\r\n - Best Nut: **${nutMax.amount}**\r\n - Worst Nut: **${nutMin.amount}**` - ) - .addFields( - { name: '[0]', value: `x${stats[0].count}`, inline: true }, - { name: '[1]', value: `x${stats[1].count}`, inline: true }, - { name: '[2]', value: `x${stats[2].count}`, inline: true }, - { name: '[3]', value: `x${stats[3].count}`, inline: true }, - { name: '[4]', value: `x${stats[4].count}`, inline: true }, - { name: '[5]', value: `x${stats[5].count}`, inline: true }, - { name: '[6]', value: `x${stats[6].count}`, inline: true }, - { name: '[7]', value: `x${stats[7].count}`, inline: true }, - { name: '[8]', value: `x${stats[8].count}`, inline: true }, - { name: '[9]', value: `x${stats[9].count}`, inline: true } + `Total Nut Actions: **${totalCount}**\r\n` + + `Total Nuts nutted: **${totalNuts}**\r\n` + + `Nut Average: **${nutAvg.toFixed(3)}**\r\n` + + `Best Nut: **${nutMax.number} (x${nutMax.count})**\r\n` + + `Worst Nut: **${nutMin.number} (x${nutMin.count})**` ) + .addFields(fields) .setColor(0x51267) .setTimestamp() - .setThumbnail(interaction.guild.iconURL()) - await interaction.editReply({ - embeds: [embed] - }) + .setThumbnail(interaction.guild.iconURL()); + + await interaction.editReply({ embeds: [embed] }); } + async function nutsCooldown(interaction) { const db = mClient.db(process.env.M_DB) const nutsColl = db.collection('items_cooldowns') @@ -215,10 +231,11 @@ async function nutsNut(interaction) { const db = mClient.db(process.env.M_DB) const nutsColl = db.collection('items_nuts') const cdColl = db.collection('items_cooldowns') + const nutsStatsColl = db.collection('stats_nuts') const cdData = await cdColl.findOne({ userID: interaction.user.id }) const embed = new EmbedBuilder() - .setThumbnail('https://cdn.discordapp.com/attachments/1152723542836772914/1152991361113538621/png-transparent-subscription-box-label-bag-mysterious-miscellaneous-purple-blue-thumbnail-PhotoRoom.png-PhotoRoom.png') + .setImage('https://e7.pngegg.com/pngimages/1011/894/png-clipart-gift-christmas-box-mystery-gift-box-holidays-box-thumbnail.png') let content const images = { @@ -249,6 +266,15 @@ async function nutsNut(interaction) { upsert: true }) + await nutsStatsColl.findOneAndUpdate({ + userID: interaction.user.id + }, { + $inc: { [`stat.${amount}`]: 1 } + }, { + upsert: true + } + ); + if (amount) { content = `Du hast **${amount}** Nüsse bekommen!` if (amount > 8) { @@ -262,6 +288,7 @@ async function nutsNut(interaction) { content = `Du hast leider keine Nüsse bekommen :(` image = images["none"] } + } else { content = `Du kannst erst wieder nussen :(` image = images["onCD"] @@ -277,14 +304,14 @@ async function nutsNut(interaction) { embeds: [embed] }) await delay(1000) - embed.setThumbnail('https://i.pinimg.com/originals/9d/58/37/9d5837c6f0cb8b18be6ddd1e2742472a.gif') + embed.setImage('https://i.pinimg.com/originals/9d/58/37/9d5837c6f0cb8b18be6ddd1e2742472a.gif') await interaction.editReply({ embeds: [embed] }) await delay(1000) embed.setDescription(content) - embed.setThumbnail(image) + embed.setImage(image) await interaction.editReply({ embeds: [embed] })