mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-23 10:02:05 +02:00
Guesspionage Command
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
const Command = require('../../structures/Command');
|
||||
const { stripIndents } = require('common-tags');
|
||||
const questions = require('../../assets/json/guesspionage');
|
||||
const { SUCCESS_EMOJI_ID } = process.env;
|
||||
const guesses = ['much higher', 'higher', 'lower', 'much lower'];
|
||||
const max = 8;
|
||||
const min = 2;
|
||||
|
||||
module.exports = class GuesspionageCommand extends Command {
|
||||
constructor(client) {
|
||||
super(client, {
|
||||
name: 'guesspionage',
|
||||
group: 'games-mp',
|
||||
memberName: 'guesspionage',
|
||||
description: 'Tests your knowledge of humans as you guess how people responded to poll questions.',
|
||||
guildOnly: true,
|
||||
credit: [
|
||||
{
|
||||
name: 'Jackbox Games',
|
||||
url: 'https://www.jackboxgames.com/',
|
||||
reason: 'Original "Guesspionage" Game',
|
||||
reasonURL: 'https://www.jackboxgames.com/guesspionage/'
|
||||
},
|
||||
{
|
||||
name: 'Playstation Trophies',
|
||||
url: 'https://www.playstationtrophies.org/',
|
||||
reason: 'Question Data',
|
||||
// eslint-disable-next-line max-len
|
||||
reasonURL: 'https://www.playstationtrophies.org/game/the-jackbox-party-pack-3/trophy/157520-Guesspionage--Perfect-Surveillance.html'
|
||||
},
|
||||
{
|
||||
name: 'TrueAchievements',
|
||||
url: 'https://www.trueachievements.com/',
|
||||
reason: 'Question Data',
|
||||
reasonURL: 'https://www.trueachievements.com/forum/viewthread.aspx?tid=850920'
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
async run(msg) {
|
||||
const current = this.client.games.get(msg.channel.id);
|
||||
if (current) return msg.reply(`Please wait until the current game of \`${current.name}\` is finished.`);
|
||||
this.client.games.set(msg.channel.id, { name: this.name });
|
||||
try {
|
||||
const awaitedPlayers = await this.awaitPlayers(msg);
|
||||
if (!awaitedPlayers) {
|
||||
this.client.games.delete(msg.channel.id);
|
||||
return msg.say('Game could not be started...');
|
||||
}
|
||||
let turn = 0;
|
||||
const pts = new Map();
|
||||
for (const player of awaitedPlayers) {
|
||||
pts.set(player, {
|
||||
points: 0,
|
||||
id: player,
|
||||
user: this.client.users.get(player)
|
||||
});
|
||||
}
|
||||
const used = [];
|
||||
const userTurn = awaitedPlayers.slice(0);
|
||||
while (turn <= pts.size) {
|
||||
++turn;
|
||||
const mainUser = userTurn[0];
|
||||
userTurn.shift();
|
||||
const valid = questions.filter(
|
||||
question => !used.includes(question.text) && (msg.channel.nsfw ? true : !question.nsfw)
|
||||
);
|
||||
const question = valid[Math.floor(Math.random() * valid.length)];
|
||||
used.push(question.text);
|
||||
await msg.say(stripIndents`
|
||||
**${turn}.** ${question.text}
|
||||
|
||||
${mainUser}, what percentage do you guess?
|
||||
`);
|
||||
const initialGuessFilter = res => {
|
||||
if (res.author.id !== mainUser.id) return false;
|
||||
const int = Number.parseInt(res.content, 10);
|
||||
return int >= 0 && int <= 100;
|
||||
};
|
||||
const initialGuess = await msg.channel.awaitMessages(initialGuessFilter, {
|
||||
max: 1,
|
||||
time: 30000
|
||||
});
|
||||
if (!initialGuess.size) {
|
||||
await msg.say('Hmm... No guess? I guess you\'re getting skipped.');
|
||||
continue;
|
||||
}
|
||||
const guess = Number.parseInt(initialGuess.first().content, 10);
|
||||
await msg.say(stripIndents`
|
||||
**${guess}%**
|
||||
|
||||
Alright, everyone else, do you think the _actual_ percentage is \`higher\` or \`lower\`?
|
||||
You can also guess \`much higher\` or \`much lower\` for double points if their answer is 15% off.
|
||||
`);
|
||||
const guessed = [];
|
||||
const everyoneElseFilter = res => {
|
||||
if (res.author.id === mainUser.id) return false;
|
||||
if (guessed.includes(res.author.id)) return false;
|
||||
if (!awaitedPlayers.includes(res.author.id)) return false;
|
||||
if (!guesses.includes(res.content.toLowerCase())) return false;
|
||||
guessed.push(res.author.id);
|
||||
return true;
|
||||
};
|
||||
const everyoneElse = await msg.channel.awaitMessages(everyoneElseFilter, {
|
||||
max: awaitedPlayers.length - 1,
|
||||
time: 30000
|
||||
});
|
||||
if (!everyoneElse.size) {
|
||||
await msg.say('Come on guys, get in the game!');
|
||||
continue;
|
||||
}
|
||||
const higherLower = everyoneElse.map(res => ({ guess: res.content.toLowerCase(), id: res.author.id }));
|
||||
for (const answer of higherLower) {
|
||||
if (answer === 'higher' && guess < question.answer) {
|
||||
pts.get(answer.id).points += 1000;
|
||||
} else if (answer === 'lower' && guess > question.answer) {
|
||||
pts.get(answer.id).points += 1000;
|
||||
} else if (answer === 'much higher' && guess < question.answer && question.answer - guess >= 15) {
|
||||
pts.get(answer.id).points += 2000;
|
||||
} else if (answer === 'much lower' && guess > question.answer && guess - question.answer >= 15) {
|
||||
pts.get(answer.id).points += 2000;
|
||||
}
|
||||
}
|
||||
const diff = Math.abs(question.answer - guess);
|
||||
if (diff <= 30) pts.get(mainUser.id).points += 3000 - (diff * 100);
|
||||
await msg.say(stripIndents`
|
||||
The actual answer was... **${question.answer}%**!
|
||||
|
||||
__**Leaderboard:**__
|
||||
${this.makeLeaderboard(pts).join('\n')}
|
||||
`);
|
||||
}
|
||||
this.client.games.delete(msg.channel.id);
|
||||
const winner = this.client.users.get(pts.sort((a, b) => b.points - a.points));
|
||||
return msg.say(`Congrats, ${winner.user}!`);
|
||||
} catch (err) {
|
||||
this.client.games.delete(msg.channel.id);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async awaitPlayers(msg) {
|
||||
await msg.say(`You will need at least 1 more player (at max ${max - 1}). To join, type \`join game\`.`);
|
||||
const joined = [];
|
||||
joined.push(msg.author.id);
|
||||
const filter = res => {
|
||||
if (res.author.bot) return false;
|
||||
if (joined.includes(res.author.id)) return false;
|
||||
if (res.content.toLowerCase() !== 'join game') return false;
|
||||
joined.push(res.author.id);
|
||||
res.react(SUCCESS_EMOJI_ID || '✅').catch(() => null);
|
||||
return true;
|
||||
};
|
||||
const verify = await msg.channel.awaitMessages(filter, { max: max - 1, time: 30000 });
|
||||
verify.set(msg.id, msg);
|
||||
if (verify.size < min) return false;
|
||||
return verify.map(player => player.author.id);
|
||||
}
|
||||
|
||||
makeLeaderboard(pts) {
|
||||
let i = 0;
|
||||
let previousPts = null;
|
||||
let positionsMoved = 1;
|
||||
return pts
|
||||
.sort((a, b) => b.points - a.points)
|
||||
.map(player => {
|
||||
if (previousPts === player.points) {
|
||||
positionsMoved++;
|
||||
} else {
|
||||
i += positionsMoved;
|
||||
positionsMoved = 1;
|
||||
}
|
||||
previousPts = player.points;
|
||||
return `**${i}.** ${player.user.tag} (${player.points} Point${player.points === 1 ? '' : 's'})`;
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user