Add infinite ranges & macro options

This commit is contained in:
dakedres 2023-05-20 15:27:32 -06:00
parent 18853be664
commit 3aa24443d4
2 changed files with 78 additions and 15 deletions

View File

@ -1,6 +1,7 @@
const constants = { const constants = {
rollRegex: /^(\d+)?([dhl])(\d+)(\s*([+\-*x\/])\s*(\d+))?/, rollRegex: /^(\d+)?([dhl])(\d+)(\s*([+\-*x\/])\s*(\d+))?/,
descriptionRegex: /\s*(\d+(-\d+)?)?([^;\n]+)/g, optionRollRegex: /^(\d+)?(([dhl])(\d+))?(\s*[+\-*x\/]\s*\d+)?/,
descriptionRegex: /\s*(\d+(-(\d+)?)?)?([^;\n]+)/g,
macroNameRegex: /^[a-z0-9]+$/, macroNameRegex: /^[a-z0-9]+$/,
commands: { commands: {

View File

@ -8,9 +8,37 @@ dotenv.config()
const replies = new Map() const replies = new Map()
const commands = new Map() const commands = new Map()
const db = new ClassicLevel('./db') const db = new ClassicLevel('./db')
const parseRollInt = (value, defaultValue) =>
value ? parseInt(value) : defaultValue
const parseRoll = content => { const parseOptionRoll = expression => {
let match = constants.rollRegex.exec(content.trim()) let match = constants.optionRollRegex.exec(expression.trim())
let [
count,
modeSize,
mode,
size,
operationModifier,
operation,
modifier
] = match
.slice(1)
.map(v => v == undefined ? null : v) // Allow us to merge it easier
return {
count: parseRollInt(count),
mode,
size: parseRollInt(size),
operation,
modifier: parseRollInt(modifier),
descriptionConditions: pullDescription(expression, match)
}
}
const parseRoll = expression => {
let match = constants.rollRegex.exec(expression.trim())
if(match == null) if(match == null)
return return
@ -24,18 +52,22 @@ const parseRoll = content => {
modifier modifier
] = match.slice(1) ] = match.slice(1)
let description = content.slice(match[0].length)
return { return {
count: count ? parseInt(count) : 1, count: parseRollInt(count, 1),
mode, mode,
size: parseInt(size), size: parseRollInt(size),
operation, operation,
modifier: modifier ? parseInt(modifier) : undefined, modifier: parseRollInt(modifier),
descriptionConditions: description && parseDescription(description) descriptionConditions: pullDescription(expression, match)
} }
} }
const pullDescription = (expression, match) => {
let description = expression.slice(match[0].length)
return description && parseDescription(description)
}
const parseDescription = description => { const parseDescription = description => {
let conditions = [], let conditions = [],
match match
@ -47,14 +79,25 @@ const parseDescription = description => {
let [ let [
range, range,
upperRangeExpression,
upperRange, upperRange,
content content
] = match.slice(1) ] = match.slice(1)
let lower = range[0],
upper
if(!upperRange) {
// Allow "X-" ranges to represent anything higher than X
upper = upperRangeExpression ? Infinity : lower
} else {
upper = upperRange[0]
}
conditions.push({ conditions.push({
range: range && { range: range && {
lower: range[0], lower,
upper: upperRange ? upperRange[1] : range[0] upper
}, },
content: content.trim() content: content.trim()
}) })
@ -69,10 +112,10 @@ const handleMessage = (message, respond) => {
if(dice == undefined) if(dice == undefined)
return // No dice return // No dice
handleDice(dice, respond) rollDice(dice, respond)
} }
const handleDice = (dice, respond) => { const rollDice = (dice, respond) => {
if(dice.size > 255) { if(dice.size > 255) {
respond('That die is way too big... .-.') respond('That die is way too big... .-.')
return return
@ -203,7 +246,14 @@ const registerMacroCommands = async guildId => {
for await (let [ name, dice ] of macros.iterator() ) for await (let [ name, dice ] of macros.iterator() )
commands.push({ commands.push({
name, name,
description: elipsify("Roll " + dice.replaceAll('\n', ';'), 100) description: elipsify("Roll " + dice.replaceAll('\n', ';'), 100),
options: [
{
name: "options",
description: "Dice, modifiers, or descriptions to apply over the macro",
type: 3
}
]
}) })
await rest.put( await rest.put(
@ -358,8 +408,20 @@ client.on('interactionCreate', async interaction => {
if(roll) { if(roll) {
let dice = parseRoll(roll) let dice = parseRoll(roll)
let optionsRoll = interaction.options.get('options').value
if(optionsRoll) {
let optionDice = parseOptionRoll(optionsRoll)
handleDice(dice, content => interaction.reply(content) ) for(let [ key, value ] of Object.entries(optionDice)) {
if(value)
dice[key] = value
}
console.log(dice)
}
rollDice(dice, content => interaction.reply(content) )
} }
}) })