Skip to content
This repository was archived by the owner on Sep 1, 2023. It is now read-only.

Commit e8bfee0

Browse files
committed
seven and zero
1 parent 9858f5b commit e8bfee0

File tree

7 files changed

+93
-34
lines changed

7 files changed

+93
-34
lines changed

src/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ export const sendMessage = (channelID: string, content: CreateMessageOptions | s
1717
.catch(e => tryAgain ? sendMessage(channelID, content, false) : onMsgError(e, { channelID }));
1818

1919
export const editMessage = (message: Message, content: CreateMessageOptions | string, tryAgain = true): Promise<void | Message<AnyTextableGuildChannel>> =>
20-
client.rest.channels
20+
message && client.rest.channels
2121
.editMessage<AnyTextableGuildChannel>(message.channelID, message.id, typeof content === "string" ? { content } : content)
2222
.catch(e => tryAgain ? editMessage(message, content, false) : onMsgError(e, message));
2323

2424
export const deleteMessage = (message: Message, tryAgain = true) =>
25-
client.rest.channels
25+
message && client.rest.channels
2626
.deleteMessage(message.channel.id, message.id)
2727
.catch(() => tryAgain && deleteMessage(message, false));
2828

src/components.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,11 @@ export const SettingsSelectMenu = (game: UnoGame<false>) => new ComponentBuilder
243243
value: SettingsIDs.ALLOW_CARD_STACKING,
244244
description: game.settings.allowStacking ? "Enabled" : "Disabled"
245245
},
246-
// {
247-
// label: "7 and 0 (does not work)",
248-
// value: SettingsIDs.SEVEN_AND_ZERO,
249-
// description: game.settings.sevenAndZero ? "Enabled" : "Disabled"
250-
// }
246+
{
247+
label: "7 and 0",
248+
value: SettingsIDs.SEVEN_AND_ZERO,
249+
description: game.settings.sevenAndZero ? "Enabled" : "Disabled"
250+
}
251251
]
252252
})
253253
.toJSON();

src/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const autoStartTimeout = 305;
9090
// its "just" 25 days but i still doubt a game will go on for longer than that
9191
export const veryLongTime = 2_147_483.647;
9292

93-
// do NOT use "__" in id's
93+
// do NOT use "__" in any id's
9494
export const ButtonIDs = Object.freeze({
9595
JOIN_GAME: "join",
9696
LEAVE_GAME_BEFORE_START: "leave",

src/gameLogic/index.ts

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import database from "../database.js";
88
import { config } from "../index.js";
99
import timeouts from "../timeouts.js";
1010
import { UnoGame } from "../types.js";
11-
import { cancelGameMessageFail, getPlayerMember, getUsername, hasStarted, next, toHumanReadableTime, toTitleCase } from "../utils.js";
11+
import { cancelGameMessageFail, getUsername, hasStarted, next, toHumanReadableTime, toTitleCase } from "../utils.js";
1212
import { makeSettingsModal, onGameJoin, onSettingsChange } from "./notStarted.js";
13-
import { onCardPlayed, onColorPlayed, onForceDrawPlayed } from "./playedCards.js";
13+
import { onCardPlayed, onColorPlayed, onForceDrawPlayed, onSevenPlayed } from "./playedCards.js";
1414
import { leaveGame, onGameButtonPress } from "./started.js";
1515

1616
export const games: { [channelId: string]: UnoGame<boolean> } = new Proxy({}, {
@@ -23,15 +23,16 @@ export const games: { [channelId: string]: UnoGame<boolean> } = new Proxy({}, {
2323

2424
export function onTimeout(game: UnoGame<true>, player: string) {
2525
if (!games[game.channelID] || player !== game.currentPlayer || game.uid !== games[game.channelID].uid) return;
26-
const kickedPlayer = getPlayerMember(game, player);
26+
const guild = client.guilds.get(game.guildID);
2727

2828
game.currentPlayer = next(game.players, game.players.indexOf(player));
2929
if (game.settings.kickOnTimeout) {
3030
game.players.splice(game.players.indexOf(player), 1);
3131
game.playersWhoLeft.push(player);
3232
}
33+
3334
sendMessage(game.channelID,
34-
`**${kickedPlayer?.nick ?? kickedPlayer?.username}** was ${game.settings.kickOnTimeout ? "removed" : "skipped"} for inactivity`
35+
`**${getUsername(player, true, guild)}** was ${game.settings.kickOnTimeout ? "removed" : "skipped"} for inactivity`
3536
);
3637
if (game.players.length <= 1) {
3738
timeouts.delete(game.channelID);
@@ -141,18 +142,35 @@ export function onSelectMenu(ctx: ComponentInteraction<ComponentTypes.STRING_SEL
141142
const game = games[ctx.channel.id];
142143
if (!game) return;
143144

144-
if ((ctx.data.customID === SelectIDs.CHOOSE_CARD || ctx.data.customID === SelectIDs.CHOOSE_CARD_ABOVE_25)
145-
&& hasStarted(game)
146-
)
147-
onCardPlayed(ctx, game);
148-
else if (ctx.data.customID === SelectIDs.CHOOSE_COLOR && hasStarted(game))
149-
onColorPlayed(ctx, game);
150-
else if (ctx.data.customID === SelectIDs.FORCEFUL_DRAW && hasStarted(game))
151-
onForceDrawPlayed(ctx, game);
152-
else if ((ctx.data.customID === SelectIDs.EDIT_GAME_SETTINGS || ctx.data.customID === SelectIDs.EDIT_GAME_SETTINGS_RULES)
153-
&& !hasStarted(game)
154-
)
155-
onSettingsChange(ctx, game);
145+
switch (ctx.data.customID) {
146+
case SelectIDs.CHOOSE_CARD:
147+
case SelectIDs.CHOOSE_CARD_ABOVE_25: {
148+
hasStarted(game) && onCardPlayed(ctx, game);
149+
break;
150+
}
151+
case SelectIDs.CHOOSE_COLOR: {
152+
hasStarted(game) && onColorPlayed(ctx, game);
153+
break;
154+
}
155+
case SelectIDs.FORCEFUL_DRAW: {
156+
hasStarted(game) && onForceDrawPlayed(ctx, game);
157+
break;
158+
}
159+
case SelectIDs.PLAYER_USER_SELECT: {
160+
hasStarted(game) && onSevenPlayed(ctx, game);
161+
break;
162+
}
163+
case SelectIDs.EDIT_GAME_SETTINGS:
164+
case SelectIDs.EDIT_GAME_SETTINGS_RULES: {
165+
!hasStarted(game) && onSettingsChange(ctx, game);
166+
break;
167+
}
168+
default: {
169+
ctx.createFollowup({
170+
content: `The \`${ctx.data.customID}\` select menu is missing a handler; this is a bug`
171+
});
172+
}
173+
}
156174
}
157175

158176
export function onModalSubmit(ctx: ModalSubmitInteraction) {

src/gameLogic/notStarted.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ export function onSettingsChange(ctx: ComponentInteraction<ComponentTypes.STRING
230230
game.settings.canRejoin = next(rejoinOptionOrder, rejoinOptionOrder.indexOf(game.settings.canRejoin));
231231
break;
232232
}
233+
case SettingsIDs.SEVEN_AND_ZERO: {
234+
game.settings.sevenAndZero = !game.settings.sevenAndZero;
235+
break;
236+
}
233237
default: {
234238
ctx.createFollowup({
235239
content: `The **${ctx.data.values.raw[0]}** setting is missing a handler. this is a bug`

src/gameLogic/playedCards.ts

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ComponentInteraction, ComponentTypes, MessageFlags } from "oceanic.js";
22

33
import { deleteMessage, sendMessage } from "../client.js";
4-
import { CardColorSelect, PickCardSelect } from "../components.js";
4+
import { CardColorSelect, PickCardSelect, PlayerUserSelect } from "../components.js";
55
import { cardEmotes, cards, colors, uniqueVariants, variants } from "../constants.js";
66
import database from "../database.js";
77
import { config } from "../index.js";
@@ -71,6 +71,8 @@ export function onColorPlayed(ctx: ComponentInteraction<ComponentTypes.STRING_SE
7171
game.cards[ctx.member.id].splice(game.cards[ctx.member.id].indexOf(variant), 1);
7272
game.currentPlayer = next(game.players, game.players.indexOf(game.currentPlayer));
7373
ctx.deleteOriginal();
74+
deleteMessage(ctx.message.channel.messages.get(ctx.message.messageReference?.messageID));
75+
7476
if (game.cards[ctx.member.id].length === 0) return;
7577
sendMessage(ctx.channel.id, `
7678
${`**${getUsername(ctx.member.id, true, ctx.guild)}** played ${cardEmotes[variant]} ${toTitleCase(variant)}, switching the color to ${color}`}\
@@ -97,6 +99,21 @@ export function onForceDrawPlayed(ctx: ComponentInteraction<ComponentTypes.STRIN
9799
else onCardPlayed(ctx, game, true);
98100
}
99101

102+
export function onSevenPlayed(ctx: ComponentInteraction<ComponentTypes.STRING_SELECT>, game: UnoGame<true>) {
103+
if (game.currentPlayer !== ctx.member.id) return;
104+
const id = ctx.data.values.raw[0];
105+
106+
[game.cards[ctx.member.id], game.cards[id]] = [game.cards[id], game.cards[ctx.member.id]];
107+
sendMessage(ctx.channel.id, `**${getUsername(ctx.member.id, true, ctx.guild)}** played \
108+
${cardEmotes[game.currentCard]} ${toTitleCase(game.currentCard)}
109+
**${getUsername(ctx.member.id, true, ctx.guild)}** switched cards with **${getUsername(id, true, ctx.guild)}**`);
110+
111+
game.currentPlayer = next(game.players, game.players.indexOf(game.currentPlayer));
112+
ctx.deleteOriginal();
113+
deleteMessage(ctx.message.channel.messages.get(ctx.message.messageReference?.messageID));
114+
sendGameMessage(game);
115+
}
116+
100117
export function onCardPlayed(ctx: ComponentInteraction<ComponentTypes.STRING_SELECT>, game: UnoGame<true>, ignoreDrawStack = false) {
101118
if (game.currentPlayer !== ctx.member.id) return;
102119
const cardPlayed = ctx.data.values.raw[0] as Card | "draw" | "skip";
@@ -122,9 +139,10 @@ export function onCardPlayed(ctx: ComponentInteraction<ComponentTypes.STRING_SEL
122139

123140
if (uniqueVariants.includes(color)) {
124141
return ctx.createFollowup({
125-
content: "Choose a color",
126-
components: CardColorSelect(color as typeof uniqueVariants[number])
127-
}).then(() => ctx.deleteOriginal());
142+
content: `<@${ctx.member.id}> Choose a color`,
143+
components: CardColorSelect(color as typeof uniqueVariants[number]),
144+
allowedMentions: { users: true }
145+
});
128146
}
129147

130148
if (cardPlayed === "skip" && (!game.settings.allowSkipping || (game.lastPlayer.id !== game.currentPlayer && !wasLastTurnBlocked(game))))
@@ -200,9 +218,25 @@ You drew ${cardEmotes[newCards[0]]}`,
200218
extraInfo = `**${getUsername(game.currentPlayer, true, ctx.guild)}** was skipped`;
201219
break;
202220
}
203-
case "7":
221+
case "7": {
222+
if (!game.settings.sevenAndZero) break;
223+
224+
return ctx.createFollowup({
225+
content: `<@${ctx.member.id}> Choose a player`,
226+
components: PlayerUserSelect(game),
227+
allowedMentions: { users: true }
228+
});
229+
}
204230
case "0": {
205-
// TODO
231+
if (!game.settings.sevenAndZero) break;
232+
extraInfo = "All players' cards have been switched!";
233+
234+
const keys = Object.keys(game.cards);
235+
keys.unshift(keys.pop());
236+
game.cards = Object.fromEntries(Object.entries(game.cards).map(([_, value], i) =>
237+
[keys[i], value]
238+
));
239+
break;
206240
}
207241
}
208242

@@ -224,6 +258,7 @@ You drew ${cardEmotes[newCards[0]]}`,
224258
: `**${getUsername(ctx.member.id, true, ctx.guild)}** played ${cardEmotes[cardPlayed]} ${toTitleCase(cardPlayed)}`}\
225259
${extraInfo.length ? `\n${extraInfo}` : ""}`
226260
);
261+
227262
if (cardPlayed !== "draw" || !game.settings.allowSkipping) {
228263
sendGameMessage(game);
229264
} else {

src/gameLogic/started.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,14 @@ export function onGameButtonPress(ctx: ComponentInteraction<ComponentTypes.BUTTO
129129
case ButtonIDs.VIEW_GAME_SETTINGS: {
130130
return ctx.createFollowup({
131131
content: `Kick on timeout: **${game.settings.kickOnTimeout ? "Enabled" : "Disabled"}**
132-
Skipping turns: **${game.settings.allowSkipping ? "Enabled" : "Disabled"}**
133-
Stack +2's and +4's: **${game.settings.allowStacking ? "Enabled" : "Disabled"}**
134132
Randomize order of players: **${game.settings.randomizePlayerList ? "Enabled" : "Disabled"}**
135133
Resend game message: **${game.settings.resendGameMessage ? "Enabled" : "Disabled"}**
136-
Can join mid game: **${game.settings.resendGameMessage ? "Yes" : "No"}**
137-
Anti sabotage: **find out 🚎**`,
134+
Joining mid game: **${game.settings.canRejoin === "no" ? "Disabled" : "Enabled"}**
135+
Anti sabotage: **find out :troll\\:**
136+
137+
Skipping turns: **${game.settings.allowSkipping ? "Enabled" : "Disabled"}**
138+
Stack +2's and +4's: **${game.settings.allowStacking ? "Enabled" : "Disabled"}**
139+
7 and 0: **${game.settings.sevenAndZero ? "Enabled" : "Disabled"}**`,
138140
flags: MessageFlags.EPHEMERAL
139141
});
140142
}

0 commit comments

Comments
 (0)