Skip to content

Commit

Permalink
join button, catch old draw/pass buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
Californ1a committed Jun 2, 2021
1 parent 3679287 commit af1db35
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 37 deletions.
1 change: 1 addition & 0 deletions commands/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async function draw(interaction, chan) {
const name = (card.color) ? card.toString() : card.value.toString();
const n2 = (name.includes("WILD_DRAW")) ? "WD4" : (name.includes("DRAW")) ? `${name.split(" ")[0]} DT` : name;
await interaction.reply(`You drew a ${n2.toLowerCase()}`, { ephemeral: true });
// TODO: pass button
}

exports.run = draw;
Expand Down
2 changes: 1 addition & 1 deletion commands/play.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ async function play(interaction, chan, opts, bot) {
}
chan.uno.players.get(p.name).interaction = interaction;
const c = chan.uno.game.discardedCard.value.toString().toLowerCase();
await interaction.reply(`Played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew ${(c.includes("two") ? "2" : "4")} cards.` : ""}`, {
await interaction.reply(`${interaction.member} played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew ${(c.includes("two") ? "2" : "4")} cards.` : ""}`, {
allowedMentions: {
users: [],
},
Expand Down
9 changes: 8 additions & 1 deletion game/botBrain.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,15 @@ async function botPlay(chan, matchingHand, callUno = true) {
const cardColors = [];
const handWithoutWilds = player.hand.filter(c => !c.value.toString().includes("WILD"));
handWithoutWilds.forEach((c) => {
cardColors.push(c.color.toString()); // Create list of colors in hand
if (c.color.toString() !== chan.uno.game.discardedCard.color.toString()) {
// Create list of colors in hand not matching current color
cardColors.push(c.color.toString());
}
});
if (cardColors.length === 0) {
// All cards in hand had same color as the current card
cardColors.push(chan.uno.game.discardedCard.color.toString());
}
const cardCols = countOccurrences(cardColors);

const keys = Object.keys(cardCols);
Expand Down
68 changes: 39 additions & 29 deletions game/game.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { MessageActionRow, MessageButton, MessageEmbed } = require("discord.js");
const { MessageButton, MessageEmbed } = require("discord.js");
const { Card, Values, Colors } = require("uno-engine");
const { addButton, colorToButtonStyle, buttonsToMessageActions } = require("../util/buttons.js");
const errHandler = require("../util/err.js");
const botTurn = require("./botBrain.js");
const cardImages = require("../data/unocardimages.json");
Expand Down Expand Up @@ -43,20 +44,6 @@ function reset(chan) {
chan.uno = null;
}

function addButton(buttons, button) {
const last = buttons[buttons.length - 1];
if (last.length !== 5) {
last.push(button);
} else if (buttons.length !== 5) {
buttons.push([button]);
}
return buttons;
}

function colorToButtonStyle(color) {
return (color === "BLUE") ? "PRIMARY" : (color === "GREEN") ? "SUCCESS" : (color === "RED") ? "DANGER" : "SECONDARY";
}

function createButtons(hand, discard) {
let buttons = [
[],
Expand Down Expand Up @@ -122,7 +109,7 @@ function createButtons(hand, discard) {
// .setStyle("SECONDARY")
// .setEmoji("⏭️");
// buttons = addButton(buttons, passButton);
return buttons.map(b => new MessageActionRow().addComponents(b));
return buttonsToMessageActions(buttons);
}

async function playedWildCard(inter, chan, value, pid) {
Expand All @@ -133,8 +120,9 @@ async function playedWildCard(inter, chan, value, pid) {
.setStyle(colorToButtonStyle(c.toUpperCase()))), [
[],
]);
console.log(inter.type);
await inter.update(inter.message.content, {
components: buttons.map(b => new MessageActionRow().addComponents(b)),
components: buttonsToMessageActions(buttons),
});
const colorCollector = inter.message.createMessageComponentInteractionCollector(() => true, {
max: 1,
Expand Down Expand Up @@ -165,7 +153,7 @@ async function playedWildCard(inter, chan, value, pid) {

await inter2.update(card.toString(), { components: [] });
chan.uno.players.get(p.name).interaction = inter2;
await inter2.followUp(`Played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew 4 cards.` : ""}`, {
await inter2.followUp(`${inter2.member} played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew 4 cards.` : ""}`, {
allowedMentions: {
users: [],
},
Expand Down Expand Up @@ -198,6 +186,11 @@ async function sendHandWithButtons(chan, player, handStr, rows) {
const cardArr = inter.customID.split(" ");

if (cardArr.length === 1) {
if (chan.uno.drawn) {
await inter.update(inter.message.content, { components: [] });
await inter.followUp("You cannot draw twice in a row.", { ephemeral: true });
return false;
}
chan.uno.game.draw();

const card = chan.uno.game.currentPlayer.hand[chan.uno.game.currentPlayer.hand.length - 1];
Expand Down Expand Up @@ -227,21 +220,34 @@ async function sendHandWithButtons(chan, player, handStr, rows) {
.setStyle("SECONDARY")
.setEmoji("⏭️");
buttons = addButton(buttons, passBtn);
// TODO: change draw and pass to channel messages so other players can see them
// TODO: move buttons to a new ephemeral message

await inter.update(`You drew a ${n2.toLowerCase()}`, {
components: buttons.map(b => new MessageActionRow().addComponents(b)),
ephemeral: true,
components: buttonsToMessageActions(buttons),
});
await chan.send(`${inter.member} drew`, { allowedMentions: { users: [] } });

const passCollector = inter.message.createMessageComponentInteractionCollector(() => true, {
max: 1,
});
const inter2 = await new Promise((resolve) => {
passCollector.on("collect", resolve);
});
console.log(`Collected ${inter2.customID}`);
if (chan.uno.game.currentPlayer.name !== inter2.member.id) {
await inter2.update(inter2.message.content, { components: [] });
await inter2.followUp("It's not your turn.", { ephemeral: true });
return false;
}
if (chan.uno.playerCustomID !== pid) {
inter2.update(inter.message.content, { components: [] });
inter2.followUp("You can't use old Uno buttons.", { ephemeral: true });
return false;
}
if (inter2.customID === "PASS") {
chan.uno.game.pass();
inter2.update("Passed", { components: [] });
await inter2.update("Passed", { components: [] });
await chan.send(`${inter2.member} passed`, { allowedMentions: { users: [] } });
chan.uno.drawn = false;
return true;
}
Expand All @@ -261,7 +267,7 @@ async function sendHandWithButtons(chan, player, handStr, rows) {
}
player.interaction = inter2;
const c = chan.uno.game.discardedCard.value.toString().toLowerCase();
await inter2.followUp(`Played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew ${(c.includes("two") ? "2" : "4")} cards.` : ""}`, {
await inter2.followUp(`${inter2.member} played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew ${(c.includes("two") ? "2" : "4")} cards.` : ""}`, {
allowedMentions: {
users: [],
},
Expand All @@ -288,7 +294,7 @@ async function sendHandWithButtons(chan, player, handStr, rows) {
}
player.interaction = inter;
console.log("getPlainCard(card)", getPlainCard(card));
await inter.followUp(`Played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew 2 cards.` : ""}`, {
await inter.followUp(`${inter.member} played ${getPlainCard(card)}${(drawn.didDraw) ? `, ${drawn.player} drew 2 cards.` : ""}`, {
allowedMentions: {
users: [],
},
Expand All @@ -315,7 +321,7 @@ async function nextTurn(chan) {
if (handArr.length === 0) {
return; // game.on end triggers
}
const str = `${player} is up (${handArr.length}) - Card: ${chan.uno.game.discardedCard.toString()}`;
const str = `${player} (${handArr.length}) is up - Card: ${chan.uno.game.discardedCard.toString()}`;
const file = { files: [getCardImage(chan.uno.game.discardedCard)] };
await chan.send(str, file);

Expand All @@ -334,7 +340,7 @@ async function nextTurn(chan) {
await player.interaction.followUp(`Your Uno hand: ${handStr}\nToo many cards to create buttons - use \`/play\` command.`, { ephemeral: true });
}
} catch (e) {
await chan.send(`Could not send your hand, ${player}, use \`/hand\` to view it.`);
await chan.send(`An error occurred, ${player}, use slash comamnds.`);
errHandler("error", e);
}
}
Expand Down Expand Up @@ -409,7 +415,7 @@ async function finished(chan, err, winner, score) {
.setColor(embedColor);
const msg = await chan.send("Game finished!", {
embed,
components: buttons.map(b => new MessageActionRow().addComponents(b)),
components: buttonsToMessageActions(buttons),
});
const startCollector = msg.createMessageComponentInteractionCollector(() => true, {
max: 1,
Expand All @@ -425,8 +431,12 @@ async function finished(chan, err, winner, score) {
if (inter.customID === "BOT") {
opts.bot = true;
}
// TODO: join button on new game
start(inter, chan, opts, reset, nextTurn, finished);
if (!chan.uno?.running) {
start(inter, chan, opts, reset, nextTurn, finished);
return;
}
await inter.update(inter.message.content, { components: [] });
await inter.followUp("Uno is already running.", { ephemeral: true });
}

module.exports = {
Expand Down
46 changes: 40 additions & 6 deletions game/gameStart.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
const { Collection } = require("discord.js");
const { Collection, MessageButton } = require("discord.js");
const { Game } = require("uno-engine");
const { addButton, buttonsToMessageActions } = require("../util/buttons.js");
const sleep = require("./sleep.js");
const errHandler = require("../util/err.js");

async function startMsg(i, msg) {
async function startMsg(i, msg, options) {
let type = "reply";
if (i.type === "MESSAGE_COMPONENT") {
if (i.type === "MESSAGE_COMPONENT") { // TODO: check i.replied
await i.update(i.message.content, { components: [] });
type = "followUp";
}
i[type](msg);
const m = await i[type](msg, options);
if (m) {
return m;
}
return i.fetchReply();
}

async function start(interaction, chan, opts, reset, nextTurn, finished) {
Expand Down Expand Up @@ -55,8 +60,37 @@ async function start(interaction, chan, opts, reset, nextTurn, finished) {
const { id } = chan.uno;
if (!solo) {
const startTime = 30;
await startMsg(interaction, `An Uno game${(botPlayer) ? " *with the bot*" : ""} will be started in ${startTime}s! Use \`/join\` to join.`);
await sleep(startTime * 1000);
// TODO: join button on new game

const joinBtn = new MessageButton()
.setCustomID("JOIN")
.setLabel("Join")
.setStyle("SUCCESS")
.setEmoji("⏩");
const buttons = addButton([
[],
], joinBtn);

const msg = await startMsg(interaction, `An Uno game${(botPlayer) ? " *with the bot*" : ""} will be started in ${startTime}s! Use \`/join\` or click the button to join.`, {
components: buttonsToMessageActions(buttons),
});
const joinCollector = msg.createMessageComponentInteractionCollector(() => true, {
time: startTime * 1000,
});
joinCollector.on("collect", async (i) => {
if (chan.uno.players.has(i.member.id)) {
await i.reply("You are already in the current game.", { ephemeral: true });
return;
}
chan.uno.players.set(i.member.id, i.member);
chan.uno.players.get(i.member.id).interaction = i;
i.reply(`${i.member} joined - Player ${chan.uno.players.size}`, { allowedMentions: { users: [] } });
});
await new Promise((resolve) => { // Wait full duration before starting game
joinCollector.on("end", resolve);
});
msg.edit(msg.content, { components: [] });
// await sleep(startTime * 1000);
} else {
await startMsg(interaction, "Uno is starting!");
}
Expand Down
25 changes: 25 additions & 0 deletions util/buttons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { MessageActionRow } = require("discord.js");

function addButton(buttons, button) {
const last = buttons[buttons.length - 1];
if (last.length !== 5) {
last.push(button);
} else if (buttons.length !== 5) {
buttons.push([button]);
}
return buttons;
}

function colorToButtonStyle(color) {
return (color === "BLUE") ? "PRIMARY" : (color === "GREEN") ? "SUCCESS" : (color === "RED") ? "DANGER" : "SECONDARY";
}

function buttonsToMessageActions(buttons) {
return buttons.map(b => new MessageActionRow().addComponents(b));
}

module.exports = {
addButton,
colorToButtonStyle,
buttonsToMessageActions,
};

0 comments on commit af1db35

Please sign in to comment.