Started work on adding count decorator

This commit is contained in:
Ean Milligan (Bastion) 2022-05-19 02:53:30 -04:00
parent 04d7324769
commit a270a4b8f7
7 changed files with 50 additions and 27 deletions

View File

@ -98,6 +98,7 @@ The Artificer comes with a few supplemental commands to the main rolling command
* `[[d20/40]]` will roll a d20 die and divide it by 40.
* `[[((d20+20) - 10) / 5]]` will roll a d20, add 20 to that roll, subtract off 10, and finally divide by 5.
* This command also has some useful decorators that can used. These decorators simply need to be placed after all rolls in the message:
* `-c` - Count - Shows the Count Embed, containing the count of successful rolls, failed rolls, rerolls, drops, and explosions
* `-nd` - No Details - Suppresses all details of the requested roll
* `-snd` - Super No Details - Suppresses all details of the requested roll and hides no details message
* `-s` - Spoiler - Spoilers all details of the requested roll
@ -134,8 +135,9 @@ Available Endpoints and Methods Required:
* `channel` - The Discord Channel ID that the bot is to send the results into.
* `rollstr` - A roll string formatted identically to the roll command detailed in the "Available Commands" section.
* Optional query parameters (these parameters do not require values unless specified):
* `snd` - Super No Details - Suppresses all details of the requested roll and hides no details message.
* `c` - Count - Shows the Count Embed, containing the count of successful rolls, failed rolls, rerolls, drops, and explosions
* `nd` - No Details - Suppresses all details of the requested roll.
* `snd` - Super No Details - Suppresses all details of the requested roll and hides no details message.
* `s` - Spoiler - Spoilers all details of the requested roll.
* `m` - Maximize Roll - Rolls the theoretical maximum roll, cannot be used with Nominal roll.
* `n` - Nominal Roll - Rolls the theoretical nominal roll, cannot be used with Maximise roll.
@ -200,11 +202,6 @@ If you choose to run version `1.1.0` or newer, ensure you disable the API in `co
---
## Development Plans
Current and future plans are listed on [the Milestones page](https://github.com/Burn-E99/TheArtificer/milestones).
---
## Privacy Policy and Terms of Service
The Artificer has a Privacy Policy and Terms of Service to detail expectations of what user data is stored and how users should use The Artificer. The following Privacy Policy and Terms of Service only apply to the officially hosted version of The Artificer (`The Artificer#8166`, Discord ID: `789045930011656223`).

View File

@ -19,6 +19,7 @@ import {
LT, log
} from "../deps.ts";
import { RollModifiers } from "./mod.d.ts";
import { dbClient, queries } from "./db.ts";
import solver from "./solver/_index.ts";
import {
@ -238,8 +239,21 @@ const start = async (): Promise<void> => {
// Clip off the leading prefix. API calls must be formatted with a prefix at the start to match how commands are sent in Discord
rollCmd = rollCmd.substring(rollCmd.indexOf(config.prefix) + 2).replace(/%20/g, " ");
const modifiers: RollModifiers = {
noDetails: false,
superNoDetails: false,
spoiler: "",
maxRoll: query.has("m"),
nominalRoll: query.has("n"),
gmRoll: false,
gms: [],
order: query.has("o") ? (query.get("o")?.toLowerCase() || "") : "",
valid: true,
count: query.has("c")
};
// Parse the roll and get the return text
const returnmsg = solver.parseRoll(rollCmd, config.prefix, config.postfix, query.has("m"), query.has("n"), query.has("o") ? (query.get("o")?.toLowerCase() || "") : "");
const returnmsg = solver.parseRoll(rollCmd, modifiers);
// Alert users why this message just appeared and how they can report abues pf this feature
const apiPrefix = hideWarn ? '' : `The following roll was conducted using my built in API. If someone in this channel did not request this roll, please report API abuse here: <${config.api.supportURL}>\n\n`;

View File

@ -42,7 +42,7 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
// Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in
const rollCmd = `${command} ${args.join(" ")}`;
const returnmsg = solver.parseRoll(rollCmd, config.prefix, config.postfix, modifiers.maxRoll, modifiers.nominalRoll, modifiers.order) || { error: true, errorCode: "EmptyMessage", errorMsg: "Error: Empty message", line1: "", line2: "", line3: "" };
const returnmsg = solver.parseRoll(rollCmd, modifiers) || { error: true, errorCode: "EmptyMessage", errorMsg: "Error: Empty message", line1: "", line2: "", line3: "" };
let returnText = "";

View File

@ -22,7 +22,8 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
gmRoll: false,
gms: [],
order: "",
valid: false
valid: false,
count: false
};
// Check if any of the args are command flags and pull those out into the modifiers object
@ -30,6 +31,9 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
log(LT.LOG, `Checking ${command}${args.join(" ")} for command modifiers ${i}`);
let defaultCase = false;
switch (args[i].toLowerCase()) {
case "-c":
modifiers.count = true;
break;
case "-nd":
modifiers.noDetails = true;
break;
@ -69,6 +73,7 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
}
break;
case "-o":
// Shift the -o out of the array so the next item is the direction
args.splice(i, 1);
if (!args[i] || args[i].toLowerCase()[0] !== "d" && args[i].toLowerCase()[0] !== "a") {

View File

@ -365,6 +365,10 @@ export const constantCmds = {
name: "`-gm @user1 @user2 @usern` - GM Roll",
value: "Rolls the requested roll in GM mode, suppressing all publicly shown results and details and sending the results directly to the specified GMs",
inline: true
}, {
name: "`-c` - Count Rolls",
value: "Shows the Count Embed, containing the count of successful rolls, failed rolls, rerolls, drops, and explosions",
inline: true
}, {
name: "`-o [direction]` - Order Roll",
value: `Rolls the requested roll and orders the results in the requested direction

4
src/mod.d.ts vendored
View File

@ -9,6 +9,7 @@ export type EmojiConf = {
deleteSender: boolean
};
// RollModifiers is the structure to keep track of the decorators applied to a roll command
export type RollModifiers = {
noDetails: boolean,
superNoDetails: boolean,
@ -18,5 +19,6 @@ export type RollModifiers = {
gmRoll: boolean,
gms: string[],
order: string,
valid: boolean
valid: boolean,
count: boolean
}

View File

@ -5,14 +5,15 @@ import {
import config from "../../config.ts";
import { RollModifiers } from "../mod.d.ts";
import { SolvedStep, SolvedRoll, ReturnData } from "./solver.d.ts";
import { compareTotalRolls, escapeCharacters } from "./rollUtils.ts";
import { formatRoll } from "./rollFormatter.ts";
import { fullSolver } from "./solver.ts";
// parseRoll(fullCmd, localPrefix, localPostfix, maximiseRoll, nominalRoll)
// parseRoll(fullCmd, modifiers)
// parseRoll handles converting fullCmd into a computer readable format for processing, and finally executes the solving
export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: string, maximiseRoll: boolean, nominalRoll: boolean, order: string): SolvedRoll => {
export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll => {
const returnmsg = {
error: false,
errorMsg: "",
@ -25,7 +26,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
// Whole function lives in a try-catch to allow safe throwing of errors on purpose
try {
// Split the fullCmd by the command prefix to allow every roll/math op to be handled individually
const sepRolls = fullCmd.split(localPrefix);
const sepRolls = fullCmd.split(config.prefix);
const tempReturnData: ReturnData[] = [];
@ -33,7 +34,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
for (let i = 0; i < sepRolls.length; i++) {
log(LT.LOG, `Parsing roll ${fullCmd} | Working ${sepRolls[i]}`);
// Split the current iteration on the command postfix to separate the operation to be parsed and the text formatting after the opertaion
const [tempConf, tempFormat] = sepRolls[i].split(localPostfix);
const [tempConf, tempFormat] = sepRolls[i].split(config.postfix);
// Remove all spaces from the operation config and split it by any operator (keeping the operator in mathConf for fullSolver to do math on)
const mathConf: (string | number | SolvedStep)[] = <(string | number | SolvedStep)[]>tempConf.replace(/ /g, "").split(/([-+()*/%^])/g);
@ -66,7 +67,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
mathConf[i] = parseFloat(mathConf[i].toString());
} else if (/([0123456789])/g.test(mathConf[i].toString())) {
// If there is a number somewhere in mathconf[i] but there are also other characters preventing it from parsing correctly as a number, it should be a dice roll, parse it as such (if it for some reason is not a dice roll, formatRoll/roll will handle it)
mathConf[i] = formatRoll(mathConf[i].toString(), maximiseRoll, nominalRoll);
mathConf[i] = formatRoll(mathConf[i].toString(), modifiers.maxRoll, modifiers.nominalRoll);
} else if (mathConf[i].toString().toLowerCase() === "e") {
// If the operand is the constant e, create a SolvedStep for it
mathConf[i] = {
@ -130,23 +131,23 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
let line3 = "";
// If maximiseRoll or nominalRoll are on, mark the output as such, else use default formatting
if (maximiseRoll) {
line1 = ` requested the theoretical maximum of: \`${localPrefix}${fullCmd}\``;
if (modifiers.maxRoll) {
line1 = ` requested the theoretical maximum of: \`${config.prefix}${fullCmd}\``;
line2 = "Theoretical Maximum Results: ";
} else if (nominalRoll) {
line1 = ` requested the theoretical nominal of: \`${localPrefix}${fullCmd}\``;
} else if (modifiers.nominalRoll) {
line1 = ` requested the theoretical nominal of: \`${config.prefix}${fullCmd}\``;
line2 = "Theoretical Nominal Results: ";
} else if (order === "a") {
line1 = ` requested the following rolls to be ordered from least to greatest: \`${localPrefix}${fullCmd}\``;
} else if (modifiers.order === "a") {
line1 = ` requested the following rolls to be ordered from least to greatest: \`${config.prefix}${fullCmd}\``;
line2 = "Results: ";
tempReturnData.sort(compareTotalRolls);
} else if (order === "d") {
line1 = ` requested the following rolls to be ordered from greatest to least: \`${localPrefix}${fullCmd}\``;
} else if (modifiers.order === "d") {
line1 = ` requested the following rolls to be ordered from greatest to least: \`${config.prefix}${fullCmd}\``;
line2 = "Results: ";
tempReturnData.sort(compareTotalRolls);
tempReturnData.reverse();
} else {
line1 = ` rolled: \`${localPrefix}${fullCmd}\``;
line1 = ` rolled: \`${config.prefix}${fullCmd}\``;
line2 = "Results: ";
}
@ -167,7 +168,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
}
// Populate line2 (the results) and line3 (the details) with their data
if (order === "") {
if (modifiers.order === "") {
line2 += `${preFormat}${e.rollTotal}${postFormat}${escapeCharacters(e.rollPostFormat, "|*_~`")}`;
} else {
// If order is on, turn rolls into csv without formatting
@ -180,7 +181,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
});
// If order is on, remove trailing ", "
if (order !== "") {
if (modifiers.order !== "") {
line2 = line2.substring(0, (line2.length - 2));
}
@ -213,7 +214,7 @@ export const parseRoll = (fullCmd: string, localPrefix: string, localPostfix: st
if (errorDetails === "-") {
errorMsg += "\nNote: Negative numbers are not supported";
} else if (errorDetails === " ") {
errorMsg += `\nNote: Every roll must be closed by ${localPostfix}`;
errorMsg += `\nNote: Every roll must be closed by ${config.postfix}`;
}
break;
case "NoZerosAllowed":