Skip to content

Commit 1e17038

Browse files
committed
games: Support autostart as a command
1 parent 484587d commit 1e17038

3 files changed

Lines changed: 58 additions & 13 deletions

File tree

src/i18n/languages/english.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export default {
7373
],
7474
NOT_STARTED: 'The game has not started yet.',
7575
CANNOT_START: 'Cannot start the game! Check the players.',
76+
AUTOSTART_QUEUED: 'The game has been queued to start in {{time}}.',
7677
NOT_WATCHING: "You aren't watching this game, though...",
7778
NOW_WATCHING: 'You are now watching the game of {{game}} between {{players}}.',
7879
NO_LONGER_WATCHING: 'You are no longer watching the game of {{game}} between {{players}}.',

src/ps/commands/games/core.tsx

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { renderBackups, renderMenu } from '@/ps/games/menus';
55
import { parseMod } from '@/ps/games/mods';
66
import { generateId } from '@/ps/games/utils';
77
import { ChatError } from '@/utils/chatError';
8+
import { fromHumanTime, toHumanTime } from '@/utils/humanTime';
9+
import { Timer } from '@/utils/timer';
810
import { toId } from '@/utils/toId';
911

1012
import type { NoTranslate, ToTranslate, TranslationFn } from '@/i18n/types';
@@ -218,20 +220,57 @@ export const command: PSCommand[] = Object.entries(Games).map(([_gameId, Game]):
218220
}
219221
},
220222
},
221-
...conditionalCommand(Game.meta.autostart === false, {
222-
name: 'start',
223-
aliases: ['s', 'go', 'g'],
224-
help: 'Starts a game if it does not have an auto-start.',
225-
syntax: 'CMD [id]',
226-
perms: Symbol.for('games.create'),
227-
async run({ message, arg, $T }): Promise<void> {
228-
const { game } = getGame(arg, { action: 'start', user: message.author.id }, { room: message.target, $T });
229-
if (game.started) throw new ChatError($T('GAME.ALREADY_STARTED'));
230-
if (!game.startable()) throw new ChatError($T('GAME.CANNOT_START'));
231-
game.start();
232-
game.closeSignups(false);
223+
...conditionalCommand(
224+
Game.meta.autostart === false,
225+
{
226+
name: 'start',
227+
aliases: ['s', 'go', 'g'],
228+
help: 'Starts a game if it does not have an auto-start.',
229+
syntax: 'CMD [id]',
230+
perms: Symbol.for('games.create'),
231+
async run({ message, arg, $T }): Promise<void> {
232+
const { game } = getGame(arg, { action: 'start', user: message.author.id }, { room: message.target, $T });
233+
if (game.started) throw new ChatError($T('GAME.ALREADY_STARTED'));
234+
if (!game.startable()) throw new ChatError($T('GAME.CANNOT_START'));
235+
game.start();
236+
game.closeSignups(false);
237+
},
233238
},
234-
}),
239+
{
240+
name: 'autostart',
241+
aliases: ['as', 'auto', 'schedule'],
242+
help: 'Automatically starts the target game at the given time.',
243+
syntax: 'CMD [id], [time]',
244+
perms: Symbol.for('games.create'),
245+
async run({ message, arg, $T }): Promise<void> {
246+
const { game, ctx } = getGame(arg, { action: 'start', user: message.author.id }, { room: message.target, $T });
247+
const startIn = fromHumanTime(ctx);
248+
if (!startIn) throw new ChatError($T('GAME.INVALID_INPUT'));
249+
if (game.started) throw new ChatError($T('GAME.ALREADY_STARTED'));
250+
if (game.scheduledStart) {
251+
game.scheduledStart.cancel();
252+
message.reply(
253+
$T('COMMANDS.TIMER.CANCELLED', {
254+
timeLeft: toHumanTime(game.scheduledStart.endTime - Date.now(), undefined, $T),
255+
comment: ' for game autostart',
256+
})
257+
);
258+
game.scheduledStart = null;
259+
}
260+
game.scheduledStart = new Timer(
261+
() => {
262+
if (game.started) return;
263+
if (!game.startable()) return game.room.send($T('GAME.CANNOT_START'));
264+
game.start();
265+
game.closeSignups(false);
266+
},
267+
startIn,
268+
'Game start queued by ${message.author.name}'
269+
);
270+
message.reply($T('GAME.AUTOSTART_QUEUED', { time: toHumanTime(startIn, undefined, $T) }));
271+
},
272+
}
273+
),
235274
reaction: {
236275
name: 'reaction',
237276
aliases: ['x', '!!'],

src/ps/games/game.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class BaseGame<State extends BaseState> {
6161
sides: boolean;
6262

6363
started: boolean = false;
64+
scheduledStart: Timer | null = null;
6465
createdAt: Date = new Date();
6566
startedAt?: Date;
6667
endedAt?: Date;
@@ -453,6 +454,10 @@ export class BaseGame<State extends BaseState> {
453454
setUGOPlayed(this.meta.id, player.id, prev => prev + 1);
454455
});
455456
}
457+
if (this.scheduledStart) {
458+
this.scheduledStart.cancel();
459+
this.scheduledStart = null;
460+
}
456461
return { success: true, data: null };
457462
}
458463

0 commit comments

Comments
 (0)