@yipe/dice 0.8.1 → 0.10.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/README.md +169 -19
- package/dist/builder/ac.d.ts.map +1 -1
- package/dist/builder/ast.d.ts +32 -2
- package/dist/builder/ast.d.ts.map +1 -1
- package/dist/builder/attack.d.ts.map +1 -1
- package/dist/builder/dc.d.ts.map +1 -1
- package/dist/builder/example.d.ts +4 -4
- package/dist/builder/example.d.ts.map +1 -1
- package/dist/builder/index.cjs +889 -90
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.d.ts +1 -0
- package/dist/builder/index.d.ts.map +1 -1
- package/dist/builder/index.js +886 -91
- package/dist/builder/index.js.map +1 -1
- package/dist/builder/roll.d.ts +5 -1
- package/dist/builder/roll.d.ts.map +1 -1
- package/dist/builder/save.d.ts.map +1 -1
- package/dist/index.cjs +178 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +177 -16
- package/dist/index.js.map +1 -1
- package/dist/parser/dice.d.ts +14 -0
- package/dist/parser/dice.d.ts.map +1 -1
- package/dist/parser/rollType.d.ts +58 -0
- package/dist/parser/rollType.d.ts.map +1 -0
- package/dist/pmf/pmf.d.ts +10 -4
- package/dist/pmf/pmf.d.ts.map +1 -1
- package/dist/pmf/query.d.ts +26 -0
- package/dist/pmf/query.d.ts.map +1 -1
- package/dist/turn/index.d.ts +3 -0
- package/dist/turn/index.d.ts.map +1 -0
- package/dist/turn/plan.d.ts +55 -0
- package/dist/turn/plan.d.ts.map +1 -0
- package/dist/turn/state.d.ts +23 -0
- package/dist/turn/state.d.ts.map +1 -0
- package/dist/turn/turn.d.ts +149 -0
- package/dist/turn/turn.d.ts.map +1 -0
- package/dist/turn/types.d.ts +99 -0
- package/dist/turn/types.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/parser/dice.d.ts
CHANGED
|
@@ -8,6 +8,20 @@ export interface DicePrivateData {
|
|
|
8
8
|
except?: Dice | Record<string, never>;
|
|
9
9
|
/** Keep-highest/lowest selector applied when a die is multiplied out. */
|
|
10
10
|
keep?: (values: number[]) => number;
|
|
11
|
+
/** Set on a freshly parsed flat `dN`/`hdN` atom: its own face count and whether it rerolls a
|
|
12
|
+
* natural 1 once (Halfling Luck). Read by {@link parseExpression} in parser.ts to recover a
|
|
13
|
+
* base check die's natural-max identity after it has been convolved with bonus to-hit dice
|
|
14
|
+
* and modifiers, for a correct plain-`crit` probability. See parser.ts's "Track a flat ...
|
|
15
|
+
* base check die" comment. */
|
|
16
|
+
checkDie?: {
|
|
17
|
+
sides: number;
|
|
18
|
+
rerollOne: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** Set on the result of a tracked AC gate (see parser.ts): the exact "natural max, any bonus
|
|
21
|
+
* roll" sub-distribution, already isolated from the rest of the to-hit total. A plain `crit`
|
|
22
|
+
* clause reads this directly instead of peeling the combined expression's single highest
|
|
23
|
+
* face, which is wrong whenever bonus dice are present. */
|
|
24
|
+
natMaxCritSlice?: Dice;
|
|
11
25
|
}
|
|
12
26
|
/**
|
|
13
27
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dice.d.ts","sourceRoot":"","sources":["../../src/parser/dice.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,kBAAkB,EAElB,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAYjC,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iEAAiE;IACjE,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,yEAAyE;IACzE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"dice.d.ts","sourceRoot":"","sources":["../../src/parser/dice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { RollType } from "../common/types.js";
|
|
2
|
+
import { PMF } from "../pmf/pmf.js";
|
|
3
|
+
/**
|
|
4
|
+
* Parse without throwing — for UI code that reparses on every keystroke, where
|
|
5
|
+
* a transiently invalid expression is normal rather than exceptional.
|
|
6
|
+
*
|
|
7
|
+
* Also accepts a *signed* integer, which the grammar rejects: `"-3"` becomes a
|
|
8
|
+
* delta at -3, `"+7"` one at 7. Unsigned integers need no help — `parse("7")`
|
|
9
|
+
* already returns a delta at 7 — but a half-typed damage field is a bare signed
|
|
10
|
+
* number often enough to be worth covering.
|
|
11
|
+
*
|
|
12
|
+
* The failure value is {@link PMF.empty}, which has **mass 0**, not a
|
|
13
|
+
* distribution. Convolving it collapses the whole result to mass 0, so a caller
|
|
14
|
+
* combining several expressions should check `mass()` (or skip empties) rather
|
|
15
|
+
* than assume a usable PMF. Anywhere a bad expression should be surfaced instead
|
|
16
|
+
* of absorbed, call {@link parse} and handle `DiceParseError`.
|
|
17
|
+
*
|
|
18
|
+
* Takes no second argument on purpose. {@link parse}'s is `n`, the substitution
|
|
19
|
+
* value for an `n`-dice expression — not an epsilon — so forwarding one here
|
|
20
|
+
* would silently reinterpret it: `tryParse("nd6", 1e-9)` rolled `1d6` and
|
|
21
|
+
* reported 3.5 where the default `n` of 0 means no dice at all.
|
|
22
|
+
*
|
|
23
|
+
* @returns the parsed PMF, or an empty (mass 0) PMF for input that is neither a
|
|
24
|
+
* valid expression nor an integer.
|
|
25
|
+
*/
|
|
26
|
+
export declare function tryParse(expression: string): PMF;
|
|
27
|
+
/**
|
|
28
|
+
* Rewrite an expression's attack roll to a different d20 {@link RollType},
|
|
29
|
+
* leaving everything else — damage, crit clause, miss clause, bonuses —
|
|
30
|
+
* untouched.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* withRollType("(d20 + 8 AC 16) * (1d4 + 4)", "advantage");
|
|
34
|
+
* // "(d20 > d20 + 8 AC 16) * (1d4 + 4)"
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* **Every** `AC` group is rewritten, because one expression can hold several
|
|
38
|
+
* attacks (`(d20 + 8 AC 16) * (1d8) + (d20 + 5 AC 16) * (1d6)`) and leaving the
|
|
39
|
+
* later ones flat would quietly chart the wrong curve.
|
|
40
|
+
*
|
|
41
|
+
* A `DC` group is the *target's* saving throw, which the attacker's advantage
|
|
42
|
+
* does not touch, so save expressions come back unchanged — as does anything
|
|
43
|
+
* with no attack roll at all. This makes the function safe to map over a mixed
|
|
44
|
+
* list of expressions.
|
|
45
|
+
*
|
|
46
|
+
* Assumes **one check per group**, which is what every well-formed attack or
|
|
47
|
+
* save expression looks like and what `modelToExpression` emits. The grammar
|
|
48
|
+
* will swallow a group naming two — `(d20 + 5 DC 16 + d20 + 8 AC 16)` parses,
|
|
49
|
+
* as a single `AC` check whose roll happens to contain the save's 0/1 result —
|
|
50
|
+
* but that is not an expression anyone means, and the roll type it should get is
|
|
51
|
+
* undefined. Such input is rewritten on a best-effort basis rather than
|
|
52
|
+
* diagnosed.
|
|
53
|
+
*
|
|
54
|
+
* A halfling-luck `h` prefix is preserved on the first die of each run, since it
|
|
55
|
+
* describes the same roll.
|
|
56
|
+
*/
|
|
57
|
+
export declare function withRollType(expression: string, rollType: RollType): string;
|
|
58
|
+
//# sourceMappingURL=rollType.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollType.d.ts","sourceRoot":"","sources":["../../src/parser/rollType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAMjC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAchD;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAkB3E"}
|
package/dist/pmf/pmf.d.ts
CHANGED
|
@@ -270,10 +270,16 @@ export declare class PMF {
|
|
|
270
270
|
scaleDamage(factor: number, rounding?: "floor" | "round" | "ceil"): PMF;
|
|
271
271
|
private getPMFCombineCacheKey;
|
|
272
272
|
/**
|
|
273
|
-
* A
|
|
274
|
-
* cache keys change
|
|
275
|
-
*
|
|
276
|
-
*
|
|
273
|
+
* A content fingerprint of every bin (probability, per-label `count`, per-label `attr`) plus
|
|
274
|
+
* the `normalized` flag, so convolution/power cache keys change whenever the underlying
|
|
275
|
+
* numbers do. Mass/bin-count/face-sum alone are not content-unique: `mapDamage` variants can
|
|
276
|
+
* keep the same identifier, support, mass, and face sum while differing in per-bin
|
|
277
|
+
* probabilities or in the `count`/`attr` channels `convolve()`/`power()` actually propagate --
|
|
278
|
+
* that previously let `power()` return one PMF's cached result for a different PMF. Memoized
|
|
279
|
+
* because a PMF is immutable once constructed -- this avoids re-deriving the key on every
|
|
280
|
+
* convolve()/power() call (including cache hits). Bin order is sorted by damage value (and
|
|
281
|
+
* label keys sorted within each bin) so two equal-content PMFs built via different code paths
|
|
282
|
+
* fingerprint identically regardless of Map insertion order.
|
|
277
283
|
*/
|
|
278
284
|
fingerprint(): string;
|
|
279
285
|
convolve(other: PMF, eps?: number, raw?: boolean): PMF;
|
package/dist/pmf/pmf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pmf.d.ts","sourceRoot":"","sources":["../../src/pmf/pmf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAmB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAOtE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAIpC,eAAO,MAAM,QAAQ,uBAAkC,CAAC;AAExD;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sFAAsF;IACtF,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,2FAA2F;IAC3F,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,uGAAuG;IACvG,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9B;;;;OAIG;IACH,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9B,iGAAiG;IACjG,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oFAAoF;IACpF,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,GAAG;aAeI,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;aACrB,OAAO;aACP,UAAU;aACV,UAAU,EAAE,MAAM;IAClC,OAAO,CAAC,oBAAoB;IAjB9B,OAAO,CAAC,MAAM,CAAC,eAAe,CAAK;IAGnC,OAAO,CAAC,QAAQ,CAAC,CAAW;IAC5B,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAS;IAE9B,YACkB,GAAG,GAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAa,EACjC,OAAO,SAAM,EACb,UAAU,UAAQ,EAClB,UAAU,GAAE,MAAwC,EAC5D,oBAAoB,UAAO,EACjC;IAEJ,MAAM,CAAC,KAAK,CAAC,OAAO,SAAM,EAAE,UAAU,SAAU,OAE/C;IAGD,MAAM,CAAC,IAAI,CAAC,OAAO,SAAM,GAAG,GAAG,CAI9B;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAM,GAAG,GAAG,CAE9C;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAM,GAAG,GAAG,CAIlC;IAGD,MAAM,CAAC,SAAS,IAAI,GAAG,CAEtB;IAGD,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAEnD;IAED,MAAM,CAAC,UAAU,SAEhB;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,CACX,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,GAAG,EACf,kBAAkB,EAAE,MAAM,GACzB,GAAG,CAmCL;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,GAAG,CAEhE;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAE5B;IAED;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,SAAS,CACd,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAC5D,GAAG,SAAM,GACR,GAAG,CAsCL;IAED;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,GAAG,CACR,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAC5D,GAAG,SAAM,GACR,GAAG,CAkBL;IACD;;;;;;;;OAQG;IACH;;;;;OAKG;IACH,cAAc,IAAI,OAAO,CASxB;IAED,eAAe,IAAI,GAAG,CAgCrB;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,SAAM,GAAG,GAAG,CAyBpD;IAMD,OAAO,CAAC,sBAAsB;IASvB,mBAAmB,IAAI,OAAO,CAEpC;IAED,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"pmf.d.ts","sourceRoot":"","sources":["../../src/pmf/pmf.ts"],"names":[],"mappings":"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"}
|
package/dist/pmf/query.d.ts
CHANGED
|
@@ -457,6 +457,32 @@ export declare class DiceQuery {
|
|
|
457
457
|
avg: number;
|
|
458
458
|
max: number;
|
|
459
459
|
}>;
|
|
460
|
+
/**
|
|
461
|
+
* Per-outcome probabilities and damage ranges, aggregated over the individual
|
|
462
|
+
* singles rather than read off the combined distribution.
|
|
463
|
+
*
|
|
464
|
+
* `damageRange` is the sum, over every single that can produce the outcome, of
|
|
465
|
+
* that single's own conditional damage range: "what this outcome contributes
|
|
466
|
+
* across the whole turn when every attack that can produce it does". Linear in
|
|
467
|
+
* the number of attacks by construction.
|
|
468
|
+
*
|
|
469
|
+
* Prefer this over {@link DiceQuery.snapshot} for a multi-attack query.
|
|
470
|
+
* `snapshot` reads `damageRange` off the combined PMF's `count`, which the
|
|
471
|
+
* convolution accumulates as an expected count, so its `avg` is size-biased
|
|
472
|
+
* for N≥2 (its own doc comment says so). The two agree for a single attack.
|
|
473
|
+
*
|
|
474
|
+
* Only outcomes that actually occur appear in the result.
|
|
475
|
+
*
|
|
476
|
+
* Like every `singles`-based helper on this class, it describes the singles
|
|
477
|
+
* and not an explicitly provided `combined`. `Turn.toQuery()` supplies one whose
|
|
478
|
+
* distribution also contains rider attacks that are absent from `singles`
|
|
479
|
+
* (an `otherwise([unarmed, unarmed])` flurry, say), so those attacks do not
|
|
480
|
+
* appear here. For rider-inclusive figures read the combined distribution
|
|
481
|
+
* directly: {@link DiceQuery.outcomeTotals}, {@link DiceQuery.outcomeDamageRanges}.
|
|
482
|
+
*
|
|
483
|
+
* @param outcomes Which outcomes to consider; defaults to every canonical one.
|
|
484
|
+
*/
|
|
485
|
+
outcomeStats(outcomes?: readonly OutcomeType[]): Map<OutcomeType, OutcomeSnapshot>;
|
|
460
486
|
/**
|
|
461
487
|
* Snapshot of the distribution in the exact shape the UI consumes.
|
|
462
488
|
* - outcome probabilities are "at least one" (and equal to "all" for a single PMF)
|
package/dist/pmf/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/pmf/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,OAAO,CAAC;AAEzD;;;;;;;;;GASG;AAEH,qBAAa,SAAS;IACpB,SAAgB,OAAO,EAAE,GAAG,EAAE,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,SAAS,CAAC,CAAM;IACxB,OAAO,CAAC,iBAAiB,CAAC,CAAM;IAEhC,YAAY,OAAO,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,SAAM,EAe1D;IAED;;;;;;;OAOG;IACH,IAAI,QAAQ,IAAI,GAAG,CAOlB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAI7B;IAEX;;;;;;;;;;;;;;;;;;OAkBG;IACH,uBAAuB,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/pmf/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/turn/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { PMF } from "../pmf/pmf.js";
|
|
2
|
+
import type { Trigger, TurnSpec } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* A resolved, validated turn: the ordered steps to walk, plus the trigger
|
|
5
|
+
* groups it tracks. Building this is where every {@link TurnSpecError} is raised,
|
|
6
|
+
* so the walk itself can assume a well-formed plan.
|
|
7
|
+
*/
|
|
8
|
+
export interface TurnPlan {
|
|
9
|
+
steps: readonly Step[];
|
|
10
|
+
/** One entry per distinct `of` set; each holds the step indices that update it. */
|
|
11
|
+
groupCount: number;
|
|
12
|
+
/** Declared attacks only, in order — what `DiceQuery.singles` gets. */
|
|
13
|
+
attackPMFs: readonly PMF[];
|
|
14
|
+
/** Every attack id, in declaration order. */
|
|
15
|
+
attackIds: readonly string[];
|
|
16
|
+
/** Every rider id, in declaration order, including `every-hit` riders. */
|
|
17
|
+
riderIds: readonly string[];
|
|
18
|
+
/** Rider id → step index, for `fireProbability` and `not-fired`. */
|
|
19
|
+
riderSteps: ReadonlyMap<string, number>;
|
|
20
|
+
/**
|
|
21
|
+
* `every-hit` rider id → the group index whose "something landed" bit answers
|
|
22
|
+
* P(it fired at least once). Such riders are folded into their sources' slices
|
|
23
|
+
* rather than becoming steps, so they have no step index.
|
|
24
|
+
*/
|
|
25
|
+
perHitGroups: ReadonlyMap<string, number>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One step of the turn. `slices` non-null ⇒ the step rolls its own attack and
|
|
29
|
+
* advances the groups listed in `updates`; null ⇒ it is pure damage whose amount
|
|
30
|
+
* depends only on the mode it fires in.
|
|
31
|
+
*/
|
|
32
|
+
export interface Step {
|
|
33
|
+
id: string;
|
|
34
|
+
/** Declared attacks always fire; riders consult their trigger. */
|
|
35
|
+
trigger: Trigger | null;
|
|
36
|
+
/** Outcome-labelled sub-mass PMFs, masses summing to 1. */
|
|
37
|
+
slices: {
|
|
38
|
+
hit: PMF;
|
|
39
|
+
crit: PMF;
|
|
40
|
+
miss: PMF;
|
|
41
|
+
} | null;
|
|
42
|
+
/** Pure-damage payloads, mass 1 each. */
|
|
43
|
+
damage: {
|
|
44
|
+
hit: PMF;
|
|
45
|
+
crit: PMF;
|
|
46
|
+
} | null;
|
|
47
|
+
/** Group indices this step's outcome advances. */
|
|
48
|
+
updates: readonly number[];
|
|
49
|
+
/** Group index this step's trigger reads, or -1 for `not-fired` / always-fires. */
|
|
50
|
+
reads: number;
|
|
51
|
+
/** For `not-fired`: the step index of the rider being negated. */
|
|
52
|
+
negates: number;
|
|
53
|
+
}
|
|
54
|
+
export declare function buildPlan(spec: TurnSpec, eps?: number): TurnPlan;
|
|
55
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/turn/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAKV,OAAO,EACP,QAAQ,EAET,MAAM,SAAS,CAAC;AAGjB;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,UAAU,EAAE,SAAS,GAAG,EAAE,CAAC;IAC3B,6CAA6C;IAC7C,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,oEAAoE;IACpE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;OAIG;IACH,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,2DAA2D;IAC3D,MAAM,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI,CAAC;IAClD,yCAAyC;IACzC,MAAM,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,IAAI,CAAC;IACvC,kDAAkD;IAClD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;CACjB;AA6FD,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAY,GAAG,QAAQ,CAoRrE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-group trigger state, packed into one byte.
|
|
3
|
+
*
|
|
4
|
+
* A "group" is one distinct set of source ids referenced by a trigger. Everything
|
|
5
|
+
* any trigger needs to know about a group is which outcome landed *first*, whether
|
|
6
|
+
* anything crit, and whether anything missed — so the whole turn state is one byte
|
|
7
|
+
* per group and the state space stays small (12 codes per group, ~10 reachable).
|
|
8
|
+
*
|
|
9
|
+
* Layout: `first << 2 | anyCrit << 1 | anyMiss`, where `first` is one of
|
|
10
|
+
* {@link FIRST_NONE} / {@link FIRST_HIT} / {@link FIRST_CRIT}. Readers decode with
|
|
11
|
+
* `code >> 2`, `code & CRIT_BIT`, `code & MISS_BIT`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const FIRST_NONE = 0;
|
|
14
|
+
export declare const FIRST_HIT = 1;
|
|
15
|
+
export declare const FIRST_CRIT = 2;
|
|
16
|
+
export declare const CRIT_BIT = 2;
|
|
17
|
+
export declare const MISS_BIT = 1;
|
|
18
|
+
/** A group that has seen nothing yet: no first landing, no crit, no miss. */
|
|
19
|
+
export declare const START_CODE: number;
|
|
20
|
+
export type StepOutcome = "hit" | "crit" | "miss";
|
|
21
|
+
/** Fold one source outcome into a group's state. */
|
|
22
|
+
export declare function advance(code: number, outcome: StepOutcome): number;
|
|
23
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/turn/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,eAAO,MAAM,QAAQ,IAAI,CAAC;AAC1B,eAAO,MAAM,QAAQ,IAAI,CAAC;AAE1B,6EAA6E;AAC7E,eAAO,MAAM,UAAU,QAAkB,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,oDAAoD;AACpD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CASlE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { PMF } from "../pmf/pmf.js";
|
|
2
|
+
import { DiceQuery } from "../pmf/query.js";
|
|
3
|
+
import type { Attack, Rider, RiderDamage, RiderOptions, Source, TurnSpec } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* A turn of attacks plus conditional damage riders, resolved to one **exact**
|
|
6
|
+
* joint distribution.
|
|
7
|
+
*
|
|
8
|
+
* Riders are correlated with the attacks that trigger them, so a rider cannot be
|
|
9
|
+
* a separate `DiceQuery` single convolved in afterwards: that preserves the mean
|
|
10
|
+
* but corrupts the distribution (two daggers + Sneak Attack report P(0 damage) of
|
|
11
|
+
* 0.015 instead of the true 0.1225). `Turn` owns the sources and enumerates the
|
|
12
|
+
* joint outcome space instead, carrying one byte of state per trigger group.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const dagger = d20.plus(8).ac(16).onHit(d4.plus(4));
|
|
16
|
+
* const rogue = turn([dagger, dagger]).rider({ damage: roll(3, d6), on: "first-hit" });
|
|
17
|
+
* rogue.mean(); // 18.6225
|
|
18
|
+
*/
|
|
19
|
+
export declare class Turn {
|
|
20
|
+
private readonly eps;
|
|
21
|
+
private readonly declaredAttacks;
|
|
22
|
+
private readonly riders;
|
|
23
|
+
private readonly plan;
|
|
24
|
+
private resolved?;
|
|
25
|
+
private constructor();
|
|
26
|
+
/**
|
|
27
|
+
* Builds a turn from plain data, throwing {@link TurnSpecError} if it is
|
|
28
|
+
* malformed. Use this from a UI, where `error.code` maps to the field state to
|
|
29
|
+
* show.
|
|
30
|
+
*/
|
|
31
|
+
static from(spec: TurnSpec, eps?: number): Turn;
|
|
32
|
+
/**
|
|
33
|
+
* Appends an attack, throwing {@link TurnSpecError} if that makes the turn
|
|
34
|
+
* invalid.
|
|
35
|
+
*
|
|
36
|
+
* A rider with no explicit `of` watches every declared attack *including ones
|
|
37
|
+
* appended after it*, because `of` is resolved when the plan is built rather
|
|
38
|
+
* than when the rider is added. Pass an explicit `of` to pin a rider to the
|
|
39
|
+
* attacks it already saw. One attack must exist before a rider with a default
|
|
40
|
+
* `of` is added, or the build fails `unknown-id`.
|
|
41
|
+
*/
|
|
42
|
+
attack(source: Source, id?: string): Turn;
|
|
43
|
+
/**
|
|
44
|
+
* Appends `count` copies of the same attack — the Extra Attack case, which is
|
|
45
|
+
* most of 5e. Argument order mirrors `roll(count, die)`.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* turn().attacks(4, greatsword).onEveryHit(d6); // fighter 20 + hunter's mark
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @throws {RangeError} if `count` is not a positive integer.
|
|
52
|
+
*/
|
|
53
|
+
attacks(count: number, source: Source): Turn;
|
|
54
|
+
/**
|
|
55
|
+
* Appends a rider, throwing {@link TurnSpecError} if that makes the turn
|
|
56
|
+
* invalid. The `onX` methods below are the readable way to call this.
|
|
57
|
+
*/
|
|
58
|
+
rider(rider: Rider): Turn;
|
|
59
|
+
/**
|
|
60
|
+
* Fires once, on the first source that lands, in that source's mode — so a
|
|
61
|
+
* crit on the first landing attack doubles the rider's dice. Sneak Attack.
|
|
62
|
+
*/
|
|
63
|
+
onFirstHit(damage: RiderDamage, options?: RiderOptions): Turn;
|
|
64
|
+
/**
|
|
65
|
+
* Fires once if any source crit, always in crit mode. Divine Smite: nothing is
|
|
66
|
+
* lost by holding it for a crit, so this is "any", not "first".
|
|
67
|
+
*/
|
|
68
|
+
onAnyCrit(damage: RiderDamage, options?: RiderOptions): Turn;
|
|
69
|
+
/**
|
|
70
|
+
* Fires once if any source missed. The reroll gate: a reroll is a fresh attack,
|
|
71
|
+
* so pass one as the damage. Kensei's Unerring Accuracy, Lucky.
|
|
72
|
+
*/
|
|
73
|
+
onAnyMiss(damage: RiderDamage, options?: RiderOptions): Turn;
|
|
74
|
+
/**
|
|
75
|
+
* Fires once per source that lands, in that hit's mode — so it can fire several
|
|
76
|
+
* times in a turn. Hunter's Mark, Hex, Rage.
|
|
77
|
+
*/
|
|
78
|
+
onEveryHit(damage: RiderDamage, options?: RiderOptions): Turn;
|
|
79
|
+
/**
|
|
80
|
+
* Damage for the turns where the rider added just before this one did *not*
|
|
81
|
+
* fire: "flurry of blows if I didn't smite".
|
|
82
|
+
*
|
|
83
|
+
* ```ts
|
|
84
|
+
* turn([dagger, dagger])
|
|
85
|
+
* .onAnyCrit(roll(2, d8)) // smite
|
|
86
|
+
* .otherwise([flurry, flurry]) // ... or two more attacks
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* Always binds to the *immediately* preceding rider, so the two are branches of
|
|
90
|
+
* one decision and can never both land. Note that chaining it therefore
|
|
91
|
+
* alternates rather than laddering: `a.otherwise(b).otherwise(c)` makes `c`
|
|
92
|
+
* fire whenever `b` did not, which is exactly when `a` did. For a genuine
|
|
93
|
+
* three-way priority chain, name the riders and use explicit `not-fired`
|
|
94
|
+
* triggers against the right one.
|
|
95
|
+
*/
|
|
96
|
+
otherwise(damage: RiderDamage, options?: Omit<RiderOptions, "of">): Turn;
|
|
97
|
+
/**
|
|
98
|
+
* The exact joint distribution: mass 1, outcome-labelled. Resolved once and
|
|
99
|
+
* cached.
|
|
100
|
+
*
|
|
101
|
+
* There is no `toPMF(eps)` to match the builders: a turn's epsilon is fixed
|
|
102
|
+
* when it is constructed, because the plan is validated and its sources are
|
|
103
|
+
* resolved at that point.
|
|
104
|
+
*/
|
|
105
|
+
get pmf(): PMF;
|
|
106
|
+
/** Mean damage for the turn. */
|
|
107
|
+
mean(): number;
|
|
108
|
+
/**
|
|
109
|
+
* A query whose `singles` are the **declared attacks** and whose combined
|
|
110
|
+
* distribution is the exact turn PMF.
|
|
111
|
+
*
|
|
112
|
+
* Riders are inside the combined PMF, not in `singles`, so singles-based
|
|
113
|
+
* helpers (`probAtLeastOne`, `countSinglesWith`, `outcomeStats`) describe the
|
|
114
|
+
* attacks only. Read rider-inclusive statistics off the combined PMF —
|
|
115
|
+
* `outcomeTotals`, `outcomeDamageRanges`, `damageAttributionChartModel`.
|
|
116
|
+
*/
|
|
117
|
+
toQuery(): DiceQuery;
|
|
118
|
+
/**
|
|
119
|
+
* Attack ids in declaration order, including the `attack 1`, `attack 2`, …
|
|
120
|
+
* defaults given to bare sources. These are the names `of` accepts.
|
|
121
|
+
*/
|
|
122
|
+
get attackIds(): readonly string[];
|
|
123
|
+
/**
|
|
124
|
+
* Rider ids in declaration order, including the `rider 1`, `rider 2`, …
|
|
125
|
+
* defaults. These are the names {@link Turn.fireProbability} accepts.
|
|
126
|
+
*/
|
|
127
|
+
get riderIds(): readonly string[];
|
|
128
|
+
/**
|
|
129
|
+
* P(this rider fired). For an `every-hit` rider it is P(at least one source
|
|
130
|
+
* hit), since that rider can fire more than once in a turn.
|
|
131
|
+
*
|
|
132
|
+
* @throws {TurnSpecError} `unknown-id` if `id` is not a rider — attack ids
|
|
133
|
+
* included, since attacks always happen and have no firing probability.
|
|
134
|
+
*/
|
|
135
|
+
fireProbability(id: string): number;
|
|
136
|
+
private resolve;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Starts a {@link Turn}. Takes one attack or a list of them, so the two common
|
|
140
|
+
* shapes both read straight:
|
|
141
|
+
*
|
|
142
|
+
* ```ts
|
|
143
|
+
* turn(greatsword).onAnyCrit(roll(4, d8)); // one attack
|
|
144
|
+
* turn([dagger, dagger]).onFirstHit(roll(3, d6)); // two
|
|
145
|
+
* turn().attacks(4, greatsword); // four
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export declare function turn(attacks?: Attack | readonly Attack[], eps?: number): Turn;
|
|
149
|
+
//# sourceMappingURL=turn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../../src/turn/turn.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAYzC,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EACL,WAAW,EACX,YAAY,EACZ,MAAM,EACN,QAAQ,EACT,MAAM,SAAS,CAAC;AA6CjB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoB;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAsD;IAEvE,OAAO,eAeN;IAED;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAY,GAAG,IAAI,CAEnD;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAGxC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ3C;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAExB;IAED;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI,CAEhE;IAED;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI,CAE/D;IAED;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI,CAE/D;IAED;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI,CAEhE;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CACP,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAM,GACrC,IAAI,CAwBN;IAED;;;;;;;OAOG;IACH,IAAI,GAAG,IAAI,GAAG,CAEb;IAED,gCAAgC;IAChC,IAAI,IAAI,MAAM,CAEb;IAED;;;;;;;;OAQG;IACH,OAAO,IAAI,SAAS,CAEnB;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,SAAS,MAAM,EAAE,CAEjC;IAED;;;OAGG;IACH,IAAI,QAAQ,IAAI,SAAS,MAAM,EAAE,CAEhC;IAED;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAYlC;IAED,OAAO,CAAC,OAAO;CA6HhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAClB,OAAO,GAAE,MAAM,GAAG,SAAS,MAAM,EAAO,EACxC,GAAG,GAAE,MAAY,GAChB,IAAI,CAKN"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { PMF } from "../pmf/pmf.js";
|
|
2
|
+
/**
|
|
3
|
+
* Triggers that read the outcomes of source attacks, as opposed to `not-fired`,
|
|
4
|
+
* which reads another rider. Includes `any-miss`, so this is not "hit triggers".
|
|
5
|
+
*/
|
|
6
|
+
export type AttackTriggerOn = "first-hit" | "any-crit" | "any-miss" | "every-hit";
|
|
7
|
+
/**
|
|
8
|
+
* When a rider fires. JSON-safe, so a consumer can persist this verbatim and hand
|
|
9
|
+
* it straight back in a {@link TurnSpec}.
|
|
10
|
+
*
|
|
11
|
+
* - `first-hit` — the first source that lands. Fires in that source's mode, so a
|
|
12
|
+
* crit on the *first* landing attack doubles the rider's dice (Sneak Attack).
|
|
13
|
+
* - `any-crit` — at least one source crit. Always fires in crit mode (Divine Smite).
|
|
14
|
+
* - `any-miss` — at least one source missed. The reroll gate (Unerring Accuracy, Lucky).
|
|
15
|
+
* - `every-hit` — once per landing source, in that hit's mode (Hunter's Mark, Hex, Rage).
|
|
16
|
+
* - `not-fired` — the named rider did **not** fire ("flurry of blows if I didn't smite").
|
|
17
|
+
*
|
|
18
|
+
* For the attack triggers `of` is a list of attack ids and defaults to every
|
|
19
|
+
* declared attack, which is what most riders mean. For `not-fired` it is the
|
|
20
|
+
* single required id of the rider being negated — negating a set of riders has
|
|
21
|
+
* no unambiguous meaning, so the type does not offer it.
|
|
22
|
+
*/
|
|
23
|
+
export type Trigger = {
|
|
24
|
+
on: AttackTriggerOn;
|
|
25
|
+
of?: readonly string[];
|
|
26
|
+
} | {
|
|
27
|
+
on: "not-fired";
|
|
28
|
+
of: string;
|
|
29
|
+
};
|
|
30
|
+
/** Anything that can produce a PMF: `RollBuilder`, `AttackBuilder`, `SaveBuilder`, or a `PMF`. */
|
|
31
|
+
export interface ToPMF {
|
|
32
|
+
toPMF(eps?: number): PMF;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Rider or attack damage. Strings are not accepted: a parsed expression cannot
|
|
36
|
+
* have its dice doubled, so a string rider would deal single dice on a crit. Call
|
|
37
|
+
* `parse()` yourself if that is what you want.
|
|
38
|
+
*/
|
|
39
|
+
export type Damage = PMF | ToPMF;
|
|
40
|
+
/**
|
|
41
|
+
* Same shape as {@link Damage}, named separately because the requirement is
|
|
42
|
+
* stronger: a source must resolve to an *outcome-labelled* PMF carrying
|
|
43
|
+
* hit/crit/miss, which no type can express. Supplying one that does not is a
|
|
44
|
+
* `not-an-attack` {@link TurnSpecError} at build time, not a compile error.
|
|
45
|
+
*/
|
|
46
|
+
export type Source = Damage;
|
|
47
|
+
/** One payload, or several to convolve: Flurry of Blows is `[flurry, flurry]`. */
|
|
48
|
+
export type RiderDamage = Damage | readonly Damage[];
|
|
49
|
+
/** Everything about a rider except what it does and when — see `Turn.onFirstHit`. */
|
|
50
|
+
export interface RiderOptions {
|
|
51
|
+
/** Required only if another rider names this one in `of`. */
|
|
52
|
+
id?: string;
|
|
53
|
+
/** Which attacks to watch. Defaults to every declared attack. */
|
|
54
|
+
of?: readonly string[];
|
|
55
|
+
/** Defaults to `damage` with dice doubled when that is possible, else `damage`. */
|
|
56
|
+
critDamage?: RiderDamage;
|
|
57
|
+
}
|
|
58
|
+
export type Rider = Trigger & {
|
|
59
|
+
id?: string;
|
|
60
|
+
damage: RiderDamage;
|
|
61
|
+
critDamage?: RiderDamage;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* A bare source gets the id `attack 1`, `attack 2`, … in declaration order.
|
|
65
|
+
*
|
|
66
|
+
* Unlike {@link Rider}, the id lives in a wrapper rather than on the value
|
|
67
|
+
* itself: an attack's value is a builder or PMF that this module does not own,
|
|
68
|
+
* so there is nowhere to hang a field.
|
|
69
|
+
*/
|
|
70
|
+
export type Attack = Source | {
|
|
71
|
+
id: string;
|
|
72
|
+
source: Source;
|
|
73
|
+
};
|
|
74
|
+
export interface TurnSpec {
|
|
75
|
+
attacks: readonly Attack[];
|
|
76
|
+
riders?: readonly Rider[];
|
|
77
|
+
}
|
|
78
|
+
export type TurnSpecErrorCode = "unknown-id" | "duplicate-id" | "self-reference" | "cycle" | "not-an-attack" | "unused-crit-damage" | "too-many-groups";
|
|
79
|
+
/**
|
|
80
|
+
* A malformed turn. `code` is a stable contract: consumer UIs map it to their own
|
|
81
|
+
* states (greyed dropdown option, "trigger missing" row error, …) instead of
|
|
82
|
+
* re-implementing validation.
|
|
83
|
+
*/
|
|
84
|
+
export declare class TurnSpecError extends Error {
|
|
85
|
+
readonly code: TurnSpecErrorCode;
|
|
86
|
+
readonly id: string;
|
|
87
|
+
constructor(code: TurnSpecErrorCode, id: string, message: string);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* How many distinct `of` sets a single turn may track.
|
|
91
|
+
*
|
|
92
|
+
* Each group multiplies the state space, so the cap is a cost ceiling rather
|
|
93
|
+
* than a modelling limit. Measured on four attacks with two riders per group:
|
|
94
|
+
* 2.1ms for one group, 3.1 for two, 5.9 for three, 23.5 for four — roughly 4x
|
|
95
|
+
* per group. Real builds use one or two (the goliath rogue/monk/paladin uses
|
|
96
|
+
* one), so four leaves plenty of room while keeping an AC sweep viable.
|
|
97
|
+
*/
|
|
98
|
+
export declare const MAX_TRIGGER_GROUPS = 4;
|
|
99
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/turn/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB,WAAW,GACX,UAAU,GACV,UAAU,GACV,WAAW,CAAC;AAEhB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,OAAO,GACf;IAAE,EAAE,EAAE,eAAe,CAAC;IAAC,EAAE,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC/C;IAAE,EAAE,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC,kGAAkG;AAClG,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAE5B,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;AAErD,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,EAAE,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvB,mFAAmF;IACnF,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,cAAc,GACd,gBAAgB,GAChB,OAAO,GACP,eAAe,GACf,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAEpC,QAAQ,CAAC,IAAI,EAAE,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM;IAFrB,YACW,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAIhB;CACF;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC"}
|