diff --git a/src/artigen/dice/executeRoll.ts b/src/artigen/dice/executeRoll.ts index aa49291..ab0e1a4 100644 --- a/src/artigen/dice/executeRoll.ts +++ b/src/artigen/dice/executeRoll.ts @@ -92,6 +92,8 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed flagRoll(rollConf, rolling); + loggingEnabled && log(LT.LOG, `${getLoopCount()} Roll done ${JSON.stringify(rolling)}`); + // Push the newly created roll and loop again rollSet.push(rolling); } @@ -138,11 +140,13 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed newReroll.roll = minMaxOverride; } else { // If nominalRoll is on, set the roll to the average roll of dieSize, otherwise generate a new random roll - newReroll.roll = genRoll(rollConf.dieSize, modifiers, rollConf.dPercent); + newReroll.roll = rollConf.type === 'fate' ? genFateRoll(modifiers) : genRoll(rollConf.dieSize, modifiers, rollConf.dPercent); } flagRoll(rollConf, newReroll); + loggingEnabled && log(LT.LOG, `${getLoopCount()} Roll done ${JSON.stringify(newReroll)}`); + // Slot this new roll in after the current iteration so it can be processed in the next loop rollSet.splice(i + 1, 0, newReroll); } else if ( @@ -157,13 +161,15 @@ export const executeRoll = (rollStr: string, modifiers: RollModifiers): Executed // Copy the template to fill out for this iteration const newExplodingRoll = getTemplateRoll(); // If maximizeRoll is on, set the roll to the dieSize, else if nominalRoll is on, set the roll to the average roll of dieSize, else generate a new random roll - newExplodingRoll.roll = genRoll(rollConf.dieSize, modifiers, rollConf.dPercent); + newExplodingRoll.roll = rollConf.type === 'fate' ? genFateRoll(modifiers) : genRoll(rollConf.dieSize, modifiers, rollConf.dPercent); newExplodingRoll.size = rollConf.dieSize; // Always mark this roll as exploding newExplodingRoll.exploding = true; flagRoll(rollConf, newExplodingRoll); + loggingEnabled && log(LT.LOG, `${getLoopCount()} Roll done ${JSON.stringify(newExplodingRoll)}`); + // Slot this new roll in after the current iteration so it can be processed in the next loop rollSet.splice(i + 1, 0, newExplodingRoll); } diff --git a/src/artigen/dice/getRollConf.ts b/src/artigen/dice/getRollConf.ts index ed3a2c1..0bdea52 100644 --- a/src/artigen/dice/getRollConf.ts +++ b/src/artigen/dice/getRollConf.ts @@ -211,7 +211,7 @@ export const getRollConf = (rollStr: string): RollConf => { loggingEnabled && log(LT.LOG, `${getLoopCount()} Handling ${rollConf.type} ${rollStr} | Parsing remains ${remains}`); // Find the next number in the remains to be able to cut out the rule name - let afterSepIdx = remains.search(/\d/); + let afterSepIdx = remains.search(/[-\d]/); if (afterSepIdx < 0) { afterSepIdx = remains.length; } @@ -220,6 +220,7 @@ export const getRollConf = (rollStr: string): RollConf => { const tempSep = remains.slice(0, afterSepIdx); let noNumberAfter = false; NumberlessDiceOptions.some((opt) => { + loopCountCheck(); if (tempSep.startsWith(opt) && tempSep !== opt) { afterSepIdx = opt.length; noNumberAfter = true; @@ -232,13 +233,15 @@ export const getRollConf = (rollStr: string): RollConf => { const tSep = remains.slice(0, afterSepIdx); remains = remains.slice(afterSepIdx); // Find the next non-number in the remains to be able to cut out the count/num - let afterNumIdx = noNumberAfter ? 0 : remains.search(/\D/); + let afterNumIdx = noNumberAfter ? 0 : remains.search(/(?![-\d])/); if (afterNumIdx < 0) { afterNumIdx = remains.length; } // Save the count/num to tNum leaving it in remains for the time being const tNum = parseInt(remains.slice(0, afterNumIdx)); + loggingEnabled && log(LT.LOG, `${getLoopCount()} tSep: ${tSep} ${afterSepIdx}, tNum: ${tNum} ${afterNumIdx}`); + // Switch on rule name switch (tSep) { case DiceOptions.Drop: @@ -303,7 +306,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.RerollLt: // Configure reroll for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.reroll.on = true; - ltAddToRange(tSep, rollConf.reroll.nums, tNum); + ltAddToRange(tSep, rollConf.reroll.nums, tNum, rollConf.type); break; case DiceOptions.CritSuccess: case DiceOptions.CritSuccessEqu: @@ -319,7 +322,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.CritSuccessLt: // Configure CritScore for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.critScore.on = true; - ltAddToRange(tSep, rollConf.critScore.range, tNum); + ltAddToRange(tSep, rollConf.critScore.range, tNum, rollConf.type); break; case DiceOptions.CritFail: case DiceOptions.CritFailEqu: @@ -335,7 +338,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.CritFailLt: // Configure CritFail for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.critFail.on = true; - ltAddToRange(tSep, rollConf.critFail.range, tNum); + ltAddToRange(tSep, rollConf.critFail.range, tNum, rollConf.type); break; case DiceOptions.Exploding: case DiceOptions.ExplodeOnce: @@ -370,7 +373,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.CompoundingExplosionLt: // Configure Exploding for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.exploding.on = true; - ltAddToRange(tSep, rollConf.exploding.nums, tNum); + ltAddToRange(tSep, rollConf.exploding.nums, tNum, rollConf.type); break; case DiceOptions.MatchingTotal: rollConf.match.returnTotal = true; @@ -416,7 +419,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.SuccessLt: // Configure success for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.success.on = true; - ltAddToRange(tSep, rollConf.success.range, tNum); + ltAddToRange(tSep, rollConf.success.range, tNum, rollConf.type); break; case DiceOptions.Fail: case DiceOptions.FailEqu: @@ -432,7 +435,7 @@ export const getRollConf = (rollStr: string): RollConf => { case DiceOptions.FailLt: // Configure fail for all numbers less than or equal to tNum (this could happen multiple times, but why) rollConf.fail.on = true; - ltAddToRange(tSep, rollConf.fail.range, tNum); + ltAddToRange(tSep, rollConf.fail.range, tNum, rollConf.type); break; default: // Throw error immediately if unknown op is encountered diff --git a/src/artigen/math/mathTokenizer.ts b/src/artigen/math/mathTokenizer.ts index 46d1542..7c53e7c 100644 --- a/src/artigen/math/mathTokenizer.ts +++ b/src/artigen/math/mathTokenizer.ts @@ -31,7 +31,8 @@ export const tokenizeMath = (cmd: string, modifiers: RollModifiers, previousResu .replace(cmdSplitRegex, '') .replace(internalWrapRegex, '') .replace(/ /g, '') - .split(/(\*\*)|([-+()*/^]|(?])- for breaking on - correctly with fate dice) (x\d+(\.\d*)?) x# for variables + .split(/(\*\*)|([+()*/^]|(?])-)|(x\d+(\.\d*)?)/g) .filter((x) => x); loggingEnabled && log(LT.LOG, `Split roll into mathConf ${JSON.stringify(mathConf)}`); diff --git a/src/artigen/utils/rangeAdder.ts b/src/artigen/utils/rangeAdder.ts index ed5ac59..3d3b090 100644 --- a/src/artigen/utils/rangeAdder.ts +++ b/src/artigen/utils/rangeAdder.ts @@ -1,5 +1,7 @@ import { log, LogTypes as LT } from '@Log4Deno'; +import { RollType } from 'artigen/dice/dice.d.ts'; + import { getLoopCount, loopCountCheck } from 'artigen/managers/loopManager.ts'; import { loggingEnabled } from 'artigen/utils/logFlag.ts'; @@ -18,7 +20,7 @@ const internalAddMultipleToRange = (tSep: string, range: Array, start: n }; // Add numbers less than or equal to tNum to range -export const ltAddToRange = (tSep: string, range: Array, tNum: number) => internalAddMultipleToRange(tSep, range, 0, tNum); +export const ltAddToRange = (tSep: string, range: Array, tNum: number, rollType: RollType) => internalAddMultipleToRange(tSep, range, rollType === 'fate' ? -1 : 0, tNum); // Add numbers greater than or equal to tNum to range export const gtrAddToRange = (tSep: string, range: Array, tNum: number, dieSize: number) => internalAddMultipleToRange(tSep, range, tNum, dieSize);