@randsum/dice
Version:
A flexible, type-safe dice roller for tabletop RPGs, game development, and probability simulations
64 lines (63 loc) • 2.35 kB
JavaScript
import { CapModifier, DropModifier, ExplodeModifier, MinusModifier, PlusModifier, ReplaceModifier, RerollModifier, UniqueModifier, coreNotationPattern, isDiceNotation, optionsConverter } from '@randsum/core';
import { D } from '../D';
import { isD } from '../guards/isD';
export function normalizeArgument(argument) {
const options = optionsFromArgument(argument);
return {
argument,
options,
die: dieForArgument(argument),
notation: optionsConverter.toNotation(options),
description: optionsConverter.toDescription(options)
};
}
function optionsFromArgument(argument) {
if (isD(argument)) {
return argument.toOptions;
}
if (isDiceNotation(argument)) {
const coreNotationMatch = argument.match(coreNotationPattern) ?? '';
const coreMatch = coreNotationMatch[0];
const modifiersString = argument.replace(coreMatch, '');
const [quantity, sides = ''] = coreMatch.split(/[Dd]/);
if (sides.includes('{')) {
return {
quantity: Number(quantity),
sides: [...sides.replaceAll(/{|}/g, '')]
};
}
return {
quantity: Number(quantity),
sides: Number(sides),
...{
modifiers: {
...DropModifier.parse(modifiersString),
...ExplodeModifier.parse(modifiersString),
...UniqueModifier.parse(modifiersString),
...ReplaceModifier.parse(modifiersString),
...RerollModifier.parse(modifiersString),
...CapModifier.parse(modifiersString),
...PlusModifier.parse(modifiersString),
...MinusModifier.parse(modifiersString)
}
}
};
}
if (Array.isArray(argument)) {
return { quantity: 1, sides: argument.map(String) };
}
if (typeof argument === 'string' || typeof argument === 'number') {
return { quantity: 1, sides: Number(argument) };
}
return argument;
}
function dieForArgument(argument) {
if (isD(argument)) {
return argument;
}
const options = optionsFromArgument(argument);
if (Array.isArray(options.sides)) {
return D(options.sides);
}
return D(options.sides);
}