diff --git a/src/artigen/dice/dice.d.ts b/src/artigen/dice/dice.d.ts index ee14276..8647b01 100644 --- a/src/artigen/dice/dice.d.ts +++ b/src/artigen/dice/dice.d.ts @@ -72,6 +72,16 @@ interface RangeConf { range: number[]; } +// Sort interface +interface SortDisabled { + on: false; + direction: ''; +} +interface SortEnabled { + on: true; + direction: 'a' | 'd'; +} + // D% configuration export interface DPercentConf { on: boolean; @@ -108,6 +118,7 @@ export interface RollConf { minCount: number; returnTotal: boolean; }; + sort: SortDisabled | SortEnabled; } export interface SumOverride { diff --git a/src/artigen/dice/diceOptions.ts b/src/artigen/dice/diceOptions.ts index f60cacf..32de61d 100644 --- a/src/artigen/dice/diceOptions.ts +++ b/src/artigen/dice/diceOptions.ts @@ -39,10 +39,16 @@ export const DiceOptions = Object.freeze({ CompoundingExplosionEqu: '!!=', Matching: 'm', MatchingTotal: 'mt', + Sort: 's', + SortAsc: 'sa', + SortDesc: 'sd', }); // Should be ordered such that 'mt' will be encountered before 'm' export const NumberlessDiceOptions = [ + DiceOptions.SortDesc, + DiceOptions.SortAsc, + DiceOptions.Sort, DiceOptions.MatchingTotal, DiceOptions.Matching, DiceOptions.CompoundingExplosion, diff --git a/src/artigen/dice/executeRoll.ts b/src/artigen/dice/executeRoll.ts index a40b3de..9d74dbd 100644 --- a/src/artigen/dice/executeRoll.ts +++ b/src/artigen/dice/executeRoll.ts @@ -5,7 +5,7 @@ import { genFateRoll, genRoll } from 'artigen/dice/randomRoll.ts'; import { getRollConf } from 'artigen/dice/getRollConf.ts'; import { loggingEnabled } from 'artigen/utils/logFlag.ts'; -import { compareOrigIdx, compareRolls } from 'artigen/utils/sortFuncs.ts'; +import { compareOrigIdx, compareRolls, compareRollsReverse } from 'artigen/utils/sortFuncs.ts'; import { getLoopCount, loopCountCheck } from 'artigen/managers/loopManager.ts'; import { generateRollVals } from 'artigen/utils/rollValCounter.ts'; @@ -370,5 +370,9 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): [RollSet } } + if (rollConf.sort.on) { + rollSet.sort(rollConf.sort.direction === 'a' ? compareRolls : compareRollsReverse); + } + return [rollSet, sumOverride]; }; diff --git a/src/artigen/dice/getRollConf.ts b/src/artigen/dice/getRollConf.ts index 58703f3..54fa8ba 100644 --- a/src/artigen/dice/getRollConf.ts +++ b/src/artigen/dice/getRollConf.ts @@ -67,6 +67,10 @@ export const getRollConf = (rollStr: string): RollConf => { minCount: 2, returnTotal: false, }, + sort: { + on: false, + direction: '', + }, }; // If the dPts is not long enough, throw error @@ -404,6 +408,15 @@ export const getRollConf = (rollStr: string): RollConf => { rollConf.match.minCount = tNum; } break; + case DiceOptions.Sort: + case DiceOptions.SortAsc: + rollConf.sort.on = true; + rollConf.sort.direction = 'a'; + break; + case DiceOptions.SortDesc: + rollConf.sort.on = true; + rollConf.sort.direction = 'd'; + break; default: // Throw error immediately if unknown op is encountered throw new Error(`UnknownOperation_${tSep}`); diff --git a/src/artigen/utils/sortFuncs.ts b/src/artigen/utils/sortFuncs.ts index e552ed6..f4e45ea 100644 --- a/src/artigen/utils/sortFuncs.ts +++ b/src/artigen/utils/sortFuncs.ts @@ -2,18 +2,24 @@ import { ReturnData } from 'artigen/artigen.d.ts'; import { RollSet } from 'artigen/dice/dice.d.ts'; -// compareRolls(a, b) returns -1|0|1 -// compareRolls is used to order an array of RollSets by RollSet.roll -export const compareRolls = (a: RollSet, b: RollSet): number => { +const internalCompareRolls = (a: RollSet, b: RollSet, dir: 1 | -1): number => { if (a.roll < b.roll) { - return -1; + return -1 * dir; } if (a.roll > b.roll) { - return 1; + return 1 * dir; } return 0; }; +// compareRolls(a, b) returns -1|0|1 +// compareRolls is used to order an array of RollSets by RollSet.roll +export const compareRolls = (a: RollSet, b: RollSet): number => internalCompareRolls(a, b, 1); + +// compareRolls(a, b) returns -1|0|1 +// compareRolls is used to order an array of RollSets by RollSet.roll reversed +export const compareRollsReverse = (a: RollSet, b: RollSet): number => internalCompareRolls(a, b, -1); + const internalCompareTotalRolls = (a: ReturnData, b: ReturnData, dir: 1 | -1): number => { if (a.rollTotal < b.rollTotal) { return -1 * dir; diff --git a/src/commands/helpLibrary/diceOptions.ts b/src/commands/helpLibrary/diceOptions.ts index adf3bda..0b030ca 100644 --- a/src/commands/helpLibrary/diceOptions.ts +++ b/src/commands/helpLibrary/diceOptions.ts @@ -2,7 +2,7 @@ import config from '~config'; import { HelpContents, HelpPage } from 'commands/helpLibrary/helpLibrary.d.ts'; -const name = 'Roll20 Dice Options'; +const name = 'Dice Options'; const description = `\`${config.prefix}xdydzracsq!${config.postfix}\` Rolls all configs requested, you may repeat the command multiple times in the same message (just ensure you close each roll with \`${config.postfix}\`).`; const dict = new Map([ @@ -246,6 +246,20 @@ The basic \`m\` option will only add labels without modifying the results, where ], }, ], + [ + 'sorting-dice', + { + name: 'Sorting Dice', + description: `**Usage:** \`xdys\`, \`xdysa\`, or \`xdysd\` +\`s\` and \`sa\` will sort the dice in ascending order within the roll +\`sd\` will sort the dice in descending order within the roll`, + example: [ + '`[[10d6s]]` => [__1__ + __1__ + 2 + 2 + 3 + 3 + 3 + 5 + **6** + **6**] = **__32__**', + '`[[10d6sa]]` => [__1__ + __1__ + 2 + 2 + 3 + 3 + 3 + 5 + **6** + **6**] = **__32__**', + '`[[10d6sd]]` => [**6** + **6** + **6** + 5 + 4 + 4 + 2 + __1__ + __1__ + __1__] = **__36__**', + ], + }, + ], ]); export const DiceOptionsHelpPages: HelpPage = {