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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EvaluatorError } from '../../errors.js';
|
|
2
2
|
import { createDieResult } from '../die.js';
|
|
3
3
|
import { chargeDie } from '../env.js';
|
|
4
|
+
import { inheritCritRule } from './crit-threshold.js';
|
|
4
5
|
import { isVersusDc } from './flags.js';
|
|
5
6
|
export const DEFAULT_MAX_EXPLODE_ITERATIONS = 1_000;
|
|
6
7
|
export function buildShouldExplode(operator, thresholdValue) {
|
|
@@ -27,8 +28,8 @@ function rollExplosion(sides, rng, env) {
|
|
|
27
28
|
function explodeLimitError(maxIterations) {
|
|
28
29
|
return new EvaluatorError(`Explode iteration limit of ${maxIterations} exceeded`, 'EXPLODE_LIMIT_EXCEEDED', 'Explode');
|
|
29
30
|
}
|
|
30
|
-
function canExplode(die) {
|
|
31
|
-
if (isVersusDc(die))
|
|
31
|
+
function canExplode(die, hasVersusDc) {
|
|
32
|
+
if (hasVersusDc && isVersusDc(die))
|
|
32
33
|
return false;
|
|
33
34
|
if (die.modifiers.includes('dropped'))
|
|
34
35
|
return false;
|
|
@@ -40,7 +41,7 @@ function applyAppendingExplode(pool, shouldExplode, rng, env, storeResult) {
|
|
|
40
41
|
const result = [];
|
|
41
42
|
for (const original of pool) {
|
|
42
43
|
result.push(original);
|
|
43
|
-
if (!canExplode(original))
|
|
44
|
+
if (!canExplode(original, env.hasVersusDc))
|
|
44
45
|
continue;
|
|
45
46
|
const sides = original.sides;
|
|
46
47
|
let lastRaw = original.result;
|
|
@@ -52,6 +53,7 @@ function applyAppendingExplode(pool, shouldExplode, rng, env, storeResult) {
|
|
|
52
53
|
const raw = rollExplosion(sides, rng, env);
|
|
53
54
|
const die = createDieResult(sides, raw, ['exploded', 'kept']);
|
|
54
55
|
die.result = storeResult(raw);
|
|
56
|
+
inheritCritRule(env, original, die, raw);
|
|
55
57
|
result.push(die);
|
|
56
58
|
lastRaw = raw;
|
|
57
59
|
iterations += 1;
|
|
@@ -70,7 +72,7 @@ export function applyStandardExplode(pool, shouldExplode, rng, env) {
|
|
|
70
72
|
}
|
|
71
73
|
export function applyCompoundExplode(pool, shouldExplode, rng, env) {
|
|
72
74
|
for (const original of pool) {
|
|
73
|
-
if (!canExplode(original))
|
|
75
|
+
if (!canExplode(original, env.hasVersusDc))
|
|
74
76
|
continue;
|
|
75
77
|
const sides = original.sides;
|
|
76
78
|
let accumulated = original.result;
|
|
@@ -89,7 +91,7 @@ export function applyCompoundExplode(pool, shouldExplode, rng, env) {
|
|
|
89
91
|
}
|
|
90
92
|
if (!exploded)
|
|
91
93
|
continue;
|
|
92
|
-
original.initialResult
|
|
94
|
+
original.initialResult ??= original.result;
|
|
93
95
|
original.result = accumulated;
|
|
94
96
|
if (!original.modifiers.includes('exploded')) {
|
|
95
97
|
original.modifiers = [...original.modifiers, 'exploded'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explode.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/explode.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAgB,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWxC,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,CAAC;AAapD,MAAM,UAAU,kBAAkB,CAChC,QAA+B,EAC/B,cAAkC;IAElC,IAAI,QAAQ,IAAI,IAAI,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QAC/C,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,KAAK,KAAK,CAAC;IAC7C,CAAC;IACD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,GAAG;YACN,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC;QAC7C,KAAK,IAAI;YACP,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,cAAc,CAAC;QAC9C,KAAK,GAAG;YACN,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,cAAc,CAAC;QAC7C,KAAK,IAAI;YACP,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,cAAc,CAAC;QAC9C,KAAK,GAAG;YACN,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,cAAc,CAAC;IACjD,CAAC;AACH,CAAC;AAKD,SAAS,aAAa,CAAC,KAAa,EAAE,GAAQ,EAAE,GAAY;IAC1D,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC1B,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,iBAAiB,CAAC,aAAqB;IAC9C,OAAO,IAAI,cAAc,CACvB,8BAA8B,aAAa,WAAW,EACtD,wBAAwB,EACxB,SAAS,CACV,CAAC;AACJ,CAAC;AAYD,SAAS,UAAU,CAAC,GAAc;
|
|
1
|
+
{"version":3,"file":"explode.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/explode.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ import type { DieModifier, DieResult } from '../../types.js';
|
|
|
18
18
|
* operates on. Nothing may sum, select, clamp, reroll, explode, or tally them
|
|
19
19
|
* — a `d10` on the DC side must never come back clamped to 20, and
|
|
20
20
|
* `{1d20 vs 2d10, 1d4}>=5` must not count the DC faces as successes.
|
|
21
|
+
*
|
|
22
|
+
* ! Call this behind the shared `hasVersusDc` env flag, never bare. Unguarded
|
|
23
|
+
* ! inside a per-die loop it cost 11-38% on notation that cannot carry the tag
|
|
24
|
+
* ! (#281); the flag is `false` until a `vs` has actually tagged something.
|
|
21
25
|
*/
|
|
22
26
|
export declare function isVersusDc(die: DieResult): boolean;
|
|
23
27
|
/** Kept/dropped selection flags — rebuilt by every keep/drop pass. */
|
|
@@ -28,6 +32,12 @@ export declare const SELECTION_FLAGS: readonly DieModifier[];
|
|
|
28
32
|
* sub-rolls) so the top-level successes/failures scan cannot count it.
|
|
29
33
|
*/
|
|
30
34
|
export declare const SELECTION_AND_TALLY_FLAGS: readonly DieModifier[];
|
|
35
|
+
/**
|
|
36
|
+
* {@link SELECTION_AND_TALLY_FLAGS} plus `'meta'`, for a meta context merging
|
|
37
|
+
* into a parent. Meta operands nest (`((1d2)d4)d6`), so a die passes through
|
|
38
|
+
* the merge once per level and the tag must be rebuilt, not appended.
|
|
39
|
+
*/
|
|
40
|
+
export declare const META_MERGE_FLAGS: readonly DieModifier[];
|
|
31
41
|
/** Selection flags plus `rerolled` — reassigned on every reroll pass. */
|
|
32
42
|
export declare const REROLL_SLOT_FLAGS: readonly DieModifier[];
|
|
33
43
|
/** Returns `modifiers` with every flag in `excluded` removed. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAElD;AAED,sEAAsE;AACtE,eAAO,MAAM,eAAe,EAAE,SAAS,WAAW,EAAwB,CAAC;AAE3E;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,WAAW,EAK3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAMlD,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,iBAAiB,EAAE,SAAS,WAAW,EAAoC,CAAC;AAEzF,iEAAiE;AACjE,wBAAgB,UAAU,CACxB,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC/B,WAAW,EAAE,CAEf;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAC1B,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,QAAQ,EAAE,SAAS,WAAW,EAAE,EAChC,GAAG,KAAK,EAAE,WAAW,EAAE,GACtB,WAAW,EAAE,CAEf"}
|
|
@@ -8,6 +8,13 @@ export const SELECTION_AND_TALLY_FLAGS = [
|
|
|
8
8
|
'success',
|
|
9
9
|
'failure',
|
|
10
10
|
];
|
|
11
|
+
export const META_MERGE_FLAGS = [
|
|
12
|
+
'kept',
|
|
13
|
+
'dropped',
|
|
14
|
+
'success',
|
|
15
|
+
'failure',
|
|
16
|
+
'meta',
|
|
17
|
+
];
|
|
11
18
|
export const REROLL_SLOT_FLAGS = ['kept', 'dropped', 'rerolled'];
|
|
12
19
|
export function stripFlags(modifiers, excluded) {
|
|
13
20
|
return modifiers.filter((modifier) => !excluded.includes(modifier));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/flags.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/flags.ts"],"names":[],"mappings":"AA2BA,MAAM,UAAU,UAAU,CAAC,GAAc;IACvC,OAAO,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAGD,MAAM,CAAC,MAAM,eAAe,GAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAO3E,MAAM,CAAC,MAAM,yBAAyB,GAA2B;IAC/D,MAAM;IACN,SAAS;IACT,SAAS;IACT,SAAS;CACV,CAAC;AAOF,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,MAAM;IACN,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;CACP,CAAC;AAGF,MAAM,CAAC,MAAM,iBAAiB,GAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAGzF,MAAM,UAAU,UAAU,CACxB,SAAiC,EACjC,QAAgC;IAEhC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC;AAGD,MAAM,UAAU,YAAY,CAC1B,SAAiC,EACjC,QAAgC,EAChC,GAAG,KAAoB;IAEvB,OAAO,CAAC,GAAG,UAAU,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -17,12 +17,14 @@ import type { DieResult, KeepDropSpec } from '../../types.js';
|
|
|
17
17
|
* Dice already carrying `'dropped'` (reroll intermediates, meta dice, a
|
|
18
18
|
* preceding chain's losers) are ineligible for selection and stay dropped.
|
|
19
19
|
*/
|
|
20
|
-
export declare function markDroppedIndices(dice: DieResult[], count: number, kind: KeepDropSpec['kind'], selector: KeepDropSpec['selector'], droppedMask: Uint8Array): void;
|
|
20
|
+
export declare function markDroppedIndices(dice: DieResult[], count: number, kind: KeepDropSpec['kind'], selector: KeepDropSpec['selector'], droppedMask: Uint8Array, hasVersusDc: boolean): void;
|
|
21
21
|
/**
|
|
22
22
|
* Calculates total from dice, excluding dropped dice.
|
|
23
23
|
*
|
|
24
24
|
* @param dice - Array of die results
|
|
25
|
+
* @param hasVersusDc - Shared env flag; skips the DC exclusion when no `vs` has
|
|
26
|
+
* tagged anything
|
|
25
27
|
* @returns Sum of non-dropped dice
|
|
26
28
|
*/
|
|
27
|
-
export declare function sumKeptDice(dice: DieResult[]): number;
|
|
29
|
+
export declare function sumKeptDice(dice: DieResult[], hasVersusDc: boolean): number;
|
|
28
30
|
//# sourceMappingURL=keep-drop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keep-drop.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/keep-drop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAM9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,EAAE,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAC1B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,EAClC,WAAW,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"keep-drop.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/keep-drop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAM9D;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,EAAE,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAC1B,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,EAClC,WAAW,EAAE,UAAU,EACvB,WAAW,EAAE,OAAO,GACnB,IAAI,CAgDN;AAuDD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,CAS3E"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isVersusDc } from './flags.js';
|
|
2
|
-
export function markDroppedIndices(dice, count, kind, selector, droppedMask) {
|
|
2
|
+
export function markDroppedIndices(dice, count, kind, selector, droppedMask, hasVersusDc) {
|
|
3
3
|
if (count === 1) {
|
|
4
|
-
markSingleExtreme(dice, kind, selector, droppedMask);
|
|
4
|
+
markSingleExtreme(dice, kind, selector, droppedMask, hasVersusDc);
|
|
5
5
|
return;
|
|
6
6
|
}
|
|
7
7
|
const eligible = [];
|
|
@@ -9,7 +9,7 @@ export function markDroppedIndices(dice, count, kind, selector, droppedMask) {
|
|
|
9
9
|
const die = dice[index];
|
|
10
10
|
if (die == null)
|
|
11
11
|
continue;
|
|
12
|
-
if (isVersusDc(die))
|
|
12
|
+
if (hasVersusDc && isVersusDc(die))
|
|
13
13
|
continue;
|
|
14
14
|
if (die.modifiers.includes('dropped')) {
|
|
15
15
|
droppedMask[index] = 1;
|
|
@@ -35,7 +35,7 @@ export function markDroppedIndices(dice, count, kind, selector, droppedMask) {
|
|
|
35
35
|
droppedMask[item.index] = 1;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
function markSingleExtreme(dice, kind, selector, droppedMask) {
|
|
38
|
+
function markSingleExtreme(dice, kind, selector, droppedMask, hasVersusDc) {
|
|
39
39
|
const isKeep = kind === 'keep';
|
|
40
40
|
const wantHighest = selector === 'highest';
|
|
41
41
|
let extremeIndex = -1;
|
|
@@ -44,7 +44,7 @@ function markSingleExtreme(dice, kind, selector, droppedMask) {
|
|
|
44
44
|
const die = dice[index];
|
|
45
45
|
if (die == null)
|
|
46
46
|
continue;
|
|
47
|
-
if (isVersusDc(die))
|
|
47
|
+
if (hasVersusDc && isVersusDc(die))
|
|
48
48
|
continue;
|
|
49
49
|
if (die.modifiers.includes('dropped')) {
|
|
50
50
|
droppedMask[index] = 1;
|
|
@@ -69,10 +69,10 @@ function markSingleExtreme(dice, kind, selector, droppedMask) {
|
|
|
69
69
|
if (!isKeep && extremeIndex !== -1)
|
|
70
70
|
droppedMask[extremeIndex] = 1;
|
|
71
71
|
}
|
|
72
|
-
export function sumKeptDice(dice) {
|
|
72
|
+
export function sumKeptDice(dice, hasVersusDc) {
|
|
73
73
|
let total = 0;
|
|
74
74
|
for (const die of dice) {
|
|
75
|
-
if (isVersusDc(die))
|
|
75
|
+
if (hasVersusDc && isVersusDc(die))
|
|
76
76
|
continue;
|
|
77
77
|
if (!die.modifiers.includes('dropped'))
|
|
78
78
|
total += die.result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keep-drop.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/keep-drop.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkBxC,MAAM,UAAU,kBAAkB,CAChC,IAAiB,EACjB,KAAa,EACb,IAA0B,EAC1B,QAAkC,EAClC,WAAuB;
|
|
1
|
+
{"version":3,"file":"keep-drop.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/keep-drop.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkBxC,MAAM,UAAU,kBAAkB,CAChC,IAAiB,EACjB,KAAa,EACb,IAA0B,EAC1B,QAAkC,EAClC,WAAuB,EACvB,WAAoB;IAEpB,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAClE,OAAO;IACT,CAAC;IAED,MAAM,QAAQ,GAAkB,EAAE,CAAC;IAEnC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,GAAG,IAAI,IAAI;YAAE,SAAS;QAC1B,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE7C,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;IAG/B,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;QAAE,OAAO;IAG3D,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACnD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO;IACT,CAAC;IAGD,QAAQ,CAAC,IAAI,CACX,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CACvF,CAAC;IAIF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAE7C,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,IAAI,IAAI,IAAI;YAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AASD,SAAS,iBAAiB,CACxB,IAAiB,EACjB,IAA0B,EAC1B,QAAkC,EAClC,WAAuB,EACvB,WAAoB;IAEpB,MAAM,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;IAC/B,MAAM,WAAW,GAAG,QAAQ,KAAK,SAAS,CAAC;IAE3C,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IAEtB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,GAAG,IAAI,IAAI;YAAE,SAAS;QAC1B,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE7C,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAEvB,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;YACxB,YAAY,GAAG,KAAK,CAAC;YACrB,aAAa,GAAG,MAAM,CAAC;YACvB,SAAS;QACX,CAAC;QAED,IAAI,WAAW,CAAC,CAAC,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;YAElE,IAAI,MAAM;gBAAE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;YAC1C,YAAY,GAAG,KAAK,CAAC;YACrB,aAAa,GAAG,MAAM,CAAC;QACzB,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAID,IAAI,CAAC,MAAM,IAAI,YAAY,KAAK,CAAC,CAAC;QAAE,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC;AAUD,MAAM,UAAU,WAAW,CAAC,IAAiB,EAAE,WAAoB;IACjE,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC7C,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC;IAC9D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reroll.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"reroll.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3D,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AAsCnD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CA+Bb;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,EAAE,EACjB,QAAQ,EAAE,SAAS,EACnB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAyBb"}
|
|
@@ -2,24 +2,30 @@ import { EvaluatorError } from '../../errors.js';
|
|
|
2
2
|
import { createDieResult, createFateDieResult } from '../die.js';
|
|
3
3
|
import { chargeDie } from '../env.js';
|
|
4
4
|
import { matchesCondition } from './compare.js';
|
|
5
|
+
import { inheritCritRule } from './crit-threshold.js';
|
|
5
6
|
import { isVersusDc, REROLL_SLOT_FLAGS, rewriteFlags } from './flags.js';
|
|
6
7
|
export const DEFAULT_MAX_REROLL_ITERATIONS = 1_000;
|
|
7
|
-
function rollReplacement(
|
|
8
|
+
function rollReplacement(parent, rng, env) {
|
|
8
9
|
chargeDie(env, 'Reroll');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const sides = parent.sides;
|
|
11
|
+
const die = sides === 0
|
|
12
|
+
? createFateDieResult(rng.nextInt(-1, 1), [])
|
|
13
|
+
: createDieResult(sides, rng.nextInt(1, sides), []);
|
|
14
|
+
inheritCritRule(env, parent, die);
|
|
15
|
+
return die;
|
|
12
16
|
}
|
|
13
17
|
function rerollLimitError(maxIterations) {
|
|
14
18
|
return new EvaluatorError(`Reroll iteration limit of ${maxIterations} exceeded`, 'REROLL_LIMIT_EXCEEDED', 'Reroll');
|
|
15
19
|
}
|
|
16
|
-
function canReroll(die) {
|
|
17
|
-
|
|
20
|
+
function canReroll(die, hasVersusDc) {
|
|
21
|
+
if (hasVersusDc && isVersusDc(die))
|
|
22
|
+
return false;
|
|
23
|
+
return !die.modifiers.includes('dropped');
|
|
18
24
|
}
|
|
19
25
|
export function applyRecursiveReroll(pool, operator, value, rng, env) {
|
|
20
26
|
const result = [];
|
|
21
27
|
for (const original of pool) {
|
|
22
|
-
if (!canReroll(original)) {
|
|
28
|
+
if (!canReroll(original, env.hasVersusDc)) {
|
|
23
29
|
result.push(original);
|
|
24
30
|
continue;
|
|
25
31
|
}
|
|
@@ -31,7 +37,7 @@ export function applyRecursiveReroll(pool, operator, value, rng, env) {
|
|
|
31
37
|
}
|
|
32
38
|
current.modifiers = rewriteFlags(current.modifiers, REROLL_SLOT_FLAGS, 'rerolled', 'dropped');
|
|
33
39
|
result.push(current);
|
|
34
|
-
current = rollReplacement(current
|
|
40
|
+
current = rollReplacement(current, rng, env);
|
|
35
41
|
iterations += 1;
|
|
36
42
|
}
|
|
37
43
|
current.modifiers = rewriteFlags(current.modifiers, REROLL_SLOT_FLAGS, 'kept');
|
|
@@ -42,7 +48,7 @@ export function applyRecursiveReroll(pool, operator, value, rng, env) {
|
|
|
42
48
|
export function applyRerollOnce(pool, operator, value, rng, env) {
|
|
43
49
|
const result = [];
|
|
44
50
|
for (const original of pool) {
|
|
45
|
-
if (!canReroll(original)) {
|
|
51
|
+
if (!canReroll(original, env.hasVersusDc)) {
|
|
46
52
|
result.push(original);
|
|
47
53
|
continue;
|
|
48
54
|
}
|
|
@@ -53,7 +59,7 @@ export function applyRerollOnce(pool, operator, value, rng, env) {
|
|
|
53
59
|
}
|
|
54
60
|
original.modifiers = rewriteFlags(original.modifiers, REROLL_SLOT_FLAGS, 'rerolled', 'dropped');
|
|
55
61
|
result.push(original);
|
|
56
|
-
const replacement = rollReplacement(original
|
|
62
|
+
const replacement = rollReplacement(original, rng, env);
|
|
57
63
|
replacement.modifiers = rewriteFlags(replacement.modifiers, REROLL_SLOT_FLAGS, 'kept');
|
|
58
64
|
result.push(replacement);
|
|
59
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reroll.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,SAAS,EAAgB,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAazE,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"reroll.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/reroll.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,5 +23,5 @@ import type { DieResult } from '../../types.js';
|
|
|
23
23
|
* Relies on `Array.prototype.sort` being stable — equal-valued dice retain
|
|
24
24
|
* their original insertion order.
|
|
25
25
|
*/
|
|
26
|
-
export declare function sortDice(dice: DieResult[], order: 'ascending' | 'descending'): DieResult[];
|
|
26
|
+
export declare function sortDice(dice: DieResult[], order: 'ascending' | 'descending', hasVersusDc: boolean): DieResult[];
|
|
27
27
|
//# sourceMappingURL=sort.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,
|
|
1
|
+
{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,SAAS,EAAE,EACjB,KAAK,EAAE,WAAW,GAAG,YAAY,EACjC,WAAW,EAAE,OAAO,GACnB,SAAS,EAAE,CAgBb"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isVersusDc } from './flags.js';
|
|
2
|
-
export function sortDice(dice, order) {
|
|
2
|
+
export function sortDice(dice, order, hasVersusDc) {
|
|
3
3
|
const cmp = order === 'ascending'
|
|
4
4
|
? (a, b) => a.result - b.result
|
|
5
5
|
: (a, b) => b.result - a.result;
|
|
6
|
-
|
|
7
|
-
if (sortable.length === dice.length)
|
|
6
|
+
if (!hasVersusDc || !dice.some(isVersusDc))
|
|
8
7
|
return [...dice].sort(cmp);
|
|
8
|
+
const sortable = dice.filter((die) => !isVersusDc(die));
|
|
9
9
|
sortable.sort(cmp);
|
|
10
10
|
let next = 0;
|
|
11
11
|
return dice.map((die) => (isVersusDc(die) ? die : sortable[next++]));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWxC,MAAM,UAAU,QAAQ,
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/sort.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAWxC,MAAM,UAAU,QAAQ,CACtB,IAAiB,EACjB,KAAiC,EACjC,WAAoB;IAEpB,MAAM,GAAG,GACP,KAAK,KAAK,WAAW;QACnB,CAAC,CAAC,CAAC,CAAY,EAAE,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM;QACrD,CAAC,CAAC,CAAC,CAAY,EAAE,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAI1D,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAIvE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,QAAQ,CAAC,IAAI,EAAE,CAAe,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
* excluded from counting and are never tagged.
|
|
11
11
|
*
|
|
12
12
|
* Mutates the input pool in place to add `'success'` / `'failure'` modifier
|
|
13
|
-
* flags — mirrors the mutation pattern of explode and reroll modifiers.
|
|
13
|
+
* flags — mirrors the mutation pattern of explode and reroll modifiers. Each
|
|
14
|
+
* tag is written at most once per die: a group counted after its members
|
|
15
|
+
* (`{4d6>=5}>=1`) runs this pass twice over the same dice, and the parse-time
|
|
16
|
+
* reject that blocks a direct `4d6>=5>=4` does not reach through a group.
|
|
14
17
|
*
|
|
15
18
|
* @module evaluator/modifiers/success-count
|
|
16
19
|
*/
|
|
@@ -20,5 +23,5 @@ export type SuccessCountResult = {
|
|
|
20
23
|
successes: number;
|
|
21
24
|
failures: number;
|
|
22
25
|
};
|
|
23
|
-
export declare function countSuccesses(dice: DieResult[], threshold: ResolvedComparePoint, failThreshold
|
|
26
|
+
export declare function countSuccesses(dice: DieResult[], threshold: ResolvedComparePoint, failThreshold: ResolvedComparePoint | undefined, hasVersusDc: boolean): SuccessCountResult;
|
|
24
27
|
//# sourceMappingURL=success-count.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"success-count.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"success-count.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAItE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,EAAE,EACjB,SAAS,EAAE,oBAAoB,EAC/B,aAAa,EAAE,oBAAoB,GAAG,SAAS,EAC/C,WAAW,EAAE,OAAO,GACnB,kBAAkB,CAmCpB"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { matchesCondition } from './compare.js';
|
|
2
2
|
import { isVersusDc } from './flags.js';
|
|
3
|
-
export function countSuccesses(dice, threshold, failThreshold) {
|
|
3
|
+
export function countSuccesses(dice, threshold, failThreshold, hasVersusDc) {
|
|
4
4
|
let successes = 0;
|
|
5
5
|
let failures = 0;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
continue;
|
|
6
|
+
const pool = hasVersusDc ? dice.filter((die) => !isVersusDc(die)) : dice;
|
|
7
|
+
for (const die of pool) {
|
|
9
8
|
if (die.modifiers.includes('dropped'))
|
|
10
9
|
continue;
|
|
11
10
|
if (matchesCondition(die.result, threshold.operator, threshold.value)) {
|
|
12
|
-
die.modifiers.
|
|
11
|
+
if (!die.modifiers.includes('success'))
|
|
12
|
+
die.modifiers.push('success');
|
|
13
13
|
successes += 1;
|
|
14
14
|
continue;
|
|
15
15
|
}
|
|
16
16
|
if (failThreshold != null &&
|
|
17
17
|
matchesCondition(die.result, failThreshold.operator, failThreshold.value)) {
|
|
18
|
-
die.modifiers.
|
|
18
|
+
if (!die.modifiers.includes('failure'))
|
|
19
|
+
die.modifiers.push('failure');
|
|
19
20
|
failures += 1;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"success-count.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"success-count.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/success-count.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQxC,MAAM,UAAU,cAAc,CAC5B,IAAiB,EACjB,SAA+B,EAC/B,aAA+C,EAC/C,WAAoB;IAEpB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,QAAQ,GAAG,CAAC,CAAC;IAQjB,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAMzE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS;QAEhD,IAAI,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtE,SAAS,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QAED,IACE,aAAa,IAAI,IAAI;YACrB,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,EACzE,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtE,QAAQ,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC9D,CAAC"}
|
package/dist/parser/ast.d.ts
CHANGED
|
@@ -56,8 +56,11 @@ export type DiceNode = NodeSpan & {
|
|
|
56
56
|
* Fate/Fudge dice node (`dF`).
|
|
57
57
|
* Each die produces a result in {-1, 0, +1}. No configurable sides.
|
|
58
58
|
*
|
|
59
|
-
* Fate dice carry `sides: 0` as a sentinel in their `DieResult`,
|
|
60
|
-
*
|
|
59
|
+
* Fate dice carry `sides: 0` as a sentinel in their `DieResult`, so the
|
|
60
|
+
* default `critical`/`fumble` rule never fires — it is guarded on `sides > 1`,
|
|
61
|
+
* which also stops a `+1` face from reading as a fumbled 1. An explicit
|
|
62
|
+
* threshold still applies: `4dFcs>0` and `4dFcf=-1` set the flags, while the
|
|
63
|
+
* bare `cs`/`cf` forms are rejected at parse time.
|
|
61
64
|
*
|
|
62
65
|
* @category AST
|
|
63
66
|
*/
|
|
@@ -295,9 +298,10 @@ export type SortNode = NodeSpan & {
|
|
|
295
298
|
readonly target: ASTNode;
|
|
296
299
|
};
|
|
297
300
|
/**
|
|
298
|
-
* Sentinel for bare `cs` / `cf` without a ComparePoint. Resolved
|
|
299
|
-
*
|
|
300
|
-
*
|
|
301
|
+
* Sentinel for bare `cs` / `cf` without a ComparePoint. Resolved at
|
|
302
|
+
* evaluation time against each die's own `sides` and its natural face
|
|
303
|
+
* (`initialResult ?? result`): critical when that face equals `sides`,
|
|
304
|
+
* fumble when it equals 1.
|
|
301
305
|
*
|
|
302
306
|
* @category AST
|
|
303
307
|
*/
|
|
@@ -305,8 +309,9 @@ export type CritThreshold = ComparePoint | 'default';
|
|
|
305
309
|
/**
|
|
306
310
|
* Critical threshold modifier node (`cs`, `cf`).
|
|
307
311
|
*
|
|
308
|
-
* Overrides the default `critical`/`fumble` flag logic for
|
|
309
|
-
*
|
|
312
|
+
* Overrides the default `critical`/`fumble` flag logic for `target`'s dice
|
|
313
|
+
* pool — including dice an enclosing `!` or `r` adds to it afterwards, which
|
|
314
|
+
* `target` never produced. Bare `cs`/`cf` uses the `'default'` sentinel
|
|
310
315
|
* (max face / 1). Custom thresholds accept any ComparePoint. Chaining
|
|
311
316
|
* collapses into a single node — `1d20cs=20cs=1cf>18` has two success
|
|
312
317
|
* and one fail threshold. Display-only: does not change `total`,
|
package/dist/parser/ast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"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"}
|
package/dist/parser/ast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/parser/ast.ts"],"names":[],"mappings":"AAoaA,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;AACtC,CAAC;AAUD,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC;AACtC,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;AACjC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,OAAO,CAAC,IAAa;IACnC,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC;AAC/B,CAAC;AAUD,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAUD,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,OAAO,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AACvC,CAAC;AAUD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breakdown rendering with consumer-supplied markers.
|
|
3
|
+
*
|
|
4
|
+
* `RollResult.rendered` bakes one markdown dialect into a string. This module
|
|
5
|
+
* rebuilds the same breakdown from `RollResult.parts`, letting the caller
|
|
6
|
+
* decide how each die is marked — HTML spans, ANSI codes, Telegram
|
|
7
|
+
* MarkdownV2, or nothing at all. Import it from `roll-parser/render`.
|
|
8
|
+
*
|
|
9
|
+
* @module render
|
|
10
|
+
*/
|
|
11
|
+
import type { DieResult, RollResult } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Per-die markers. Every slot is optional; an omitted slot leaves the die's
|
|
14
|
+
* text untouched, so `{}` renders a breakdown with no markup whatsoever.
|
|
15
|
+
*
|
|
16
|
+
* `text` arrives as the die's value already wrapped by any inner mark, and
|
|
17
|
+
* composition order is fixed: `critical` then `fumble` innermost, then
|
|
18
|
+
* exactly one of `dropped`, `success`, or `failure` outermost — matching the
|
|
19
|
+
* priority `RollResult.rendered` uses, where a dropped die is never also
|
|
20
|
+
* shown as a success.
|
|
21
|
+
*
|
|
22
|
+
* @example A die that is both critical and dropped
|
|
23
|
+
* ```typescript
|
|
24
|
+
* { critical: (_die, text) => `<b>${text}</b>`, dropped: (_die, text) => `<s>${text}</s>` }
|
|
25
|
+
* // renders <s><b>20</b></s>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @category Rendering
|
|
29
|
+
*/
|
|
30
|
+
export type DieMarks = {
|
|
31
|
+
/** Excluded from the total by `kh`/`kl`/`dh`/`dl`, a reroll, or group selection. */
|
|
32
|
+
dropped?: (die: DieResult, text: string) => string;
|
|
33
|
+
/** Met a success-count threshold. */
|
|
34
|
+
success?: (die: DieResult, text: string) => string;
|
|
35
|
+
/** Met a failure threshold. */
|
|
36
|
+
failure?: (die: DieResult, text: string) => string;
|
|
37
|
+
/** `DieResult.critical` — the default rule or an explicit `cs` threshold. */
|
|
38
|
+
critical?: (die: DieResult, text: string) => string;
|
|
39
|
+
/** `DieResult.fumble` — the default rule or an explicit `cf` threshold. */
|
|
40
|
+
fumble?: (die: DieResult, text: string) => string;
|
|
41
|
+
/**
|
|
42
|
+
* Wraps a whole sub-roll dropped by group selection (`{1d8, 1d10}kh1`).
|
|
43
|
+
*
|
|
44
|
+
* Inside it, `dropped`, `success`, and `failure` are suppressed — the
|
|
45
|
+
* wrapper already carries the verdict, and marking a dropped die inside a
|
|
46
|
+
* dropped sub-roll says nothing extra. `critical` and `fumble` still apply:
|
|
47
|
+
* they describe the face, not the selection. A nested `droppedGroup` also
|
|
48
|
+
* survives, so `{{1d6, 1d8}kh1, 1d10}kh1` can wrap twice.
|
|
49
|
+
*/
|
|
50
|
+
droppedGroup?: (inner: string) => string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The marks `RollResult.rendered` itself uses. Applied when
|
|
54
|
+
* {@link renderBreakdown} is called without a `marks` argument; spread it to
|
|
55
|
+
* override one slot while keeping the rest markdown.
|
|
56
|
+
*
|
|
57
|
+
* @category Rendering
|
|
58
|
+
*/
|
|
59
|
+
export declare const MARKDOWN_MARKS: DieMarks;
|
|
60
|
+
/**
|
|
61
|
+
* Rebuilds a roll's breakdown from `RollResult.parts`, applying `marks` to
|
|
62
|
+
* every die.
|
|
63
|
+
*
|
|
64
|
+
* With no `marks` the output is byte-identical to `RollResult.rendered` — a
|
|
65
|
+
* property test pins that over generated notation. Pass any object to take
|
|
66
|
+
* over: omitted slots render plain, so `{}` strips markup entirely and
|
|
67
|
+
* `{ ...MARKDOWN_MARKS, critical: … }` keeps the rest of the markdown.
|
|
68
|
+
*
|
|
69
|
+
* The trailing `= <total>` is included, and becomes the degree label for a
|
|
70
|
+
* `vs` roll, exactly as `rendered` does.
|
|
71
|
+
*
|
|
72
|
+
* @param result - A finished result from `roll` or `evaluate`
|
|
73
|
+
* @param marks - Per-die markers; defaults to {@link MARKDOWN_MARKS}
|
|
74
|
+
* @returns The rendered breakdown
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* import { roll } from 'roll-parser';
|
|
79
|
+
* import { renderBreakdown } from 'roll-parser/render';
|
|
80
|
+
* import { createMockRng } from 'roll-parser/testing';
|
|
81
|
+
*
|
|
82
|
+
* const result = roll('4d6kh3', { rng: createMockRng([3, 6, 2, 5]) });
|
|
83
|
+
*
|
|
84
|
+
* renderBreakdown(result); // '4d6[3, 6, ~~2~~, 5] = 14'
|
|
85
|
+
* renderBreakdown(result, {}); // '4d6[3, 6, 2, 5] = 14'
|
|
86
|
+
* renderBreakdown(result, {
|
|
87
|
+
* dropped: (_die, text) => `<s>${text}</s>`,
|
|
88
|
+
* critical: (_die, text) => `<b>${text}</b>`,
|
|
89
|
+
* }); // '4d6[3, <b>6</b>, <s>2</s>, 5] = 14'
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @category Rendering
|
|
93
|
+
*/
|
|
94
|
+
export declare function renderBreakdown(result: RollResult, marks?: DieMarks): string;
|
|
95
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,SAAS,EAKT,UAAU,EACX,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,oFAAoF;IACpF,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,+BAA+B;IAC/B,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,QAK5B,CAAC;AAuRF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,GAAE,QAAyB,GAAG,MAAM,CAI5F"}
|