Add Min flag and add -max as option for max flag
This commit is contained in:
parent
5bef3878cc
commit
4207021fa9
|
@ -5,7 +5,7 @@ meta {
|
|||
}
|
||||
|
||||
get {
|
||||
url: http://localhost:8166/api/roll?user=[discord-user-id]&channel=[discord-channel-id]&rollstr=[artificer-roll-cmd]&documentation=All items below are optional. Flags do not need values.&nd=[no-details-flag]&snd=[super-no-details-flag]&s=[spoiler-results-flag]&m=[max-roll-flag, cannot be used with n flag]&n=[nominal-roll-flag, cannot be used with m flag]&gms=[csv-of-discord-user-ids-to-be-dmed-results]&o=[order-rolls, must be a or d]&c=[count-flag]
|
||||
url: http://localhost:8166/api/roll?user=[discord-user-id]&channel=[discord-channel-id]&rollstr=[artificer-roll-cmd]&documentation=All items below are optional. Flags do not need values.&nd=[no-details-flag]&snd=[super-no-details-flag]&s=[spoiler-results-flag]&m or max=[max-roll-flag, cannot be used with n flag]&min=[[min-roll-flag, cannot be used with n or max&n=[nominal-roll-flag, cannot be used with max or min flag]&gms=[csv-of-discord-user-ids-to-be-dmed-results]&o=[order-rolls, must be a or d]&c=[count-flag]
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ params:query {
|
|||
nd: [no-details-flag]
|
||||
snd: [super-no-details-flag]
|
||||
s: [spoiler-results-flag]
|
||||
m: [max-roll-flag, cannot be used with n flag]
|
||||
n: [nominal-roll-flag, cannot be used with m flag]
|
||||
m or max: [max-roll-flag, cannot be used with n flag]
|
||||
min: [[min-roll-flag, cannot be used with n or max
|
||||
n: [nominal-roll-flag, cannot be used with max or min flag]
|
||||
gms: [csv-of-discord-user-ids-to-be-dmed-results]
|
||||
o: [order-rolls, must be a or d]
|
||||
c: [count-flag]
|
||||
|
|
|
@ -20,6 +20,7 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
|
|||
superNoDetails: false,
|
||||
spoiler: '',
|
||||
maxRoll: false,
|
||||
minRoll: false,
|
||||
nominalRoll: false,
|
||||
gmRoll: false,
|
||||
gms: [],
|
||||
|
@ -46,9 +47,13 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
|
|||
case '-s':
|
||||
modifiers.spoiler = '||';
|
||||
break;
|
||||
case '-max':
|
||||
case '-m':
|
||||
modifiers.maxRoll = true;
|
||||
break;
|
||||
case '-min':
|
||||
modifiers.minRoll = true;
|
||||
break;
|
||||
case '-n':
|
||||
modifiers.nominalRoll = true;
|
||||
break;
|
||||
|
@ -106,9 +111,11 @@ export const getModifiers = (m: DiscordenoMessage, args: string[], command: stri
|
|||
}
|
||||
}
|
||||
|
||||
// maxRoll and nominalRoll cannot both be on, throw an error
|
||||
if (modifiers.maxRoll && modifiers.nominalRoll) {
|
||||
m.edit(generateRollError(errorType, 'Cannot maximize and nominize the roll at the same time')).catch((e) => utils.commonLoggers.messageEditError('getModifiers.ts:106', m, e));
|
||||
// maxRoll, minRoll, and nominalRoll cannot be on at same time, throw an error
|
||||
if ([modifiers.maxRoll, modifiers.minRoll, modifiers.nominalRoll].filter((b) => b).length > 1) {
|
||||
m.edit(generateRollError(errorType, 'Can only use one of the following at a time:\n`maximize`, `minimize`, `nominal`')).catch((e) =>
|
||||
utils.commonLoggers.messageEditError('getModifiers.ts:106', m, e)
|
||||
);
|
||||
|
||||
if (DEVMODE && config.logRolls) {
|
||||
// If enabled, log rolls so we can verify the bots math
|
||||
|
|
|
@ -84,7 +84,8 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
|
|||
noDetails: query.has('nd'),
|
||||
superNoDetails: query.has('snd'),
|
||||
spoiler: query.has('s') ? '||' : '',
|
||||
maxRoll: query.has('m'),
|
||||
maxRoll: query.has('m') || query.has('max'),
|
||||
minRoll: query.has('min'),
|
||||
nominalRoll: query.has('n'),
|
||||
gmRoll: query.has('gms'),
|
||||
gms: query.has('gms') ? (query.get('gms') || '').split(',') : [],
|
||||
|
|
|
@ -16,6 +16,7 @@ export type RollModifiers = {
|
|||
superNoDetails: boolean;
|
||||
spoiler: string;
|
||||
maxRoll: boolean;
|
||||
minRoll: boolean;
|
||||
nominalRoll: boolean;
|
||||
gmRoll: boolean;
|
||||
gms: string[];
|
||||
|
|
|
@ -8,7 +8,7 @@ import config from '../../config.ts';
|
|||
|
||||
import { RollModifiers } from '../mod.d.ts';
|
||||
import { CountDetails, ReturnData, SolvedRoll, SolvedStep } from './solver.d.ts';
|
||||
import { compareTotalRolls, escapeCharacters, loggingEnabled } from './rollUtils.ts';
|
||||
import { compareTotalRolls, compareTotalRollsReverse, escapeCharacters, loggingEnabled } from './rollUtils.ts';
|
||||
import { formatRoll } from './rollFormatter.ts';
|
||||
import { fullSolver } from './solver.ts';
|
||||
|
||||
|
@ -151,7 +151,7 @@ export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll
|
|||
i += 2;
|
||||
} else if (!operators.includes(mathConf[i].toString())) {
|
||||
// If nothing else has handled it by now, try it as a roll
|
||||
const formattedRoll = formatRoll(mathConf[i].toString(), modifiers.maxRoll, modifiers.nominalRoll);
|
||||
const formattedRoll = formatRoll(mathConf[i].toString(), modifiers);
|
||||
mathConf[i] = formattedRoll.solvedStep;
|
||||
tempCountDetails.push(formattedRoll.countDetails);
|
||||
}
|
||||
|
@ -197,13 +197,14 @@ export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll
|
|||
let line2 = '';
|
||||
let line3 = '';
|
||||
|
||||
// If maximizeRoll or nominalRoll are on, mark the output as such, else use default formatting
|
||||
if (modifiers.maxRoll) {
|
||||
line1 = ` requested the theoretical maximum of:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = 'Theoretical Maximum Results: ';
|
||||
} else if (modifiers.nominalRoll) {
|
||||
line1 = ` requested the theoretical nominal of:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = 'Theoretical Nominal Results: ';
|
||||
// If a theoretical roll is requested, mark the output as such, else use default formatting
|
||||
if (modifiers.maxRoll || modifiers.minRoll || modifiers.nominalRoll) {
|
||||
const theoreticalTexts = ['Maximum', 'Minimum', 'Nominal'];
|
||||
const theoreticalBools = [modifiers.maxRoll, modifiers.minRoll, modifiers.nominalRoll];
|
||||
const theoreticalText = theoreticalTexts[theoreticalBools.indexOf(true)];
|
||||
|
||||
line1 = ` requested the Theoretical ${theoreticalText} of:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = `Theoretical ${theoreticalText} Results: `;
|
||||
} else if (modifiers.order === 'a') {
|
||||
line1 = ` requested the following rolls to be ordered from least to greatest:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = 'Results: ';
|
||||
|
@ -211,8 +212,7 @@ export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll
|
|||
} else if (modifiers.order === 'd') {
|
||||
line1 = ` requested the following rolls to be ordered from greatest to least:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = 'Results: ';
|
||||
tempReturnData.sort(compareTotalRolls);
|
||||
tempReturnData.reverse();
|
||||
tempReturnData.sort(compareTotalRollsReverse);
|
||||
} else {
|
||||
line1 = ` rolled:\n\`${config.prefix}${fullCmd}\``;
|
||||
line2 = 'Results: ';
|
||||
|
|
|
@ -8,17 +8,18 @@ import { roll } from './roller.ts';
|
|||
import { rollCounter } from './counter.ts';
|
||||
import { RollFormat } from './solver.d.ts';
|
||||
import { loggingEnabled } from './rollUtils.ts';
|
||||
import { RollModifiers } from '../mod.d.ts';
|
||||
|
||||
// formatRoll(rollConf, maximizeRoll, nominalRoll) returns one SolvedStep
|
||||
// formatRoll(rollConf, modifiers) returns one SolvedStep
|
||||
// formatRoll handles creating and formatting the completed rolls into the SolvedStep format
|
||||
export const formatRoll = (rollConf: string, maximizeRoll: boolean, nominalRoll: boolean): RollFormat => {
|
||||
export const formatRoll = (rollConf: string, modifiers: RollModifiers): RollFormat => {
|
||||
let tempTotal = 0;
|
||||
let tempDetails = '[';
|
||||
let tempCrit = false;
|
||||
let tempFail = false;
|
||||
|
||||
// Generate the roll, passing flags thru
|
||||
const tempRollSet = roll(rollConf, maximizeRoll, nominalRoll);
|
||||
const tempRollSet = roll(rollConf, modifiers);
|
||||
|
||||
// Loop thru all parts of the roll to document everything that was done to create the total roll
|
||||
tempRollSet.forEach((e) => {
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
// Log4Deno deps
|
||||
LT,
|
||||
} from '../../deps.ts';
|
||||
import { RollModifiers } from '../mod.d.ts';
|
||||
|
||||
import { ReturnData, RollSet } from './solver.d.ts';
|
||||
|
||||
|
@ -10,23 +11,25 @@ export const loggingEnabled = false;
|
|||
|
||||
// genRoll(size) returns number
|
||||
// genRoll rolls a die of size size and returns the result
|
||||
export const genRoll = (size: number, maximizeRoll: boolean, nominalRoll: boolean): number => {
|
||||
if (maximizeRoll) {
|
||||
export const genRoll = (size: number, modifiers: RollModifiers): number => {
|
||||
if (modifiers.maxRoll) {
|
||||
return size;
|
||||
} else if (modifiers.minRoll) {
|
||||
return 1;
|
||||
} else {
|
||||
// Math.random * size will return a decimal number between 0 and size (excluding size), so add 1 and floor the result to not get 0 as a result
|
||||
return nominalRoll ? size / 2 + 0.5 : Math.floor(Math.random() * size + 1);
|
||||
return modifiers.nominalRoll ? size / 2 + 0.5 : Math.floor(Math.random() * size + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// genFateRoll returns -1|0|1
|
||||
// genFateRoll turns a d6 into a fate die, with sides: -1, -1, 0, 0, 1, 1
|
||||
export const genFateRoll = (maximizeRoll: boolean, nominalRoll: boolean): number => {
|
||||
if (nominalRoll) {
|
||||
export const genFateRoll = (modifiers: RollModifiers): number => {
|
||||
if (modifiers.nominalRoll) {
|
||||
return 0;
|
||||
} else {
|
||||
const sides = [-1, -1, 0, 0, 1, 1];
|
||||
return sides[genRoll(6, maximizeRoll, nominalRoll) - 1];
|
||||
return sides[genRoll(6, modifiers) - 1];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,18 +45,24 @@ export const compareRolls = (a: RollSet, b: RollSet): number => {
|
|||
return 0;
|
||||
};
|
||||
|
||||
// compareTotalRolls(a, b) returns -1|0|1
|
||||
// compareTotalRolls is used to order an array of RollSets by RollSet.roll
|
||||
export const compareTotalRolls = (a: ReturnData, b: ReturnData): number => {
|
||||
const internalCompareTotalRolls = (a: ReturnData, b: ReturnData, dir: 1 | -1): number => {
|
||||
if (a.rollTotal < b.rollTotal) {
|
||||
return -1;
|
||||
return -1 * dir;
|
||||
}
|
||||
if (a.rollTotal > b.rollTotal) {
|
||||
return 1;
|
||||
return 1 * dir;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
// compareTotalRolls(a, b) returns -1|0|1
|
||||
// compareTotalRolls is used to order an array of RollSets by RollSet.roll
|
||||
export const compareTotalRolls = (a: ReturnData, b: ReturnData): number => internalCompareTotalRolls(a, b, 1);
|
||||
|
||||
// compareTotalRollsReverse(a, b) returns 1|0|-1
|
||||
// compareTotalRollsReverse is used to order an array of RollSets by RollSet.roll reversed
|
||||
export const compareTotalRollsReverse = (a: ReturnData, b: ReturnData): number => internalCompareTotalRolls(a, b, -1);
|
||||
|
||||
// compareRolls(a, b) returns -1|0|1
|
||||
// compareRolls is used to order an array of RollSets by RollSet.origIdx
|
||||
export const compareOrigIdx = (a: RollSet, b: RollSet): number => {
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
|
||||
import { RollConf, RollSet, RollType } from './solver.d.ts';
|
||||
import { compareOrigIdx, compareRolls, genFateRoll, genRoll, loggingEnabled } from './rollUtils.ts';
|
||||
import { RollModifiers } from '../mod.d.ts';
|
||||
|
||||
// Call with loopCountCheck(++loopCount);
|
||||
// Will ensure if maxLoops is 10, 10 loops will be allowed, 11 will not.
|
||||
|
@ -20,9 +21,9 @@ const throwDoubleSepError = (sep: string): void => {
|
|||
throw new Error(`DoubleSeparator_${sep}`);
|
||||
};
|
||||
|
||||
// roll(rollStr, maximizeRoll, nominalRoll) returns RollSet
|
||||
// roll parses and executes the rollStr, if needed it will also make the roll the maximum or average
|
||||
export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolean): RollSet[] => {
|
||||
// roll(rollStr, modifiers) returns RollSet
|
||||
// roll parses and executes the rollStr
|
||||
export const roll = (rollStr: string, modifiers: RollModifiers): RollSet[] => {
|
||||
/* Roll Capabilities
|
||||
* Deciphers and rolls a single dice roll set
|
||||
*
|
||||
|
@ -494,7 +495,7 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
|
|||
// Copy the template to fill out for this iteration
|
||||
const rolling = getTemplateRoll();
|
||||
// If maximizeRoll is on, set the roll to the dieSize, else if nominalRoll is on, set the roll to the average roll of dieSize, else generate a new random roll
|
||||
rolling.roll = rollType === 'fate' ? genFateRoll(maximizeRoll, nominalRoll) : genRoll(rollConf.dieSize, maximizeRoll, nominalRoll);
|
||||
rolling.roll = rollType === 'fate' ? genFateRoll(modifiers) : genRoll(rollConf.dieSize, modifiers);
|
||||
// Set origIdx of roll
|
||||
rolling.origIdx = i;
|
||||
|
||||
|
@ -534,22 +535,33 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
|
|||
|
||||
// Copy the template to fill out for this iteration
|
||||
const newReroll = getTemplateRoll();
|
||||
if (maximizeRoll) {
|
||||
if (modifiers.maxRoll && !minMaxOverride) {
|
||||
// If maximizeRoll is on and we've entered the reroll code, dieSize is not allowed, determine the next best option and always return that
|
||||
if (!minMaxOverride) {
|
||||
mmLoop: for (let m = rollConf.dieSize - 1; m > 0; m--) {
|
||||
mmMaxLoop: for (let m = rollConf.dieSize - 1; m > 0; m--) {
|
||||
loopCountCheck(++loopCount);
|
||||
|
||||
if (!rollConf.reroll.nums.includes(m)) {
|
||||
minMaxOverride = m;
|
||||
break mmLoop;
|
||||
break mmMaxLoop;
|
||||
}
|
||||
}
|
||||
} else if (modifiers.minRoll && !minMaxOverride) {
|
||||
// If minimizeRoll is on and we've entered the reroll code, 1 is not allowed, determine the next best option and always return that
|
||||
mmMinLoop: for (let m = 2; m <= rollConf.dieSize; m++) {
|
||||
loopCountCheck(++loopCount);
|
||||
|
||||
if (!rollConf.reroll.nums.includes(m)) {
|
||||
minMaxOverride = m;
|
||||
break mmMinLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (modifiers.maxRoll || modifiers.minRoll) {
|
||||
newReroll.roll = minMaxOverride;
|
||||
} else {
|
||||
// If nominalRoll is on, set the roll to the average roll of dieSize, otherwise generate a new random roll
|
||||
newReroll.roll = genRoll(rollConf.dieSize, maximizeRoll, nominalRoll);
|
||||
newReroll.roll = genRoll(rollConf.dieSize, modifiers);
|
||||
}
|
||||
|
||||
// If critScore arg is on, check if the roll should be a crit, if its off, check if the roll matches the die size
|
||||
|
@ -579,7 +591,7 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
|
|||
// Copy the template to fill out for this iteration
|
||||
const newExplodingRoll = getTemplateRoll();
|
||||
// If maximizeRoll is on, set the roll to the dieSize, else if nominalRoll is on, set the roll to the average roll of dieSize, else generate a new random roll
|
||||
newExplodingRoll.roll = genRoll(rollConf.dieSize, maximizeRoll, nominalRoll);
|
||||
newExplodingRoll.roll = genRoll(rollConf.dieSize, modifiers);
|
||||
// Always mark this roll as exploding
|
||||
newExplodingRoll.exploding = true;
|
||||
|
||||
|
|
Loading…
Reference in New Issue