UNPKG

@randsum/dice

Version:

A flexible, type-safe dice roller for tabletop RPGs, game development, and probability simulations

86 lines (76 loc) 2.27 kB
import { CapModifier, DropModifier, ExplodeModifier, MinusModifier, PlusModifier, ReplaceModifier, RerollModifier, UniqueModifier, coreNotationPattern, isDiceNotation, optionsConverter } from '@randsum/core' import { D } from '../D' import { isD } from '../guards/isD' import type { RollArgument, RollParams } from '../types' export function normalizeArgument(argument: RollArgument): RollParams { const options = optionsFromArgument(argument) return { argument, options, die: dieForArgument(argument), notation: optionsConverter.toNotation(options), description: optionsConverter.toDescription(options) } as RollParams } function optionsFromArgument(argument: RollArgument): RollParams['options'] { 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: RollArgument): RollParams['die'] { if (isD(argument)) { return argument } const options = optionsFromArgument(argument) if (Array.isArray(options.sides)) { return D(options.sides) } return D(options.sides) }