const { EmbedBuilder, ButtonStyle, ButtonBuilder, ActionRowBuilder, } = require("discord.js"); const embedColor = require("../../fonctions/embedColor.js"); const db = require("../../fonctions/database.js"); const cardValues = { A: 11, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, J: 10, Q: 10, K: 10, }; const cardSymbols = ["♠️", "♥️", "♦️", "♣️"]; const usersWithGameInProgress = new Map(); setInterval(() => { usersWithGameInProgress.clear(); }, 180000); function drawCard() { const symbol = cardSymbols[Math.floor(Math.random() * cardSymbols.length)]; const value = Object.keys(cardValues)[ Math.floor(Math.random() * Object.keys(cardValues).length) ]; return { symbol, value }; } module.exports = { aliases: ["bj"], description: "Joue au blackjack.", emote: "🃏", utilisation: "", permission: 0, async execute(message, args, client) { if (args.length !== 1) { embedColor(message.author.id, message.guild.id).then((color) => { const embed = new EmbedBuilder() .setTitle("🃏 Blackjack") .setDescription( `Vous devez spécifier une mise. Exemple : \`&blackjack 100\`.`, ) .setColor(color) .setTimestamp() .setFooter({ text: `Demandé par ${message.author.tag}`, iconURL: message.author.displayAvatarURL(), }); return message.reply({ embeds: [embed], allowedMentions: { repliedUser: false }, }); }); } else if (isNaN(args[0])) { embedColor(message.author.id, message.guild.id).then((color) => { const embed = new EmbedBuilder() .setTitle("🃏 Blackjack") .setDescription(`La mise doit être un nombre.`) .setColor(color) .setTimestamp() .setFooter({ text: `Demandé par ${message.author.tag}`, iconURL: message.author.displayAvatarURL(), }); return message.reply({ embeds: [embed], allowedMentions: { repliedUser: false }, }); }); } else if (args[0] < 25) { embedColor(message.author.id, message.guild.id).then((color) => { const embed = new EmbedBuilder() .setTitle("🃏 Blackjack") .setDescription(`La mise doit être supérieure ou égale à \`25\`.`) .setColor(color) .setTimestamp() .setFooter({ text: `Demandé par ${message.author.tag}`, iconURL: message.author.displayAvatarURL(), }); return message.reply({ embeds: [embed], allowedMentions: { repliedUser: false }, }); }); } const pocket = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket); } }, ); }); if (pocket < args[0]) { embedColor(message.author.id, message.guild.id).then((color) => { const embed = new EmbedBuilder() .setTitle("🃏 Blackjack") .setDescription( `Vous n'avez pas assez d'argent pour miser cette somme.`, ) .setColor(color) .setTimestamp() .setFooter({ text: `Demandé par ${message.author.tag}`, iconURL: message.author.displayAvatarURL(), }); return message.reply({ embeds: [embed], allowedMentions: { repliedUser: false }, }); }); } else { const user = message.author; const guildId = message.guild.id; const currencyName = "coins"; let amount = args[0]; let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); const playerCards = [drawCard(), drawCard()]; const dealerCards = [drawCard()]; const playerTotal = playerCards.reduce( (total, card) => total + cardValues[card.value], 0, ); if (playerTotal === 21 && playerCards.length === 2) { const blackjackPayoutMultiplier = 1.25; const winnings = Math.floor(amount * blackjackPayoutMultiplier); let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [pocketAmount + winnings, message.author.id, message.guild.id], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); const winEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription( `Félicitations ! Vous avez un blackjack naturel et vous avez gagné ${winnings} ${currencyName}.`, ) .setColor("#0099ff"); return message.reply({ embeds: [winEmbed], allowedMentions: { repliedUser: false }, }); } const embed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setThumbnail( "https://cdn.discordapp.com/attachments/1120446538544595005/1190016467257802843/kumarhane-poker.gif?ex=65a04433&is=658dcf33&hm=3ea3b7c74eb724d17249e3a60968f8c10b7d85452f3684b969a02a17ca79ab3e&", ) .addFields( { name: "Votre main", value: `Cartes: ${playerCards.map((card) => card.symbol + " " + card.value).join(" ")}\nTotal: ${playerTotal}`, inline: true, }, { name: "Main du croupier", value: `Cartes: ${dealerCards[0].symbol + " " + dealerCards[0].value} ?\nTotal: ?`, inline: true, }, ) .setColor("#0099ff"); const row = new ActionRowBuilder().addComponents( new ButtonBuilder() .setCustomId("blackjack_hit") .setLabel("Hit") .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId("blackjack_stand") .setLabel("Stand") .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId("blackjack_cancel") .setLabel("Annuler") .setStyle(ButtonStyle.Danger), ); const msg = await message.channel.send({ embeds: [embed], components: [row], allowedMentions: { repliedUser: false }, }); const collector = msg.createMessageComponentCollector({ time: 60000 }); await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [pocketAmount - amount, message.author.id, message.guild.id], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); usersWithGameInProgress.set(user.id); collector.on("collect", async (i) => { if (i.user.id !== user.id) { return i.reply({ content: ":x: Vous n'avez pas la permission d'interagir avec ces boutons", ephemeral: true, }); } await i.deferUpdate(); if (i.customId === "blackjack_hit") { playerCards.push(drawCard()); let playerTotal = playerCards.reduce( (total, card) => total + cardValues[card.value], 0, ); if (playerTotal === 21) { const winnings = amount * 1.5; let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [pocketAmount + winnings, message.author.id, message.guild.id], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); const winEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription( `Félicitations ! Vous avez atteint 21. Vous avez gagné ${winnings} ${currencyName}.`, ) .setColor("#0099ff"); message.reply({ embeds: [winEmbed], allowedMentions: { repliedUser: false }, }); usersWithGameInProgress.delete(user.id); collector.stop(); } else if (playerTotal > 21) { const loseEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription( `Vous avez dépassé 21. Vous avez perdu ${amount} ${currencyName}.`, ) .setColor("#0099ff"); message.reply({ embeds: [loseEmbed], allowedMentions: { repliedUser: false }, }); collector.stop(); } else { embed.spliceFields(0, 1, { name: "Votre main", value: `Cartes: ${playerCards.map((card) => card.symbol + " " + card.value).join(" ")}\nTotal: ${playerTotal}`, inline: true, }); i.editReply({ embeds: [embed] }); } usersWithGameInProgress.delete(user.id); } else if (i.customId === "blackjack_stand") { let dealerTotal = dealerCards.reduce( (total, card) => total + cardValues[card.value], 0, ); while (dealerTotal < 17) { dealerCards.push(drawCard()); dealerTotal = dealerCards.reduce( (total, card) => total + cardValues[card.value], 0, ); } const playerTotal = playerCards.reduce( (total, card) => total + cardValues[card.value], 0, ); let result; if (dealerTotal > 21) { result = `Le croupier a dépassé 21. Vous gagnez ${amount * 1.5} ${currencyName}. !`; let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [ pocketAmount + amount * 1.5, message.author.id, message.guild.id, ], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); const winEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription(result) .setColor("#0099ff"); message.reply({ embeds: [winEmbed], allowedMentions: { repliedUser: false }, }); usersWithGameInProgress.delete(user.id); } else if (dealerTotal > playerTotal) { result = `Le croupier a ${dealerTotal} et gagne. Vous avez perdu ${amount} ${currencyName}.`; const loseEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription(result) .setColor("#0099ff"); message.reply({ embeds: [loseEmbed], allowedMentions: { repliedUser: false }, }); usersWithGameInProgress.delete(user.id); } else if (dealerTotal < playerTotal) { let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); const winnings = amount * 1.5; await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [pocketAmount + winnings, message.author.id, message.guild.id], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); result = `Vous gagnez ! Vous avez gagné ${winnings} ${currencyName}.`; const winEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription(result) .setColor("#0099ff"); message.reply({ embeds: [winEmbed], allowedMentions: { repliedUser: false }, }); usersWithGameInProgress.delete(user.id); } else { result = "Il y a eu égalité. Vous récupérez votre mise."; let pocketAmount = (await db.get(`${guildId}.pocket.${user.id}`)) || 0; await db.set(`${guildId}.pocket.${user.id}`, pocketAmount + amount); const tieEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription(result) .setColor("#0099ff"); message.reply({ embeds: [tieEmbed], allowedMentions: { repliedUser: false }, }); } usersWithGameInProgress.delete(user.id); collector.stop(); } else if (i.customId === "blackjack_cancel") { let pocketAmount = await new Promise((resolve, reject) => { db.get( `SELECT pocket FROM users WHERE userId = ? AND guildId = ?`, [message.author.id, message.guild.id], (err, row) => { if (err) { reject(err); } else { resolve(row.pocket || 0); } }, ); }); await new Promise((resolve, reject) => { db.run( `UPDATE users SET pocket = ? WHERE userId = ? AND guildId = ?`, [pocketAmount + amount / 2, message.author.id, message.guild.id], (err) => { if (err) { reject(err); } else { resolve(); } }, ); }); const cancelEmbed = new EmbedBuilder() .setTitle("Blackjack 🎲") .setDescription( "Partie annulée. Vous récupérez la moitié de votre mise.", ) .setColor("#0099ff"); message.reply({ embeds: [cancelEmbed], allowedMentions: { repliedUser: false }, }); usersWithGameInProgress.delete(user.id); collector.stop(); } }); } }, };