@dicelette/core 1.28.1 → 1.28.3
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/dist/index.d.mts +40 -16
- package/dist/index.d.ts +40 -16
- package/dist/index.js +520 -442
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +513 -437
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -60,7 +60,9 @@ __export(index_exports, {
|
|
|
60
60
|
replaceFormulaInDice: () => replaceFormulaInDice,
|
|
61
61
|
replaceInFormula: () => replaceInFormula,
|
|
62
62
|
replaceUnknown: () => replaceUnknown,
|
|
63
|
+
resolveFormulaHint: () => resolveFormulaHint,
|
|
63
64
|
roll: () => roll,
|
|
65
|
+
splitDiceComment: () => splitDiceComment,
|
|
64
66
|
standardizeDice: () => standardizeDice,
|
|
65
67
|
templateSchema: () => templateSchema,
|
|
66
68
|
testDiceRegistered: () => testDiceRegistered,
|
|
@@ -277,211 +279,261 @@ function includeDiceType(dice, diceType, userStats) {
|
|
|
277
279
|
}
|
|
278
280
|
|
|
279
281
|
// src/roll.ts
|
|
280
|
-
var
|
|
281
|
-
var
|
|
282
|
+
var import_rpg_dice_roller8 = require("@dice-roller/rpg-dice-roller");
|
|
283
|
+
var import_mathjs10 = require("mathjs");
|
|
282
284
|
|
|
283
285
|
// src/dice/bulk.ts
|
|
284
|
-
var
|
|
285
|
-
var
|
|
286
|
+
var import_rpg_dice_roller7 = require("@dice-roller/rpg-dice-roller");
|
|
287
|
+
var import_mathjs8 = require("mathjs");
|
|
286
288
|
|
|
287
|
-
// src/
|
|
289
|
+
// src/utils.ts
|
|
290
|
+
var import_uniformize2 = require("uniformize");
|
|
288
291
|
var import_rpg_dice_roller3 = require("@dice-roller/rpg-dice-roller");
|
|
289
|
-
var
|
|
292
|
+
var import_random_js2 = require("random-js");
|
|
290
293
|
|
|
291
|
-
// src/
|
|
294
|
+
// src/verify_template.ts
|
|
292
295
|
var import_mathjs = require("mathjs");
|
|
296
|
+
var import_random_js = require("random-js");
|
|
293
297
|
var import_uniformize = require("uniformize");
|
|
294
298
|
var import_rpg_dice_roller2 = require("@dice-roller/rpg-dice-roller");
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
function levenshteinDistance(str1, str2) {
|
|
306
|
-
const matrix = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null));
|
|
307
|
-
for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
|
|
308
|
-
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;
|
|
309
|
-
for (let j = 1; j <= str2.length; j++) {
|
|
310
|
-
for (let i = 1; i <= str1.length; i++) {
|
|
311
|
-
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
312
|
-
matrix[j][i] = Math.min(
|
|
313
|
-
matrix[j][i - 1] + 1,
|
|
314
|
-
// insertion
|
|
315
|
-
matrix[j - 1][i] + 1,
|
|
316
|
-
// deletion
|
|
317
|
-
matrix[j - 1][i - 1] + cost
|
|
318
|
-
// substitution
|
|
319
|
-
);
|
|
299
|
+
function evalStatsDice(testDice, allStats, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto, pity) {
|
|
300
|
+
let dice = testDice.trimEnd();
|
|
301
|
+
if (allStats && Object.keys(allStats).length > 0) {
|
|
302
|
+
const names = Object.keys(allStats);
|
|
303
|
+
for (const name of names) {
|
|
304
|
+
const regex = new RegExp(escapeRegex(name.standardize()), "gi");
|
|
305
|
+
if (dice.standardize().match(regex)) {
|
|
306
|
+
const statValue = allStats[name];
|
|
307
|
+
dice = dice.standardize().replace(regex, statValue.toString()).trimEnd();
|
|
308
|
+
}
|
|
320
309
|
}
|
|
321
310
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
for (const [normalizedKey, original] of normalizedStats) {
|
|
329
|
-
if (normalizedKey.startsWith(searchTerm))
|
|
330
|
-
candidates.push([original, calculateSimilarity(searchTerm, normalizedKey)]);
|
|
331
|
-
}
|
|
332
|
-
if (candidates.length === 1) return candidates[0][0];
|
|
333
|
-
if (candidates.length > 0) {
|
|
334
|
-
candidates.sort((a, b) => b[1] - a[1]);
|
|
335
|
-
if (candidates[0][1] >= similarityThreshold) return candidates[0][0];
|
|
336
|
-
}
|
|
337
|
-
let bestMatch;
|
|
338
|
-
let bestSimilarity = 0;
|
|
339
|
-
for (const [normalizedKey, original] of normalizedStats) {
|
|
340
|
-
const similarity = calculateSimilarity(searchTerm, normalizedKey);
|
|
341
|
-
if (similarity === 1) return original;
|
|
342
|
-
if (similarity > bestSimilarity && similarity >= similarityThreshold) {
|
|
343
|
-
bestSimilarity = similarity;
|
|
344
|
-
bestMatch = original;
|
|
345
|
-
}
|
|
311
|
+
try {
|
|
312
|
+
if (!roll(replaceFormulaInDice(replaceExpByRandom(dice)), engine, pity))
|
|
313
|
+
throw new DiceTypeError(dice, "evalStatsDice", "no roll result");
|
|
314
|
+
return testDice;
|
|
315
|
+
} catch (error) {
|
|
316
|
+
throw new DiceTypeError(dice, "evalStatsDice", error);
|
|
346
317
|
}
|
|
347
|
-
return bestMatch;
|
|
348
318
|
}
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
319
|
+
function diceRandomParse(value, template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
320
|
+
if (!template.statistics) return replaceFormulaInDice(value.standardize());
|
|
321
|
+
value = value.standardize();
|
|
322
|
+
const statNames = Object.keys(template.statistics);
|
|
323
|
+
let newDice = value;
|
|
324
|
+
for (const name of statNames) {
|
|
325
|
+
const regex = new RegExp(escapeRegex(name.standardize()), "gi");
|
|
326
|
+
if (value.match(regex)) {
|
|
327
|
+
let max;
|
|
328
|
+
let min;
|
|
329
|
+
const foundStat = template.statistics?.[name];
|
|
330
|
+
if (foundStat) {
|
|
331
|
+
max = foundStat.max;
|
|
332
|
+
min = foundStat.min;
|
|
333
|
+
}
|
|
334
|
+
const total = template.total || 100;
|
|
335
|
+
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
336
|
+
newDice = value.replace(regex, randomStatValue.toString());
|
|
337
|
+
}
|
|
353
338
|
}
|
|
354
|
-
return
|
|
355
|
-
searchTerm.standardize(),
|
|
356
|
-
normalizeRecord,
|
|
357
|
-
similarityThreshold
|
|
358
|
-
) || null;
|
|
339
|
+
return replaceFormulaInDice(newDice);
|
|
359
340
|
}
|
|
360
|
-
function
|
|
361
|
-
|
|
341
|
+
function diceTypeRandomParse(dice, template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
342
|
+
dice = replaceExpByRandom(dice);
|
|
343
|
+
if (!template.statistics) return dice;
|
|
344
|
+
const firstStatNotcombinaison = Object.keys(template.statistics).find(
|
|
345
|
+
(stat) => !template.statistics?.[stat].combinaison
|
|
346
|
+
);
|
|
347
|
+
if (!firstStatNotcombinaison) return dice;
|
|
348
|
+
const stats = template.statistics[firstStatNotcombinaison];
|
|
349
|
+
const { min, max } = stats;
|
|
350
|
+
const total = template.total || 100;
|
|
351
|
+
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
352
|
+
return replaceFormulaInDice(dice.replaceAll("$", randomStatValue.toString()));
|
|
362
353
|
}
|
|
363
|
-
function
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
354
|
+
function evalCombinaison(combinaison, stats) {
|
|
355
|
+
const newStats = {};
|
|
356
|
+
for (const [stat, combin] of Object.entries(combinaison)) {
|
|
357
|
+
let formula = combin.standardize();
|
|
358
|
+
for (const [statName, value] of Object.entries(stats)) {
|
|
359
|
+
const regex = new RegExp(statName.standardize(), "gi");
|
|
360
|
+
formula = formula.replace(regex, value.toString());
|
|
361
|
+
}
|
|
362
|
+
try {
|
|
363
|
+
newStats[stat] = (0, import_mathjs.evaluate)(formula);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
throw new FormulaError(stat, "evalCombinaison", error);
|
|
366
|
+
}
|
|
370
367
|
}
|
|
371
|
-
return
|
|
368
|
+
return newStats;
|
|
372
369
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
370
|
+
function evalOneCombinaison(combinaison, stats) {
|
|
371
|
+
let formula = combinaison.standardize();
|
|
372
|
+
for (const [statName, value] of Object.entries(stats)) {
|
|
373
|
+
const regex = new RegExp(statName.standardize(), "gi");
|
|
374
|
+
formula = formula.replace(regex, value.toString());
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
return (0, import_mathjs.evaluate)(formula);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
throw new FormulaError(combinaison, "evalOneCombinaison", error);
|
|
380
|
+
}
|
|
377
381
|
}
|
|
378
|
-
function
|
|
379
|
-
return
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
);
|
|
382
|
+
function convertNumber(number) {
|
|
383
|
+
if (number === void 0 || number === null) return void 0;
|
|
384
|
+
if (number.toString().length === 0 || Number.isNaN(Number.parseInt(number.toString(), 10)))
|
|
385
|
+
return void 0;
|
|
386
|
+
if (isNumber(number)) return Number.parseInt(number.toString(), 10);
|
|
387
|
+
return void 0;
|
|
383
388
|
}
|
|
384
|
-
function
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
389
|
+
function verifyTemplateValue(template, verify = true, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
390
|
+
const parsedTemplate = templateSchema.parse(template);
|
|
391
|
+
const { success, failure } = parsedTemplate.critical ?? {};
|
|
392
|
+
const criticicalVal = {
|
|
393
|
+
success: convertNumber(success),
|
|
394
|
+
failure: convertNumber(failure)
|
|
395
|
+
};
|
|
396
|
+
const statistiqueTemplate = {
|
|
397
|
+
diceType: parsedTemplate.diceType,
|
|
398
|
+
statistics: parsedTemplate.statistics,
|
|
399
|
+
critical: criticicalVal,
|
|
400
|
+
total: parsedTemplate.total,
|
|
401
|
+
charName: parsedTemplate.charName,
|
|
402
|
+
damage: parsedTemplate.damage,
|
|
403
|
+
customCritical: parsedTemplate.customCritical,
|
|
404
|
+
forceDistrib: parsedTemplate.forceDistrib
|
|
405
|
+
};
|
|
406
|
+
if (!verify) return statistiqueTemplate;
|
|
407
|
+
if (statistiqueTemplate.diceType) {
|
|
408
|
+
if (statistiqueTemplate.diceType.match(DETECT_CRITICAL)) {
|
|
409
|
+
throw new DiceTypeError(
|
|
410
|
+
statistiqueTemplate.diceType,
|
|
411
|
+
"critical_dice_type",
|
|
412
|
+
"contains critical detection: should be in custom critical instead"
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
const cleanedDice2 = diceTypeRandomParse(
|
|
416
|
+
statistiqueTemplate.diceType,
|
|
417
|
+
statistiqueTemplate,
|
|
418
|
+
engine
|
|
419
|
+
);
|
|
420
|
+
const rolled = roll(cleanedDice2, engine);
|
|
421
|
+
if (!rolled) throw new DiceTypeError(cleanedDice2, "no_roll_result", "no roll result");
|
|
393
422
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const [,
|
|
400
|
-
|
|
423
|
+
if (statistiqueTemplate.customCritical) {
|
|
424
|
+
if (!statistiqueTemplate.diceType) {
|
|
425
|
+
throw new DiceTypeError("no_dice_type", "no_dice_type", "no dice type");
|
|
426
|
+
}
|
|
427
|
+
const customCritical = statistiqueTemplate.customCritical;
|
|
428
|
+
for (const [, custom] of Object.entries(customCritical)) {
|
|
429
|
+
const cleanedDice2 = createCriticalCustom(
|
|
430
|
+
statistiqueTemplate.diceType,
|
|
431
|
+
custom,
|
|
432
|
+
statistiqueTemplate,
|
|
433
|
+
engine
|
|
434
|
+
);
|
|
435
|
+
const rolled = roll(cleanedDice2, engine);
|
|
436
|
+
if (!rolled)
|
|
437
|
+
throw new DiceTypeError(cleanedDice2, "verifyTemplateValue", "no roll result");
|
|
438
|
+
}
|
|
401
439
|
}
|
|
402
|
-
|
|
440
|
+
testDiceRegistered(statistiqueTemplate, engine);
|
|
441
|
+
testStatCombinaison(statistiqueTemplate, engine);
|
|
442
|
+
return statistiqueTemplate;
|
|
403
443
|
}
|
|
404
|
-
function
|
|
405
|
-
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
444
|
+
function testDiceRegistered(template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
445
|
+
if (!template.damage) return;
|
|
446
|
+
if (Object.keys(template.damage).length === 0) throw new EmptyObjectError();
|
|
447
|
+
if (Object.keys(template.damage).length > 25) throw new TooManyDice();
|
|
448
|
+
for (const [name, dice] of Object.entries(template.damage)) {
|
|
449
|
+
if (!dice) continue;
|
|
450
|
+
const diceReplaced = replaceExpByRandom(dice);
|
|
451
|
+
const randomDiceParsed = diceRandomParse(diceReplaced, template, engine);
|
|
452
|
+
try {
|
|
453
|
+
const rolled = roll(randomDiceParsed, engine);
|
|
454
|
+
if (!rolled) throw new DiceTypeError(name, "no_roll_result", dice);
|
|
455
|
+
} catch (error) {
|
|
456
|
+
throw new DiceTypeError(name, "testDiceRegistered", error);
|
|
411
457
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
result += outsideText.slice(lastIndex);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function testStatCombinaison(template, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
461
|
+
if (!template.statistics) return;
|
|
462
|
+
const onlycombinaisonStats = Object.fromEntries(
|
|
463
|
+
Object.entries(template.statistics).filter(
|
|
464
|
+
([_, value]) => value.combinaison !== void 0
|
|
465
|
+
)
|
|
466
|
+
);
|
|
467
|
+
const allOtherStats = Object.fromEntries(
|
|
468
|
+
Object.entries(template.statistics).filter(([_, value]) => !value.combinaison)
|
|
469
|
+
);
|
|
470
|
+
if (Object.keys(onlycombinaisonStats).length === 0) return;
|
|
471
|
+
const allStats = Object.keys(template.statistics).filter(
|
|
472
|
+
(stat) => !template.statistics[stat].combinaison
|
|
473
|
+
);
|
|
474
|
+
if (allStats.length === 0) throw new NoStatisticsError();
|
|
475
|
+
const error = [];
|
|
476
|
+
for (const [stat, value] of Object.entries(onlycombinaisonStats)) {
|
|
477
|
+
let formula = value.combinaison;
|
|
478
|
+
for (const [other, data] of Object.entries(allOtherStats)) {
|
|
479
|
+
const { max, min } = data;
|
|
480
|
+
const total = template.total || 100;
|
|
481
|
+
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
482
|
+
const regex = new RegExp(other, "gi");
|
|
483
|
+
formula = formula.replace(regex, randomStatValue.toString());
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
(0, import_mathjs.evaluate)(formula);
|
|
487
|
+
} catch (e) {
|
|
488
|
+
error.push(stat);
|
|
444
489
|
}
|
|
445
|
-
dice = result;
|
|
446
490
|
}
|
|
447
|
-
if (
|
|
448
|
-
return
|
|
491
|
+
if (error.length > 0) throw new FormulaError(error.join(", "), "testStatCombinaison");
|
|
492
|
+
return;
|
|
449
493
|
}
|
|
450
|
-
function
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
if (
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
const result = (0, import_mathjs.evaluate)(formulae);
|
|
459
|
-
modifiedDice = modifiedDice.replace(match.groups.formula, result.toString());
|
|
460
|
-
} catch (error) {
|
|
461
|
-
throw new FormulaError(match.groups.formula, "replaceFormulasInDice", error);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
494
|
+
function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) {
|
|
495
|
+
let randomStatValue = total + 1;
|
|
496
|
+
const random = new import_random_js.Random(engine || import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto);
|
|
497
|
+
while (randomStatValue >= total || randomStatValue === 0) {
|
|
498
|
+
if (max && min) randomStatValue = randomInt(min, max, engine, random);
|
|
499
|
+
else if (max) randomStatValue = randomInt(1, max, engine, random);
|
|
500
|
+
else if (min) randomStatValue = randomInt(min, total, engine, random);
|
|
501
|
+
else randomStatValue = randomInt(1, total, engine, random);
|
|
464
502
|
}
|
|
465
|
-
return
|
|
503
|
+
return randomStatValue;
|
|
466
504
|
}
|
|
467
|
-
|
|
468
|
-
|
|
505
|
+
|
|
506
|
+
// src/utils.ts
|
|
507
|
+
function splitDiceComment(dice) {
|
|
508
|
+
const match = /\s+(#|\/{2}|\[|\/\*)(?<comment>.*)/i.exec(dice);
|
|
509
|
+
if (!match?.groups) return { dice: dice.trimEnd(), comment: void 0 };
|
|
510
|
+
const comment = match.groups.comment.trim() || void 0;
|
|
511
|
+
return { dice: dice.slice(0, match.index).trimEnd(), comment };
|
|
512
|
+
}
|
|
513
|
+
function escapeRegex(string) {
|
|
514
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
515
|
+
}
|
|
516
|
+
function standardizeDice(dice) {
|
|
517
|
+
return dice.replace(
|
|
518
|
+
/(\[[^\]]+])|([^[]+)/g,
|
|
519
|
+
(_match, insideBrackets, outsideText) => insideBrackets ? insideBrackets : outsideText.standardize().replaceAll("df", "dF")
|
|
520
|
+
);
|
|
469
521
|
}
|
|
470
522
|
function isNumber(value) {
|
|
471
523
|
return value !== void 0 && (typeof value === "number" || !Number.isNaN(Number(value)) && typeof value === "string" && value.trim().length > 0);
|
|
472
524
|
}
|
|
473
|
-
function replaceExpByRandom(dice, engine =
|
|
525
|
+
function replaceExpByRandom(dice, engine = import_rpg_dice_roller3.NumberGenerator.engines.nodeCrypto) {
|
|
474
526
|
const diceRegex = /\{exp( ?\|\| ?(?<default>\d+))?}/gi;
|
|
475
527
|
return dice.replace(diceRegex, (_match, _p1, _p2, _offset, _string, groups) => {
|
|
476
528
|
const defaultValue = groups?.default;
|
|
477
529
|
return defaultValue ?? randomInt(1, 999, engine).toString();
|
|
478
530
|
});
|
|
479
531
|
}
|
|
480
|
-
function randomInt(min, max, engine =
|
|
481
|
-
if (!rng) rng = new
|
|
532
|
+
function randomInt(min, max, engine = import_rpg_dice_roller3.NumberGenerator.engines.nodeCrypto, rng) {
|
|
533
|
+
if (!rng) rng = new import_random_js2.Random(engine || void 0);
|
|
482
534
|
return rng.integer(min, max);
|
|
483
535
|
}
|
|
484
|
-
function createCriticalCustom(dice, customCritical, template, engine =
|
|
536
|
+
function createCriticalCustom(dice, customCritical, template, engine = import_rpg_dice_roller3.NumberGenerator.engines.nodeCrypto) {
|
|
485
537
|
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
486
538
|
let customDice = dice;
|
|
487
539
|
const compareValue = diceTypeRandomParse(customCritical.value, template, engine);
|
|
@@ -494,6 +546,8 @@ function createCriticalCustom(dice, customCritical, template, engine = import_rp
|
|
|
494
546
|
}
|
|
495
547
|
|
|
496
548
|
// src/dice/compare.ts
|
|
549
|
+
var import_rpg_dice_roller4 = require("@dice-roller/rpg-dice-roller");
|
|
550
|
+
var import_mathjs2 = require("mathjs");
|
|
497
551
|
function isTrivialComparison(maxValue, minValue, compare) {
|
|
498
552
|
const canSucceed = canComparisonSucceed(maxValue, compare, minValue);
|
|
499
553
|
const canFail = canComparisonFail(maxValue, compare, minValue);
|
|
@@ -524,7 +578,7 @@ function canComparisonFail(maxRollValue, compare, minRollValue = 1) {
|
|
|
524
578
|
return true;
|
|
525
579
|
}
|
|
526
580
|
}
|
|
527
|
-
function rollCompare(value, engine =
|
|
581
|
+
function rollCompare(value, engine = import_rpg_dice_roller4.NumberGenerator.engines.nodeCrypto, pity) {
|
|
528
582
|
if (isNumber(value)) return { value: Number.parseInt(value, 10) };
|
|
529
583
|
if (!value || typeof value === "string" && value.trim() === "") {
|
|
530
584
|
return { value: 0, diceResult: value };
|
|
@@ -543,7 +597,7 @@ function rollCompare(value, engine = import_rpg_dice_roller3.NumberGenerator.eng
|
|
|
543
597
|
diceResult: rollComp?.result
|
|
544
598
|
};
|
|
545
599
|
}
|
|
546
|
-
function getCompare(dice, compareRegex, engine =
|
|
600
|
+
function getCompare(dice, compareRegex, engine = import_rpg_dice_roller4.NumberGenerator.engines.nodeCrypto, pity) {
|
|
547
601
|
if (dice.match(/((\{.*,(.*)+\}|([><=!]+\d+f))([><=]|!=)+\d+\}?)|\{(.*)(([><=]|!=)+).*\}/))
|
|
548
602
|
return { dice, compare: void 0 };
|
|
549
603
|
dice = dice.replace(SIGN_REGEX_SPACE, "");
|
|
@@ -599,7 +653,7 @@ function canComparisonSucceed(maxRollValue, compare, minRollValue) {
|
|
|
599
653
|
var import_mathjs4 = require("mathjs");
|
|
600
654
|
|
|
601
655
|
// src/dice/signs.ts
|
|
602
|
-
var
|
|
656
|
+
var import_rpg_dice_roller5 = require("@dice-roller/rpg-dice-roller");
|
|
603
657
|
var import_mathjs3 = require("mathjs");
|
|
604
658
|
|
|
605
659
|
// src/dice/replace.ts
|
|
@@ -689,7 +743,7 @@ function inverseSign(sign) {
|
|
|
689
743
|
return "==";
|
|
690
744
|
}
|
|
691
745
|
}
|
|
692
|
-
function compareSignFormule(toRoll, compareRegex, element, diceResult, engine =
|
|
746
|
+
function compareSignFormule(toRoll, compareRegex, element, diceResult, engine = import_rpg_dice_roller5.NumberGenerator.engines.nodeCrypto, pity, rollBounds) {
|
|
693
747
|
let results = "";
|
|
694
748
|
let trivial = false;
|
|
695
749
|
const compareResult = getCompare(toRoll, compareRegex, engine);
|
|
@@ -750,43 +804,278 @@ function normalizeExplodingSuccess(dice) {
|
|
|
750
804
|
parsedValue = 0;
|
|
751
805
|
}
|
|
752
806
|
}
|
|
753
|
-
const normalizedSegment = "!";
|
|
754
|
-
const replacedDice = dice.replace(match[0], normalizedSegment);
|
|
755
|
-
return {
|
|
756
|
-
dice: replacedDice,
|
|
757
|
-
originalDice: dice,
|
|
758
|
-
sign: normalizedSign,
|
|
759
|
-
value: parsedValue,
|
|
760
|
-
normalizedSegment,
|
|
761
|
-
originalSegment: match[0]
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
function countExplodingSuccesses(diceRoll, sign, value) {
|
|
765
|
-
const rollsArray = Array.isArray(diceRoll) ? diceRoll : [diceRoll];
|
|
766
|
-
const flatValues = [];
|
|
767
|
-
for (const dr of rollsArray) {
|
|
768
|
-
const groups = dr.rolls ?? [];
|
|
769
|
-
for (const group of groups) {
|
|
770
|
-
const innerRolls = group.rolls ?? [];
|
|
771
|
-
for (const roll2 of innerRolls) {
|
|
772
|
-
if (typeof roll2.value === "number") flatValues.push(roll2.value);
|
|
807
|
+
const normalizedSegment = "!";
|
|
808
|
+
const replacedDice = dice.replace(match[0], normalizedSegment);
|
|
809
|
+
return {
|
|
810
|
+
dice: replacedDice,
|
|
811
|
+
originalDice: dice,
|
|
812
|
+
sign: normalizedSign,
|
|
813
|
+
value: parsedValue,
|
|
814
|
+
normalizedSegment,
|
|
815
|
+
originalSegment: match[0]
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function countExplodingSuccesses(diceRoll, sign, value) {
|
|
819
|
+
const rollsArray = Array.isArray(diceRoll) ? diceRoll : [diceRoll];
|
|
820
|
+
const flatValues = [];
|
|
821
|
+
for (const dr of rollsArray) {
|
|
822
|
+
const groups = dr.rolls ?? [];
|
|
823
|
+
for (const group of groups) {
|
|
824
|
+
const innerRolls = group.rolls ?? [];
|
|
825
|
+
for (const roll2 of innerRolls) {
|
|
826
|
+
if (typeof roll2.value === "number") flatValues.push(roll2.value);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return flatValues.reduce(
|
|
831
|
+
(acc, current) => acc + (matchComparison(sign, current, value) ? 1 : 0),
|
|
832
|
+
0
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// src/dice/extract.ts
|
|
837
|
+
var import_rpg_dice_roller6 = require("@dice-roller/rpg-dice-roller");
|
|
838
|
+
|
|
839
|
+
// src/similarities/generateStatsDice.ts
|
|
840
|
+
var import_mathjs5 = require("mathjs");
|
|
841
|
+
|
|
842
|
+
// src/similarities/similarity.ts
|
|
843
|
+
function calculateSimilarity(str1, str2) {
|
|
844
|
+
const longer = str1.length > str2.length ? str1 : str2;
|
|
845
|
+
const shorter = str1.length > str2.length ? str2 : str1;
|
|
846
|
+
if (longer.length === 0) return 1;
|
|
847
|
+
const distance = levenshteinDistance(longer, shorter);
|
|
848
|
+
return (longer.length - distance) / longer.length;
|
|
849
|
+
}
|
|
850
|
+
function levenshteinDistance(str1, str2) {
|
|
851
|
+
const matrix = Array(str2.length + 1).fill(null).map(() => Array(str1.length + 1).fill(null));
|
|
852
|
+
for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
|
|
853
|
+
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;
|
|
854
|
+
for (let j = 1; j <= str2.length; j++) {
|
|
855
|
+
for (let i = 1; i <= str1.length; i++) {
|
|
856
|
+
const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
|
|
857
|
+
matrix[j][i] = Math.min(
|
|
858
|
+
matrix[j][i - 1] + 1,
|
|
859
|
+
// insertion
|
|
860
|
+
matrix[j - 1][i] + 1,
|
|
861
|
+
// deletion
|
|
862
|
+
matrix[j - 1][i - 1] + cost
|
|
863
|
+
// substitution
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
return matrix[str2.length][str1.length];
|
|
868
|
+
}
|
|
869
|
+
function findBestStatMatch(searchTerm, normalizedStats, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
870
|
+
const exact = normalizedStats.get(searchTerm);
|
|
871
|
+
if (exact) return exact;
|
|
872
|
+
const candidates = [];
|
|
873
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
874
|
+
if (normalizedKey.startsWith(searchTerm))
|
|
875
|
+
candidates.push([original, calculateSimilarity(searchTerm, normalizedKey)]);
|
|
876
|
+
}
|
|
877
|
+
if (candidates.length === 1) return candidates[0][0];
|
|
878
|
+
if (candidates.length > 0) {
|
|
879
|
+
candidates.sort((a, b) => b[1] - a[1]);
|
|
880
|
+
if (candidates[0][1] >= similarityThreshold) return candidates[0][0];
|
|
881
|
+
}
|
|
882
|
+
let bestMatch;
|
|
883
|
+
let bestSimilarity = 0;
|
|
884
|
+
for (const [normalizedKey, original] of normalizedStats) {
|
|
885
|
+
const similarity = calculateSimilarity(searchTerm, normalizedKey);
|
|
886
|
+
if (similarity === 1) return original;
|
|
887
|
+
if (similarity > bestSimilarity && similarity >= similarityThreshold) {
|
|
888
|
+
bestSimilarity = similarity;
|
|
889
|
+
bestMatch = original;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return bestMatch;
|
|
893
|
+
}
|
|
894
|
+
function findBestRecord(record, searchTerm, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
895
|
+
const normalizeRecord = /* @__PURE__ */ new Map();
|
|
896
|
+
for (const key of Object.keys(record)) {
|
|
897
|
+
normalizeRecord.set(key.standardize(), key);
|
|
898
|
+
}
|
|
899
|
+
return findBestStatMatch(
|
|
900
|
+
searchTerm.standardize(),
|
|
901
|
+
normalizeRecord,
|
|
902
|
+
similarityThreshold
|
|
903
|
+
) || null;
|
|
904
|
+
}
|
|
905
|
+
function replaceUnknown(dice, replacer) {
|
|
906
|
+
return dice.replaceAll(REMOVER_PATTERN.STAT_MATCHER, replacer).replaceAll("+0", "").replaceAll("-0", "");
|
|
907
|
+
}
|
|
908
|
+
function verifyStatMatcherPattern(dice, replaceUnknow) {
|
|
909
|
+
if (REMOVER_PATTERN.STAT_MATCHER.test(dice)) {
|
|
910
|
+
if (replaceUnknow)
|
|
911
|
+
return replaceUnknown(dice, replaceUnknow);
|
|
912
|
+
const matched = dice.matchAll(new RegExp(REMOVER_PATTERN.STAT_MATCHER));
|
|
913
|
+
const stats = matched ? Array.from(matched, (m) => m?.[0]).map((s) => `\`${s}\``).join(", ") : "unknown";
|
|
914
|
+
throw new DiceTypeError(stats, "unknown_stats");
|
|
915
|
+
}
|
|
916
|
+
return dice.replaceAll("+0", "").replaceAll("-0", "");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// src/similarities/generateStatsDice.ts
|
|
920
|
+
function handleDiceAfterD(tokenStd, normalizedStats) {
|
|
921
|
+
const diceMatch = /^(\d*)d(.+)$/i.exec(tokenStd);
|
|
922
|
+
if (!diceMatch) return null;
|
|
923
|
+
const diceCount = diceMatch[1] || "";
|
|
924
|
+
const afterD = diceMatch[2];
|
|
925
|
+
const bestMatch = findBestStatMatch(afterD, normalizedStats, 1);
|
|
926
|
+
if (bestMatch) {
|
|
927
|
+
const [, value] = bestMatch;
|
|
928
|
+
return `${diceCount}d${value.toString()}`;
|
|
929
|
+
}
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
function handleSimpleToken(tokenStd, token, normalizedStats, minThreshold) {
|
|
933
|
+
const bestMatch = findBestStatMatch(tokenStd, normalizedStats, minThreshold);
|
|
934
|
+
if (bestMatch) {
|
|
935
|
+
const [, value] = bestMatch;
|
|
936
|
+
return value.toString();
|
|
937
|
+
}
|
|
938
|
+
return token;
|
|
939
|
+
}
|
|
940
|
+
function generateStatsDice(originalDice, stats, minThreshold = 0.6, dollarValue) {
|
|
941
|
+
let dice = originalDice.standardize();
|
|
942
|
+
if (stats && Object.keys(stats).length > 0) {
|
|
943
|
+
const normalizedStats = /* @__PURE__ */ new Map();
|
|
944
|
+
for (const [key, value] of Object.entries(stats)) {
|
|
945
|
+
const normalized = key.standardize();
|
|
946
|
+
normalizedStats.set(normalized, [key, value]);
|
|
947
|
+
}
|
|
948
|
+
const partsRegex = /(\[[^\]]+])|([^[]+)/g;
|
|
949
|
+
let result = "";
|
|
950
|
+
let match;
|
|
951
|
+
while ((match = partsRegex.exec(dice)) !== null) {
|
|
952
|
+
const insideBrackets = match[1];
|
|
953
|
+
const outsideText = match[2];
|
|
954
|
+
if (insideBrackets) {
|
|
955
|
+
result += insideBrackets;
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
if (!outsideText) {
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
const tokenRegex = /(\$?[\p{L}\p{N}_.]+)/gu;
|
|
962
|
+
let lastIndex = 0;
|
|
963
|
+
let tokenMatch;
|
|
964
|
+
while ((tokenMatch = tokenRegex.exec(outsideText)) !== null) {
|
|
965
|
+
result += outsideText.slice(lastIndex, tokenMatch.index);
|
|
966
|
+
const token = tokenMatch[0];
|
|
967
|
+
const tokenHasDollar = token.startsWith("$");
|
|
968
|
+
const tokenForCompare = tokenHasDollar ? token.slice(1) : token;
|
|
969
|
+
const tokenStd = tokenForCompare.standardize();
|
|
970
|
+
const diceReplacement = handleDiceAfterD(tokenStd, normalizedStats);
|
|
971
|
+
if (diceReplacement) {
|
|
972
|
+
result += diceReplacement;
|
|
973
|
+
lastIndex = tokenRegex.lastIndex;
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
result += handleSimpleToken(tokenStd, token, normalizedStats, minThreshold);
|
|
977
|
+
lastIndex = tokenRegex.lastIndex;
|
|
978
|
+
}
|
|
979
|
+
result += outsideText.slice(lastIndex);
|
|
980
|
+
}
|
|
981
|
+
dice = result;
|
|
982
|
+
}
|
|
983
|
+
if (dollarValue) dice = dice.replaceAll("$", dollarValue);
|
|
984
|
+
return replaceFormulaInDice(dice);
|
|
985
|
+
}
|
|
986
|
+
function replaceFormulaInDice(dice) {
|
|
987
|
+
const formula = /(?<formula>\{{2}(.+?)}{2})/gim;
|
|
988
|
+
let match;
|
|
989
|
+
let modifiedDice = dice;
|
|
990
|
+
while ((match = formula.exec(dice)) !== null) {
|
|
991
|
+
if (match.groups?.formula) {
|
|
992
|
+
const formulae = match.groups.formula.replaceAll("{{", "").replaceAll("}}", "");
|
|
993
|
+
try {
|
|
994
|
+
const result = (0, import_mathjs5.evaluate)(formulae);
|
|
995
|
+
modifiedDice = modifiedDice.replace(match.groups.formula, result.toString());
|
|
996
|
+
} catch (error) {
|
|
997
|
+
throw new FormulaError(match.groups.formula, "replaceFormulasInDice", error);
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
return cleanedDice(modifiedDice);
|
|
1002
|
+
}
|
|
1003
|
+
function cleanedDice(dice) {
|
|
1004
|
+
return dice.replaceAll("+-", "-").replaceAll("--", "+").replaceAll("++", "+").replaceAll("=>", ">=").replaceAll("=<", "<=").trimEnd();
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// src/similarities/resolveFormula.ts
|
|
1008
|
+
var import_mathjs6 = require("mathjs");
|
|
1009
|
+
function toFiniteNumber(value) {
|
|
1010
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1011
|
+
return void 0;
|
|
1012
|
+
}
|
|
1013
|
+
function substituteFormulaTokens(expr, resolvedStats, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
1014
|
+
return expr.replace(/([\p{L}\p{M}._-]+)/gu, (token) => {
|
|
1015
|
+
const match = findBestStatMatch(token, resolvedStats, similarityThreshold);
|
|
1016
|
+
return match !== void 0 ? match.toString() : token;
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
function resolveFormulaHint(formula, allAttributes, similarityThreshold = MIN_THRESHOLD_MATCH) {
|
|
1020
|
+
const trimmed = formula.trim();
|
|
1021
|
+
if (!trimmed) return { kind: "not-formula" };
|
|
1022
|
+
if (isNumber(trimmed)) return { kind: "not-formula" };
|
|
1023
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1024
|
+
const pending = /* @__PURE__ */ new Map();
|
|
1025
|
+
for (const [name, val] of Object.entries(allAttributes)) {
|
|
1026
|
+
const norm = name.standardize();
|
|
1027
|
+
if (typeof val === "number") {
|
|
1028
|
+
if (Number.isFinite(val)) resolved.set(norm, val);
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
const t = val.trim();
|
|
1032
|
+
if (!t) continue;
|
|
1033
|
+
if (isNumber(t)) {
|
|
1034
|
+
const numeric = Number(t);
|
|
1035
|
+
if (Number.isFinite(numeric)) resolved.set(norm, numeric);
|
|
1036
|
+
} else {
|
|
1037
|
+
pending.set(norm, t.standardize());
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
for (const [normName, expr2] of pending) {
|
|
1041
|
+
pending.set(normName, substituteFormulaTokens(expr2, resolved, similarityThreshold));
|
|
1042
|
+
}
|
|
1043
|
+
let progress = true;
|
|
1044
|
+
while (pending.size > 0 && progress) {
|
|
1045
|
+
progress = false;
|
|
1046
|
+
for (const [normName, expr2] of pending) {
|
|
1047
|
+
try {
|
|
1048
|
+
const result = toFiniteNumber((0, import_mathjs6.evaluate)(expr2));
|
|
1049
|
+
if (result === void 0) continue;
|
|
1050
|
+
resolved.set(normName, result);
|
|
1051
|
+
pending.delete(normName);
|
|
1052
|
+
progress = true;
|
|
1053
|
+
for (const [otherNorm, otherExpr] of pending) {
|
|
1054
|
+
pending.set(
|
|
1055
|
+
otherNorm,
|
|
1056
|
+
substituteFormulaTokens(otherExpr, resolved, similarityThreshold)
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
} catch {
|
|
773
1060
|
}
|
|
774
1061
|
}
|
|
775
1062
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
1063
|
+
const normFormula = trimmed.standardize();
|
|
1064
|
+
const expr = substituteFormulaTokens(normFormula, resolved, similarityThreshold);
|
|
1065
|
+
try {
|
|
1066
|
+
const result = toFiniteNumber((0, import_mathjs6.evaluate)(expr));
|
|
1067
|
+
if (result !== void 0) return { kind: "resolved", value: result };
|
|
1068
|
+
return { kind: "error" };
|
|
1069
|
+
} catch {
|
|
1070
|
+
return { kind: "error" };
|
|
1071
|
+
}
|
|
780
1072
|
}
|
|
781
1073
|
|
|
782
|
-
// src/dice/extract.ts
|
|
783
|
-
var import_rpg_dice_roller5 = require("@dice-roller/rpg-dice-roller");
|
|
784
|
-
|
|
785
1074
|
// src/dice/calculator.ts
|
|
786
|
-
var
|
|
1075
|
+
var import_mathjs7 = require("mathjs");
|
|
787
1076
|
function calculator(sign, value, total) {
|
|
788
1077
|
if (sign === "^") sign = "**";
|
|
789
|
-
return (0,
|
|
1078
|
+
return (0, import_mathjs7.evaluate)(`${total} ${sign} ${value}`);
|
|
790
1079
|
}
|
|
791
1080
|
|
|
792
1081
|
// src/dice/extract.ts
|
|
@@ -821,10 +1110,10 @@ function extractValuesFromOutput(output) {
|
|
|
821
1110
|
}
|
|
822
1111
|
return values;
|
|
823
1112
|
}
|
|
824
|
-
function getRollBounds(dice, engine =
|
|
1113
|
+
function getRollBounds(dice, engine = import_rpg_dice_roller6.NumberGenerator.engines.nodeCrypto) {
|
|
825
1114
|
try {
|
|
826
|
-
const roller = new
|
|
827
|
-
|
|
1115
|
+
const roller = new import_rpg_dice_roller6.DiceRoller();
|
|
1116
|
+
import_rpg_dice_roller6.NumberGenerator.generator.engine = engine;
|
|
828
1117
|
const rollResult = roller.roll(dice);
|
|
829
1118
|
const instance = Array.isArray(rollResult) ? rollResult[0] : rollResult;
|
|
830
1119
|
const { minTotal, maxTotal } = instance;
|
|
@@ -849,7 +1138,7 @@ function setSortOrder(toRoll, sort) {
|
|
|
849
1138
|
}
|
|
850
1139
|
function prepareDice(diceInput) {
|
|
851
1140
|
let dice = standardizeDice(replaceFormulaInDice(diceInput)).replace(/^\+/, "").replaceAll("=>", ">=").replaceAll("=<", "<=").trimStart();
|
|
852
|
-
dice = dice.replaceAll(
|
|
1141
|
+
dice = dice.replaceAll(REMOVER_PATTERN.CRITICAL_BLOCK, "").trimEnd();
|
|
853
1142
|
const explodingSuccess = normalizeExplodingSuccess(dice);
|
|
854
1143
|
if (explodingSuccess) dice = explodingSuccess.dice;
|
|
855
1144
|
let diceDisplay;
|
|
@@ -901,9 +1190,8 @@ function handleBulkRolls(dice, isCurlyBulk, bulkContent, compare, explodingSucce
|
|
|
901
1190
|
const bulkProcessContent = isCurlyBulk ? bulkContent : dice;
|
|
902
1191
|
const diceArray = bulkProcessContent.split("#");
|
|
903
1192
|
const numberOfDice = Number.parseInt(diceArray[0], 10);
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const comments = commentsMatch ? commentsMatch[2] : void 0;
|
|
1193
|
+
const { dice: diceToRollBase, comment: comments } = splitDiceComment(diceArray[1]);
|
|
1194
|
+
let diceToRoll = diceToRollBase;
|
|
907
1195
|
let curlyCompare;
|
|
908
1196
|
if (isCurlyBulk) {
|
|
909
1197
|
const curlyCompareRegex = diceToRoll.match(SIGN_REGEX_SPACE);
|
|
@@ -937,8 +1225,8 @@ function handleBulkRolls(dice, isCurlyBulk, bulkContent, compare, explodingSucce
|
|
|
937
1225
|
sort
|
|
938
1226
|
);
|
|
939
1227
|
}
|
|
940
|
-
const roller = new
|
|
941
|
-
|
|
1228
|
+
const roller = new import_rpg_dice_roller7.DiceRoller();
|
|
1229
|
+
import_rpg_dice_roller7.NumberGenerator.generator.engine = engine;
|
|
942
1230
|
for (let i = 0; i < numberOfDice; i++) {
|
|
943
1231
|
try {
|
|
944
1232
|
roller.roll(diceToRoll);
|
|
@@ -960,8 +1248,8 @@ function handleBulkRolls(dice, isCurlyBulk, bulkContent, compare, explodingSucce
|
|
|
960
1248
|
function handleBulkRollsWithComparison(numberOfDice, diceToRoll, comments, activeCompare, explodingSuccess, diceDisplay, isCurlyBulk, curlyCompare, compare, engine, sort) {
|
|
961
1249
|
const results = [];
|
|
962
1250
|
let successCount = 0;
|
|
963
|
-
const roller = new
|
|
964
|
-
|
|
1251
|
+
const roller = new import_rpg_dice_roller7.DiceRoller();
|
|
1252
|
+
import_rpg_dice_roller7.NumberGenerator.generator.engine = engine;
|
|
965
1253
|
let trivialComparisonDetected = false;
|
|
966
1254
|
const formatOutput = (output, addStar) => {
|
|
967
1255
|
const formatted = addStar && isCurlyBulk ? output.replace(
|
|
@@ -995,7 +1283,7 @@ function handleBulkRollsWithComparison(numberOfDice, diceToRoll, comments, activ
|
|
|
995
1283
|
results.push(formattedRollOutput);
|
|
996
1284
|
} else {
|
|
997
1285
|
const rollTotal = rollInstance.total;
|
|
998
|
-
const isSuccess = (0,
|
|
1286
|
+
const isSuccess = (0, import_mathjs8.evaluate)(
|
|
999
1287
|
`${rollTotal}${activeCompare.sign}${activeCompare.value}`
|
|
1000
1288
|
);
|
|
1001
1289
|
if (isSuccess) successCount++;
|
|
@@ -1058,7 +1346,7 @@ function handleBulkRollsWithComparison(numberOfDice, diceToRoll, comments, activ
|
|
|
1058
1346
|
}
|
|
1059
1347
|
|
|
1060
1348
|
// src/dice/pity.ts
|
|
1061
|
-
var
|
|
1349
|
+
var import_mathjs9 = require("mathjs");
|
|
1062
1350
|
function handlePitySystem(dice, compare, diceRoll, roller, engine) {
|
|
1063
1351
|
const currentRoll = Array.isArray(diceRoll) ? diceRoll[0] : diceRoll;
|
|
1064
1352
|
const maxPossible = currentRoll ? currentRoll.maxTotal : null;
|
|
@@ -1066,7 +1354,7 @@ function handlePitySystem(dice, compare, diceRoll, roller, engine) {
|
|
|
1066
1354
|
if (!isComparisonPossible) {
|
|
1067
1355
|
return { rerollCount: 0 };
|
|
1068
1356
|
}
|
|
1069
|
-
let isFail = (0,
|
|
1357
|
+
let isFail = (0, import_mathjs9.evaluate)(`${roller.total}${compare.sign}${compare.value}`);
|
|
1070
1358
|
if (isFail) {
|
|
1071
1359
|
return { rerollCount: 0 };
|
|
1072
1360
|
}
|
|
@@ -1081,14 +1369,14 @@ function handlePitySystem(dice, compare, diceRoll, roller, engine) {
|
|
|
1081
1369
|
}
|
|
1082
1370
|
rerollCount++;
|
|
1083
1371
|
if (res && res.total !== void 0) {
|
|
1084
|
-
isFail = (0,
|
|
1372
|
+
isFail = (0, import_mathjs9.evaluate)(`${res.total}${compare.sign}${compare.value}`);
|
|
1085
1373
|
}
|
|
1086
1374
|
}
|
|
1087
1375
|
return { rerollCount, result: res };
|
|
1088
1376
|
}
|
|
1089
1377
|
|
|
1090
1378
|
// src/roll.ts
|
|
1091
|
-
function roll(dice, engine =
|
|
1379
|
+
function roll(dice, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto, pity, sort, comment) {
|
|
1092
1380
|
if (sort === "none" /* None */) sort = void 0;
|
|
1093
1381
|
const prepared = prepareDice(dice);
|
|
1094
1382
|
if (!prepared.dice.includes("d")) return void 0;
|
|
@@ -1129,10 +1417,12 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1129
1417
|
sort
|
|
1130
1418
|
);
|
|
1131
1419
|
}
|
|
1132
|
-
const roller = new
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1420
|
+
const roller = new import_rpg_dice_roller8.DiceRoller();
|
|
1421
|
+
import_rpg_dice_roller8.NumberGenerator.generator.engine = engine;
|
|
1422
|
+
const splitResult = splitDiceComment(processedDice);
|
|
1423
|
+
const diceBase = comment !== void 0 ? processedDice.trimEnd() : splitResult.dice;
|
|
1424
|
+
const resolvedComment = comment ?? splitResult.comment;
|
|
1425
|
+
const diceWithoutComment = setSortOrder(diceBase, sort);
|
|
1136
1426
|
let diceRoll;
|
|
1137
1427
|
try {
|
|
1138
1428
|
diceRoll = roller.roll(diceWithoutComment);
|
|
@@ -1148,8 +1438,6 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1148
1438
|
);
|
|
1149
1439
|
compare.trivial = trivial ? true : void 0;
|
|
1150
1440
|
}
|
|
1151
|
-
const commentMatch = processedDice.match(COMMENT_REGEX);
|
|
1152
|
-
const comment = commentMatch ? commentMatch[2] : void 0;
|
|
1153
1441
|
let rerollCount = 0;
|
|
1154
1442
|
let pityResult;
|
|
1155
1443
|
if (pity && compare) {
|
|
@@ -1166,7 +1454,7 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1166
1454
|
return {
|
|
1167
1455
|
...pityResult,
|
|
1168
1456
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : processedDice,
|
|
1169
|
-
comment,
|
|
1457
|
+
comment: resolvedComment,
|
|
1170
1458
|
compare,
|
|
1171
1459
|
modifier: modificator,
|
|
1172
1460
|
pityLogs: rerollCount,
|
|
@@ -1188,7 +1476,7 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1188
1476
|
return {
|
|
1189
1477
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : prepared.diceDisplay,
|
|
1190
1478
|
result: resultOutput,
|
|
1191
|
-
comment,
|
|
1479
|
+
comment: resolvedComment,
|
|
1192
1480
|
compare: compare ? compare : void 0,
|
|
1193
1481
|
modifier: modificator,
|
|
1194
1482
|
total: successes,
|
|
@@ -1199,7 +1487,7 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1199
1487
|
return {
|
|
1200
1488
|
dice: prepared.isSimpleCurly ? finalDiceDisplay : processedDice,
|
|
1201
1489
|
result: resultOutput,
|
|
1202
|
-
comment,
|
|
1490
|
+
comment: resolvedComment,
|
|
1203
1491
|
compare: compare ? compare : void 0,
|
|
1204
1492
|
modifier: modificator,
|
|
1205
1493
|
total: roller.total,
|
|
@@ -1207,7 +1495,7 @@ function roll(dice, engine = import_rpg_dice_roller7.NumberGenerator.engines.nod
|
|
|
1207
1495
|
trivial: compare?.trivial ? true : void 0
|
|
1208
1496
|
};
|
|
1209
1497
|
}
|
|
1210
|
-
function sharedRolls(dice, engine =
|
|
1498
|
+
function sharedRolls(dice, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto, pity, explodingSuccessMain, diceDisplay, isSharedCurly, sort) {
|
|
1211
1499
|
if (!explodingSuccessMain)
|
|
1212
1500
|
explodingSuccessMain = normalizeExplodingSuccess(dice.split(";")[0] ?? dice);
|
|
1213
1501
|
if (explodingSuccessMain) {
|
|
@@ -1242,13 +1530,13 @@ function sharedRolls(dice, engine = import_rpg_dice_roller7.NumberGenerator.engi
|
|
|
1242
1530
|
const sortFromMain = getSortOrder(diceMain);
|
|
1243
1531
|
const rollBounds = getRollBounds(diceMain, engine);
|
|
1244
1532
|
let diceResult = roll(diceMain, engine, pity, sort);
|
|
1245
|
-
if (!diceResult
|
|
1533
|
+
if (!diceResult?.total) {
|
|
1246
1534
|
if (hidden) {
|
|
1247
1535
|
diceResult = roll(fixParenthesis(split[0]), engine, pity, sort);
|
|
1248
1536
|
hidden = false;
|
|
1249
1537
|
} else return void 0;
|
|
1250
1538
|
}
|
|
1251
|
-
if (!diceResult
|
|
1539
|
+
if (!diceResult?.total) return void 0;
|
|
1252
1540
|
if (explodingSuccessMain && diceResult.result) {
|
|
1253
1541
|
const values = extractValuesFromOutput(diceResult.result);
|
|
1254
1542
|
diceResult.total = values.filter(
|
|
@@ -1290,7 +1578,7 @@ function sharedRolls(dice, engine = import_rpg_dice_roller7.NumberGenerator.engi
|
|
|
1290
1578
|
const { diceAll } = replaceText(element, diceResult.total, diceResult.dice);
|
|
1291
1579
|
let successCount = 0;
|
|
1292
1580
|
try {
|
|
1293
|
-
const evaluated = (0,
|
|
1581
|
+
const evaluated = (0, import_mathjs10.evaluate)(toRoll);
|
|
1294
1582
|
successCount = evaluated ? 1 : 0;
|
|
1295
1583
|
} catch (error) {
|
|
1296
1584
|
const evaluated = roll(toRoll, engine, pity);
|
|
@@ -1324,7 +1612,7 @@ function sharedRolls(dice, engine = import_rpg_dice_roller7.NumberGenerator.engi
|
|
|
1324
1612
|
diceResult.dice
|
|
1325
1613
|
);
|
|
1326
1614
|
try {
|
|
1327
|
-
const evaluated = (0,
|
|
1615
|
+
const evaluated = (0, import_mathjs10.evaluate)(toRoll);
|
|
1328
1616
|
results.push(`\u25C8 ${comment}${diceAll}: ${formule} = ${evaluated}`);
|
|
1329
1617
|
total += Number.parseInt(evaluated, 10);
|
|
1330
1618
|
} catch (error) {
|
|
@@ -1353,7 +1641,7 @@ function sharedRolls(dice, engine = import_rpg_dice_roller7.NumberGenerator.engi
|
|
|
1353
1641
|
trivial: hasTrivialComparison ? true : void 0
|
|
1354
1642
|
};
|
|
1355
1643
|
}
|
|
1356
|
-
function replaceInFormula(element, diceResult, compareResult, res, engine =
|
|
1644
|
+
function replaceInFormula(element, diceResult, compareResult, res, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto, pity) {
|
|
1357
1645
|
const { formule, diceAll } = replaceText(
|
|
1358
1646
|
element,
|
|
1359
1647
|
diceResult.total ?? 0,
|
|
@@ -1363,7 +1651,7 @@ function replaceInFormula(element, diceResult, compareResult, res, engine = impo
|
|
|
1363
1651
|
const invertedSign = res ? compareResult.compare.sign : inverseSign(compareResult.compare.sign);
|
|
1364
1652
|
let evaluateRoll;
|
|
1365
1653
|
try {
|
|
1366
|
-
evaluateRoll = (0,
|
|
1654
|
+
evaluateRoll = (0, import_mathjs10.evaluate)(compareResult.dice);
|
|
1367
1655
|
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;
|
|
1368
1656
|
} catch (error) {
|
|
1369
1657
|
const evaluateRoll2 = roll(compareResult.dice, engine, pity);
|
|
@@ -1372,218 +1660,6 @@ function replaceInFormula(element, diceResult, compareResult, res, engine = impo
|
|
|
1372
1660
|
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll2}${invertedSign}${compareResult.compare?.value}`;
|
|
1373
1661
|
}
|
|
1374
1662
|
}
|
|
1375
|
-
|
|
1376
|
-
// src/verify_template.ts
|
|
1377
|
-
var import_mathjs9 = require("mathjs");
|
|
1378
|
-
var import_random_js2 = require("random-js");
|
|
1379
|
-
var import_uniformize2 = require("uniformize");
|
|
1380
|
-
var import_rpg_dice_roller8 = require("@dice-roller/rpg-dice-roller");
|
|
1381
|
-
function evalStatsDice(testDice, allStats, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto, pity) {
|
|
1382
|
-
let dice = testDice.trimEnd();
|
|
1383
|
-
if (allStats && Object.keys(allStats).length > 0) {
|
|
1384
|
-
const names = Object.keys(allStats);
|
|
1385
|
-
for (const name of names) {
|
|
1386
|
-
const regex = new RegExp(escapeRegex(name.standardize()), "gi");
|
|
1387
|
-
if (dice.standardize().match(regex)) {
|
|
1388
|
-
const statValue = allStats[name];
|
|
1389
|
-
dice = dice.standardize().replace(regex, statValue.toString()).trimEnd();
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
try {
|
|
1394
|
-
if (!roll(replaceFormulaInDice(replaceExpByRandom(dice)), engine, pity))
|
|
1395
|
-
throw new DiceTypeError(dice, "evalStatsDice", "no roll result");
|
|
1396
|
-
return testDice;
|
|
1397
|
-
} catch (error) {
|
|
1398
|
-
throw new DiceTypeError(dice, "evalStatsDice", error);
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
function diceRandomParse(value, template, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1402
|
-
if (!template.statistics) return replaceFormulaInDice(value.standardize());
|
|
1403
|
-
value = value.standardize();
|
|
1404
|
-
const statNames = Object.keys(template.statistics);
|
|
1405
|
-
let newDice = value;
|
|
1406
|
-
for (const name of statNames) {
|
|
1407
|
-
const regex = new RegExp(escapeRegex(name.standardize()), "gi");
|
|
1408
|
-
if (value.match(regex)) {
|
|
1409
|
-
let max;
|
|
1410
|
-
let min;
|
|
1411
|
-
const foundStat = template.statistics?.[name];
|
|
1412
|
-
if (foundStat) {
|
|
1413
|
-
max = foundStat.max;
|
|
1414
|
-
min = foundStat.min;
|
|
1415
|
-
}
|
|
1416
|
-
const total = template.total || 100;
|
|
1417
|
-
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
1418
|
-
newDice = value.replace(regex, randomStatValue.toString());
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
return replaceFormulaInDice(newDice);
|
|
1422
|
-
}
|
|
1423
|
-
function diceTypeRandomParse(dice, template, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1424
|
-
dice = replaceExpByRandom(dice);
|
|
1425
|
-
if (!template.statistics) return dice;
|
|
1426
|
-
const firstStatNotcombinaison = Object.keys(template.statistics).find(
|
|
1427
|
-
(stat) => !template.statistics?.[stat].combinaison
|
|
1428
|
-
);
|
|
1429
|
-
if (!firstStatNotcombinaison) return dice;
|
|
1430
|
-
const stats = template.statistics[firstStatNotcombinaison];
|
|
1431
|
-
const { min, max } = stats;
|
|
1432
|
-
const total = template.total || 100;
|
|
1433
|
-
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
1434
|
-
return replaceFormulaInDice(dice.replaceAll("$", randomStatValue.toString()));
|
|
1435
|
-
}
|
|
1436
|
-
function evalCombinaison(combinaison, stats) {
|
|
1437
|
-
const newStats = {};
|
|
1438
|
-
for (const [stat, combin] of Object.entries(combinaison)) {
|
|
1439
|
-
let formula = combin.standardize();
|
|
1440
|
-
for (const [statName, value] of Object.entries(stats)) {
|
|
1441
|
-
const regex = new RegExp(statName.standardize(), "gi");
|
|
1442
|
-
formula = formula.replace(regex, value.toString());
|
|
1443
|
-
}
|
|
1444
|
-
try {
|
|
1445
|
-
newStats[stat] = (0, import_mathjs9.evaluate)(formula);
|
|
1446
|
-
} catch (error) {
|
|
1447
|
-
throw new FormulaError(stat, "evalCombinaison", error);
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
return newStats;
|
|
1451
|
-
}
|
|
1452
|
-
function evalOneCombinaison(combinaison, stats) {
|
|
1453
|
-
let formula = combinaison.standardize();
|
|
1454
|
-
for (const [statName, value] of Object.entries(stats)) {
|
|
1455
|
-
const regex = new RegExp(statName.standardize(), "gi");
|
|
1456
|
-
formula = formula.replace(regex, value.toString());
|
|
1457
|
-
}
|
|
1458
|
-
try {
|
|
1459
|
-
return (0, import_mathjs9.evaluate)(formula);
|
|
1460
|
-
} catch (error) {
|
|
1461
|
-
throw new FormulaError(combinaison, "evalOneCombinaison", error);
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
function convertNumber(number) {
|
|
1465
|
-
if (number === void 0 || number === null) return void 0;
|
|
1466
|
-
if (number.toString().length === 0 || Number.isNaN(Number.parseInt(number.toString(), 10)))
|
|
1467
|
-
return void 0;
|
|
1468
|
-
if (isNumber(number)) return Number.parseInt(number.toString(), 10);
|
|
1469
|
-
return void 0;
|
|
1470
|
-
}
|
|
1471
|
-
function verifyTemplateValue(template, verify = true, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1472
|
-
const parsedTemplate = templateSchema.parse(template);
|
|
1473
|
-
const { success, failure } = parsedTemplate.critical ?? {};
|
|
1474
|
-
const criticicalVal = {
|
|
1475
|
-
success: convertNumber(success),
|
|
1476
|
-
failure: convertNumber(failure)
|
|
1477
|
-
};
|
|
1478
|
-
const statistiqueTemplate = {
|
|
1479
|
-
diceType: parsedTemplate.diceType,
|
|
1480
|
-
statistics: parsedTemplate.statistics,
|
|
1481
|
-
critical: criticicalVal,
|
|
1482
|
-
total: parsedTemplate.total,
|
|
1483
|
-
charName: parsedTemplate.charName,
|
|
1484
|
-
damage: parsedTemplate.damage,
|
|
1485
|
-
customCritical: parsedTemplate.customCritical,
|
|
1486
|
-
forceDistrib: parsedTemplate.forceDistrib
|
|
1487
|
-
};
|
|
1488
|
-
if (!verify) return statistiqueTemplate;
|
|
1489
|
-
if (statistiqueTemplate.diceType) {
|
|
1490
|
-
if (statistiqueTemplate.diceType.match(DETECT_CRITICAL)) {
|
|
1491
|
-
throw new DiceTypeError(
|
|
1492
|
-
statistiqueTemplate.diceType,
|
|
1493
|
-
"critical_dice_type",
|
|
1494
|
-
"contains critical detection: should be in custom critical instead"
|
|
1495
|
-
);
|
|
1496
|
-
}
|
|
1497
|
-
const cleanedDice2 = diceTypeRandomParse(
|
|
1498
|
-
statistiqueTemplate.diceType,
|
|
1499
|
-
statistiqueTemplate,
|
|
1500
|
-
engine
|
|
1501
|
-
);
|
|
1502
|
-
const rolled = roll(cleanedDice2, engine);
|
|
1503
|
-
if (!rolled) throw new DiceTypeError(cleanedDice2, "no_roll_result", "no roll result");
|
|
1504
|
-
}
|
|
1505
|
-
if (statistiqueTemplate.customCritical) {
|
|
1506
|
-
if (!statistiqueTemplate.diceType) {
|
|
1507
|
-
throw new DiceTypeError("no_dice_type", "no_dice_type", "no dice type");
|
|
1508
|
-
}
|
|
1509
|
-
const customCritical = statistiqueTemplate.customCritical;
|
|
1510
|
-
for (const [, custom] of Object.entries(customCritical)) {
|
|
1511
|
-
const cleanedDice2 = createCriticalCustom(
|
|
1512
|
-
statistiqueTemplate.diceType,
|
|
1513
|
-
custom,
|
|
1514
|
-
statistiqueTemplate,
|
|
1515
|
-
engine
|
|
1516
|
-
);
|
|
1517
|
-
const rolled = roll(cleanedDice2, engine);
|
|
1518
|
-
if (!rolled)
|
|
1519
|
-
throw new DiceTypeError(cleanedDice2, "verifyTemplateValue", "no roll result");
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
testDiceRegistered(statistiqueTemplate, engine);
|
|
1523
|
-
testStatCombinaison(statistiqueTemplate, engine);
|
|
1524
|
-
return statistiqueTemplate;
|
|
1525
|
-
}
|
|
1526
|
-
function testDiceRegistered(template, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1527
|
-
if (!template.damage) return;
|
|
1528
|
-
if (Object.keys(template.damage).length === 0) throw new EmptyObjectError();
|
|
1529
|
-
if (Object.keys(template.damage).length > 25) throw new TooManyDice();
|
|
1530
|
-
for (const [name, dice] of Object.entries(template.damage)) {
|
|
1531
|
-
if (!dice) continue;
|
|
1532
|
-
const diceReplaced = replaceExpByRandom(dice);
|
|
1533
|
-
const randomDiceParsed = diceRandomParse(diceReplaced, template, engine);
|
|
1534
|
-
try {
|
|
1535
|
-
const rolled = roll(randomDiceParsed, engine);
|
|
1536
|
-
if (!rolled) throw new DiceTypeError(name, "no_roll_result", dice);
|
|
1537
|
-
} catch (error) {
|
|
1538
|
-
throw new DiceTypeError(name, "testDiceRegistered", error);
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
function testStatCombinaison(template, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1543
|
-
if (!template.statistics) return;
|
|
1544
|
-
const onlycombinaisonStats = Object.fromEntries(
|
|
1545
|
-
Object.entries(template.statistics).filter(
|
|
1546
|
-
([_, value]) => value.combinaison !== void 0
|
|
1547
|
-
)
|
|
1548
|
-
);
|
|
1549
|
-
const allOtherStats = Object.fromEntries(
|
|
1550
|
-
Object.entries(template.statistics).filter(([_, value]) => !value.combinaison)
|
|
1551
|
-
);
|
|
1552
|
-
if (Object.keys(onlycombinaisonStats).length === 0) return;
|
|
1553
|
-
const allStats = Object.keys(template.statistics).filter(
|
|
1554
|
-
(stat) => !template.statistics[stat].combinaison
|
|
1555
|
-
);
|
|
1556
|
-
if (allStats.length === 0) throw new NoStatisticsError();
|
|
1557
|
-
const error = [];
|
|
1558
|
-
for (const [stat, value] of Object.entries(onlycombinaisonStats)) {
|
|
1559
|
-
let formula = value.combinaison;
|
|
1560
|
-
for (const [other, data] of Object.entries(allOtherStats)) {
|
|
1561
|
-
const { max, min } = data;
|
|
1562
|
-
const total = template.total || 100;
|
|
1563
|
-
const randomStatValue = generateRandomStat(total, max, min, engine);
|
|
1564
|
-
const regex = new RegExp(other, "gi");
|
|
1565
|
-
formula = formula.replace(regex, randomStatValue.toString());
|
|
1566
|
-
}
|
|
1567
|
-
try {
|
|
1568
|
-
(0, import_mathjs9.evaluate)(formula);
|
|
1569
|
-
} catch (e) {
|
|
1570
|
-
error.push(stat);
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
if (error.length > 0) throw new FormulaError(error.join(", "), "testStatCombinaison");
|
|
1574
|
-
return;
|
|
1575
|
-
}
|
|
1576
|
-
function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto) {
|
|
1577
|
-
let randomStatValue = total + 1;
|
|
1578
|
-
const random = new import_random_js2.Random(engine || import_rpg_dice_roller8.NumberGenerator.engines.nodeCrypto);
|
|
1579
|
-
while (randomStatValue >= total || randomStatValue === 0) {
|
|
1580
|
-
if (max && min) randomStatValue = randomInt(min, max, engine, random);
|
|
1581
|
-
else if (max) randomStatValue = randomInt(1, max, engine, random);
|
|
1582
|
-
else if (min) randomStatValue = randomInt(min, total, engine, random);
|
|
1583
|
-
else randomStatValue = randomInt(1, total, engine, random);
|
|
1584
|
-
}
|
|
1585
|
-
return randomStatValue;
|
|
1586
|
-
}
|
|
1587
1663
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1588
1664
|
0 && (module.exports = {
|
|
1589
1665
|
COMMENT_REGEX,
|
|
@@ -1626,7 +1702,9 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
1626
1702
|
replaceFormulaInDice,
|
|
1627
1703
|
replaceInFormula,
|
|
1628
1704
|
replaceUnknown,
|
|
1705
|
+
resolveFormulaHint,
|
|
1629
1706
|
roll,
|
|
1707
|
+
splitDiceComment,
|
|
1630
1708
|
standardizeDice,
|
|
1631
1709
|
templateSchema,
|
|
1632
1710
|
testDiceRegistered,
|