125 lines
3.5 KiB
JavaScript
125 lines
3.5 KiB
JavaScript
'use strict';
|
||
|
||
const config = require('config');
|
||
const timers = require('timers/promises');
|
||
|
||
const pickRandom = require('../utils/pick-random');
|
||
const style = require('../utils/style');
|
||
|
||
const countries = require('../../assets/countries-curated.json');
|
||
const states = require('../../assets/states-curated.json');
|
||
const flags = require('../../assets/flags-curated.json');
|
||
|
||
const data = { countries, states, flags };
|
||
|
||
const games = {
|
||
countries: new Map(),
|
||
states: new Map(),
|
||
flags: new Map(),
|
||
};
|
||
|
||
const questions = [
|
||
'What\'s this country?',
|
||
'Name this country.',
|
||
'Where are we going on holiday?',
|
||
'What\'s our destination?',
|
||
'I\'d never heard of that place, what\'s it called?',
|
||
];
|
||
|
||
function hint(game, context) {
|
||
if (game.name.length >= 5) {
|
||
context.sendMessage(`${style.bold(`${game.name.slice(0, 1)} ${game.name.slice(1, -1).replace(/\s/g, ' ').replace(/[^\s]/g, '_ ')}${game.name.slice(-1)}`.toUpperCase())}, the country code is ${style.bold(game.alpha2)}`, context.room.id); // eslint-disable-line no-irregular-whitespace
|
||
|
||
return;
|
||
}
|
||
|
||
context.sendMessage(`${style.bold(`${game.name.slice(0, 1)} ${game.name.slice(1).replace(/\s/g, ' ').replace(/[^\s]/g, '_ ').trim()}`.toUpperCase())}, the country code is ${style.bold(game.alpha2)}`, context.room.id); // eslint-disable-line no-irregular-whitespace
|
||
}
|
||
|
||
function play(context, type = 'countries') {
|
||
const country = pickRandom(data[type]);
|
||
const url = `${config.geo.url}${type}/${country.file}`;
|
||
|
||
games[type].set(context.room.id, {
|
||
...country,
|
||
type,
|
||
url,
|
||
regexp: new RegExp(country.fullName ? `(${country.name})|(${country.fullName})` : country.name, 'i'),
|
||
});
|
||
|
||
context.sendMessage(`${url} ${pickRandom(questions)}`, context.room.id);
|
||
context.logger.info(`Geo played '${country.name}' (${url})`);
|
||
}
|
||
|
||
function getType(command) {
|
||
if (['state', 'america'].includes(command)) {
|
||
return 'states';
|
||
}
|
||
|
||
if (['flag'].includes(command)) {
|
||
return 'flags';
|
||
}
|
||
|
||
return 'countries';
|
||
}
|
||
|
||
async function onCommand(args, context) {
|
||
const type = getType(context.command);
|
||
|
||
if (context.subcommand && !games[type].has(context.room.id)) {
|
||
context.sendMessage(`There is no country in play right now. Start a new round with ${config.prefix}geo!`, context.room.id);
|
||
return;
|
||
}
|
||
|
||
if (['skip', 'stop', 'reset'].includes(context.subcommand)) {
|
||
const game = games[type].get(context.room.id);
|
||
|
||
games[type].delete(context.room.id);
|
||
context.sendMessage(`Geo was skipped by ${context.user.prefixedUsername}. The country was ${style.bold(game.fullName ? `${game.fullName} (${game.name})` : game.name)}.`, context.room.id);
|
||
|
||
await timers.setTimeout(2000);
|
||
}
|
||
|
||
const game = games[type].get(context.room.id);
|
||
|
||
if (context.subcommand === 'hint') {
|
||
hint(game, context);
|
||
return;
|
||
}
|
||
|
||
if (game) {
|
||
context.sendMessage(game.url, context.room.id);
|
||
return;
|
||
}
|
||
|
||
play(context, type);
|
||
}
|
||
|
||
async function onMessage(message, context) {
|
||
['countries', 'states', 'flags'].forEach(async (type) => {
|
||
const game = games[type].get(context.room?.id);
|
||
|
||
if (!game) {
|
||
return;
|
||
}
|
||
|
||
if (game.regexp.test(message.body)) {
|
||
context.sendMessage(`${style.answer(game.fullName || game.name)} is the right answer! ${style.username(context.user.prefixedUsername)} gets a point.`, context.room.id);
|
||
context.setPoints(context.user);
|
||
|
||
games[type].delete(context.room.id);
|
||
|
||
await timers.setTimeout(3000);
|
||
|
||
play(context, type);
|
||
}
|
||
});
|
||
}
|
||
|
||
module.exports = {
|
||
onCommand,
|
||
onMessage,
|
||
commands: ['country', 'atlas', 'state', 'america', 'flag'],
|
||
help: 'Name the country or US state on the map! Too hard? Try ~geo:hint or ~geo:skip.',
|
||
};
|