'button collector inside button collector discord.js
So I'm trying to code a Blackjack command for my Discord bot, and the aces in Blackjack can have 2 values: 1 or 11 based on player's choice.
I'm trying to make that the player can choose to call or stay, with button interactions, and that works, for now. The thing is that when the random card is equal to 1, I want to change the labels of the buttons and create another collector to collect the 1 or 11 choice, making the code wait with an await. here's the collector:
const filter = (btnInt) => { return interaction.user.id === btnInt.user.id }
const collector = interaction.channel.createMessageComponentCollector({ filter, time: 60000 });
const aceCollector = interaction.channel.createMessageComponentCollector({ filter, max: 1, time: 30000});
collector.on("collect", async (btnInt) => {
await btnInt.deferUpdate();
switch (btnInt.customId) {
case "call":
randomCard();
if (randCard == 1) {
matchEmbed.description = `You pulled an ace! Select the value of it: ${codeLine("1")} or ${codeLine("11")}?
\n\n ** The sum of your cards (without the ace is) is: ** ${codeLine(lodash.sum(playerCards))}`;
btnInt.editReply({ embeds: [matchEmbed], components: [aceRow] });
aceCollector.on("collect", async (aceInt) => {
await aceInt.deferUpdate();
console.log(aceCollector)
if (aceInt.customId == "1") randCard = 1;
else randCard = 11;
playerCards.push(randCard);
});
aceCollector.on("end", () => {
matchEmbed.description = `**you pulled ${codeLine(randCard)} from the deck!
\n ${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Do you want to call another card or do you wanna stay? **`;
interaction.editReply({ embeds: [matchEmbed], components: [aceRow]});
});
}
else {
matchEmbed.description = `**you pulled ${codeLine(randCard)} from the deck!
\n${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Do you want to call another card or do you wanna stay? **`;
}
if (lodash.sum(playerCards) > 21) {
matchEmbed.description = `**${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n **Busted! The sum your cards are over 21!**
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Wait for the Dealer... **`;
row.components[0].setDisabled(true);
}
if (lodash.sum(playerCards) == 21) {
matchEmbed.description = `**${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n **Blackjack!**
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Wait for the Dealer... **`;
row.components[0].setDisabled(true);
}
break;
case "stay":
matchEmbed.setDescription("stay");
break;
}
btnInt.editReply({ embeds: [matchEmbed], components: [row] });
});
function randomCard() {
randCard = chance.pickone(cards);
if (randCard !== 1) {
cards.splice(cards.indexOf(randCard), 1);
playerCards.push(randCard);
}
}
When the player gets a an ace, the code goes through the if (randCard == 1), so the message in discord actually changes and even the buttons, but for some reason it instantly changes back to the normal message to call or stay.
I tried to console log something, and it does not show up, so the collector does not even start, so it won't wait. How can I solve this? Here's the full code of the command:
const { SlashCommandBuilder } = require("@discordjs/builders");
var lodash = require('lodash');
module.exports = {
data: new SlashCommandBuilder()
.setName("blackjack")
.setDescription("Play a blackjack game, I will be the dealer!")
.addIntegerOption(option =>
option.setName("bet")
.setDescription("The amount of bananas you wanna bet.")),
async execute(client, interaction, Discord, profileData) {
let players = 1;
let randCard;
let rematch = false;
const cards = chance.shuffle([
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6,
7, 7, 7, 7,
8, 8, 8, 8,
9, 9, 9, 9,
10, 10, 10, 10,
10, 10, 10, 10,
10, 10, 10, 10,
10, 10, 10, 10,
]);
const row = new Discord.MessageActionRow()
.addComponents(
new Discord.MessageButton().setCustomId("call").setLabel("Call").setStyle("SECONDARY"),
new Discord.MessageButton().setCustomId("stay").setLabel("Stay").setStyle("SECONDARY")
);
const aceRow = new Discord.MessageActionRow()
.addComponents(
new Discord.MessageButton().setCustomId("1").setLabel("1").setStyle("SECONDARY"),
new Discord.MessageButton().setCustomId("11").setLabel("11").setStyle("SECONDARY")
);
const playerCards = [
chance.pickone(cards),
chance.pickone(cards)
];
let dealerCard1 = chance.pickone(cards);
let dealerCard2 = "?";
let sum = "?";
const matchEmbed = new Discord.MessageEmbed()
.setAuthor({ name: `${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL({format: "png"})})
.setTitle("Blackjack")
.setDescription(`**${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Do you want to call another card or do you wanna stay? **`)
.setColor("BLACK");
interaction.reply({ embeds: [matchEmbed], components: [row]});
const filter = (btnInt) => { return interaction.user.id === btnInt.user.id }
const collector = interaction.channel.createMessageComponentCollector({ filter, time: 60000 });
const aceCollector = interaction.channel.createMessageComponentCollector({ filter, max: 1, time: 30000});
collector.on("collect", async (btnInt) => {
await btnInt.deferUpdate();
switch (btnInt.customId) {
case "call":
randomCard();
if (randCard == 1) {
matchEmbed.description = `You pulled an ace! Select the value of it: ${codeLine("1")} or ${codeLine("11")}?
\n\n ** The sum of your cards (without the ace is) is: ** ${codeLine(lodash.sum(playerCards))}`;
btnInt.editReply({ embeds: [matchEmbed], components: [aceRow] });
await aceCollector.on("collect", async (aceInt) => {
await aceInt.deferUpdate();
console.log(aceCollector)
if (aceInt.customId == "1") randCard = 1;
else randCard = 11;
playerCards.push(randCard);
});
await aceCollector.on("end", () => {
matchEmbed.description = `**you pulled ${codeLine(randCard)} from the deck!
\n ${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Do you want to call another card or do you wanna stay? **`;
});
}
else {
matchEmbed.description = `**you pulled ${codeLine(randCard)} from the deck!
\n${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Do you want to call another card or do you wanna stay? **`;
}
if (lodash.sum(playerCards) > 21) {
matchEmbed.description = `**${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n **Busted! The sum your cards are over 21!**
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Wait for the Dealer... **`;
row.components[0].setDisabled(false);
}
if (lodash.sum(playerCards) == 21) {
matchEmbed.description = `**${interaction.user.username}'s cards** \n${codeLine(playerCards.join(" | "))} | sum: ${codeLine(lodash.sum(playerCards))}
\n **Blackjack!**
\n\n **Dealer's cards **${codeLine(dealerCard1)} | ${codeLine(dealerCard2)} | sum: ${codeLine(sum)}
\n\n ** Wait for the Dealer... **`;
row.components[0].setDisabled(false);
}
break;
case "stay":
matchEmbed.setDescription("stay");
break;
}
btnInt.editReply({ embeds: [matchEmbed], components: [row] });
});
function randomCard() {
randCard = chance.pickone(cards);
if (randCard !== 1) {
cards.splice(cards.indexOf(randCard), 1);
playerCards.push(randCard);
}
}
}
}
Thank you!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
