UNPKG

@randsum/daggerheart

Version:

A flexible, type-safe dice roller for building Daggerheart-compatible applications

106 lines (98 loc) 2.14 kB
import { type NumericRollOptions, roll } from '@randsum/dice' import type { AdvantageDisadvantageDH, RollArgumentDH, RollResultDH, RollResultDHType } from './types' function rollArg({ modifier = 0, amplifyHope = false, amplifyFear = false }: RollArgumentDH): NumericRollOptions[] { if (amplifyHope && amplifyFear) { return [{ quantity: 2, sides: 20, modifiers: { plus: modifier } }] } if (amplifyHope) { return [{ quantity: 1, sides: 20, modifiers: { plus: modifier } }, { quantity: 1, sides: 12, modifiers: { plus: modifier } }] } if (amplifyFear) { return [{ quantity: 1, sides: 12, modifiers: { plus: modifier } }, { quantity: 1, sides: 12, modifiers: { plus: modifier } }] } return [{ quantity: 2, sides: 12, modifiers: { plus: modifier } }] } export function rollDH({ modifier = 0, rollingWith, amplifyHope = false, amplifyFear = false }: RollArgumentDH): RollResultDH { const { result: [hope, fear], total } = roll(...rollArg({ modifier, amplifyHope, amplifyFear })) if (hope === undefined || fear === undefined) { throw new Error('Failed to roll hope and fear') } const [totalWithAdvantage, advantage] = calculateTotal(total, rollingWith) return { type: calculateType(hope, fear), total: totalWithAdvantage, rolls: { hope, advantage, fear, modifier } } } function calculateType(hope: number, fear: number): RollResultDHType { if (hope === fear) { return 'critical hope' } if (hope > fear) { return 'hope' } return 'fear' } function calculateTotal( total: number, rollingWith: AdvantageDisadvantageDH | undefined ): [number, number | undefined] { if (rollingWith) { const advantage = advantageDie() if (rollingWith === 'Advantage') { return [total + advantage, advantage] } return [total - advantage, -advantage] } return [total, undefined] } function advantageDie(): number { return roll({ quantity: 1, sides: 6 }).total }