roll-parser 3.0.0 → 3.2.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 +61 -1
- package/MIGRATION.md +293 -4
- package/README.md +246 -55
- 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 +57 -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 +104 -56
- package/dist/evaluator/evaluator.js.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.d.ts +43 -5
- package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.js +24 -11
- 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 +13 -5
- package/dist/evaluator/modifiers/explode.js.map +1 -1
- package/dist/evaluator/modifiers/flags.d.ts +17 -0
- package/dist/evaluator/modifiers/flags.d.ts.map +1 -1
- package/dist/evaluator/modifiers/flags.js +4 -4
- package/dist/evaluator/modifiers/flags.js.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.d.ts +5 -5
- 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 +6 -2
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
- package/dist/evaluator/modifiers/success-count.js +9 -5
- package/dist/evaluator/modifiers/success-count.js.map +1 -1
- package/dist/notation.d.ts +13 -0
- package/dist/notation.d.ts.map +1 -0
- package/dist/notation.js +8 -0
- package/dist/notation.js.map +1 -0
- 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/parser/guards.d.ts +38 -0
- package/dist/parser/guards.d.ts.map +1 -1
- package/dist/parser/guards.js +51 -0
- package/dist/parser/guards.js.map +1 -1
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +26 -2
- package/dist/parser/parser.js.map +1 -1
- package/dist/render.d.ts +95 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +232 -0
- package/dist/render.js.map +1 -0
- package/dist/types.d.ts +64 -12
- 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 +14 -4
- package/src/cli/format.ts +15 -23
- package/src/evaluator/die.ts +2 -1
- package/src/evaluator/env.ts +58 -0
- package/src/evaluator/evaluator.ts +192 -70
- package/src/evaluator/modifiers/crit-threshold.ts +81 -15
- package/src/evaluator/modifiers/die-bound.ts +13 -4
- package/src/evaluator/modifiers/explode.ts +21 -6
- package/src/evaluator/modifiers/flags.ts +21 -4
- package/src/evaluator/modifiers/keep-drop.ts +10 -8
- package/src/evaluator/modifiers/reroll.ts +20 -11
- package/src/evaluator/modifiers/sort.ts +9 -3
- package/src/evaluator/modifiers/success-count.ts +27 -5
- package/src/notation.ts +24 -0
- package/src/parser/ast.ts +12 -7
- package/src/parser/guards.ts +92 -1
- package/src/parser/parser.ts +56 -1
- package/src/render.ts +394 -0
- package/src/types.ts +64 -12
- package/src/version.ts +1 -1
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
import { matchesCondition } from './compare.js';
|
|
2
2
|
import { isVersusDc } from './flags.js';
|
|
3
|
-
export function applyCritThresholds(dice, successThresholds, failThresholds) {
|
|
3
|
+
export function applyCritThresholds(dice, successThresholds, failThresholds, env) {
|
|
4
|
+
const rule = { success: successThresholds, fail: failThresholds };
|
|
5
|
+
env.critRules ??= new WeakMap();
|
|
6
|
+
const rules = env.critRules;
|
|
4
7
|
for (const die of dice) {
|
|
5
|
-
if (die.modifiers.includes('meta')
|
|
8
|
+
if (die.modifiers.includes('meta'))
|
|
6
9
|
continue;
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
if (env.hasVersusDc && isVersusDc(die))
|
|
11
|
+
continue;
|
|
12
|
+
applyCritRule(die, rule, die.initialResult ?? die.result);
|
|
13
|
+
rules.set(die, rule);
|
|
9
14
|
}
|
|
10
15
|
}
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
function applyCritRule(die, rule, natural) {
|
|
17
|
+
die.critical = rule.success.some((t) => matchesThreshold(t, die, natural, die.sides));
|
|
18
|
+
die.fumble = rule.fail.some((t) => matchesThreshold(t, die, natural, 1));
|
|
19
|
+
}
|
|
20
|
+
export function inheritCritRule(env, parent, child) {
|
|
21
|
+
const rules = env.critRules;
|
|
22
|
+
if (rules === undefined)
|
|
23
|
+
return;
|
|
24
|
+
const rule = rules.get(parent);
|
|
25
|
+
if (rule === undefined)
|
|
26
|
+
return;
|
|
27
|
+
applyCritRule(child, rule, child.initialResult ?? child.result);
|
|
28
|
+
rules.set(child, rule);
|
|
16
29
|
}
|
|
17
|
-
function
|
|
30
|
+
function matchesThreshold(threshold, die, natural, defaultFace) {
|
|
18
31
|
if (threshold === 'default') {
|
|
19
|
-
return
|
|
32
|
+
return natural === defaultFace && die.sides > 1;
|
|
20
33
|
}
|
|
21
34
|
return matchesCondition(die.result, threshold.operator, threshold.value);
|
|
22
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crit-threshold.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/crit-threshold.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"crit-threshold.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/crit-threshold.ts"],"names":[],"mappings":"AA8CA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASxC,MAAM,UAAU,mBAAmB,CACjC,IAAiB,EACjB,iBAA0C,EAC1C,cAAuC,EACvC,GAAY;IAEZ,MAAM,IAAI,GAAa,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IAC5E,GAAG,CAAC,SAAS,KAAK,IAAI,OAAO,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC;IAE5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QAC7C,IAAI,GAAG,CAAC,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEjD,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAOD,SAAS,aAAa,CAAC,GAAc,EAAE,IAAc,EAAE,OAAe;IACpE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACtF,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAYD,MAAM,UAAU,eAAe,CAAC,GAAY,EAAE,MAAiB,EAAE,KAAgB;IAC/E,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC;IAC5B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAEhC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO;IAE/B,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAChE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACzB,CAAC;AAOD,SAAS,gBAAgB,CACvB,SAAgC,EAChC,GAAc,EACd,OAAe,EACf,WAAmB;IAEnB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,OAAO,KAAK,WAAW,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
* `initialResult` (first writer wins, so a compound-explode accumulation
|
|
7
7
|
* that was clamped afterwards still reports its original first roll), and
|
|
8
8
|
* the die is tagged `'min'` / `'max'` so parts consumers can tell a clamped
|
|
9
|
-
* value from a natural one.
|
|
9
|
+
* value from a natural one. The tag is written at most once, so a chain of
|
|
10
|
+
* same-kind bounds (`4d6min3min4`) leaves a die carrying a single `'min'`.
|
|
10
11
|
*
|
|
11
12
|
* `critical` / `fumble` keep reflecting the natural face — a clamped 1 is
|
|
12
13
|
* still a fumble, matching the raw-face crit semantics used everywhere else.
|
|
14
|
+
* A following bare `cs`/`cf` agrees; a following *explicit* threshold
|
|
15
|
+
* (`4d6min5cs>4`) is a predicate over the clamped value and overrides it.
|
|
13
16
|
* Meta dice (rolled to compute counts/sides/modifier args) are skipped.
|
|
14
17
|
* Dropped dice are clamped too — they are excluded from totals anyway, and
|
|
15
18
|
* clamping them keeps the rendered pool consistent.
|
|
@@ -22,5 +25,5 @@ import type { DieResult } from '../../types.js';
|
|
|
22
25
|
* `bound: 'min'` lifts lower results up to `value`; `'max'` caps higher
|
|
23
26
|
* results down to it. Untouched dice keep their tags.
|
|
24
27
|
*/
|
|
25
|
-
export declare function applyDieBound(dice: DieResult[], bound: 'min' | 'max', value: number): void;
|
|
28
|
+
export declare function applyDieBound(dice: DieResult[], bound: 'min' | 'max', value: number, hasVersusDc: boolean): void;
|
|
26
29
|
//# sourceMappingURL=die-bound.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"die-bound.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/die-bound.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"die-bound.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/die-bound.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EAAE,EACjB,KAAK,EAAE,KAAK,GAAG,KAAK,EACpB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,OAAO,GACnB,IAAI,CAYN"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { isVersusDc } from './flags.js';
|
|
2
|
-
export function applyDieBound(dice, bound, value) {
|
|
2
|
+
export function applyDieBound(dice, bound, value, hasVersusDc) {
|
|
3
3
|
for (const die of dice) {
|
|
4
|
-
if (die.modifiers.includes('meta')
|
|
4
|
+
if (die.modifiers.includes('meta'))
|
|
5
|
+
continue;
|
|
6
|
+
if (hasVersusDc && isVersusDc(die))
|
|
5
7
|
continue;
|
|
6
8
|
const clamped = bound === 'min' ? Math.max(die.result, value) : Math.min(die.result, value);
|
|
7
9
|
if (clamped === die.result)
|
|
8
10
|
continue;
|
|
9
11
|
die.initialResult ??= die.result;
|
|
10
12
|
die.result = clamped;
|
|
11
|
-
die.modifiers.
|
|
13
|
+
if (!die.modifiers.includes(bound))
|
|
14
|
+
die.modifiers.push(bound);
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
//# sourceMappingURL=die-bound.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"die-bound.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/die-bound.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"die-bound.js","sourceRoot":"","sources":["../../../src/evaluator/modifiers/die-bound.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAOxC,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,KAAoB,EACpB,KAAa,EACb,WAAoB;IAEpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QAC7C,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE7C,MAAM,OAAO,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5F,IAAI,OAAO,KAAK,GAAG,CAAC,MAAM;YAAE,SAAS;QAErC,GAAG,CAAC,aAAa,KAAK,GAAG,CAAC,MAAM,CAAC;QACjC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explode.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/explode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;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":"explode.d.ts","sourceRoot":"","sources":["../../../src/evaluator/modifiers/explode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;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;AAIpD;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,OAAQ,CAAC;AAEpD;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAE1E;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,GAAG,SAAS,EAC/B,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,aAAa,CAgBf;AAoGD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAEb;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAkCb;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,EAAE,EACjB,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,SAAS,EAAE,CAEb"}
|
|
@@ -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,13 @@ 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
|
+
if (die.result !== raw)
|
|
57
|
+
die.initialResult = raw;
|
|
58
|
+
if (env.insideVersus) {
|
|
59
|
+
env.explosionDice ??= new WeakSet();
|
|
60
|
+
env.explosionDice.add(die);
|
|
61
|
+
}
|
|
62
|
+
inheritCritRule(env, original, die);
|
|
55
63
|
result.push(die);
|
|
56
64
|
lastRaw = raw;
|
|
57
65
|
iterations += 1;
|
|
@@ -70,7 +78,7 @@ export function applyStandardExplode(pool, shouldExplode, rng, env) {
|
|
|
70
78
|
}
|
|
71
79
|
export function applyCompoundExplode(pool, shouldExplode, rng, env) {
|
|
72
80
|
for (const original of pool) {
|
|
73
|
-
if (!canExplode(original))
|
|
81
|
+
if (!canExplode(original, env.hasVersusDc))
|
|
74
82
|
continue;
|
|
75
83
|
const sides = original.sides;
|
|
76
84
|
let accumulated = original.result;
|
|
@@ -89,7 +97,7 @@ export function applyCompoundExplode(pool, shouldExplode, rng, env) {
|
|
|
89
97
|
}
|
|
90
98
|
if (!exploded)
|
|
91
99
|
continue;
|
|
92
|
-
original.initialResult
|
|
100
|
+
original.initialResult ??= original.result;
|
|
93
101
|
original.result = accumulated;
|
|
94
102
|
if (!original.modifiers.includes('exploded')) {
|
|
95
103
|
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,16 +18,33 @@ 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
|
|
24
|
+
* ! tag; 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. */
|
|
24
28
|
export declare const SELECTION_FLAGS: readonly DieModifier[];
|
|
29
|
+
/**
|
|
30
|
+
* Success-count tally flags — rebuilt by every counting pass. A group lets a
|
|
31
|
+
* second count reach a pool the first one already tagged (`{4d6>=5}<=2f5`);
|
|
32
|
+
* stripping these first is what keeps the outermost count the only one the
|
|
33
|
+
* tags describe.
|
|
34
|
+
*/
|
|
35
|
+
export declare const TALLY_FLAGS: readonly DieModifier[];
|
|
25
36
|
/**
|
|
26
37
|
* Selection flags plus the success-count tally flags. Stripped when a die
|
|
27
38
|
* leaves the pool that tagged it (meta sub-expressions, dropped group
|
|
28
39
|
* sub-rolls) so the top-level successes/failures scan cannot count it.
|
|
29
40
|
*/
|
|
30
41
|
export declare const SELECTION_AND_TALLY_FLAGS: readonly DieModifier[];
|
|
42
|
+
/**
|
|
43
|
+
* {@link SELECTION_AND_TALLY_FLAGS} plus `'meta'`, for a meta context merging
|
|
44
|
+
* into a parent. Meta operands nest (`((1d2)d4)d6`), so a die passes through
|
|
45
|
+
* the merge once per level and the tag must be rebuilt, not appended.
|
|
46
|
+
*/
|
|
47
|
+
export declare const META_MERGE_FLAGS: readonly DieModifier[];
|
|
31
48
|
/** Selection flags plus `rerolled` — reassigned on every reroll pass. */
|
|
32
49
|
export declare const REROLL_SLOT_FLAGS: readonly DieModifier[];
|
|
33
50
|
/** 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;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,WAAW,EAA2B,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,WAAW,EAG3D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAA2C,CAAC;AAE/F,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"}
|
|
@@ -2,12 +2,12 @@ export function isVersusDc(die) {
|
|
|
2
2
|
return die.modifiers.includes('dc');
|
|
3
3
|
}
|
|
4
4
|
export const SELECTION_FLAGS = ['kept', 'dropped'];
|
|
5
|
+
export const TALLY_FLAGS = ['success', 'failure'];
|
|
5
6
|
export const SELECTION_AND_TALLY_FLAGS = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
'success',
|
|
9
|
-
'failure',
|
|
7
|
+
...SELECTION_FLAGS,
|
|
8
|
+
...TALLY_FLAGS,
|
|
10
9
|
];
|
|
10
|
+
export const META_MERGE_FLAGS = [...SELECTION_AND_TALLY_FLAGS, 'meta'];
|
|
11
11
|
export const REROLL_SLOT_FLAGS = ['kept', 'dropped', 'rerolled'];
|
|
12
12
|
export function stripFlags(modifiers, excluded) {
|
|
13
13
|
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;AAQ3E,MAAM,CAAC,MAAM,WAAW,GAA2B,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAO1E,MAAM,CAAC,MAAM,yBAAyB,GAA2B;IAC/D,GAAG,eAAe;IAClB,GAAG,WAAW;CACf,CAAC;AAOF,MAAM,CAAC,MAAM,gBAAgB,GAA2B,CAAC,GAAG,yBAAyB,EAAE,MAAM,CAAC,CAAC;AAG/F,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,12 @@ 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
|
+
* Sums the dice a keep/drop pass left standing.
|
|
23
23
|
*
|
|
24
|
-
* @param
|
|
25
|
-
*
|
|
24
|
+
* @param hasVersusDc - Shared env flag; skips the DC exclusion when no `vs` has
|
|
25
|
+
* tagged anything
|
|
26
26
|
*/
|
|
27
|
-
export declare function sumKeptDice(dice: DieResult[]): number;
|
|
27
|
+
export declare function sumKeptDice(dice: DieResult[], hasVersusDc: boolean): number;
|
|
28
28
|
//# 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;;;;;GAKG;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":"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"}
|
|
@@ -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":"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,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAazE,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AAQnD,SAAS,eAAe,CAAC,MAAiB,EAAE,GAAQ,EAAE,GAAY;IAChE,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC3B,MAAM,GAAG,GACP,KAAK,KAAK,CAAC;QACT,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QAC7C,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAExD,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,aAAqB;IAC7C,OAAO,IAAI,cAAc,CACvB,6BAA6B,aAAa,WAAW,EACrD,uBAAuB,EACvB,QAAQ,CACT,CAAC;AACJ,CAAC;AAMD,SAAS,SAAS,CAAC,GAAc,EAAE,WAAoB;IACrD,IAAI,WAAW,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC5C,CAAC;AAUD,MAAM,UAAU,oBAAoB,CAClC,IAAiB,EACjB,QAAmB,EACnB,KAAa,EACb,GAAQ,EACR,GAAY;IAEZ,MAAM,MAAM,GAAgB,EAAE,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,GAAG,QAAQ,CAAC;QACvB,IAAI,UAAU,GAAG,CAAC,CAAC;QAInB,OAAO,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YACzD,IAAI,UAAU,IAAI,GAAG,CAAC,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,gBAAgB,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAClD,CAAC;YAED,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAC9F,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAErB,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAC7C,UAAU,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAC/E,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAOD,MAAM,UAAU,eAAe,CAC7B,IAAiB,EACjB,QAAmB,EACnB,KAAa,EACb,GAAQ,EACR,GAAY;IAEZ,MAAM,MAAM,GAAgB,EAAE,CAAC;IAE/B,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QAGD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YACxD,QAAQ,CAAC,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC;YACjF,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QAED,QAAQ,CAAC,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAChG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtB,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACxD,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -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,11 @@
|
|
|
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. The
|
|
14
|
+
* tags are rebuilt, not appended: a group counted after its members
|
|
15
|
+
* (`{4d6>=5}<=2f5`) runs this pass twice over the same dice, and the outermost
|
|
16
|
+
* pass is the one whose arithmetic `RollResult.successes` / `failures` and the
|
|
17
|
+
* rendered markers report.
|
|
14
18
|
*
|
|
15
19
|
* @module evaluator/modifiers/success-count
|
|
16
20
|
*/
|
|
@@ -20,5 +24,5 @@ export type SuccessCountResult = {
|
|
|
20
24
|
successes: number;
|
|
21
25
|
failures: number;
|
|
22
26
|
};
|
|
23
|
-
export declare function countSuccesses(dice: DieResult[], threshold: ResolvedComparePoint, failThreshold
|
|
27
|
+
export declare function countSuccesses(dice: DieResult[], threshold: ResolvedComparePoint, failThreshold: ResolvedComparePoint | undefined, hasVersusDc: boolean, poolAlreadyCounted: boolean): SuccessCountResult;
|
|
24
28
|
//# 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;;;;;;;;;;;;;;;;;;;GAmBG;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,EACpB,kBAAkB,EAAE,OAAO,GAC1B,kBAAkB,CAwCpB"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { matchesCondition } from './compare.js';
|
|
2
|
-
import { isVersusDc } from './flags.js';
|
|
3
|
-
export function countSuccesses(dice, threshold, failThreshold) {
|
|
2
|
+
import { isVersusDc, stripFlags, TALLY_FLAGS } from './flags.js';
|
|
3
|
+
export function countSuccesses(dice, threshold, failThreshold, hasVersusDc, poolAlreadyCounted) {
|
|
4
4
|
let successes = 0;
|
|
5
5
|
let failures = 0;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const pool = hasVersusDc ? dice.filter((die) => !isVersusDc(die)) : dice;
|
|
7
|
+
if (poolAlreadyCounted) {
|
|
8
|
+
for (const die of pool) {
|
|
9
|
+
die.modifiers = stripFlags(die.modifiers, TALLY_FLAGS);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
for (const die of pool) {
|
|
9
13
|
if (die.modifiers.includes('dropped'))
|
|
10
14
|
continue;
|
|
11
15
|
if (matchesCondition(die.result, threshold.operator, threshold.value)) {
|
|
@@ -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":"AAsBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQjE,MAAM,UAAU,cAAc,CAC5B,IAAiB,EACjB,SAA+B,EAC/B,aAA+C,EAC/C,WAAoB,EACpB,kBAA2B;IAE3B,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;IAKzE,IAAI,kBAAkB,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,GAAG,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,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,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,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,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,QAAQ,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notation serialization shared by the two breakdown builders — the
|
|
3
|
+
* evaluator's `expression`/`rendered` strings and `render.ts`.
|
|
4
|
+
*
|
|
5
|
+
* @module notation
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Appends a modifier code to the expression built so far, separating the two
|
|
9
|
+
* with a space when concatenating them would re-lex as a single identifier.
|
|
10
|
+
* The space is the same separator the input used to make them parse.
|
|
11
|
+
*/
|
|
12
|
+
export declare function joinModifierCode(expression: string, code: string): string;
|
|
13
|
+
//# sourceMappingURL=notation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notation.d.ts","sourceRoot":"","sources":["../src/notation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzE"}
|
package/dist/notation.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const BARE_MODIFIER_END = /(?:cs|cf|sd|s)$/;
|
|
2
|
+
const STARTS_WITH_LETTER = /^[A-Za-z]/;
|
|
3
|
+
export function joinModifierCode(expression, code) {
|
|
4
|
+
return BARE_MODIFIER_END.test(expression) && STARTS_WITH_LETTER.test(code)
|
|
5
|
+
? `${expression} ${code}`
|
|
6
|
+
: `${expression}${code}`;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=notation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notation.js","sourceRoot":"","sources":["../src/notation.ts"],"names":[],"mappings":"AAUA,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAE5C,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAOvC,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,IAAY;IAC/D,OAAO,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QACxE,CAAC,CAAC,GAAG,UAAU,IAAI,IAAI,EAAE;QACzB,CAAC,CAAC,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC;AAC7B,CAAC"}
|