'use strict'; const config = require('config'); const { intervalToDuration } = require('date-fns'); const style = require('../utils/style'); const pickRandom = require('../utils/pick-random'); const ducks = new Map(); let shots = new Map(); function launchDuck(context) { ducks.delete(context.room?.id); shots = new Map(); const interval = Array.isArray(config.duck.interval) ? ((Math.random() * (config.duck.interval[1] - config.duck.interval[0])) + config.duck.interval[0]) * 1000 : config.duck.interval * 1000; setTimeout(() => { if (context.bot.rooms.length === 0) { return; } const rooms = Object.values(context.bot.rooms); const room = rooms[Math.floor(Math.random() * rooms.length)]; ducks.set(room.id, new Date()); context.sendMessage(`Quack! ${config.duck.duck}`, room.id); }, interval); } function onCommand(args, context) { const duck = ducks.get(context.room.id); if (!duck && ['bang', 'shoot'].includes(context.command)) { const message = pickRandom([ `There is no duck, what are you shooting at, ${context.user.prefixedUsername}?!`, `You're wasting bullets, ${context.user.prefixedUsername}, there is no duck!`, `The only quack is you, ${context.user.prefixedUsername}...`, ]); context.sendMessage(message, context.room.id); return; } if (!duck && ['befriend', 'bef'].includes(context.command)) { const message = pickRandom([ `You're trying to befriend a non-existent duck, ${context.user.prefixedUsername}...`, `There aren't any ducks to befriend, ${context.user.prefixedUsername}...`, `That's no duck, ${context.user.prefixedUsername} ✈️`, ]); context.sendMessage(message, context.room.id); return; } const hit = Math.random() > config.duck.missRatio; const time = new Date().getTime() - duck.getTime(); const distance = time < 60 * 1000 // show digits up to one minute ? `${(time / 1000).toFixed(3)} seconds` : `${Object.entries(intervalToDuration({ start: duck, end: new Date() })) .filter(([, value]) => value > 0) .map(([key, value]) => `${value} ${key}`) .join(', ')} and ${time % 1000} milliseconds`; if (['bang', 'shoot'].includes(context.command)) { if (hit) { context.sendMessage(`${context.user.prefixedUsername}: You shot a duck in ${style.bold(style.red(distance))}`, context.room.id); launchDuck(context); context.setPoints(context.user, 1, { key: 'bang' }); return; } const message = pickRandom([ `How could you miss ${style.italic('that')}, ${context.user.prefixedUsername}...?!`, `That's a miss! Better luck next time, ${context.user.prefixedUsername}.`, `The duck outsmarted you, ${context.user.prefixedUsername}`, `Channeling Gareth Southgate, ${context.user.prefixedUsername}? You missed!`, `Oh, and that's a bad miss, ${context.user.prefixedUsername}.`, ]); shots.set(context.user.id, new Date()); context.sendMessage(message, context.room.id); return; } if (['bef', 'befriend'].includes(context.command)) { if (hit) { context.sendMessage(`${context.user.prefixedUsername}: You befriended a duck in ${style.bold(style.sky(distance))}`, context.room.id); launchDuck(context); context.setPoints(context.user, 1, { key: 'befriend' }); return; } const message = pickRandom([ `The duck does not want to be your friend right now, ${context.user.prefixedUsername}`, `The duck would like some time for itself, ${context.user.prefixedUsername}`, `The duck isn't in the mood right now, ${context.user.prefixedUsername}`, ]); shots.set(context.user.id, new Date()); context.sendMessage(message, context.room.id); } } module.exports = { name: 'Duck', commands: ['bang', 'shoot', 'bef', 'befriend'], help: `There are ducks on the loose! When you see one, you can be nice and ${config.prefix}befriend them, or... ${config.prefix}bang`, onStart: launchDuck, onCommand, };