roll-parser 3.0.0 → 3.1.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/CHANGELOG.md +36 -1
- package/MIGRATION.md +73 -1
- package/README.md +85 -19
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +8 -7
- package/dist/cli/format.js.map +1 -1
- package/dist/evaluator/die.d.ts +2 -1
- package/dist/evaluator/die.d.ts.map +1 -1
- package/dist/evaluator/die.js.map +1 -1
- package/dist/evaluator/env.d.ts +31 -0
- package/dist/evaluator/env.d.ts.map +1 -1
- package/dist/evaluator/env.js.map +1 -1
- package/dist/evaluator/evaluator.d.ts.map +1 -1
- package/dist/evaluator/evaluator.js +29 -21
- package/dist/evaluator/evaluator.js.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.d.ts +57 -4
- package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.js +27 -8
- package/dist/evaluator/modifiers/crit-threshold.js.map +1 -1
- package/dist/evaluator/modifiers/die-bound.d.ts +5 -2
- package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -1
- package/dist/evaluator/modifiers/die-bound.js +6 -3
- package/dist/evaluator/modifiers/die-bound.js.map +1 -1
- package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
- package/dist/evaluator/modifiers/explode.js +7 -5
- package/dist/evaluator/modifiers/explode.js.map +1 -1
- package/dist/evaluator/modifiers/flags.d.ts +10 -0
- package/dist/evaluator/modifiers/flags.d.ts.map +1 -1
- package/dist/evaluator/modifiers/flags.js +7 -0
- package/dist/evaluator/modifiers/flags.js.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.d.ts +4 -2
- package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.js +7 -7
- package/dist/evaluator/modifiers/keep-drop.js.map +1 -1
- package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
- package/dist/evaluator/modifiers/reroll.js +16 -10
- package/dist/evaluator/modifiers/reroll.js.map +1 -1
- package/dist/evaluator/modifiers/sort.d.ts +1 -1
- package/dist/evaluator/modifiers/sort.d.ts.map +1 -1
- package/dist/evaluator/modifiers/sort.js +3 -3
- package/dist/evaluator/modifiers/sort.js.map +1 -1
- package/dist/evaluator/modifiers/success-count.d.ts +5 -2
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
- package/dist/evaluator/modifiers/success-count.js +7 -6
- package/dist/evaluator/modifiers/success-count.js.map +1 -1
- package/dist/parser/ast.d.ts +12 -7
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js.map +1 -1
- package/dist/render.d.ts +95 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +227 -0
- package/dist/render.js.map +1 -0
- package/dist/types.d.ts +49 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -1
- package/src/cli/format.ts +15 -23
- package/src/evaluator/die.ts +2 -1
- package/src/evaluator/env.ts +32 -0
- package/src/evaluator/evaluator.ts +48 -21
- package/src/evaluator/modifiers/crit-threshold.ts +95 -10
- package/src/evaluator/modifiers/die-bound.ts +13 -4
- package/src/evaluator/modifiers/explode.ts +12 -6
- package/src/evaluator/modifiers/flags.ts +17 -0
- package/src/evaluator/modifiers/keep-drop.ts +9 -5
- package/src/evaluator/modifiers/reroll.ts +20 -11
- package/src/evaluator/modifiers/sort.ts +9 -3
- package/src/evaluator/modifiers/success-count.ts +21 -6
- package/src/parser/ast.ts +12 -7
- package/src/render.ts +392 -0
- package/src/types.ts +49 -9
- package/src/version.ts +1 -1
package/dist/render.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { DegreeOfSuccess } from './types.js';
|
|
2
|
+
export const MARKDOWN_MARKS = {
|
|
3
|
+
dropped: (_die, text) => `~~${text}~~`,
|
|
4
|
+
success: (_die, text) => `**${text}**`,
|
|
5
|
+
failure: (_die, text) => `__${text}__`,
|
|
6
|
+
droppedGroup: (inner) => `~~${inner}~~`,
|
|
7
|
+
};
|
|
8
|
+
const KEEP_DROP_CODES = {
|
|
9
|
+
keep: { highest: 'kh', lowest: 'kl' },
|
|
10
|
+
drop: { highest: 'dh', lowest: 'dl' },
|
|
11
|
+
};
|
|
12
|
+
const EXPLODE_MARKERS = {
|
|
13
|
+
standard: '!',
|
|
14
|
+
compound: '!!',
|
|
15
|
+
penetrating: '!p',
|
|
16
|
+
};
|
|
17
|
+
const DEGREE_LABELS = {
|
|
18
|
+
[DegreeOfSuccess.CriticalFailure]: 'Critical Failure',
|
|
19
|
+
[DegreeOfSuccess.Failure]: 'Failure',
|
|
20
|
+
[DegreeOfSuccess.Success]: 'Success',
|
|
21
|
+
[DegreeOfSuccess.CriticalSuccess]: 'Critical Success',
|
|
22
|
+
};
|
|
23
|
+
const BARE_VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
24
|
+
function comparePointCode(point) {
|
|
25
|
+
return `${point.operator}${point.value}`;
|
|
26
|
+
}
|
|
27
|
+
function critCode(prefix, threshold) {
|
|
28
|
+
return threshold === 'default' ? prefix : `${prefix}${comparePointCode(threshold)}`;
|
|
29
|
+
}
|
|
30
|
+
function keepDropCode(spec) {
|
|
31
|
+
return `${KEEP_DROP_CODES[spec.kind][spec.selector]}${spec.count}`;
|
|
32
|
+
}
|
|
33
|
+
function failCode(point) {
|
|
34
|
+
return point.operator === '=' ? `f${point.value}` : `f${comparePointCode(point)}`;
|
|
35
|
+
}
|
|
36
|
+
function expr(part) {
|
|
37
|
+
switch (part.type) {
|
|
38
|
+
case 'literal':
|
|
39
|
+
return String(part.value);
|
|
40
|
+
case 'variable':
|
|
41
|
+
return String(part.value);
|
|
42
|
+
case 'dice':
|
|
43
|
+
return `${part.count}d${part.sides}`;
|
|
44
|
+
case 'fateDice':
|
|
45
|
+
return `${part.count}dF`;
|
|
46
|
+
case 'grouped':
|
|
47
|
+
return `(${expr(part.inner)})`;
|
|
48
|
+
case 'binaryOp':
|
|
49
|
+
return `${expr(part.left)} ${part.operator} ${expr(part.right)}`;
|
|
50
|
+
case 'unaryOp':
|
|
51
|
+
return `-${expr(part.operand)}`;
|
|
52
|
+
case 'group':
|
|
53
|
+
return `{${part.parts.map(expr).join(', ')}}`;
|
|
54
|
+
case 'functionCall':
|
|
55
|
+
return `${part.name}(${part.args.map(expr).join(', ')})`;
|
|
56
|
+
case 'keepDrop':
|
|
57
|
+
return `${expr(part.target)}${part.specs.map(keepDropCode).join('')}`;
|
|
58
|
+
case 'explode':
|
|
59
|
+
return `${expr(part.target)}${explodeCode(part)}`;
|
|
60
|
+
case 'reroll':
|
|
61
|
+
return `${expr(part.target)}${part.once ? 'ro' : 'r'}${comparePointCode(part.condition)}`;
|
|
62
|
+
case 'dieBound':
|
|
63
|
+
return `${expr(part.target)}${dieBoundCode(part)}`;
|
|
64
|
+
case 'sort':
|
|
65
|
+
return `${expr(part.target)}${part.order === 'ascending' ? 's' : 'sd'}`;
|
|
66
|
+
case 'critThreshold':
|
|
67
|
+
return `${expr(part.target)}${critThresholdCode(part)}`;
|
|
68
|
+
case 'successCount':
|
|
69
|
+
return `${expr(part.target)}${successCountCode(part)}`;
|
|
70
|
+
case 'versus':
|
|
71
|
+
return `${expr(part.roll)} vs ${expr(part.dc)}`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function explodeCode(part) {
|
|
75
|
+
const marker = EXPLODE_MARKERS[part.variant];
|
|
76
|
+
return part.threshold == null ? marker : `${marker}${comparePointCode(part.threshold)}`;
|
|
77
|
+
}
|
|
78
|
+
function dieBoundCode(part) {
|
|
79
|
+
return part.value < 0 ? `${part.bound}(${part.value})` : `${part.bound}${part.value}`;
|
|
80
|
+
}
|
|
81
|
+
function critThresholdCode(part) {
|
|
82
|
+
return [
|
|
83
|
+
...part.successThresholds.map((threshold) => critCode('cs', threshold)),
|
|
84
|
+
...part.failThresholds.map((threshold) => critCode('cf', threshold)),
|
|
85
|
+
].join('');
|
|
86
|
+
}
|
|
87
|
+
function successCountCode(part) {
|
|
88
|
+
const fail = part.failThreshold == null ? '' : failCode(part.failThreshold);
|
|
89
|
+
return `${comparePointCode(part.threshold)}${fail}`;
|
|
90
|
+
}
|
|
91
|
+
function collectDice(part, out) {
|
|
92
|
+
switch (part.type) {
|
|
93
|
+
case 'dice':
|
|
94
|
+
case 'fateDice':
|
|
95
|
+
case 'sort':
|
|
96
|
+
case 'explode':
|
|
97
|
+
case 'reroll':
|
|
98
|
+
case 'successCount':
|
|
99
|
+
for (const die of part.rolls)
|
|
100
|
+
out.push(die);
|
|
101
|
+
return;
|
|
102
|
+
case 'grouped':
|
|
103
|
+
collectDice(part.inner, out);
|
|
104
|
+
return;
|
|
105
|
+
case 'unaryOp':
|
|
106
|
+
collectDice(part.operand, out);
|
|
107
|
+
return;
|
|
108
|
+
case 'binaryOp':
|
|
109
|
+
collectDice(part.left, out);
|
|
110
|
+
collectDice(part.right, out);
|
|
111
|
+
return;
|
|
112
|
+
case 'keepDrop':
|
|
113
|
+
case 'dieBound':
|
|
114
|
+
case 'critThreshold':
|
|
115
|
+
collectDice(part.target, out);
|
|
116
|
+
return;
|
|
117
|
+
case 'group':
|
|
118
|
+
for (const sub of part.parts)
|
|
119
|
+
collectDice(sub, out);
|
|
120
|
+
return;
|
|
121
|
+
case 'functionCall':
|
|
122
|
+
for (const arg of part.args)
|
|
123
|
+
collectDice(arg, out);
|
|
124
|
+
return;
|
|
125
|
+
case 'versus':
|
|
126
|
+
collectDice(part.roll, out);
|
|
127
|
+
collectDice(part.dc, out);
|
|
128
|
+
return;
|
|
129
|
+
case 'literal':
|
|
130
|
+
case 'variable':
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function poolOf(part) {
|
|
135
|
+
const dice = [];
|
|
136
|
+
collectDice(part, dice);
|
|
137
|
+
return dice;
|
|
138
|
+
}
|
|
139
|
+
function markDie(die, marks, plain) {
|
|
140
|
+
let text = String(die.result);
|
|
141
|
+
if (die.critical)
|
|
142
|
+
text = marks.critical?.(die, text) ?? text;
|
|
143
|
+
if (die.fumble)
|
|
144
|
+
text = marks.fumble?.(die, text) ?? text;
|
|
145
|
+
if (plain)
|
|
146
|
+
return text;
|
|
147
|
+
const { modifiers } = die;
|
|
148
|
+
if (modifiers.includes('dropped'))
|
|
149
|
+
return marks.dropped?.(die, text) ?? text;
|
|
150
|
+
if (modifiers.includes('success'))
|
|
151
|
+
return marks.success?.(die, text) ?? text;
|
|
152
|
+
if (modifiers.includes('failure'))
|
|
153
|
+
return marks.failure?.(die, text) ?? text;
|
|
154
|
+
return text;
|
|
155
|
+
}
|
|
156
|
+
function renderPool(dice, marks, plain) {
|
|
157
|
+
const shown = [];
|
|
158
|
+
for (const die of dice) {
|
|
159
|
+
if (die.modifiers.includes('meta'))
|
|
160
|
+
continue;
|
|
161
|
+
shown.push(markDie(die, marks, plain));
|
|
162
|
+
}
|
|
163
|
+
return `[${shown.join(', ')}]`;
|
|
164
|
+
}
|
|
165
|
+
function renderModifier(target, code, dice, marks, plain) {
|
|
166
|
+
const pool = dice.length === 0 ? '' : renderPool(dice, marks, plain);
|
|
167
|
+
return `${expr(target)}${code}${pool}`;
|
|
168
|
+
}
|
|
169
|
+
function renderPart(part, marks, plain) {
|
|
170
|
+
switch (part.type) {
|
|
171
|
+
case 'literal':
|
|
172
|
+
return String(part.value);
|
|
173
|
+
case 'variable': {
|
|
174
|
+
const display = BARE_VARIABLE.test(part.name) ? `@${part.name}` : `@{${part.name}}`;
|
|
175
|
+
return `${display}[${part.value}]`;
|
|
176
|
+
}
|
|
177
|
+
case 'dice':
|
|
178
|
+
case 'fateDice':
|
|
179
|
+
return `${expr(part)}${renderPool(part.rolls, marks, plain)}`;
|
|
180
|
+
case 'grouped':
|
|
181
|
+
return `(${renderPart(part.inner, marks, plain)})`;
|
|
182
|
+
case 'binaryOp':
|
|
183
|
+
return `${renderPart(part.left, marks, plain)} ${part.operator} ${renderPart(part.right, marks, plain)}`;
|
|
184
|
+
case 'unaryOp':
|
|
185
|
+
return `-${renderPart(part.operand, marks, plain)}`;
|
|
186
|
+
case 'functionCall': {
|
|
187
|
+
const args = part.args.map((arg) => renderPart(arg, marks, plain)).join(', ');
|
|
188
|
+
return `${part.name}(${args})`;
|
|
189
|
+
}
|
|
190
|
+
case 'versus':
|
|
191
|
+
return `${renderPart(part.roll, marks, plain)} vs ${renderPart(part.dc, marks, plain)}`;
|
|
192
|
+
case 'group':
|
|
193
|
+
return renderGroup(part, marks, plain);
|
|
194
|
+
case 'keepDrop':
|
|
195
|
+
return part.target.type === 'group' && part.target.keptIndices != null
|
|
196
|
+
? renderPart(part.target, marks, plain)
|
|
197
|
+
: `${expr(part.target)}${renderPool(poolOf(part.target), marks, plain)}`;
|
|
198
|
+
case 'explode':
|
|
199
|
+
return renderModifier(part.target, explodeCode(part), part.rolls, marks, plain);
|
|
200
|
+
case 'reroll':
|
|
201
|
+
return renderModifier(part.target, `${part.once ? 'ro' : 'r'}${comparePointCode(part.condition)}`, part.rolls, marks, plain);
|
|
202
|
+
case 'successCount':
|
|
203
|
+
return renderModifier(part.target, successCountCode(part), part.rolls, marks, plain);
|
|
204
|
+
case 'dieBound':
|
|
205
|
+
return `${expr(part.target)}${dieBoundCode(part)}${renderPool(poolOf(part.target), marks, plain)}`;
|
|
206
|
+
case 'sort':
|
|
207
|
+
return `${expr(part.target)}${part.order === 'ascending' ? 's' : 'sd'}${renderPool(part.rolls, marks, plain)}`;
|
|
208
|
+
case 'critThreshold':
|
|
209
|
+
return `${expr(part.target)}${critThresholdCode(part)}${renderPool(poolOf(part.target), marks, plain)}`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function renderGroup(part, marks, plain) {
|
|
213
|
+
const { keptIndices } = part;
|
|
214
|
+
const subRolls = part.parts.map((sub, index) => {
|
|
215
|
+
if (keptIndices == null || keptIndices.includes(index)) {
|
|
216
|
+
return renderPart(sub, marks, plain);
|
|
217
|
+
}
|
|
218
|
+
const inner = renderPart(sub, marks, true);
|
|
219
|
+
return marks.droppedGroup?.(inner) ?? inner;
|
|
220
|
+
});
|
|
221
|
+
return `{${subRolls.join(', ')}}`;
|
|
222
|
+
}
|
|
223
|
+
export function renderBreakdown(result, marks = MARKDOWN_MARKS) {
|
|
224
|
+
const trailing = result.degree == null ? String(result.total) : DEGREE_LABELS[result.degree];
|
|
225
|
+
return `${renderPart(result.parts, marks, false)} = ${trailing}`;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -37,9 +37,12 @@ export type ResolvedComparePoint = {
|
|
|
37
37
|
readonly value: number;
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
40
|
-
* A resolved crit threshold — `'default'` means the per-die default rule
|
|
41
|
-
*
|
|
42
|
-
*
|
|
40
|
+
* A resolved crit threshold — `'default'` means the per-die default rule,
|
|
41
|
+
* which is what bare `cs` / `cf` produce. It reads the natural face
|
|
42
|
+
* (`initialResult ?? result`): critical when it equals `sides`, fumble when
|
|
43
|
+
* it equals 1, both only for `sides > 1`. An explicit ComparePoint instead
|
|
44
|
+
* reads the die's current `result`, so a preceding modifier that rewrote it
|
|
45
|
+
* is visible to the comparison.
|
|
43
46
|
*
|
|
44
47
|
* @category Results
|
|
45
48
|
*/
|
|
@@ -64,10 +67,14 @@ export type ResolvedCritThreshold = ResolvedComparePoint | 'default';
|
|
|
64
67
|
*
|
|
65
68
|
* `'meta'` is the one tag with no counterpart in the notation. Dice counts,
|
|
66
69
|
* sides, modifier counts and computed thresholds may themselves be dice
|
|
67
|
-
* (`(1d4)d6`, `4d6kh(1d2)`, `1d6!>(1d2+3)`). Those inner dice
|
|
68
|
-
*
|
|
69
|
-
* `RollResult.rolls` tagged `'meta'` so an audit log can still
|
|
70
|
-
* meta-expression rolled.
|
|
70
|
+
* (`(1d4)d6`, `4d6kh(1d2)`, `1d6!>(1d2+3)`). Those inner dice belong to no
|
|
71
|
+
* pool: they never appear on a `dice` or `fateDice` part, and they are
|
|
72
|
+
* appended to `RollResult.rolls` tagged `'meta'` so an audit log can still
|
|
73
|
+
* show what the meta-expression rolled.
|
|
74
|
+
*
|
|
75
|
+
* The four whole-pool views — `sort`, `explode`, `reroll`, and `successCount`
|
|
76
|
+
* `rolls` — are snapshots of an evaluation context rather than of a pool, so
|
|
77
|
+
* they do carry meta dice. Filter them out when summing or displaying a pool.
|
|
71
78
|
*
|
|
72
79
|
* `'dc'` marks the DC side of a `vs` comparison. Unlike `'meta'` these dice do
|
|
73
80
|
* render — `1d20[3] vs 2d10[5, 6]` shows both sides — but they are not part of
|
|
@@ -148,9 +155,19 @@ export type DieResult = {
|
|
|
148
155
|
initialResult?: number;
|
|
149
156
|
/** Modifiers applied to this die */
|
|
150
157
|
modifiers: DieModifier[];
|
|
151
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* True if the die met its critical criteria — by default, rolling the
|
|
160
|
+
* maximum face on a die with more than one side. That default never fires
|
|
161
|
+
* on `d1` or on Fate dice (`sides = 0` has no maximum face), but an
|
|
162
|
+
* explicit `cs` threshold does: `4dFcs>0` flags every `+1`.
|
|
163
|
+
*/
|
|
152
164
|
critical: boolean;
|
|
153
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* True if the die met its fumble criteria — by default, rolling a 1 on a
|
|
167
|
+
* die with more than one side. As with {@link DieResult.critical}, the
|
|
168
|
+
* default never fires on `d1` or Fate dice, while an explicit `cf`
|
|
169
|
+
* threshold does: `4dFcf=-1` flags every `-1`.
|
|
170
|
+
*/
|
|
154
171
|
fumble: boolean;
|
|
155
172
|
};
|
|
156
173
|
/**
|
|
@@ -296,11 +313,29 @@ export type RollPart = (RollPartBase & {
|
|
|
296
313
|
type: 'explode';
|
|
297
314
|
variant: 'standard' | 'compound' | 'penetrating';
|
|
298
315
|
threshold?: ResolvedComparePoint;
|
|
316
|
+
/**
|
|
317
|
+
* The expanded pool. Standard and penetrating explosions append dice
|
|
318
|
+
* that exist nowhere under `target`, so this is the only view of the
|
|
319
|
+
* pool the modifier actually produced. Compound explosions accumulate
|
|
320
|
+
* in place, making it the same dice as `target` carries.
|
|
321
|
+
*
|
|
322
|
+
* Like `RollResult.rolls` — and unlike the pool under `target` — this
|
|
323
|
+
* keeps `'meta'` dice. Filter them out before counting or displaying.
|
|
324
|
+
*/
|
|
325
|
+
rolls: DieResult[];
|
|
299
326
|
target: RollPart;
|
|
300
327
|
}) | (RollPartBase & {
|
|
301
328
|
type: 'reroll';
|
|
302
329
|
once: boolean;
|
|
303
330
|
condition: ResolvedComparePoint;
|
|
331
|
+
/**
|
|
332
|
+
* The post-reroll pool: discarded intermediates (`'rerolled'` +
|
|
333
|
+
* `'dropped'`) alongside their replacements. Both are appended rather
|
|
334
|
+
* than substituted, so neither appears under `target`.
|
|
335
|
+
*
|
|
336
|
+
* Keeps `'meta'` dice, as `RollResult.rolls` does.
|
|
337
|
+
*/
|
|
338
|
+
rolls: DieResult[];
|
|
304
339
|
target: RollPart;
|
|
305
340
|
}) | (RollPartBase & {
|
|
306
341
|
type: 'dieBound';
|
|
@@ -311,6 +346,11 @@ export type RollPart = (RollPartBase & {
|
|
|
311
346
|
type: 'successCount';
|
|
312
347
|
threshold: ResolvedComparePoint;
|
|
313
348
|
failThreshold?: ResolvedComparePoint;
|
|
349
|
+
/**
|
|
350
|
+
* The tallied pool, sharing `DieResult` references with `target`.
|
|
351
|
+
* Keeps `'meta'` dice, as `RollResult.rolls` does.
|
|
352
|
+
*/
|
|
353
|
+
rolls: DieResult[];
|
|
314
354
|
target: RollPart;
|
|
315
355
|
successes: number;
|
|
316
356
|
failures: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAiIA,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,2EAAmB,CAAA;IACnB,2DAAW,CAAA;IACX,2DAAW,CAAA;IACX,2EAAmB,CAAA;AACrB,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "3.
|
|
1
|
+
export declare const version = "3.1.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '3.
|
|
1
|
+
export const version = '3.1.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roll-parser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "High-performance dice notation parser for tabletop RPGs. TypeScript-first, runs on Node, Bun, and browsers with zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"default": "./dist/index.js"
|
|
14
14
|
},
|
|
15
|
+
"./render": {
|
|
16
|
+
"types": "./dist/render.d.ts",
|
|
17
|
+
"default": "./dist/render.js"
|
|
18
|
+
},
|
|
15
19
|
"./testing": {
|
|
16
20
|
"types": "./dist/testing.d.ts",
|
|
17
21
|
"default": "./dist/testing.js"
|
|
@@ -112,6 +116,12 @@
|
|
|
112
116
|
"import": "{ roll }",
|
|
113
117
|
"limit": "12 kB"
|
|
114
118
|
},
|
|
119
|
+
{
|
|
120
|
+
"name": "render.js — { renderBreakdown }",
|
|
121
|
+
"path": "dist/render.js",
|
|
122
|
+
"import": "{ renderBreakdown }",
|
|
123
|
+
"limit": "2 kB"
|
|
124
|
+
},
|
|
115
125
|
{
|
|
116
126
|
"name": "testing.js — { createMockRng }",
|
|
117
127
|
"path": "dist/testing.js",
|
package/src/cli/format.ts
CHANGED
|
@@ -6,8 +6,22 @@
|
|
|
6
6
|
* @module cli/format
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { type DieMarks, renderBreakdown } from '../render.js';
|
|
9
10
|
import type { RollResult } from '../types.js';
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Terminal stand-ins for the markdown markers `RollResult.rendered` uses:
|
|
14
|
+
* dropped dice become `(value)`, successes `[value]`, failures `{value}`, so
|
|
15
|
+
* the per-die classification stays visible with no markup dependency. A
|
|
16
|
+
* dropped group sub-roll takes the same parentheses as a dropped die.
|
|
17
|
+
*/
|
|
18
|
+
const TERMINAL_MARKS: DieMarks = {
|
|
19
|
+
dropped: (_die, text) => `(${text})`,
|
|
20
|
+
success: (_die, text) => `[${text}]`,
|
|
21
|
+
failure: (_die, text) => `{${text}}`,
|
|
22
|
+
droppedGroup: (inner) => `(${inner})`,
|
|
23
|
+
};
|
|
24
|
+
|
|
11
25
|
/**
|
|
12
26
|
* Output mode selectors for {@link formatResult}.
|
|
13
27
|
*/
|
|
@@ -42,27 +56,5 @@ export function formatResult(result: RollResult, options: FormatOptions = {}): s
|
|
|
42
56
|
return String(result.total);
|
|
43
57
|
}
|
|
44
58
|
|
|
45
|
-
return
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Converts markdown-style dice markers to terminal-friendly forms.
|
|
50
|
-
*
|
|
51
|
-
* The evaluator uses markdown syntax in the rendered field:
|
|
52
|
-
* `~~value~~` — dropped dice or dropped group sub-rolls
|
|
53
|
-
* `**value**` — dice counted as success
|
|
54
|
-
* `__value__` — dice counted as failure
|
|
55
|
-
*
|
|
56
|
-
* For plain terminals these become `(value)`, `[value]`, and `{value}` so
|
|
57
|
-
* the per-die classification stays visible without any markup dependency.
|
|
58
|
-
* Dropped spans can wrap a whole sub-roll (e.g. `~~1d8[2]~~` from
|
|
59
|
-
* `{1d8, 1d10}kh1`), so the strikethrough pattern accepts any tilde-free
|
|
60
|
-
* content, not just a single number. The evaluator never nests `~~`
|
|
61
|
-
* (see `stripInnerMarkers`), so the tilde-free span match is safe.
|
|
62
|
-
*/
|
|
63
|
-
function formatRendered(rendered: string): string {
|
|
64
|
-
return rendered
|
|
65
|
-
.replace(/\*\*(-?\d+)\*\*/g, '[$1]')
|
|
66
|
-
.replace(/__(-?\d+)__/g, '{$1}')
|
|
67
|
-
.replace(/~~([^~]+)~~/g, '($1)');
|
|
59
|
+
return renderBreakdown(result, TERMINAL_MARKS);
|
|
68
60
|
}
|
package/src/evaluator/die.ts
CHANGED
|
@@ -37,7 +37,8 @@ export function createDieResult(
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Creates a Fate/Fudge die result. Uses `sides = 0` as a sentinel — Fate dice
|
|
40
|
-
* have no max-face concept, so `critical` and `fumble`
|
|
40
|
+
* have no max-face concept, so `critical` and `fumble` start `false` and the
|
|
41
|
+
* default rule never sets them. An explicit `cs`/`cf` threshold still can.
|
|
41
42
|
*/
|
|
42
43
|
export function createFateDieResult(result: number, modifiers: DieModifier[]): DieResult {
|
|
43
44
|
return {
|
package/src/evaluator/env.ts
CHANGED
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
import { EvaluatorError } from '../errors.js';
|
|
12
12
|
import type { ASTNode } from '../parser/ast.js';
|
|
13
|
+
import type { DieResult, ResolvedCritThreshold } from '../types.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A resolved `cs`/`cf` pair, recorded per die so that dice minted later by
|
|
17
|
+
* explode or reroll can be judged by the rule the user declared instead of
|
|
18
|
+
* the built-in default.
|
|
19
|
+
*/
|
|
20
|
+
export type CritRule = {
|
|
21
|
+
readonly success: readonly ResolvedCritThreshold[];
|
|
22
|
+
readonly fail: readonly ResolvedCritThreshold[];
|
|
23
|
+
};
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
26
|
* Per-evaluation shared environment (created once, shared across all branches).
|
|
@@ -35,6 +46,27 @@ export type EvalEnv = {
|
|
|
35
46
|
* left-chain check.
|
|
36
47
|
*/
|
|
37
48
|
insideVersus: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* `true` once a `vs` has tagged its DC dice `'dc'`. Lets every pool
|
|
51
|
+
* operation skip its per-die `isVersusDc` check outright — the tag exists in
|
|
52
|
+
* a small minority of notation, and the call inside the loop cost 11-38% on
|
|
53
|
+
* keep/drop, success, and sort notation that can never carry one (#281).
|
|
54
|
+
*
|
|
55
|
+
* ! Monotonic: set by `evalVersus`, never cleared. `insideVersus` is not a
|
|
56
|
+
* ! model for it — that flag resets in a `finally`, and it is false exactly
|
|
57
|
+
* ! when the tagged DC dice become visible to the enclosing pool.
|
|
58
|
+
*/
|
|
59
|
+
hasVersusDc: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Crit rule per die, keyed on the `DieResult` object itself. Populated by
|
|
62
|
+
* `applyCritThresholds`; read by explode and reroll so a die they mint
|
|
63
|
+
* inherits the rule of the die it descended from.
|
|
64
|
+
*
|
|
65
|
+
* Out of band rather than a `DieResult` field because `DieResult` is public
|
|
66
|
+
* and serialized. `undefined` until the first `cs`/`cf` node — declared here
|
|
67
|
+
* so the shape stays stable for notation that has none.
|
|
68
|
+
*/
|
|
69
|
+
critRules: WeakMap<DieResult, CritRule> | undefined;
|
|
38
70
|
/**
|
|
39
71
|
* User-supplied variable map for `@name` / `@{name}` references. Always
|
|
40
72
|
* defined — `evaluate()` defaults to an empty object so lookups can be
|