@dicelette/core 1.23.0 → 1.24.0
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 +169 -73
- package/dist/index.d.ts +169 -73
- package/dist/index.js +695 -308
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +675 -308
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
COMMENT_REGEX: () => COMMENT_REGEX,
|
|
24
24
|
DETECT_CRITICAL: () => DETECT_CRITICAL,
|
|
25
25
|
DiceTypeError: () => DiceTypeError,
|
|
26
|
+
EXPLODING_SUCCESS_REGEX: () => EXPLODING_SUCCESS_REGEX,
|
|
26
27
|
EmptyObjectError: () => EmptyObjectError,
|
|
27
28
|
FormulaError: () => FormulaError,
|
|
28
29
|
MaxGreater: () => MaxGreater,
|
|
@@ -31,9 +32,14 @@ __export(index_exports, {
|
|
|
31
32
|
SIGN_REGEX: () => SIGN_REGEX,
|
|
32
33
|
SIGN_REGEX_SPACE: () => SIGN_REGEX_SPACE,
|
|
33
34
|
SYMBOL_DICE: () => SYMBOL_DICE,
|
|
35
|
+
SortOrder: () => SortOrder,
|
|
34
36
|
TooManyDice: () => TooManyDice,
|
|
35
37
|
TooManyStats: () => TooManyStats,
|
|
36
38
|
calculator: () => calculator,
|
|
39
|
+
canComparisonFail: () => canComparisonFail,
|
|
40
|
+
canComparisonSucceed: () => canComparisonSucceed,
|
|
41
|
+
compareSignFormule: () => compareSignFormule,
|
|
42
|
+
countExplodingSuccesses: () => countExplodingSuccesses,
|
|
37
43
|
createCriticalCustom: () => createCriticalCustom,
|
|
38
44
|
diceRandomParse: () => diceRandomParse,
|
|
39
45
|
diceTypeRandomParse: () => diceTypeRandomParse,
|
|
@@ -41,15 +47,29 @@ __export(index_exports, {
|
|
|
41
47
|
evalCombinaison: () => evalCombinaison,
|
|
42
48
|
evalOneCombinaison: () => evalOneCombinaison,
|
|
43
49
|
evalStatsDice: () => evalStatsDice,
|
|
50
|
+
extractValuesFromOutput: () => extractValuesFromOutput,
|
|
51
|
+
fixParenthesis: () => fixParenthesis,
|
|
52
|
+
formatComment: () => formatComment,
|
|
44
53
|
generateRandomStat: () => generateRandomStat,
|
|
45
54
|
generateStatsDice: () => generateStatsDice,
|
|
55
|
+
getCompare: () => getCompare,
|
|
46
56
|
getEngine: () => getEngine,
|
|
47
57
|
getEngineId: () => getEngineId,
|
|
58
|
+
getModifier: () => getModifier,
|
|
59
|
+
getRollBounds: () => getRollBounds,
|
|
60
|
+
inverseSign: () => inverseSign,
|
|
48
61
|
isNumber: () => isNumber,
|
|
62
|
+
isTrivialComparison: () => isTrivialComparison,
|
|
63
|
+
matchComparison: () => matchComparison,
|
|
64
|
+
normalizeExplodingSuccess: () => normalizeExplodingSuccess,
|
|
49
65
|
randomInt: () => randomInt,
|
|
50
66
|
replaceExpByRandom: () => replaceExpByRandom,
|
|
51
67
|
replaceFormulaInDice: () => replaceFormulaInDice,
|
|
68
|
+
replaceInFormula: () => replaceInFormula,
|
|
69
|
+
replaceText: () => replaceText,
|
|
70
|
+
replaceUnwantedText: () => replaceUnwantedText,
|
|
52
71
|
roll: () => roll,
|
|
72
|
+
rollCompare: () => rollCompare,
|
|
53
73
|
standardizeDice: () => standardizeDice,
|
|
54
74
|
templateSchema: () => templateSchema,
|
|
55
75
|
testDiceRegistered: () => testDiceRegistered,
|
|
@@ -58,140 +78,178 @@ __export(index_exports, {
|
|
|
58
78
|
});
|
|
59
79
|
module.exports = __toCommonJS(index_exports);
|
|
60
80
|
|
|
61
|
-
// src/dice.ts
|
|
62
|
-
var import_rpg_dice_roller = require("@dice-roller/rpg-dice-roller");
|
|
81
|
+
// src/dice/calculator.ts
|
|
63
82
|
var import_mathjs = require("mathjs");
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return !canSucceed || !canFail;
|
|
68
|
-
}
|
|
69
|
-
function canComparisonFail(maxRollValue, compare, minRollValue = 1) {
|
|
70
|
-
switch (compare.sign) {
|
|
71
|
-
case ">":
|
|
72
|
-
return minRollValue <= compare.value;
|
|
73
|
-
// failure if roll <= value
|
|
74
|
-
case ">=":
|
|
75
|
-
return minRollValue < compare.value;
|
|
76
|
-
// failure if roll < value
|
|
77
|
-
case "<":
|
|
78
|
-
return maxRollValue >= compare.value;
|
|
79
|
-
// failure if roll >= value
|
|
80
|
-
case "<=":
|
|
81
|
-
return maxRollValue > compare.value;
|
|
82
|
-
// failure if roll > value
|
|
83
|
-
case "=":
|
|
84
|
-
case "==":
|
|
85
|
-
return minRollValue !== compare.value || maxRollValue !== compare.value;
|
|
86
|
-
// can differ
|
|
87
|
-
case "!=":
|
|
88
|
-
return minRollValue <= compare.value && compare.value <= maxRollValue;
|
|
89
|
-
// equality possible
|
|
90
|
-
default:
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function getCompare(dice, compareRegex, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity) {
|
|
95
|
-
if (dice.match(/((\{.*,(.*)+\}|([><=!]+\d+f))([><=]|!=)+\d+\}?)|\{(.*)(([><=]|!=)+).*\}/))
|
|
96
|
-
return { dice, compare: void 0 };
|
|
97
|
-
dice = dice.replace(SIGN_REGEX_SPACE, "");
|
|
98
|
-
let compare;
|
|
99
|
-
const calc = compareRegex[2];
|
|
100
|
-
const sign = calc.match(/[+-/*^]/)?.[0];
|
|
101
|
-
const compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];
|
|
102
|
-
if (sign) {
|
|
103
|
-
const toCalc = calc.replace(SIGN_REGEX, "").replace(/\s/g, "").replace(/;(.*)/, "");
|
|
104
|
-
const rCompare = rollCompare(toCalc, engine, pity);
|
|
105
|
-
const total = (0, import_mathjs.evaluate)(rCompare.value.toString());
|
|
106
|
-
dice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);
|
|
107
|
-
compare = {
|
|
108
|
-
sign: compareSign,
|
|
109
|
-
value: total,
|
|
110
|
-
originalDice: rCompare.dice,
|
|
111
|
-
rollValue: rCompare.diceResult
|
|
112
|
-
};
|
|
113
|
-
} else {
|
|
114
|
-
const rcompare = rollCompare(calc, engine, pity);
|
|
115
|
-
compare = {
|
|
116
|
-
sign: compareSign,
|
|
117
|
-
value: rcompare.value,
|
|
118
|
-
originalDice: rcompare.dice,
|
|
119
|
-
rollValue: rcompare.diceResult
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
return { dice, compare };
|
|
123
|
-
}
|
|
124
|
-
function rollCompare(value, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity) {
|
|
125
|
-
if (isNumber(value)) return { value: Number.parseInt(value, 10) };
|
|
126
|
-
if (!value || typeof value === "string" && value.trim() === "") {
|
|
127
|
-
return { value: 0, diceResult: value };
|
|
128
|
-
}
|
|
129
|
-
const rollComp = roll(value, engine, pity);
|
|
130
|
-
if (!rollComp?.total) {
|
|
131
|
-
try {
|
|
132
|
-
return { value: (0, import_mathjs.evaluate)(value), diceResult: value };
|
|
133
|
-
} catch (error) {
|
|
134
|
-
return { value: 0, diceResult: value };
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
dice: value,
|
|
139
|
-
value: rollComp.total,
|
|
140
|
-
diceResult: rollComp?.result
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
function createCriticalCustom(dice, customCritical, template, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto) {
|
|
144
|
-
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
145
|
-
let customDice = dice;
|
|
146
|
-
const compareValue = diceTypeRandomParse(customCritical.value, template, engine);
|
|
147
|
-
if (compareValue.includes("$"))
|
|
148
|
-
throw new DiceTypeError(compareValue, "createCriticalCustom");
|
|
149
|
-
const comparaison = `${customCritical.sign}${compareValue}`;
|
|
150
|
-
if (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);
|
|
151
|
-
else customDice += comparaison;
|
|
152
|
-
return diceTypeRandomParse(customDice, template, engine);
|
|
153
|
-
}
|
|
154
|
-
function getModifier(dice) {
|
|
155
|
-
const modifier = dice.matchAll(/(\+|-|%|\/|\^|\*|\*{2})(\d+)/gi);
|
|
156
|
-
let modificator;
|
|
157
|
-
for (const mod of modifier) {
|
|
158
|
-
if (modificator) {
|
|
159
|
-
const sign = modificator.sign;
|
|
160
|
-
let value = modificator.value;
|
|
161
|
-
if (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));
|
|
162
|
-
modificator = {
|
|
163
|
-
sign: mod[1],
|
|
164
|
-
value
|
|
165
|
-
};
|
|
166
|
-
} else {
|
|
167
|
-
modificator = {
|
|
168
|
-
sign: mod[1],
|
|
169
|
-
value: Number.parseInt(mod[2], 10)
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return modificator;
|
|
83
|
+
function calculator(sign, value, total) {
|
|
84
|
+
if (sign === "^") sign = "**";
|
|
85
|
+
return (0, import_mathjs.evaluate)(`${total} ${sign} ${value}`);
|
|
174
86
|
}
|
|
175
|
-
|
|
87
|
+
|
|
88
|
+
// src/dice/compare.ts
|
|
89
|
+
var import_rpg_dice_roller2 = require("@dice-roller/rpg-dice-roller");
|
|
90
|
+
var import_mathjs3 = require("mathjs");
|
|
91
|
+
|
|
92
|
+
// src/interfaces/constant.ts
|
|
93
|
+
var COMMENT_REGEX = /\s+(#|\/{2}|\[|\/\*)(?<comment>.*)/gi;
|
|
94
|
+
var SIGN_REGEX = /==|!=|(?<![!<>])>=|(?<![!<>])<=|(?<!!)(?<![<>])>|(?<!!)(?<![<>])<|(?<!!)(?<![<>])=/;
|
|
95
|
+
var SIGN_REGEX_SPACE = /(==|!=|(?<![!<>])>=|(?<![!<>])<=|(?<!!)(?<![<>])>|(?<!!)(?<![<>])<|(?<!!)(?<![<>])=)(\S+)/;
|
|
96
|
+
var SYMBOL_DICE = "&";
|
|
97
|
+
var DETECT_CRITICAL = /\{\*?c[fs]:([<>=]|!=)+(.+?)}/gim;
|
|
98
|
+
var OPTIONAL_COMMENT = /\s+(#|\/{2}|\[|\/\*)?(?<comment>.*)/gi;
|
|
99
|
+
|
|
100
|
+
// src/roll.ts
|
|
101
|
+
var import_rpg_dice_roller = require("@dice-roller/rpg-dice-roller");
|
|
102
|
+
var import_mathjs2 = require("mathjs");
|
|
103
|
+
function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity, sort) {
|
|
104
|
+
if (sort === "none" /* None */) sort = void 0;
|
|
176
105
|
dice = standardizeDice(replaceFormulaInDice(dice)).replace(/^\+/, "").replaceAll("=>", ">=").replaceAll("=<", "<=").trimStart();
|
|
177
106
|
if (!dice.includes("d")) return void 0;
|
|
178
107
|
dice = dice.replaceAll(DETECT_CRITICAL, "").trimEnd();
|
|
108
|
+
const explodingSuccess = normalizeExplodingSuccess(dice);
|
|
109
|
+
if (explodingSuccess) dice = explodingSuccess.dice;
|
|
110
|
+
let diceDisplay;
|
|
111
|
+
if (dice.includes(";")) {
|
|
112
|
+
const mainDice = dice.split(";")[0];
|
|
113
|
+
diceDisplay = explodingSuccess?.originalDice ?? mainDice;
|
|
114
|
+
} else diceDisplay = explodingSuccess?.originalDice ?? dice;
|
|
115
|
+
const curlyBulkMatch = dice.match(/^\{(\d+#.*)\}$/);
|
|
116
|
+
const isCurlyBulk = !!curlyBulkMatch;
|
|
117
|
+
let bulkContent = "";
|
|
118
|
+
if (isCurlyBulk) bulkContent = curlyBulkMatch[1];
|
|
179
119
|
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
180
120
|
let compare;
|
|
181
|
-
if (dice.includes(";"))
|
|
121
|
+
if (dice.includes(";"))
|
|
122
|
+
return sharedRolls(dice, engine, pity, explodingSuccess, diceDisplay);
|
|
182
123
|
dice = fixParenthesis(dice);
|
|
183
124
|
const modificator = getModifier(dice);
|
|
184
|
-
if (compareRegex) {
|
|
125
|
+
if (compareRegex && !isCurlyBulk) {
|
|
185
126
|
const compareResult = getCompare(dice, compareRegex, engine, pity);
|
|
186
127
|
dice = compareResult.dice;
|
|
187
128
|
compare = compareResult.compare;
|
|
188
129
|
}
|
|
189
|
-
|
|
190
|
-
|
|
130
|
+
const bulkProcessContent = isCurlyBulk ? bulkContent : dice;
|
|
131
|
+
if (bulkProcessContent.match(/\d+?#(.*)/)) {
|
|
132
|
+
const diceArray = bulkProcessContent.split("#");
|
|
191
133
|
const numberOfDice = Number.parseInt(diceArray[0], 10);
|
|
192
|
-
|
|
134
|
+
let diceToRoll = diceArray[1].replace(COMMENT_REGEX, "");
|
|
193
135
|
const commentsMatch = diceArray[1].match(COMMENT_REGEX);
|
|
194
136
|
const comments = commentsMatch ? commentsMatch[2] : void 0;
|
|
137
|
+
let curlyCompare;
|
|
138
|
+
if (isCurlyBulk) {
|
|
139
|
+
const curlyCompareRegex = diceToRoll.match(SIGN_REGEX_SPACE);
|
|
140
|
+
if (curlyCompareRegex) {
|
|
141
|
+
const compareSign = curlyCompareRegex[0].match(SIGN_REGEX)?.[0];
|
|
142
|
+
const compareValue = curlyCompareRegex[2];
|
|
143
|
+
if (compareSign && compareValue) {
|
|
144
|
+
curlyCompare = {
|
|
145
|
+
sign: compareSign,
|
|
146
|
+
value: Number.parseInt(compareValue, 10)
|
|
147
|
+
};
|
|
148
|
+
diceToRoll = diceToRoll.replace(SIGN_REGEX_SPACE, "");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (sort) diceToRoll = `${diceToRoll}${sort}`;
|
|
153
|
+
const activeCompare = compare || curlyCompare || (explodingSuccess ? { sign: explodingSuccess.sign, value: explodingSuccess.value } : void 0);
|
|
154
|
+
let trivialComparisonDetected = false;
|
|
155
|
+
if (activeCompare) {
|
|
156
|
+
const results = [];
|
|
157
|
+
let successCount = 0;
|
|
158
|
+
const roller3 = new import_rpg_dice_roller.DiceRoller();
|
|
159
|
+
import_rpg_dice_roller.NumberGenerator.generator.engine = engine;
|
|
160
|
+
const formatOutput = (output, addStar) => {
|
|
161
|
+
const formatted = addStar && isCurlyBulk ? output.replace(
|
|
162
|
+
/\[([^\]]+)\]/,
|
|
163
|
+
(_m, content) => `[${content.split(",").map((d) => `${d.trim()}*`).join(", ")}]`
|
|
164
|
+
) : output;
|
|
165
|
+
return curlyCompare ? formatted.replace(/^([^:]+):/, `$1${curlyCompare.sign}${curlyCompare.value}:`) : formatted;
|
|
166
|
+
};
|
|
167
|
+
for (let i = 0; i < numberOfDice; i++) {
|
|
168
|
+
try {
|
|
169
|
+
const individualRoll = roller3.roll(diceToRoll);
|
|
170
|
+
const rollInstance = Array.isArray(individualRoll) ? individualRoll[0] : individualRoll;
|
|
171
|
+
if (!trivialComparisonDetected && activeCompare) {
|
|
172
|
+
const { maxTotal, minTotal } = rollInstance;
|
|
173
|
+
trivialComparisonDetected = isTrivialComparison(
|
|
174
|
+
maxTotal,
|
|
175
|
+
minTotal,
|
|
176
|
+
activeCompare
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
const rollOutput = rollInstance.output;
|
|
180
|
+
if (explodingSuccess) {
|
|
181
|
+
const successesForRoll = countExplodingSuccesses(
|
|
182
|
+
rollInstance,
|
|
183
|
+
explodingSuccess.sign,
|
|
184
|
+
explodingSuccess.value
|
|
185
|
+
);
|
|
186
|
+
successCount += successesForRoll;
|
|
187
|
+
let formattedRollOutput = rollOutput.replace(
|
|
188
|
+
explodingSuccess.normalizedSegment,
|
|
189
|
+
explodingSuccess.originalSegment
|
|
190
|
+
).replace(/=\s*-?\d+(?:\.\d+)?$/, `= ${successesForRoll}`);
|
|
191
|
+
formattedRollOutput = formatOutput(formattedRollOutput, false);
|
|
192
|
+
results.push(formattedRollOutput);
|
|
193
|
+
} else {
|
|
194
|
+
const rollTotal = rollInstance.total;
|
|
195
|
+
const isSuccess = (0, import_mathjs2.evaluate)(
|
|
196
|
+
`${rollTotal}${activeCompare.sign}${activeCompare.value}`
|
|
197
|
+
);
|
|
198
|
+
if (isSuccess) successCount++;
|
|
199
|
+
results.push(formatOutput(rollOutput, isSuccess));
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw new DiceTypeError(diceToRoll, "roll", error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const signSource = explodingSuccess?.originalDice ?? diceDisplay ?? dice;
|
|
206
|
+
const explodingMatch = signSource.match(EXPLODING_SUCCESS_REGEX);
|
|
207
|
+
if (explodingMatch) {
|
|
208
|
+
const [, doubledSignRaw, valueStr] = explodingMatch;
|
|
209
|
+
let doubledSign;
|
|
210
|
+
if (doubledSignRaw === "!!==") doubledSign = "==";
|
|
211
|
+
else if (doubledSignRaw === "!==") doubledSign = "!==";
|
|
212
|
+
else doubledSign = doubledSignRaw.replace(/^!/, "");
|
|
213
|
+
const signMap = {
|
|
214
|
+
">>": ">",
|
|
215
|
+
"<<": "<",
|
|
216
|
+
">>=": ">=",
|
|
217
|
+
"<<=": "<=",
|
|
218
|
+
"==": "=",
|
|
219
|
+
"!==": "!=",
|
|
220
|
+
"!!==": "="
|
|
221
|
+
};
|
|
222
|
+
const mappedSign = signMap[doubledSign];
|
|
223
|
+
const mappedValue = Number.parseFloat(valueStr);
|
|
224
|
+
if (mappedSign && !Number.isNaN(mappedValue)) {
|
|
225
|
+
const resultsString = replaceUnwantedText(results.join("; "));
|
|
226
|
+
const flatValues = resultsString.split(";").flatMap((segment) => extractValuesFromOutput(segment));
|
|
227
|
+
if (mappedSign === "!=") {
|
|
228
|
+
const equalsCount = flatValues.filter((val) => val === mappedValue).length;
|
|
229
|
+
successCount = flatValues.length - equalsCount;
|
|
230
|
+
} else {
|
|
231
|
+
successCount = flatValues.filter(
|
|
232
|
+
(val) => matchComparison(mappedSign, val, mappedValue)
|
|
233
|
+
).length;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (compare && trivialComparisonDetected) compare.trivial = true;
|
|
238
|
+
const finalDice2 = isCurlyBulk ? `{${diceToRoll}${curlyCompare?.sign}${curlyCompare?.value}}` : diceToRoll;
|
|
239
|
+
const resultOutput2 = replaceUnwantedText(results.join("; "));
|
|
240
|
+
const finalTotal = explodingSuccess ? resultOutput2.split(";").flatMap((segment) => extractValuesFromOutput(segment)).filter(
|
|
241
|
+
(val) => matchComparison(explodingSuccess.sign, val, explodingSuccess.value)
|
|
242
|
+
).length : successCount;
|
|
243
|
+
return {
|
|
244
|
+
dice: explodingSuccess ? diceDisplay : finalDice2,
|
|
245
|
+
result: resultOutput2,
|
|
246
|
+
comment: comments,
|
|
247
|
+
compare: isCurlyBulk ? void 0 : compare,
|
|
248
|
+
modifier: modificator,
|
|
249
|
+
total: finalTotal,
|
|
250
|
+
trivial: trivialComparisonDetected ? true : void 0
|
|
251
|
+
};
|
|
252
|
+
}
|
|
195
253
|
const roller2 = new import_rpg_dice_roller.DiceRoller();
|
|
196
254
|
import_rpg_dice_roller.NumberGenerator.generator.engine = engine;
|
|
197
255
|
for (let i = 0; i < numberOfDice; i++) {
|
|
@@ -201,9 +259,10 @@ function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.node
|
|
|
201
259
|
throw new DiceTypeError(diceToRoll, "roll", error);
|
|
202
260
|
}
|
|
203
261
|
}
|
|
262
|
+
const finalDice = isCurlyBulk ? `{${diceToRoll}}` : diceToRoll;
|
|
204
263
|
return {
|
|
205
|
-
dice:
|
|
206
|
-
result: roller2.output,
|
|
264
|
+
dice: finalDice,
|
|
265
|
+
result: replaceUnwantedText(roller2.output),
|
|
207
266
|
comment: comments,
|
|
208
267
|
compare: compare ? compare : void 0,
|
|
209
268
|
modifier: modificator,
|
|
@@ -212,7 +271,8 @@ function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.node
|
|
|
212
271
|
}
|
|
213
272
|
const roller = new import_rpg_dice_roller.DiceRoller();
|
|
214
273
|
import_rpg_dice_roller.NumberGenerator.generator.engine = engine;
|
|
215
|
-
|
|
274
|
+
let diceWithoutComment = dice.replace(COMMENT_REGEX, "").trimEnd();
|
|
275
|
+
if (sort) diceWithoutComment = `${diceWithoutComment}${sort}`;
|
|
216
276
|
let diceRoll;
|
|
217
277
|
try {
|
|
218
278
|
diceRoll = roller.roll(diceWithoutComment);
|
|
@@ -235,7 +295,7 @@ function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.node
|
|
|
235
295
|
const maxPossible = currentRoll ? currentRoll.maxTotal : null;
|
|
236
296
|
const isComparisonPossible = maxPossible === null || canComparisonSucceed(maxPossible, compare);
|
|
237
297
|
if (isComparisonPossible) {
|
|
238
|
-
let isFail = (0,
|
|
298
|
+
let isFail = (0, import_mathjs2.evaluate)(`${roller.total}${compare.sign}${compare.value}`);
|
|
239
299
|
if (!isFail) {
|
|
240
300
|
const maxReroll = 100;
|
|
241
301
|
while (!isFail && rerollCount < maxReroll) {
|
|
@@ -246,7 +306,7 @@ function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.node
|
|
|
246
306
|
}
|
|
247
307
|
rerollCount++;
|
|
248
308
|
if (res && res.total !== void 0)
|
|
249
|
-
isFail = (0,
|
|
309
|
+
isFail = (0, import_mathjs2.evaluate)(`${res.total}${compare.sign}${compare.value}`);
|
|
250
310
|
}
|
|
251
311
|
if (res) {
|
|
252
312
|
return {
|
|
@@ -255,21 +315,262 @@ function roll(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.node
|
|
|
255
315
|
comment,
|
|
256
316
|
compare,
|
|
257
317
|
modifier: modificator,
|
|
258
|
-
pityLogs: rerollCount
|
|
318
|
+
pityLogs: rerollCount,
|
|
319
|
+
trivial: res.trivial ?? (compare?.trivial ? true : void 0)
|
|
259
320
|
};
|
|
260
321
|
}
|
|
261
322
|
}
|
|
262
|
-
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
let resultOutput = replaceUnwantedText(roller.output);
|
|
326
|
+
if (explodingSuccess) {
|
|
327
|
+
const successes = countExplodingSuccesses(
|
|
328
|
+
diceRoll,
|
|
329
|
+
explodingSuccess.sign,
|
|
330
|
+
explodingSuccess.value
|
|
331
|
+
);
|
|
332
|
+
resultOutput = resultOutput.replace(/=\s*-?\d+(?:\.\d+)?$/, `= ${successes}`).replace(explodingSuccess.normalizedSegment, explodingSuccess.originalSegment);
|
|
333
|
+
return {
|
|
334
|
+
dice: diceDisplay,
|
|
335
|
+
result: resultOutput,
|
|
336
|
+
comment,
|
|
337
|
+
compare: compare ? compare : void 0,
|
|
338
|
+
modifier: modificator,
|
|
339
|
+
total: successes,
|
|
340
|
+
pityLogs: rerollCount > 0 ? rerollCount : void 0,
|
|
341
|
+
trivial: compare?.trivial ? true : void 0
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
return {
|
|
345
|
+
dice,
|
|
346
|
+
result: resultOutput,
|
|
347
|
+
comment,
|
|
348
|
+
compare: compare ? compare : void 0,
|
|
349
|
+
modifier: modificator,
|
|
350
|
+
total: roller.total,
|
|
351
|
+
pityLogs: rerollCount > 0 ? rerollCount : void 0,
|
|
352
|
+
trivial: compare?.trivial ? true : void 0
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function sharedRolls(dice, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity, explodingSuccessMain, diceDisplay) {
|
|
356
|
+
if (!explodingSuccessMain) {
|
|
357
|
+
explodingSuccessMain = normalizeExplodingSuccess(dice.split(";")[0] ?? dice);
|
|
358
|
+
}
|
|
359
|
+
if (explodingSuccessMain) {
|
|
360
|
+
dice = dice.replace(explodingSuccessMain.originalSegment, "!");
|
|
361
|
+
}
|
|
362
|
+
if (dice.match(/\d+?#(.*?)/))
|
|
363
|
+
throw new DiceTypeError(
|
|
364
|
+
dice,
|
|
365
|
+
"noBulkRoll",
|
|
366
|
+
"bulk roll are not allowed in shared rolls"
|
|
367
|
+
);
|
|
368
|
+
const results = [];
|
|
369
|
+
const mainComment = /\s+#(?<comment>.*)/.exec(dice)?.groups?.comment?.trimEnd() ?? void 0;
|
|
370
|
+
const split = dice.split(";");
|
|
371
|
+
const displayDice = diceDisplay ?? explodingSuccessMain?.originalDice ?? split[0];
|
|
372
|
+
let diceMain = fixParenthesis(split[0]);
|
|
373
|
+
const commentsRegex = /\[(?<comments>.*?)\]/gi;
|
|
374
|
+
const comments = formatComment(diceMain);
|
|
375
|
+
const diceMainWithoutComments = diceMain.replace(commentsRegex, "").trim();
|
|
376
|
+
const toHideRegex = /\((?<dice>[^)]+)\)/;
|
|
377
|
+
const toHide = toHideRegex.exec(diceMainWithoutComments)?.groups;
|
|
378
|
+
let hidden = false;
|
|
379
|
+
if (toHide?.dice) {
|
|
380
|
+
diceMain = toHide.dice;
|
|
381
|
+
hidden = true;
|
|
382
|
+
} else if (toHide) {
|
|
383
|
+
diceMain = "1d1";
|
|
384
|
+
hidden = true;
|
|
385
|
+
} else {
|
|
386
|
+
diceMain = diceMainWithoutComments;
|
|
387
|
+
}
|
|
388
|
+
const rollBounds = getRollBounds(diceMain, engine);
|
|
389
|
+
let diceResult = roll(diceMain, engine, pity);
|
|
390
|
+
if (!diceResult || !diceResult.total) {
|
|
391
|
+
if (hidden) {
|
|
392
|
+
diceResult = roll(fixParenthesis(split[0]), engine, pity);
|
|
393
|
+
hidden = false;
|
|
394
|
+
} else return void 0;
|
|
395
|
+
}
|
|
396
|
+
if (!diceResult || !diceResult.total) return void 0;
|
|
397
|
+
if (explodingSuccessMain && diceResult.result) {
|
|
398
|
+
const values = extractValuesFromOutput(diceResult.result);
|
|
399
|
+
diceResult.total = values.filter(
|
|
400
|
+
(v) => matchComparison(explodingSuccessMain.sign, v, explodingSuccessMain.value)
|
|
401
|
+
).length;
|
|
402
|
+
}
|
|
403
|
+
let aggregatedCompare = diceResult.compare;
|
|
404
|
+
let hasTrivialComparison = diceResult.compare?.trivial === true;
|
|
405
|
+
results.push(`\u203B ${comments}${diceResult.result}`);
|
|
406
|
+
let total = diceResult.total;
|
|
407
|
+
diceResult.comment = mainComment;
|
|
408
|
+
if (!total) {
|
|
409
|
+
return {
|
|
410
|
+
dice: displayDice,
|
|
411
|
+
result: results.join(";"),
|
|
412
|
+
comment: mainComment,
|
|
413
|
+
compare: aggregatedCompare,
|
|
414
|
+
modifier: diceResult.modifier,
|
|
415
|
+
total,
|
|
416
|
+
trivial: hasTrivialComparison ? true : void 0
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
for (let element of split.slice(1)) {
|
|
420
|
+
const comment = formatComment(element);
|
|
421
|
+
element = element.replaceAll(commentsRegex, "").replaceAll(OPTIONAL_COMMENT, "").trim();
|
|
422
|
+
let toRoll = element.replace(SYMBOL_DICE, `${diceResult.total}`);
|
|
423
|
+
const compareRegex = toRoll.match(SIGN_REGEX_SPACE);
|
|
424
|
+
if (compareRegex) {
|
|
425
|
+
const compareResult = compareSignFormule(
|
|
426
|
+
toRoll,
|
|
427
|
+
compareRegex,
|
|
428
|
+
element,
|
|
429
|
+
diceResult,
|
|
430
|
+
engine,
|
|
431
|
+
pity,
|
|
432
|
+
rollBounds
|
|
433
|
+
);
|
|
434
|
+
toRoll = compareResult.dice;
|
|
435
|
+
results.push(compareResult.results);
|
|
436
|
+
if (!aggregatedCompare && compareResult.compare)
|
|
437
|
+
aggregatedCompare = compareResult.compare;
|
|
438
|
+
if (compareResult.trivial) hasTrivialComparison = true;
|
|
439
|
+
} else {
|
|
440
|
+
const { formule, diceAll } = replaceText(
|
|
441
|
+
element,
|
|
442
|
+
diceResult.total,
|
|
443
|
+
diceResult.dice
|
|
444
|
+
);
|
|
445
|
+
try {
|
|
446
|
+
const evaluated = (0, import_mathjs2.evaluate)(toRoll);
|
|
447
|
+
results.push(`\u25C8 ${comment}${diceAll}: ${formule} = ${evaluated}`);
|
|
448
|
+
total += Number.parseInt(evaluated, 10);
|
|
449
|
+
} catch (error) {
|
|
450
|
+
const evaluated = roll(toRoll, engine, pity);
|
|
451
|
+
if (evaluated) {
|
|
452
|
+
results.push(
|
|
453
|
+
`\u25C8 ${comment}${diceAll}: ${evaluated.result.split(":").slice(1).join(":")}`
|
|
454
|
+
);
|
|
455
|
+
if (!aggregatedCompare && evaluated.compare)
|
|
456
|
+
aggregatedCompare = evaluated.compare;
|
|
457
|
+
if (evaluated.compare?.trivial) hasTrivialComparison = true;
|
|
458
|
+
} else results.push(`\u25C8 ${comment}${diceAll}: ${formule} = ${evaluated}`);
|
|
459
|
+
total += evaluated?.total ?? 0;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (hidden)
|
|
464
|
+
results.shift();
|
|
465
|
+
return {
|
|
466
|
+
dice: displayDice,
|
|
467
|
+
result: results.join(";"),
|
|
468
|
+
comment: mainComment,
|
|
469
|
+
compare: hasTrivialComparison && aggregatedCompare ? { ...aggregatedCompare, trivial: true } : aggregatedCompare,
|
|
470
|
+
modifier: diceResult.modifier,
|
|
471
|
+
total,
|
|
472
|
+
trivial: hasTrivialComparison ? true : void 0
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
function replaceInFormula(element, diceResult, compareResult, res, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity) {
|
|
476
|
+
const { formule, diceAll } = replaceText(
|
|
477
|
+
element,
|
|
478
|
+
diceResult.total ?? 0,
|
|
479
|
+
diceResult.dice
|
|
480
|
+
);
|
|
481
|
+
const validSign = res ? "\u2713" : "\u2715";
|
|
482
|
+
const invertedSign = res ? compareResult.compare.sign : inverseSign(compareResult.compare.sign);
|
|
483
|
+
let evaluateRoll;
|
|
484
|
+
try {
|
|
485
|
+
evaluateRoll = (0, import_mathjs2.evaluate)(compareResult.dice);
|
|
486
|
+
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;
|
|
487
|
+
} catch (error) {
|
|
488
|
+
const evaluateRoll2 = roll(compareResult.dice, engine, pity);
|
|
489
|
+
if (evaluateRoll2)
|
|
490
|
+
return `${validSign} ${diceAll}: ${evaluateRoll2.result.split(":").splice(1).join(":")}`;
|
|
491
|
+
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll2}${invertedSign}${compareResult.compare?.value}`;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function rollCompare(value, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity) {
|
|
495
|
+
if (isNumber(value)) return { value: Number.parseInt(value, 10) };
|
|
496
|
+
if (!value || typeof value === "string" && value.trim() === "") {
|
|
497
|
+
return { value: 0, diceResult: value };
|
|
498
|
+
}
|
|
499
|
+
const rollComp = roll(value, engine, pity);
|
|
500
|
+
if (!rollComp?.total) {
|
|
501
|
+
try {
|
|
502
|
+
return { value: (0, import_mathjs2.evaluate)(value), diceResult: value };
|
|
503
|
+
} catch (error) {
|
|
504
|
+
return { value: 0, diceResult: value };
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
dice: value,
|
|
509
|
+
value: rollComp.total,
|
|
510
|
+
diceResult: rollComp?.result
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// src/dice/compare.ts
|
|
515
|
+
function isTrivialComparison(maxValue, minValue, compare) {
|
|
516
|
+
const canSucceed = canComparisonSucceed(maxValue, compare, minValue);
|
|
517
|
+
const canFail = canComparisonFail(maxValue, compare, minValue);
|
|
518
|
+
return !canSucceed || !canFail;
|
|
519
|
+
}
|
|
520
|
+
function canComparisonFail(maxRollValue, compare, minRollValue = 1) {
|
|
521
|
+
switch (compare.sign) {
|
|
522
|
+
case ">":
|
|
523
|
+
return minRollValue <= compare.value;
|
|
524
|
+
// failure if roll <= value
|
|
525
|
+
case ">=":
|
|
526
|
+
return minRollValue < compare.value;
|
|
527
|
+
// failure if roll < value
|
|
528
|
+
case "<":
|
|
529
|
+
return maxRollValue >= compare.value;
|
|
530
|
+
// failure if roll >= value
|
|
531
|
+
case "<=":
|
|
532
|
+
return maxRollValue > compare.value;
|
|
533
|
+
// failure if roll > value
|
|
534
|
+
case "=":
|
|
535
|
+
case "==":
|
|
536
|
+
return minRollValue !== compare.value || maxRollValue !== compare.value;
|
|
537
|
+
// can differ
|
|
538
|
+
case "!=":
|
|
539
|
+
return minRollValue <= compare.value && compare.value <= maxRollValue;
|
|
540
|
+
// equality possible
|
|
541
|
+
default:
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function getCompare(dice, compareRegex, engine = import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto, pity) {
|
|
546
|
+
if (dice.match(/((\{.*,(.*)+\}|([><=!]+\d+f))([><=]|!=)+\d+\}?)|\{(.*)(([><=]|!=)+).*\}/))
|
|
547
|
+
return { dice, compare: void 0 };
|
|
548
|
+
dice = dice.replace(SIGN_REGEX_SPACE, "");
|
|
549
|
+
let compare;
|
|
550
|
+
const calc = compareRegex[2];
|
|
551
|
+
const sign = calc.match(/[+-/*^]/)?.[0];
|
|
552
|
+
const compareSign = compareRegex[0].match(SIGN_REGEX)?.[0];
|
|
553
|
+
if (sign) {
|
|
554
|
+
const toCalc = calc.replace(SIGN_REGEX, "").replace(/\s/g, "").replace(/;(.*)/, "");
|
|
555
|
+
const rCompare = rollCompare(toCalc, engine, pity);
|
|
556
|
+
const total = (0, import_mathjs3.evaluate)(rCompare.value.toString());
|
|
557
|
+
dice = dice.replace(SIGN_REGEX_SPACE, `${compareSign}${total}`);
|
|
558
|
+
compare = {
|
|
559
|
+
sign: compareSign,
|
|
560
|
+
value: total,
|
|
561
|
+
originalDice: rCompare.dice,
|
|
562
|
+
rollValue: rCompare.diceResult
|
|
563
|
+
};
|
|
564
|
+
} else {
|
|
565
|
+
const rcompare = rollCompare(calc, engine, pity);
|
|
566
|
+
compare = {
|
|
567
|
+
sign: compareSign,
|
|
568
|
+
value: rcompare.value,
|
|
569
|
+
originalDice: rcompare.dice,
|
|
570
|
+
rollValue: rcompare.diceResult
|
|
571
|
+
};
|
|
263
572
|
}
|
|
264
|
-
return {
|
|
265
|
-
dice,
|
|
266
|
-
result: roller.output,
|
|
267
|
-
comment,
|
|
268
|
-
compare: compare ? compare : void 0,
|
|
269
|
-
modifier: modificator,
|
|
270
|
-
total: roller.total,
|
|
271
|
-
pityLogs: rerollCount > 0 ? rerollCount : void 0
|
|
272
|
-
};
|
|
573
|
+
return { dice, compare };
|
|
273
574
|
}
|
|
274
575
|
function canComparisonSucceed(maxRollValue, compare, minRollValue) {
|
|
275
576
|
switch (compare.sign) {
|
|
@@ -292,13 +593,62 @@ function canComparisonSucceed(maxRollValue, compare, minRollValue) {
|
|
|
292
593
|
return true;
|
|
293
594
|
}
|
|
294
595
|
}
|
|
596
|
+
|
|
597
|
+
// src/dice/exploding.ts
|
|
598
|
+
var import_mathjs5 = require("mathjs");
|
|
599
|
+
|
|
600
|
+
// src/dice/signs.ts
|
|
601
|
+
var import_rpg_dice_roller3 = require("@dice-roller/rpg-dice-roller");
|
|
602
|
+
var import_mathjs4 = require("mathjs");
|
|
603
|
+
|
|
604
|
+
// src/dice/replace.ts
|
|
605
|
+
function replaceUnwantedText(dice) {
|
|
606
|
+
return dice.replaceAll(/[{}]/g, "").replaceAll(/s[ad]/gi, "");
|
|
607
|
+
}
|
|
295
608
|
function fixParenthesis(dice) {
|
|
296
609
|
const parenthesisRegex = /d\((\d+)\)/g;
|
|
297
610
|
return dice.replaceAll(parenthesisRegex, (_match, p1) => `d${p1}`);
|
|
298
611
|
}
|
|
299
|
-
function
|
|
300
|
-
|
|
301
|
-
|
|
612
|
+
function replaceText(element, total, dice) {
|
|
613
|
+
return {
|
|
614
|
+
formule: element.replace(SYMBOL_DICE, `[${total}]`).replace(/%.*%/g, "").trim(),
|
|
615
|
+
diceAll: element.replace(SYMBOL_DICE, `[${dice.replace(COMMENT_REGEX, "")}]`).replace(/%.*%/g, "").trim()
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
function formatComment(dice) {
|
|
619
|
+
const commentsRegex = /\[(?<comments>.*?)\]/;
|
|
620
|
+
const commentsMatch = commentsRegex.exec(dice);
|
|
621
|
+
const comments = commentsMatch?.groups?.comments ? `${commentsMatch.groups.comments}` : "";
|
|
622
|
+
const diceWithoutBrackets = dice.replace(commentsRegex, "");
|
|
623
|
+
const optionalCommentsRegex = /\s+(#|\/\/)(?<comment>.*)/;
|
|
624
|
+
const optionalComments = optionalCommentsRegex.exec(diceWithoutBrackets);
|
|
625
|
+
const optional = optionalComments?.groups?.comment ? `${optionalComments.groups.comment.trim()}` : "";
|
|
626
|
+
let finalComment = "";
|
|
627
|
+
if (comments && optional) finalComment = `__${comments} ${optional}__ \u2014 `;
|
|
628
|
+
else if (comments) finalComment = `__${comments}__ \u2014 `;
|
|
629
|
+
else if (optional) finalComment = `__${optional}__ \u2014 `;
|
|
630
|
+
return finalComment;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// src/dice/signs.ts
|
|
634
|
+
function matchComparison(sign, val, value) {
|
|
635
|
+
switch (sign) {
|
|
636
|
+
case ">":
|
|
637
|
+
return val > value;
|
|
638
|
+
case ">=":
|
|
639
|
+
return val >= value;
|
|
640
|
+
case "<":
|
|
641
|
+
return val < value;
|
|
642
|
+
case "<=":
|
|
643
|
+
return val <= value;
|
|
644
|
+
case "=":
|
|
645
|
+
case "==":
|
|
646
|
+
return val === value;
|
|
647
|
+
case "!=":
|
|
648
|
+
return val !== value;
|
|
649
|
+
default:
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
302
652
|
}
|
|
303
653
|
function inverseSign(sign) {
|
|
304
654
|
switch (sign) {
|
|
@@ -318,155 +668,169 @@ function inverseSign(sign) {
|
|
|
318
668
|
return "==";
|
|
319
669
|
}
|
|
320
670
|
}
|
|
321
|
-
function
|
|
322
|
-
const { formule, diceAll } = replaceText(
|
|
323
|
-
element,
|
|
324
|
-
diceResult.total ?? 0,
|
|
325
|
-
diceResult.dice
|
|
326
|
-
);
|
|
327
|
-
const validSign = res ? "\u2713" : "\u2715";
|
|
328
|
-
const invertedSign = res ? compareResult.compare.sign : inverseSign(compareResult.compare.sign);
|
|
329
|
-
let evaluateRoll;
|
|
330
|
-
try {
|
|
331
|
-
evaluateRoll = (0, import_mathjs.evaluate)(compareResult.dice);
|
|
332
|
-
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll}${invertedSign}${compareResult.compare?.value}`;
|
|
333
|
-
} catch (error) {
|
|
334
|
-
const evaluateRoll2 = roll(compareResult.dice, engine, pity);
|
|
335
|
-
if (evaluateRoll2)
|
|
336
|
-
return `${validSign} ${diceAll}: ${evaluateRoll2.result.split(":").splice(1).join(":")}`;
|
|
337
|
-
return `${validSign} ${diceAll}: ${formule} = ${evaluateRoll2}${invertedSign}${compareResult.compare?.value}`;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
function compareSignFormule(toRoll, compareRegex, element, diceResult, engine = import_rpg_dice_roller.NumberGenerator.engines.nodeCrypto, pity) {
|
|
671
|
+
function compareSignFormule(toRoll, compareRegex, element, diceResult, engine = import_rpg_dice_roller3.NumberGenerator.engines.nodeCrypto, pity, rollBounds) {
|
|
341
672
|
let results = "";
|
|
673
|
+
let trivial = false;
|
|
342
674
|
const compareResult = getCompare(toRoll, compareRegex, engine);
|
|
343
675
|
const toCompare = `${compareResult.dice}${compareResult.compare?.sign}${compareResult.compare?.value}`;
|
|
344
676
|
let res;
|
|
345
677
|
try {
|
|
346
|
-
res = (0,
|
|
678
|
+
res = (0, import_mathjs4.evaluate)(toCompare);
|
|
347
679
|
} catch (error) {
|
|
348
680
|
res = roll(toCompare, engine, pity);
|
|
349
681
|
}
|
|
350
682
|
if (typeof res === "boolean") {
|
|
683
|
+
const detectedTrivial = rollBounds && compareResult.compare ? isTrivialComparison(rollBounds.max, rollBounds.min, compareResult.compare) : false;
|
|
684
|
+
if (detectedTrivial && compareResult.compare) compareResult.compare.trivial = true;
|
|
685
|
+
if (detectedTrivial) trivial = true;
|
|
351
686
|
results = replaceInFormula(element, diceResult, compareResult, res, engine, pity);
|
|
352
687
|
} else if (res instanceof Object) {
|
|
353
688
|
const diceResult2 = res;
|
|
354
689
|
if (diceResult2.compare) {
|
|
355
|
-
const toEvaluate = (0,
|
|
690
|
+
const toEvaluate = (0, import_mathjs4.evaluate)(
|
|
356
691
|
`${diceResult2.total}${diceResult2.compare.sign}${diceResult2.compare.value}`
|
|
357
692
|
);
|
|
358
693
|
const sign = toEvaluate ? "\u2713" : "\u2715";
|
|
359
694
|
const invertedSign = toEvaluate ? diceResult2.compare.sign : inverseSign(diceResult2.compare.sign);
|
|
360
695
|
const dice = replaceText(element, 0, diceResult2.dice).diceAll;
|
|
361
696
|
results = `${sign} ${dice}: ${diceResult2.result.split(":").splice(1).join(":").trim()}${invertedSign}${diceResult2.compare.value}`;
|
|
697
|
+
if (diceResult2.compare.trivial) trivial = true;
|
|
362
698
|
}
|
|
363
699
|
}
|
|
364
|
-
return { dice: compareResult.dice, results };
|
|
700
|
+
return { dice: compareResult.dice, results, compare: compareResult.compare, trivial };
|
|
365
701
|
}
|
|
366
|
-
|
|
702
|
+
|
|
703
|
+
// src/dice/exploding.ts
|
|
704
|
+
var EXPLODING_SUCCESS_REGEX = /(!(?:>>=|<<=|!==|!!==|>>|<<|==|!=))(-?\d+(?:\.\d+)?)/;
|
|
705
|
+
function normalizeExplodingSuccess(dice) {
|
|
706
|
+
const match = dice.match(EXPLODING_SUCCESS_REGEX);
|
|
707
|
+
if (!match) return void 0;
|
|
708
|
+
const [, doubledSignRaw, valueStr] = match;
|
|
709
|
+
let doubledSign;
|
|
710
|
+
if (doubledSignRaw === "!!==") doubledSign = "==";
|
|
711
|
+
else if (doubledSignRaw === "!==") doubledSign = "!==";
|
|
712
|
+
else doubledSign = doubledSignRaw.replace(/^!/, "");
|
|
713
|
+
const signMap = {
|
|
714
|
+
">>": ">",
|
|
715
|
+
"<<": "<",
|
|
716
|
+
">>=": ">=",
|
|
717
|
+
"<<=": "<=",
|
|
718
|
+
"==": "=",
|
|
719
|
+
"!==": "!=",
|
|
720
|
+
"!!==": "="
|
|
721
|
+
};
|
|
722
|
+
const normalizedSign = signMap[doubledSign];
|
|
723
|
+
if (!normalizedSign) return void 0;
|
|
724
|
+
let parsedValue = Number.parseFloat(valueStr);
|
|
725
|
+
if (Number.isNaN(parsedValue)) {
|
|
726
|
+
try {
|
|
727
|
+
parsedValue = Number.parseFloat((0, import_mathjs5.evaluate)(valueStr));
|
|
728
|
+
} catch (_error) {
|
|
729
|
+
parsedValue = 0;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
const normalizedSegment = "!";
|
|
733
|
+
const replacedDice = dice.replace(match[0], normalizedSegment);
|
|
367
734
|
return {
|
|
368
|
-
|
|
369
|
-
|
|
735
|
+
dice: replacedDice,
|
|
736
|
+
originalDice: dice,
|
|
737
|
+
sign: normalizedSign,
|
|
738
|
+
value: parsedValue,
|
|
739
|
+
normalizedSegment,
|
|
740
|
+
originalSegment: match[0]
|
|
370
741
|
};
|
|
371
742
|
}
|
|
372
|
-
function
|
|
373
|
-
const
|
|
374
|
-
const
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return
|
|
743
|
+
function countExplodingSuccesses(diceRoll, sign, value) {
|
|
744
|
+
const rollsArray = Array.isArray(diceRoll) ? diceRoll : [diceRoll];
|
|
745
|
+
const flatValues = [];
|
|
746
|
+
for (const dr of rollsArray) {
|
|
747
|
+
const groups = dr.rolls ?? [];
|
|
748
|
+
for (const group of groups) {
|
|
749
|
+
const innerRolls = group.rolls ?? [];
|
|
750
|
+
for (const roll2 of innerRolls) {
|
|
751
|
+
if (typeof roll2.value === "number") flatValues.push(roll2.value);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
return flatValues.reduce(
|
|
756
|
+
(acc, current) => acc + (matchComparison(sign, current, value) ? 1 : 0),
|
|
757
|
+
0
|
|
758
|
+
);
|
|
385
759
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
diceMain = "1d1";
|
|
408
|
-
hidden = true;
|
|
409
|
-
} else {
|
|
410
|
-
diceMain = diceMainWithoutComments;
|
|
760
|
+
|
|
761
|
+
// src/dice/extract.ts
|
|
762
|
+
var import_rpg_dice_roller4 = require("@dice-roller/rpg-dice-roller");
|
|
763
|
+
function getModifier(dice) {
|
|
764
|
+
const modifier = dice.matchAll(/(\+|-|%|\/|\^|\*|\*{2})(\d+)/gi);
|
|
765
|
+
let modificator;
|
|
766
|
+
for (const mod of modifier) {
|
|
767
|
+
if (modificator) {
|
|
768
|
+
const sign = modificator.sign;
|
|
769
|
+
let value = modificator.value;
|
|
770
|
+
if (sign) value = calculator(sign, value, Number.parseInt(mod[2], 10));
|
|
771
|
+
modificator = {
|
|
772
|
+
sign: mod[1],
|
|
773
|
+
value
|
|
774
|
+
};
|
|
775
|
+
} else {
|
|
776
|
+
modificator = {
|
|
777
|
+
sign: mod[1],
|
|
778
|
+
value: Number.parseInt(mod[2], 10)
|
|
779
|
+
};
|
|
780
|
+
}
|
|
411
781
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
782
|
+
return modificator;
|
|
783
|
+
}
|
|
784
|
+
function extractValuesFromOutput(output) {
|
|
785
|
+
const values = [];
|
|
786
|
+
const regex = /\[([^\]]+)\]/g;
|
|
787
|
+
let match;
|
|
788
|
+
while ((match = regex.exec(output)) !== null) {
|
|
789
|
+
const segmentValues = match[1].split(",").map((v) => Number.parseInt(v.replace(/[!*]/g, "").trim(), 10)).filter((v) => !Number.isNaN(v));
|
|
790
|
+
values.push(...segmentValues);
|
|
418
791
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
);
|
|
445
|
-
try {
|
|
446
|
-
const evaluated = (0, import_mathjs.evaluate)(toRoll);
|
|
447
|
-
results.push(`\u25C8 ${comment}${diceAll}: ${formule} = ${evaluated}`);
|
|
448
|
-
total += Number.parseInt(evaluated, 10);
|
|
449
|
-
} catch (error) {
|
|
450
|
-
const evaluated = roll(toRoll, engine, pity);
|
|
451
|
-
if (evaluated)
|
|
452
|
-
results.push(
|
|
453
|
-
`\u25C8 ${comment}${diceAll}: ${evaluated.result.split(":").slice(1).join(":")}`
|
|
454
|
-
);
|
|
455
|
-
else results.push(`\u25C8 ${comment}${diceAll}: ${formule} = ${evaluated}`);
|
|
456
|
-
total += evaluated?.total ?? 0;
|
|
457
|
-
}
|
|
792
|
+
return values;
|
|
793
|
+
}
|
|
794
|
+
function getRollBounds(dice, engine = import_rpg_dice_roller4.NumberGenerator.engines.nodeCrypto) {
|
|
795
|
+
try {
|
|
796
|
+
const roller = new import_rpg_dice_roller4.DiceRoller();
|
|
797
|
+
import_rpg_dice_roller4.NumberGenerator.generator.engine = engine;
|
|
798
|
+
const rollResult = roller.roll(dice);
|
|
799
|
+
const instance = Array.isArray(rollResult) ? rollResult[0] : rollResult;
|
|
800
|
+
const { minTotal, maxTotal } = instance;
|
|
801
|
+
return { min: minTotal, max: maxTotal };
|
|
802
|
+
} catch (error) {
|
|
803
|
+
}
|
|
804
|
+
return void 0;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// src/engine.ts
|
|
808
|
+
var import_rpg_dice_roller5 = require("@dice-roller/rpg-dice-roller");
|
|
809
|
+
function getEngineId(engine) {
|
|
810
|
+
if (engine === import_rpg_dice_roller5.NumberGenerator.engines.nodeCrypto) return "nodeCrypto";
|
|
811
|
+
if (engine === import_rpg_dice_roller5.NumberGenerator.engines.nativeMath) return "nativeMath";
|
|
812
|
+
if (engine === import_rpg_dice_roller5.NumberGenerator.engines.browserCrypto) return "browserCrypto";
|
|
813
|
+
try {
|
|
814
|
+
const e = engine;
|
|
815
|
+
if (e && typeof e === "object") {
|
|
816
|
+
if (typeof e.name === "string" && e.name) return e.name;
|
|
817
|
+
if (e.constructor?.name) return e.constructor.name;
|
|
458
818
|
}
|
|
819
|
+
} catch {
|
|
820
|
+
}
|
|
821
|
+
return "unknown";
|
|
822
|
+
}
|
|
823
|
+
function getEngine(engine) {
|
|
824
|
+
switch (engine) {
|
|
825
|
+
case "nativeMath":
|
|
826
|
+
return import_rpg_dice_roller5.NumberGenerator.engines.nativeMath;
|
|
827
|
+
case "browserCrypto":
|
|
828
|
+
return import_rpg_dice_roller5.NumberGenerator.engines.browserCrypto;
|
|
829
|
+
case "nodeCrypto":
|
|
830
|
+
return import_rpg_dice_roller5.NumberGenerator.engines.nodeCrypto;
|
|
831
|
+
default:
|
|
832
|
+
return import_rpg_dice_roller5.NumberGenerator.engines.nativeMath;
|
|
459
833
|
}
|
|
460
|
-
if (hidden)
|
|
461
|
-
results.shift();
|
|
462
|
-
return {
|
|
463
|
-
dice: diceMain,
|
|
464
|
-
result: results.join(";"),
|
|
465
|
-
comment: mainComment,
|
|
466
|
-
compare: diceResult.compare,
|
|
467
|
-
modifier: diceResult.modifier,
|
|
468
|
-
total
|
|
469
|
-
};
|
|
470
834
|
}
|
|
471
835
|
|
|
472
836
|
// src/errors.ts
|
|
@@ -534,13 +898,13 @@ var NoStatisticsError = class extends Error {
|
|
|
534
898
|
}
|
|
535
899
|
};
|
|
536
900
|
|
|
537
|
-
// src/interfaces/
|
|
538
|
-
var
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
901
|
+
// src/interfaces/index.ts
|
|
902
|
+
var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
|
|
903
|
+
SortOrder2["Ascending"] = "sa";
|
|
904
|
+
SortOrder2["Descending"] = "sd";
|
|
905
|
+
SortOrder2["None"] = "none";
|
|
906
|
+
return SortOrder2;
|
|
907
|
+
})(SortOrder || {});
|
|
544
908
|
|
|
545
909
|
// src/interfaces/zod.ts
|
|
546
910
|
var import_zod = require("zod");
|
|
@@ -599,9 +963,9 @@ var templateSchema = import_zod.z.object({
|
|
|
599
963
|
});
|
|
600
964
|
|
|
601
965
|
// src/utils.ts
|
|
602
|
-
var
|
|
966
|
+
var import_mathjs6 = require("mathjs");
|
|
603
967
|
var import_uniformize = require("uniformize");
|
|
604
|
-
var
|
|
968
|
+
var import_rpg_dice_roller6 = require("@dice-roller/rpg-dice-roller");
|
|
605
969
|
var import_random_js = require("random-js");
|
|
606
970
|
function escapeRegex(string) {
|
|
607
971
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -636,11 +1000,29 @@ function generateStatsDice(originalDice, stats, dollarValue) {
|
|
|
636
1000
|
result += outsideText.slice(lastIndex, tokenMatch.index);
|
|
637
1001
|
const token = tokenMatch[0];
|
|
638
1002
|
const tokenStd = token.standardize();
|
|
1003
|
+
const diceMatch = /^(\d*)d(.+)$/i.exec(tokenStd);
|
|
1004
|
+
if (diceMatch) {
|
|
1005
|
+
const diceCount = diceMatch[1] || "";
|
|
1006
|
+
const afterD = diceMatch[2];
|
|
1007
|
+
let foundStatAfterD = false;
|
|
1008
|
+
for (const key of statKeys) {
|
|
1009
|
+
const keyStd = key.standardize();
|
|
1010
|
+
if (afterD === keyStd) {
|
|
1011
|
+
result += `${diceCount}d${stats[key].toString()}`;
|
|
1012
|
+
foundStatAfterD = true;
|
|
1013
|
+
break;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
if (foundStatAfterD) {
|
|
1017
|
+
lastIndex = tokenRegex.lastIndex;
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
639
1021
|
let bestKey = null;
|
|
640
1022
|
let bestScore = 0;
|
|
641
1023
|
for (const key of statKeys) {
|
|
642
1024
|
const keyStd = key.standardize();
|
|
643
|
-
if (tokenStd === keyStd
|
|
1025
|
+
if (tokenStd === keyStd) {
|
|
644
1026
|
bestKey = key;
|
|
645
1027
|
bestScore = 1;
|
|
646
1028
|
break;
|
|
@@ -674,7 +1056,7 @@ function replaceFormulaInDice(dice) {
|
|
|
674
1056
|
if (match.groups?.formula) {
|
|
675
1057
|
const formulae = match.groups.formula.replaceAll("{{", "").replaceAll("}}", "");
|
|
676
1058
|
try {
|
|
677
|
-
const result = (0,
|
|
1059
|
+
const result = (0, import_mathjs6.evaluate)(formulae);
|
|
678
1060
|
modifiedDice = modifiedDice.replace(match.groups.formula, result.toString());
|
|
679
1061
|
} catch (error) {
|
|
680
1062
|
throw new FormulaError(match.groups.formula, "replaceFormulasInDice", error);
|
|
@@ -689,43 +1071,17 @@ function cleanedDice(dice) {
|
|
|
689
1071
|
function isNumber(value) {
|
|
690
1072
|
return value !== void 0 && (typeof value === "number" || !Number.isNaN(Number(value)) && typeof value === "string" && value.trim().length > 0);
|
|
691
1073
|
}
|
|
692
|
-
function replaceExpByRandom(dice, engine =
|
|
1074
|
+
function replaceExpByRandom(dice, engine = import_rpg_dice_roller6.NumberGenerator.engines.nodeCrypto) {
|
|
693
1075
|
const diceRegex = /\{exp( ?\|\| ?(?<default>\d+))?}/gi;
|
|
694
1076
|
return dice.replace(diceRegex, (_match, _p1, _p2, _offset, _string, groups) => {
|
|
695
1077
|
const defaultValue = groups?.default;
|
|
696
1078
|
return defaultValue ?? randomInt(1, 999, engine).toString();
|
|
697
1079
|
});
|
|
698
1080
|
}
|
|
699
|
-
function randomInt(min, max, engine =
|
|
1081
|
+
function randomInt(min, max, engine = import_rpg_dice_roller6.NumberGenerator.engines.nodeCrypto, rng) {
|
|
700
1082
|
if (!rng) rng = new import_random_js.Random(engine || void 0);
|
|
701
1083
|
return rng.integer(min, max);
|
|
702
1084
|
}
|
|
703
|
-
function getEngineId(engine) {
|
|
704
|
-
if (engine === import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto) return "nodeCrypto";
|
|
705
|
-
if (engine === import_rpg_dice_roller2.NumberGenerator.engines.nativeMath) return "nativeMath";
|
|
706
|
-
if (engine === import_rpg_dice_roller2.NumberGenerator.engines.browserCrypto) return "browserCrypto";
|
|
707
|
-
try {
|
|
708
|
-
const e = engine;
|
|
709
|
-
if (e && typeof e === "object") {
|
|
710
|
-
if (typeof e.name === "string" && e.name) return e.name;
|
|
711
|
-
if (e.constructor?.name) return e.constructor.name;
|
|
712
|
-
}
|
|
713
|
-
} catch {
|
|
714
|
-
}
|
|
715
|
-
return "unknown";
|
|
716
|
-
}
|
|
717
|
-
function getEngine(engine) {
|
|
718
|
-
switch (engine) {
|
|
719
|
-
case "nativeMath":
|
|
720
|
-
return import_rpg_dice_roller2.NumberGenerator.engines.nativeMath;
|
|
721
|
-
case "browserCrypto":
|
|
722
|
-
return import_rpg_dice_roller2.NumberGenerator.engines.browserCrypto;
|
|
723
|
-
case "nodeCrypto":
|
|
724
|
-
return import_rpg_dice_roller2.NumberGenerator.engines.nodeCrypto;
|
|
725
|
-
default:
|
|
726
|
-
return import_rpg_dice_roller2.NumberGenerator.engines.nativeMath;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
1085
|
function levenshteinDistance(a, b) {
|
|
730
1086
|
if (a === b) return 0;
|
|
731
1087
|
const al = a.length;
|
|
@@ -753,13 +1109,24 @@ function similarityScore(a, b) {
|
|
|
753
1109
|
const max = Math.max(la, lb);
|
|
754
1110
|
return 1 - dist / max;
|
|
755
1111
|
}
|
|
1112
|
+
function createCriticalCustom(dice, customCritical, template, engine = import_rpg_dice_roller6.NumberGenerator.engines.nodeCrypto) {
|
|
1113
|
+
const compareRegex = dice.match(SIGN_REGEX_SPACE);
|
|
1114
|
+
let customDice = dice;
|
|
1115
|
+
const compareValue = diceTypeRandomParse(customCritical.value, template, engine);
|
|
1116
|
+
if (compareValue.includes("$"))
|
|
1117
|
+
throw new DiceTypeError(compareValue, "createCriticalCustom");
|
|
1118
|
+
const comparaison = `${customCritical.sign}${compareValue}`;
|
|
1119
|
+
if (compareRegex) customDice = customDice.replace(SIGN_REGEX_SPACE, comparaison);
|
|
1120
|
+
else customDice += comparaison;
|
|
1121
|
+
return diceTypeRandomParse(customDice, template, engine);
|
|
1122
|
+
}
|
|
756
1123
|
|
|
757
1124
|
// src/verify_template.ts
|
|
758
|
-
var
|
|
1125
|
+
var import_mathjs7 = require("mathjs");
|
|
759
1126
|
var import_random_js2 = require("random-js");
|
|
760
1127
|
var import_uniformize2 = require("uniformize");
|
|
761
|
-
var
|
|
762
|
-
function evalStatsDice(testDice, allStats, engine =
|
|
1128
|
+
var import_rpg_dice_roller7 = require("@dice-roller/rpg-dice-roller");
|
|
1129
|
+
function evalStatsDice(testDice, allStats, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto, pity) {
|
|
763
1130
|
let dice = testDice.trimEnd();
|
|
764
1131
|
if (allStats && Object.keys(allStats).length > 0) {
|
|
765
1132
|
const names = Object.keys(allStats);
|
|
@@ -779,7 +1146,7 @@ function evalStatsDice(testDice, allStats, engine = import_rpg_dice_roller3.Numb
|
|
|
779
1146
|
throw new DiceTypeError(dice, "evalStatsDice", error);
|
|
780
1147
|
}
|
|
781
1148
|
}
|
|
782
|
-
function diceRandomParse(value, template, engine =
|
|
1149
|
+
function diceRandomParse(value, template, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
783
1150
|
if (!template.statistics) return replaceFormulaInDice(value.standardize());
|
|
784
1151
|
value = value.standardize();
|
|
785
1152
|
const statNames = Object.keys(template.statistics);
|
|
@@ -801,7 +1168,7 @@ function diceRandomParse(value, template, engine = import_rpg_dice_roller3.Numbe
|
|
|
801
1168
|
}
|
|
802
1169
|
return replaceFormulaInDice(newDice);
|
|
803
1170
|
}
|
|
804
|
-
function diceTypeRandomParse(dice, template, engine =
|
|
1171
|
+
function diceTypeRandomParse(dice, template, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
805
1172
|
dice = replaceExpByRandom(dice);
|
|
806
1173
|
if (!template.statistics) return dice;
|
|
807
1174
|
const firstStatNotcombinaison = Object.keys(template.statistics).find(
|
|
@@ -823,7 +1190,7 @@ function evalCombinaison(combinaison, stats) {
|
|
|
823
1190
|
formula = formula.replace(regex, value.toString());
|
|
824
1191
|
}
|
|
825
1192
|
try {
|
|
826
|
-
newStats[stat] = (0,
|
|
1193
|
+
newStats[stat] = (0, import_mathjs7.evaluate)(formula);
|
|
827
1194
|
} catch (error) {
|
|
828
1195
|
throw new FormulaError(stat, "evalCombinaison", error);
|
|
829
1196
|
}
|
|
@@ -837,7 +1204,7 @@ function evalOneCombinaison(combinaison, stats) {
|
|
|
837
1204
|
formula = formula.replace(regex, value.toString());
|
|
838
1205
|
}
|
|
839
1206
|
try {
|
|
840
|
-
return (0,
|
|
1207
|
+
return (0, import_mathjs7.evaluate)(formula);
|
|
841
1208
|
} catch (error) {
|
|
842
1209
|
throw new FormulaError(combinaison, "evalOneCombinaison", error);
|
|
843
1210
|
}
|
|
@@ -849,7 +1216,7 @@ function convertNumber(number) {
|
|
|
849
1216
|
if (isNumber(number)) return Number.parseInt(number.toString(), 10);
|
|
850
1217
|
return void 0;
|
|
851
1218
|
}
|
|
852
|
-
function verifyTemplateValue(template, verify = true, engine =
|
|
1219
|
+
function verifyTemplateValue(template, verify = true, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
853
1220
|
const parsedTemplate = templateSchema.parse(template);
|
|
854
1221
|
const { success, failure } = parsedTemplate.critical ?? {};
|
|
855
1222
|
const criticicalVal = {
|
|
@@ -904,7 +1271,7 @@ function verifyTemplateValue(template, verify = true, engine = import_rpg_dice_r
|
|
|
904
1271
|
testStatCombinaison(statistiqueTemplate, engine);
|
|
905
1272
|
return statistiqueTemplate;
|
|
906
1273
|
}
|
|
907
|
-
function testDiceRegistered(template, engine =
|
|
1274
|
+
function testDiceRegistered(template, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
908
1275
|
if (!template.damage) return;
|
|
909
1276
|
if (Object.keys(template.damage).length === 0) throw new EmptyObjectError();
|
|
910
1277
|
if (Object.keys(template.damage).length > 25) throw new TooManyDice();
|
|
@@ -920,7 +1287,7 @@ function testDiceRegistered(template, engine = import_rpg_dice_roller3.NumberGen
|
|
|
920
1287
|
}
|
|
921
1288
|
}
|
|
922
1289
|
}
|
|
923
|
-
function testStatCombinaison(template, engine =
|
|
1290
|
+
function testStatCombinaison(template, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
924
1291
|
if (!template.statistics) return;
|
|
925
1292
|
const onlycombinaisonStats = Object.fromEntries(
|
|
926
1293
|
Object.entries(template.statistics).filter(
|
|
@@ -946,7 +1313,7 @@ function testStatCombinaison(template, engine = import_rpg_dice_roller3.NumberGe
|
|
|
946
1313
|
formula = formula.replace(regex, randomStatValue.toString());
|
|
947
1314
|
}
|
|
948
1315
|
try {
|
|
949
|
-
(0,
|
|
1316
|
+
(0, import_mathjs7.evaluate)(formula);
|
|
950
1317
|
} catch (e) {
|
|
951
1318
|
error.push(stat);
|
|
952
1319
|
}
|
|
@@ -954,9 +1321,9 @@ function testStatCombinaison(template, engine = import_rpg_dice_roller3.NumberGe
|
|
|
954
1321
|
if (error.length > 0) throw new FormulaError(error.join(", "), "testStatCombinaison");
|
|
955
1322
|
return;
|
|
956
1323
|
}
|
|
957
|
-
function generateRandomStat(total = 100, max, min, engine =
|
|
1324
|
+
function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto) {
|
|
958
1325
|
let randomStatValue = total + 1;
|
|
959
|
-
const random = new import_random_js2.Random(engine ||
|
|
1326
|
+
const random = new import_random_js2.Random(engine || import_rpg_dice_roller7.NumberGenerator.engines.nodeCrypto);
|
|
960
1327
|
while (randomStatValue >= total || randomStatValue === 0) {
|
|
961
1328
|
if (max && min) randomStatValue = randomInt(min, max, engine, random);
|
|
962
1329
|
else if (max) randomStatValue = randomInt(1, max, engine, random);
|
|
@@ -970,6 +1337,7 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
970
1337
|
COMMENT_REGEX,
|
|
971
1338
|
DETECT_CRITICAL,
|
|
972
1339
|
DiceTypeError,
|
|
1340
|
+
EXPLODING_SUCCESS_REGEX,
|
|
973
1341
|
EmptyObjectError,
|
|
974
1342
|
FormulaError,
|
|
975
1343
|
MaxGreater,
|
|
@@ -978,9 +1346,14 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
978
1346
|
SIGN_REGEX,
|
|
979
1347
|
SIGN_REGEX_SPACE,
|
|
980
1348
|
SYMBOL_DICE,
|
|
1349
|
+
SortOrder,
|
|
981
1350
|
TooManyDice,
|
|
982
1351
|
TooManyStats,
|
|
983
1352
|
calculator,
|
|
1353
|
+
canComparisonFail,
|
|
1354
|
+
canComparisonSucceed,
|
|
1355
|
+
compareSignFormule,
|
|
1356
|
+
countExplodingSuccesses,
|
|
984
1357
|
createCriticalCustom,
|
|
985
1358
|
diceRandomParse,
|
|
986
1359
|
diceTypeRandomParse,
|
|
@@ -988,15 +1361,29 @@ function generateRandomStat(total = 100, max, min, engine = import_rpg_dice_roll
|
|
|
988
1361
|
evalCombinaison,
|
|
989
1362
|
evalOneCombinaison,
|
|
990
1363
|
evalStatsDice,
|
|
1364
|
+
extractValuesFromOutput,
|
|
1365
|
+
fixParenthesis,
|
|
1366
|
+
formatComment,
|
|
991
1367
|
generateRandomStat,
|
|
992
1368
|
generateStatsDice,
|
|
1369
|
+
getCompare,
|
|
993
1370
|
getEngine,
|
|
994
1371
|
getEngineId,
|
|
1372
|
+
getModifier,
|
|
1373
|
+
getRollBounds,
|
|
1374
|
+
inverseSign,
|
|
995
1375
|
isNumber,
|
|
1376
|
+
isTrivialComparison,
|
|
1377
|
+
matchComparison,
|
|
1378
|
+
normalizeExplodingSuccess,
|
|
996
1379
|
randomInt,
|
|
997
1380
|
replaceExpByRandom,
|
|
998
1381
|
replaceFormulaInDice,
|
|
1382
|
+
replaceInFormula,
|
|
1383
|
+
replaceText,
|
|
1384
|
+
replaceUnwantedText,
|
|
999
1385
|
roll,
|
|
1386
|
+
rollCompare,
|
|
1000
1387
|
standardizeDice,
|
|
1001
1388
|
templateSchema,
|
|
1002
1389
|
testDiceRegistered,
|