make games cancellable

This commit is contained in:
Jill 2023-10-29 13:22:21 +03:00
parent 3b76e9a7ff
commit 25e4cbd60e
Signed by: oat
GPG Key ID: 33489AA58A955108
2 changed files with 28 additions and 11 deletions

View File

@ -59,4 +59,8 @@ bot.on(Events.MessageDelete, (msg) => {
console.log(`${msg.content}`);
});
process.on('uncaughtException', err => {
console.error(err);
});
bot.login(token);

View File

@ -19,12 +19,13 @@ const BAD_EMOJI = '👎';
const DEFAULT_EMOJI = '🪙';
const STOP_EMOJI = '⏹️';
const CANCEL_EMOJI = '❌';
function formatMessage(users: User[], time: number, name: string, ended = false) {
function formatMessage(users: User[], time: number, name: string, ended = false, cancelled = false) {
return `Starting a **${name}** game (${users.length} player${users.length !== 1 ? 's' : ''})\n`
+ users.map(user => `- ${user.toString()}`).join('\n') + '\n'
+ (time <= 0 ?
(ended ? '**Already ended!**' : '**Already started**') :
(cancelled ? ('**Game was cancelled**') : (ended ? '**Already ended!**' : '**Already started**')) :
`Starting in **${Math.ceil(time / 1000)}s** - react ${STOP_EMOJI} to begin now`
);
}
@ -54,8 +55,6 @@ export async function startGame(interaction: Interaction, startingUser: User, na
if (!(m instanceof Message)) return;
const emoji = m.guild?.emojis.cache.random();
await m.react(emoji || DEFAULT_EMOJI);
await m.react(STOP_EMOJI);
const started = Date.now();
const collector = m.createReactionCollector({
@ -65,19 +64,29 @@ export async function startGame(interaction: Interaction, startingUser: User, na
(emoji ? reaction.emoji.id === emoji.id : reaction.emoji.name === DEFAULT_EMOJI) &&
!participants.find(u => user.id === u.id) &&
!membersInGame.includes(user.id)
) || (reaction.emoji.name === STOP_EMOJI && user.id === startingUser.id)
)
|| (reaction.emoji.name === STOP_EMOJI && user.id === startingUser.id)
|| (reaction.emoji.name === CANCEL_EMOJI && user.id === startingUser.id)
),
time: duration,
dispose: true
});
await Promise.all([
m.react(emoji || DEFAULT_EMOJI),
m.react(STOP_EMOJI),
m.react(CANCEL_EMOJI),
]);
const updateInterval = setInterval(() => {
m.edit(formatMessage(participants, duration - (Date.now() - started), name));
}, 3_000);
collector.on('collect', (reaction, user) => {
if (reaction.emoji.name === STOP_EMOJI) {
collector.stop();
collector.stop('force-started');
} else if (reaction.emoji.name === CANCEL_EMOJI) {
collector.stop('cancelled');
} else {
participants.push(user);
membersInGame.push(user.id);
@ -91,13 +100,17 @@ export async function startGame(interaction: Interaction, startingUser: User, na
m.edit(formatMessage(participants, duration - (Date.now() - started), name));
});
collector.on('end', async () => {
collector.on('end', async (_, reason) => {
clearInterval(updateInterval);
m.edit(formatMessage(participants, 0, name));
await m.reactions.removeAll().catch(error => console.error(error));
await callback(participants, m.channel);
m.edit(formatMessage(participants, 0, name, true));
if (reason === 'cancelled') {
m.edit(formatMessage(participants, 0, name, false, true));
} else {
m.edit(formatMessage(participants, 0, name));
await callback(participants, m.channel);
m.edit(formatMessage(participants, 0, name, true));
}
membersInGame = membersInGame.filter(id => !participants.find(u => u.id === id));
});
}