#Dice parsing shenanigans
1 messages · Page 1 of 1 (latest)
Here's a very messy half-working solution overriding Roll.parse. It may be a good starting point, or alternatively you can throw it out 😆 See what you think of the regex
const functionTermRegex = Object.getOwnPropertyNames(this.MATH_PROXY).join("|");
const regex = new RegExp(`(?:((?:${functionTermRegex})\\([a-zA-Z0-9.,@\\s(\\)[\\]]*\\))d\\d+)`, "g");
const regex = new RegExp(`${functionTermRegex}\\(`, "g");
const matches = formula.matchAll(regex);
for (const match of matches) {
const start = match.index;
const end = end + match[0].length;
const lastBracketIdx = getLastBracketIdx(formula, end);
const substring = formula.substring(start, lastBracketIdx);
formula = formula.replace(substring, `(${substring})`);
}
const getLastBracketIdx = (formula, firstBracketIdx) => {
if (formula.length === 0) return null;
let bracketCount = 1;
let lastBracketIdx = 0;
for (let i = 0; i <= formula.length; i++) {
if (formula[i] === "(") {
bracketCount++;
}
else if (formula[i] === ")") {
bracketCount--;
if (bracketCount === 0) lastBracketIdx = i;
}
}
return lastBracketIdx;
};
@tulip granite idk if this pinged
Will take a look in a few, just finishing a DND session.
Ahh so you are thinking to try and put in a last minute check all formula thing before they get rolled?
Where in the code were you putting that?
That's in an override to Roll.parse. We call super at the end so it happens before the standard parsing
Gotcha it took me a bit to get my system set up to do development again so I didn't make any progress. I will keep finding time to look though!
Haha I was so close. I need to get a large sampling of formulas
(\w*([a-zA-Z0-9.,@\s()/[]]))d(\d+\D?|(?\w|()
(\w*([a-zA-Z0-9.,@\s()/[]]))d(\d+\D?|(?\w|()
bah, it is removing the slashes lol
i keep editing it lol it's so close
I've been concocting more and more elaborate scenarios that I can't handle with regex. What ones do you think actually exist lol?
this handles a LOT of scenarios
const regex = new RegExp(\\b\\w+\\(([^()]|\\([^()]*\\))*\\)d(\\d|\\(), "g");
// Find all matches
const matches = [...formula.matchAll(regex)];
// Iterate over the matches and wrap them in parentheses
let wrappedFormula = formula;
// Go in reverse to prevent the positions from changing
matches.reverse().forEach(match => {
const originalMatch = match[0];
const startPos = match.index;
const dPos = originalMatch.lastIndexOf('d'); // Find the position of 'd'
const wrappedMatch = `(${originalMatch.slice(0, dPos)})${originalMatch.slice(dPos)}`;
// Replace the match in the formula using the calculated positions
wrappedFormula = wrappedFormula.slice(0, startPos) + wrappedMatch + wrappedFormula.slice(startPos + originalMatch.length);
});
@hallow cape I was testing with a console log for the before/after and it seems like the system is already recursively walking through the inner functions so I think this works? All the roll types I was trying it worked for.
if you can test and see any not work please let me know.
Sorry I'll check it out today or tomorrow, thanks for your help
Ok so I did some tests and it looks good! I'll continue to test more and see if anything comes up; Here's the code I'm using rn for reference
static parse(formula, data) {
if ( !formula ) return [];
try {
return super.parse(formula, data);
} catch {
console.debug(`Starfinder | Parsing formula ${formula}, deferring to custom system parsing.`);
const regex = new RegExp(`\\b\\w+\\(([^()]|\\([^()]*\\))*\\)d(\\d|\\()`, "g");
// Find all matches
const matches = [...formula.matchAll(regex)];
// Iterate over the matches and wrap them in parentheses
let wrappedFormula = formula;
// Go in reverse to prevent the positions from changing
matches.reverse().forEach(match => {
const originalMatch = match[0];
const startPos = match.index;
const dPos = originalMatch.lastIndexOf('d'); // Find the position of 'd'
const wrappedMatch = `(${originalMatch.slice(0, dPos)})${originalMatch.slice(dPos)}`;
// Replace the match in the formula using the calculated positions
wrappedFormula = wrappedFormula.slice(0, startPos) + wrappedMatch + wrappedFormula.slice(startPos + originalMatch.length);
});
return super.parse(wrappedFormula, data);
}
}
The try-catch is so we only use our parsing when necessary, just in case it has any unexpected side effects
You might want to put the original error in the console log in case we need it.