@dicelette/core 1.28.2 → 1.28.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/dist/index.d.mts +15 -6
- package/dist/index.d.ts +15 -6
- package/dist/index.js +96 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -93
- package/dist/index.mjs.map +1 -1
- package/package.json +61 -57
package/dist/index.mjs
CHANGED
|
@@ -166,6 +166,7 @@ var templateSchema = z.object({
|
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
// src/regex.ts
|
|
169
|
+
var REGEX_CACHE_MAX = 500;
|
|
169
170
|
var regexCache = /* @__PURE__ */ new Map();
|
|
170
171
|
var NORMALIZE_SINGLE_DICE = (str) => str.replace(/\b1d(\d+)/gi, "d$1");
|
|
171
172
|
var REMOVER_PATTERN = {
|
|
@@ -180,6 +181,10 @@ function getCachedRegex(pattern, flags = "") {
|
|
|
180
181
|
const key = `${pattern}|${flags}`;
|
|
181
182
|
let regex = regexCache.get(key);
|
|
182
183
|
if (!regex) {
|
|
184
|
+
if (regexCache.size >= REGEX_CACHE_MAX) {
|
|
185
|
+
const oldest = regexCache.keys().next().value;
|
|
186
|
+
if (oldest !== void 0) regexCache.delete(oldest);
|
|
187
|
+
}
|
|
183
188
|
regex = new RegExp(pattern, flags);
|
|
184
189
|
regexCache.set(key, regex);
|
|
185
190
|
}
|
|
@@ -212,10 +217,6 @@ import { evaluate as evaluate10 } from "mathjs";
|
|
|
212
217
|
import { DiceRoller as DiceRoller2, NumberGenerator as NumberGenerator7 } from "@dice-roller/rpg-dice-roller";
|
|
213
218
|
import { evaluate as evaluate8 } from "mathjs";
|
|
214
219
|
|
|
215
|
-
// src/dice/compare.ts
|
|
216
|
-
import { NumberGenerator as NumberGenerator4 } from "@dice-roller/rpg-dice-roller";
|
|
217
|
-
import { evaluate as evaluate2 } from "mathjs";
|
|
218
|
-
|
|
219
220
|
// src/utils.ts
|
|
220
221
|
import "uniformize";
|
|
221
222
|
import { NumberGenerator as NumberGenerator3 } from "@dice-roller/rpg-dice-roller";
|
|
@@ -229,12 +230,12 @@ import { NumberGenerator as NumberGenerator2 } from "@dice-roller/rpg-dice-rolle
|
|
|
229
230
|
function evalStatsDice(testDice, allStats, engine = NumberGenerator2.engines.nodeCrypto, pity) {
|
|
230
231
|
let dice = testDice.trimEnd();
|
|
231
232
|
if (allStats && Object.keys(allStats).length > 0) {
|
|
233
|
+
dice = dice.standardize();
|
|
232
234
|
const names = Object.keys(allStats);
|
|
233
235
|
for (const name of names) {
|
|
234
|
-
const regex =
|
|
235
|
-
if (dice.
|
|
236
|
-
|
|
237
|
-
dice = dice.standardize().replace(regex, statValue.toString()).trimEnd();
|
|
236
|
+
const regex = getCachedRegex(name.standardize().escapeRegex(), "gi");
|
|
237
|
+
if (dice.match(regex)) {
|
|
238
|
+
dice = dice.replace(regex, allStats[name].toString()).trimEnd();
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
}
|
|
@@ -252,8 +253,8 @@ function diceRandomParse(value, template, engine = NumberGenerator2.engines.node
|
|
|
252
253
|
const statNames = Object.keys(template.statistics);
|
|
253
254
|
let newDice = value;
|
|
254
255
|
for (const name of statNames) {
|
|
255
|
-
const regex =
|
|
256
|
-
if (
|
|
256
|
+
const regex = getCachedRegex(name.standardize().escapeRegex(), "gi");
|
|
257
|
+
if (newDice.match(regex)) {
|
|
257
258
|
let max;
|
|
258
259
|
let min;
|
|
259
260
|
const foundStat = template.statistics?.[name];
|
|
@@ -263,7 +264,7 @@ function diceRandomParse(value, template, engine = NumberGenerator2.engines.node
|
|
|
263
264
|
}
|
|
264
265
|
const total = template.total || 100;
|
|
265
266
|
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
266
|
-
newDice =
|
|
267
|
+
newDice = newDice.replace(regex, randomStatValue.toString());
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
return replaceFormulaInDice(newDice);
|
|
@@ -286,7 +287,7 @@ function evalCombinaison(combinaison, stats) {
|
|
|
286
287
|
for (const [stat, combin] of Object.entries(combinaison)) {
|
|
287
288
|
let formula = combin.standardize();
|
|
288
289
|
for (const [statName, value] of Object.entries(stats)) {
|
|
289
|
-
const regex =
|
|
290
|
+
const regex = getCachedRegex(statName.standardize().escapeRegex(), "gi");
|
|
290
291
|
formula = formula.replace(regex, value.toString());
|
|
291
292
|
}
|
|
292
293
|
try {
|
|
@@ -300,7 +301,7 @@ function evalCombinaison(combinaison, stats) {
|
|
|
300
301
|
function evalOneCombinaison(combinaison, stats) {
|
|
301
302
|
let formula = combinaison.standardize();
|
|
302
303
|
for (const [statName, value] of Object.entries(stats)) {
|
|
303
|
-
const regex =
|
|
304
|
+
const regex = getCachedRegex(statName.standardize().escapeRegex(), "gi");
|
|
304
305
|
formula = formula.replace(regex, value.toString());
|
|
305
306
|
}
|
|
306
307
|
try {
|
|
@@ -348,7 +349,7 @@ function verifyTemplateValue(template, verify = true, engine = NumberGenerator2.
|
|
|
348
349
|
engine
|
|
349
350
|
);
|
|
350
351
|
const rolled = roll(cleanedDice2, engine);
|
|
351
|
-
if (!rolled) throw new DiceTypeError(cleanedDice2, "
|
|
352
|
+
if (!rolled) throw new DiceTypeError(cleanedDice2, "roll");
|
|
352
353
|
}
|
|
353
354
|
if (statistiqueTemplate.customCritical) {
|
|
354
355
|
if (!statistiqueTemplate.diceType) {
|
|
@@ -373,15 +374,16 @@ function verifyTemplateValue(template, verify = true, engine = NumberGenerator2.
|
|
|
373
374
|
}
|
|
374
375
|
function testDiceRegistered(template, engine = NumberGenerator2.engines.nodeCrypto) {
|
|
375
376
|
if (!template.damage) return;
|
|
376
|
-
|
|
377
|
-
if (
|
|
378
|
-
|
|
377
|
+
const damageEntries = Object.entries(template.damage);
|
|
378
|
+
if (damageEntries.length === 0) throw new EmptyObjectError();
|
|
379
|
+
if (damageEntries.length > 25) throw new TooManyDice();
|
|
380
|
+
for (const [name, dice] of damageEntries) {
|
|
379
381
|
if (!dice) continue;
|
|
380
382
|
const diceReplaced = replaceExpByRandom(dice);
|
|
381
383
|
const randomDiceParsed = diceRandomParse(diceReplaced, template, engine);
|
|
382
384
|
try {
|
|
383
385
|
const rolled = roll(randomDiceParsed, engine);
|
|
384
|
-
if (!rolled) throw new DiceTypeError(name, "
|
|
386
|
+
if (!rolled) throw new DiceTypeError(name, "testDiceRegistered", dice);
|
|
385
387
|
} catch (error) {
|
|
386
388
|
throw new DiceTypeError(name, "testDiceRegistered", error);
|
|
387
389
|
}
|
|
@@ -389,19 +391,14 @@ function testDiceRegistered(template, engine = NumberGenerator2.engines.nodeCryp
|
|
|
389
391
|
}
|
|
390
392
|
function testStatCombinaison(template, engine = NumberGenerator2.engines.nodeCrypto) {
|
|
391
393
|
if (!template.statistics) return;
|
|
392
|
-
const onlycombinaisonStats =
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
Object.entries(template.statistics).filter(([_, value]) => !value.combinaison)
|
|
399
|
-
);
|
|
394
|
+
const onlycombinaisonStats = {};
|
|
395
|
+
const allOtherStats = {};
|
|
396
|
+
for (const [k, v] of Object.entries(template.statistics)) {
|
|
397
|
+
if (v.combinaison !== void 0) onlycombinaisonStats[k] = v;
|
|
398
|
+
else allOtherStats[k] = v;
|
|
399
|
+
}
|
|
400
400
|
if (Object.keys(onlycombinaisonStats).length === 0) return;
|
|
401
|
-
|
|
402
|
-
(stat) => !template.statistics[stat].combinaison
|
|
403
|
-
);
|
|
404
|
-
if (allStats.length === 0) throw new NoStatisticsError();
|
|
401
|
+
if (Object.keys(allOtherStats).length === 0) throw new NoStatisticsError();
|
|
405
402
|
const error = [];
|
|
406
403
|
for (const [stat, value] of Object.entries(onlycombinaisonStats)) {
|
|
407
404
|
let formula = value.combinaison;
|
|
@@ -409,7 +406,7 @@ function testStatCombinaison(template, engine = NumberGenerator2.engines.nodeCry
|
|
|
409
406
|
const { max, min } = data;
|
|
410
407
|
const total = template.total || 100;
|
|
411
408
|
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
412
|
-
const regex =
|
|
409
|
+
const regex = getCachedRegex(other.escapeRegex(), "gi");
|
|
413
410
|
formula = formula.replace(regex, randomStatValue.toString());
|
|
414
411
|
}
|
|
415
412
|
try {
|
|
@@ -422,20 +419,20 @@ function testStatCombinaison(template, engine = NumberGenerator2.engines.nodeCry
|
|
|
422
419
|
return;
|
|
423
420
|
}
|
|
424
421
|
function generateRandomStat(total = 100, max, min, engine = NumberGenerator2.engines.nodeCrypto) {
|
|
425
|
-
|
|
422
|
+
if (total <= 1) throw new RangeError(`total must be greater than 1, got ${total}`);
|
|
426
423
|
const random = new Random(engine || NumberGenerator2.engines.nodeCrypto);
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
else randomStatValue = randomInt(1, total, engine, random);
|
|
432
|
-
}
|
|
433
|
-
return randomStatValue;
|
|
424
|
+
const effectiveMin = Math.max(min ?? 1, 1);
|
|
425
|
+
const effectiveMax = Math.min(max ?? total - 1, total - 1);
|
|
426
|
+
if (effectiveMin > effectiveMax) throw new MaxGreater(effectiveMin, effectiveMax);
|
|
427
|
+
return randomInt(effectiveMin, effectiveMax, engine, random);
|
|
434
428
|
}
|
|
435
429
|
|
|
436
430
|
// src/utils.ts
|
|
437
|
-
function
|
|
438
|
-
|
|
431
|
+
function splitDiceComment(dice) {
|
|
432
|
+
const match = /\s(#|\/{2}|\[|\/\*)(?<comment>.*)/i.exec(dice);
|
|
433
|
+
if (!match?.groups) return { dice: dice.trimEnd(), comment: void 0 };
|
|
434
|
+
const comment = match.groups.comment.trim() || void 0;
|
|
435
|
+
return { dice: dice.slice(0, match.index).trimEnd(), comment };
|
|
439
436
|
}
|
|
440
437
|
function standardizeDice(dice) {
|
|
441
438
|
return dice.replace(
|
|
@@ -470,6 +467,8 @@ function createCriticalCustom(dice, customCritical, template, engine = NumberGen
|
|
|
470
467
|
}
|
|
471
468
|
|
|
472
469
|
// src/dice/compare.ts
|
|
470
|
+
import { NumberGenerator as NumberGenerator4 } from "@dice-roller/rpg-dice-roller";
|
|
471
|
+
import { evaluate as evaluate2 } from "mathjs";
|
|
473
472
|
function isTrivialComparison(maxValue, minValue, compare) {
|
|
474
473
|
const canSucceed = canComparisonSucceed(maxValue, compare, minValue);
|
|
475
474
|
const canFail = canComparisonFail(maxValue, compare, minValue);
|
|
@@ -579,32 +578,31 @@ import { NumberGenerator as NumberGenerator5 } from "@dice-roller/rpg-dice-rolle
|
|
|
579
578
|
import { evaluate as evaluate3 } from "mathjs";
|
|
580
579
|
|
|
581
580
|
// src/dice/replace.ts
|
|
581
|
+
var PARENTHESIS_REGEX = /d\((\d+)\)/g;
|
|
582
|
+
var BRACKET_COMMENT_REGEX = /\[(?<comments>.*?)\]/;
|
|
583
|
+
var OPTIONAL_COMMENT_REGEX = /\s+(#|\/\/)(?<comment>.*)/;
|
|
582
584
|
function replaceUnwantedText(dice, sortOrder) {
|
|
583
|
-
|
|
584
|
-
if (sortOrder)
|
|
585
|
+
let d = dice.replaceAll(/[{}]/g, "").replaceAll(/s[ad]/gi, "");
|
|
586
|
+
if (sortOrder) d = sortDice(d, sortOrder);
|
|
587
|
+
if (!d.length) throw new DiceTypeError(dice, "empty_dice");
|
|
585
588
|
return d;
|
|
586
589
|
}
|
|
587
590
|
function sortDice(dice, sortOrder) {
|
|
588
591
|
if (sortOrder === "none" /* None */) return dice;
|
|
589
592
|
const dices = dice.split(/; ?/);
|
|
593
|
+
const decorated = dices.map((d) => ({
|
|
594
|
+
d,
|
|
595
|
+
v: Number.parseInt(d.split("= ")[1], 10) || 0
|
|
596
|
+
}));
|
|
590
597
|
if (sortOrder === "sa" /* Ascending */) {
|
|
591
|
-
|
|
592
|
-
const totalA = Number.parseInt(a.split("= ")[1], 10) || 0;
|
|
593
|
-
const totalB = Number.parseInt(b.split("= ")[1], 10) || 0;
|
|
594
|
-
return totalB - totalA;
|
|
595
|
-
});
|
|
598
|
+
decorated.sort((a, b) => b.v - a.v);
|
|
596
599
|
} else if (sortOrder === "sd" /* Descending */) {
|
|
597
|
-
|
|
598
|
-
const totalA = Number.parseInt(a.split("= ")[1], 10) || 0;
|
|
599
|
-
const totalB = Number.parseInt(b.split("= ")[1], 10) || 0;
|
|
600
|
-
return totalA - totalB;
|
|
601
|
-
});
|
|
600
|
+
decorated.sort((a, b) => a.v - b.v);
|
|
602
601
|
}
|
|
603
|
-
return
|
|
602
|
+
return decorated.map((x) => x.d).join("; ");
|
|
604
603
|
}
|
|
605
604
|
function fixParenthesis(dice) {
|
|
606
|
-
|
|
607
|
-
return dice.replaceAll(parenthesisRegex, (_match, p1) => `d${p1}`);
|
|
605
|
+
return dice.replaceAll(PARENTHESIS_REGEX, (_match, p1) => `d${p1}`);
|
|
608
606
|
}
|
|
609
607
|
function replaceText(element, total, dice) {
|
|
610
608
|
return {
|
|
@@ -613,12 +611,10 @@ function replaceText(element, total, dice) {
|
|
|
613
611
|
};
|
|
614
612
|
}
|
|
615
613
|
function formatComment(dice) {
|
|
616
|
-
const
|
|
617
|
-
const commentsMatch = commentsRegex.exec(dice);
|
|
614
|
+
const commentsMatch = BRACKET_COMMENT_REGEX.exec(dice);
|
|
618
615
|
const comments = commentsMatch?.groups?.comments ? `${commentsMatch.groups.comments}` : "";
|
|
619
|
-
const diceWithoutBrackets = dice.replace(
|
|
620
|
-
const
|
|
621
|
-
const optionalComments = optionalCommentsRegex.exec(diceWithoutBrackets);
|
|
616
|
+
const diceWithoutBrackets = dice.replace(BRACKET_COMMENT_REGEX, "");
|
|
617
|
+
const optionalComments = OPTIONAL_COMMENT_REGEX.exec(diceWithoutBrackets);
|
|
622
618
|
const optional = optionalComments?.groups?.comment ? `${optionalComments.groups.comment.trim()}` : "";
|
|
623
619
|
let finalComment = "";
|
|
624
620
|
if (comments && optional) finalComment = `__${comments} ${optional}__ \u2014 `;
|
|
@@ -770,23 +766,27 @@ function calculateSimilarity(str1, str2) {
|
|
|
770
766
|
return (longer.length - distance) / longer.length;
|
|
771
767
|
}
|
|
772
768
|
function levenshteinDistance(str1, str2) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
769
|
+
if (str1.length > str2.length) {
|
|
770
|
+
[str1, str2] = [str2, str1];
|
|
771
|
+
}
|
|
772
|
+
let prev = Array.from({ length: str1.length + 1 }, (_, i) => i);
|
|
773
|
+
let curr = new Array(str1.length + 1);
|
|
776
774
|
for (let j = 1; j <= str2.length; j++) {
|
|
775
|
+
curr[0] = j;
|
|
777
776
|
for (let i = 1; i <= str1.length; i++) {
|
|
778
777
|
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
779
|
-
|
|
780
|
-
|
|
778
|
+
curr[i] = Math.min(
|
|
779
|
+
curr[i - 1] + 1,
|
|
781
780
|
// insertion
|
|
782
|
-
|
|
781
|
+
prev[i] + 1,
|
|
783
782
|
// deletion
|
|
784
|
-
|
|
783
|
+
prev[i - 1] + cost
|
|
785
784
|
// substitution
|
|
786
785
|
);
|
|
787
786
|
}
|
|
787
|
+
[prev, curr] = [curr, prev];
|
|
788
788
|
}
|
|
789
|
-
return
|
|
789
|
+
return prev[str1.length];
|
|
790
790
|
}
|
|
791
791
|
function findBestStatMatch(searchTerm, normalizedStats, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
792
792
|
const exact = normalizedStats.get(searchTerm);
|
|
@@ -1060,28 +1060,23 @@ function setSortOrder(toRoll, sort) {
|
|
|
1060
1060
|
}
|
|
1061
1061
|
function prepareDice(diceInput) {
|
|
1062
1062
|
let dice = standardizeDice(replaceFormulaInDice(diceInput)).replace(/^\+/, "").replaceAll("=>", ">=").replaceAll("=<", "<=").trimStart();
|
|
1063
|
-
dice = dice.replaceAll(
|
|
1063
|
+
dice = dice.replaceAll(REMOVER_PATTERN.CRITICAL_BLOCK, "").trimEnd();
|
|
1064
1064
|
const explodingSuccess = normalizeExplodingSuccess(dice);
|
|
1065
1065
|
if (explodingSuccess) dice = explodingSuccess.dice;
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
diceDisplay = explodingSuccess?.originalDice ?? mainDice;
|
|
1070
|
-
} else {
|
|
1071
|
-
diceDisplay = explodingSuccess?.originalDice ?? dice;
|
|
1072
|
-
}
|
|
1066
|
+
const sharedSeparatorIndex = dice.indexOf(";");
|
|
1067
|
+
const hasSharedSeparator = sharedSeparatorIndex !== -1;
|
|
1068
|
+
let diceDisplay = explodingSuccess?.originalDice ?? (hasSharedSeparator ? dice.slice(0, sharedSeparatorIndex) : dice);
|
|
1073
1069
|
const curlyBulkMatch = dice.match(/^\{(\d+#.*)\}$/);
|
|
1074
1070
|
const isCurlyBulk = !!curlyBulkMatch;
|
|
1075
1071
|
const bulkContent = isCurlyBulk ? curlyBulkMatch[1] : "";
|
|
1076
|
-
const isSharedRoll = dice.includes(";");
|
|
1077
1072
|
let isSharedCurly = false;
|
|
1078
|
-
if (
|
|
1073
|
+
if (hasSharedSeparator && dice.match(/^\{.*;\s*.*\}$/)) {
|
|
1079
1074
|
dice = dice.slice(1, -1);
|
|
1080
1075
|
isSharedCurly = true;
|
|
1081
1076
|
diceDisplay = diceDisplay.slice(1);
|
|
1082
1077
|
}
|
|
1083
1078
|
let isSimpleCurly = false;
|
|
1084
|
-
if (!isCurlyBulk && !
|
|
1079
|
+
if (!isCurlyBulk && !hasSharedSeparator && dice.match(/^\{.*\}$/)) {
|
|
1085
1080
|
const innerContent = dice.slice(1, -1);
|
|
1086
1081
|
const hasModifiers = innerContent.match(/[+\-*/%^]/);
|
|
1087
1082
|
const hasComparison = innerContent.match(/(([><=!]+\d+f)|([><=]|!=)+\d+)/);
|
|
@@ -1094,7 +1089,7 @@ function prepareDice(diceInput) {
|
|
|
1094
1089
|
dice,
|
|
1095
1090
|
diceDisplay,
|
|
1096
1091
|
explodingSuccess,
|
|
1097
|
-
isSharedRoll,
|
|
1092
|
+
isSharedRoll: hasSharedSeparator,
|
|
1098
1093
|
isSharedCurly,
|
|
1099
1094
|
isCurlyBulk,
|
|
1100
1095
|
bulkContent,
|
|
@@ -1111,10 +1106,15 @@ function getSortOrder(dice) {
|
|
|
1111
1106
|
function handleBulkRolls(dice, isCurlyBulk, bulkContent, compare, explodingSuccess, diceDisplay, engine, sort) {
|
|
1112
1107
|
const bulkProcessContent = isCurlyBulk ? bulkContent : dice;
|
|
1113
1108
|
const diceArray = bulkProcessContent.split("#");
|
|
1109
|
+
if (!isNumber(diceArray[0])) {
|
|
1110
|
+
throw new DiceTypeError(dice, "bulk_number");
|
|
1111
|
+
}
|
|
1114
1112
|
const numberOfDice = Number.parseInt(diceArray[0], 10);
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1113
|
+
if (numberOfDice <= 0) {
|
|
1114
|
+
throw new DiceTypeError(dice, "bulk_zero");
|
|
1115
|
+
}
|
|
1116
|
+
const { dice: diceToRollBase, comment: comments } = splitDiceComment(diceArray[1]);
|
|
1117
|
+
let diceToRoll = diceToRollBase;
|
|
1118
1118
|
let curlyCompare;
|
|
1119
1119
|
if (isCurlyBulk) {
|
|
1120
1120
|
const curlyCompareRegex = diceToRoll.match(SIGN_REGEX_SPACE);
|
|
@@ -1295,11 +1295,12 @@ function handlePitySystem(dice, compare, diceRoll, roller, engine) {
|
|
|
1295
1295
|
isFail = evaluate9(`${res.total}${compare.sign}${compare.value}`);
|
|
1296
1296
|
}
|
|
1297
1297
|
}
|
|
1298
|
+
if (!res?.result.length) throw new DiceTypeError(dice, "empty_dice");
|
|
1298
1299
|
return { rerollCount, result: res };
|
|
1299
1300
|
}
|
|
1300
1301
|
|
|
1301
1302
|
// src/roll.ts
|
|
1302
|
-
function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
1303
|
+
function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort, comment) {
|
|
1303
1304
|
if (sort === "none" /* None */) sort = void 0;
|
|
1304
1305
|
const prepared = prepareDice(dice);
|
|
1305
1306
|
if (!prepared.dice.includes("d")) return void 0;
|
|
@@ -1342,8 +1343,10 @@ function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
|
1342
1343
|
}
|
|
1343
1344
|
const roller = new DiceRoller3();
|
|
1344
1345
|
NumberGenerator8.generator.engine = engine;
|
|
1345
|
-
|
|
1346
|
-
|
|
1346
|
+
const splitResult = splitDiceComment(processedDice);
|
|
1347
|
+
const diceBase = comment !== void 0 ? processedDice.trimEnd() : splitResult.dice;
|
|
1348
|
+
const resolvedComment = comment ?? splitResult.comment;
|
|
1349
|
+
const diceWithoutComment = setSortOrder(diceBase, sort);
|
|
1347
1350
|
let diceRoll;
|
|
1348
1351
|
try {
|
|
1349
1352
|
diceRoll = roller.roll(diceWithoutComment);
|
|
@@ -1359,8 +1362,6 @@ function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
|
1359
1362
|
);
|
|
1360
1363
|
compare.trivial = trivial ? true : void 0;
|
|
1361
1364
|
}
|
|
1362
|
-
const commentMatch = processedDice.match(COMMENT_REGEX);
|
|
1363
|
-
const comment = commentMatch ? commentMatch[2] : void 0;
|
|
1364
1365
|
let rerollCount = 0;
|
|
1365
1366
|
let pityResult;
|
|
1366
1367
|
if (pity && compare) {
|
|
@@ -1377,7 +1378,7 @@ function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
|
1377
1378
|
return {
|
|
1378
1379
|
...pityResult,
|
|
1379
1380
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : processedDice,
|
|
1380
|
-
comment,
|
|
1381
|
+
comment: resolvedComment,
|
|
1381
1382
|
compare,
|
|
1382
1383
|
modifier: modificator,
|
|
1383
1384
|
pityLogs: rerollCount,
|
|
@@ -1396,10 +1397,11 @@ function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
|
1396
1397
|
prepared.explodingSuccess.normalizedSegment,
|
|
1397
1398
|
prepared.explodingSuccess.originalSegment
|
|
1398
1399
|
);
|
|
1400
|
+
if (!resultOutput.length) throw new DiceTypeError(dice, "empty_dice");
|
|
1399
1401
|
return {
|
|
1400
1402
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : prepared.diceDisplay,
|
|
1401
1403
|
result: resultOutput,
|
|
1402
|
-
comment,
|
|
1404
|
+
comment: resolvedComment,
|
|
1403
1405
|
compare: compare ? compare : void 0,
|
|
1404
1406
|
modifier: modificator,
|
|
1405
1407
|
total: successes,
|
|
@@ -1410,7 +1412,7 @@ function roll(dice, engine = NumberGenerator8.engines.nodeCrypto, pity, sort) {
|
|
|
1410
1412
|
return {
|
|
1411
1413
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : processedDice,
|
|
1412
1414
|
result: resultOutput,
|
|
1413
|
-
comment,
|
|
1415
|
+
comment: resolvedComment,
|
|
1414
1416
|
compare: compare ? compare : void 0,
|
|
1415
1417
|
modifier: modificator,
|
|
1416
1418
|
total: roller.total,
|
|
@@ -1605,7 +1607,6 @@ export {
|
|
|
1605
1607
|
createCriticalCustom,
|
|
1606
1608
|
diceRandomParse,
|
|
1607
1609
|
diceTypeRandomParse,
|
|
1608
|
-
escapeRegex,
|
|
1609
1610
|
evalCombinaison,
|
|
1610
1611
|
evalOneCombinaison,
|
|
1611
1612
|
evalStatsDice,
|
|
@@ -1626,6 +1627,7 @@ export {
|
|
|
1626
1627
|
replaceUnknown,
|
|
1627
1628
|
resolveFormulaHint,
|
|
1628
1629
|
roll,
|
|
1630
|
+
splitDiceComment,
|
|
1629
1631
|
standardizeDice,
|
|
1630
1632
|
templateSchema,
|
|
1631
1633
|
testDiceRegistered,
|