Val
Val
DIAdiscord.js - Imagine an app
Created by Val on 8/18/2023 in #djs-questions
More concise way to edit sent embeds
I am currently dealing editing the fields of an existing embed as a reply, where I'm only changing the fields and not the base content. However, so far the only way I've seen to edit embeds is to redefine the entire embed. I tried making a baseEmbed which only containts setTitle(), .setDescription etc, and using .addFields() for the editable content. However, .addFields() mutates the existing embed rather than making a new one and as such it simply keeps adding new copies of the fields. Is there any way to get this to work without having to repeat the .setTitle() etc.?
7 replies
DIAdiscord.js - Imagine an app
Created by Val on 8/14/2023 in #djs-questions
Create a player loop for a blackjack game
Hi everyone! I'm currently implementing a game of blackjack in my bot, using an embed and buttons for the game information and functions. It is two-player, with the command to start the game having an option to mention the other player, with player 1 being the command initiator. My issue is in how to make the game loop back and forth between both players then break when someone wins. The code specifically for the game itself is below:
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
My idea for a solution is to check the current player id to flip between whose turn it is, however the "hit" collector only collects once, if I try to "hit" a second time it simply gives "this interaction has failed." How would I be able to loop through the players until one wins, by maybe allowing the collector to always collect, similar to the behaviour of addEventListener in default JS for HTML elements?
7 replies
DIAdiscord.js - Imagine an app
Created by Val on 8/14/2023 in #djs-voice
Player loop for blackjack game
Hi everyone! I'm currently implementing a game of blackjack in my bot, using an embed and buttons for the game information and functions. It is two-player, with the command to start the game having an option to mention the other player, with player 1 being the command initiator. My issue is in how to make the game loop back and forth between both players then break when someone wins. The code specifically for the game itself is below:
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
My idea for a solution is to check the current player id to flip between whose turn it is, however the "hit" collector only collects once, if I try to "hit" a second time it simply gives "this interaction has failed." How would I be able to loop through the players until one wins, by maybe allowing the collector to always collect, similar to the behaviour of addEventListener in default JS for HTML elements?
5 replies