schat2-clive/src/games/geo.js

125 lines
3.5 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'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.',
};