40 lines
1.6 KiB
TypeScript
40 lines
1.6 KiB
TypeScript
import type { ChatInputCommandInteraction } from "discord.js";
|
|
import { randomInt } from "crypto";
|
|
|
|
import type { CommandData } from "./index";
|
|
import { BotError } from "./error";
|
|
|
|
const MAX_DICE: number = 100;
|
|
const MAX_FACES: number = 9999;
|
|
|
|
async function run(interaction: ChatInputCommandInteraction) {
|
|
await interaction.deferReply(); //do these options.get things need to be await?? kinda stupid
|
|
const options = interaction.options;
|
|
const dice_num: number = (await options.get("dice_num")).value as number;
|
|
const dice_faces: number = (await options.get("dice_faces")).value as number;
|
|
const show_calc: boolean = ((await options.get("show_calc"))?.value ?? true) as boolean;
|
|
const include_zero: boolean = ((await options.get("include_zero"))?.value ?? false) as boolean;
|
|
if (dice_num < 1) throw new BotError("Must roll at least 1 dice, obviously");
|
|
//semi-arbitrary limits, discord messages can be max 2000 chars long
|
|
if (dice_num > MAX_DICE) throw new BotError(`Max of ${MAX_DICE} dice`);
|
|
if (dice_faces > 9999) throw new BotError(`Max of ${MAX_FACES} faces`);
|
|
let rolls: number[] = [];
|
|
for (let i = 0; i < dice_num; i++) {
|
|
rolls.push(randomInt(include_zero ? 0 : 1, dice_faces + 1));
|
|
}
|
|
const result: number = rolls.reduce((accum, roll) => accum + roll, 0);
|
|
return await interaction.editReply(`Result: **${result}** ${ show_calc ? `(${ rolls.join(" + ")} = ${result})` : "" }`);
|
|
}
|
|
|
|
const data: CommandData = {
|
|
name: "roll",
|
|
description: "Roll dice",
|
|
registered_only: false,
|
|
ephemeral: false,
|
|
admin_only: false,
|
|
run,
|
|
};
|
|
|
|
export default data;
|
|
|