@platonic-dice/core 2.0.2 → 2.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.
@@ -0,0 +1,89 @@
1
+ export type TestTypeValue = import("./TestType").TestTypeValue;
2
+ export type DieTypeValue = import("./DieType").DieTypeValue;
3
+ export type RollModifierFunction = import("./RollModifier").RollModifierFunction;
4
+ export type RollModifierInstance = import("./RollModifier").RollModifierInstance;
5
+ export type BaseTestCondition = {
6
+ modifiedRange: {
7
+ min: number;
8
+ max: number;
9
+ };
10
+ };
11
+ export type TargetConditions = BaseTestCondition & {
12
+ target: number;
13
+ };
14
+ export type WithinConditions = BaseTestCondition & {
15
+ min: number;
16
+ max: number;
17
+ };
18
+ export type SpecificListConditions = BaseTestCondition & {
19
+ values: number[];
20
+ };
21
+ export type SkillConditions = BaseTestCondition & {
22
+ target: number;
23
+ critical_success?: number;
24
+ critical_failure?: number;
25
+ };
26
+ export type Conditions = TargetConditions | SkillConditions | WithinConditions | SpecificListConditions;
27
+ export type ModifiedTestConditionsInstance = InstanceType<typeof ModifiedTestConditions>;
28
+ /**
29
+ * Represents a set of validated test conditions for modified rolls.
30
+ *
31
+ * This class is similar to {@link TestConditions} but validates numeric
32
+ * targets against the achievable range after applying a modifier.
33
+ */
34
+ export class ModifiedTestConditions {
35
+ /**
36
+ * @param {TestTypeValue} testType - The test type.
37
+ * @param {Conditions} conditions - The test conditions object.
38
+ * @param {DieTypeValue} dieType - The base die type.
39
+ * @param {RollModifierFunction | RollModifierInstance} modifier - The modifier to apply.
40
+ * @throws {TypeError|RangeError} If the test type or conditions are invalid.
41
+ */
42
+ constructor(testType: TestTypeValue, conditions: Conditions, dieType: DieTypeValue, modifier: RollModifierFunction | RollModifierInstance);
43
+ /** @type {TestTypeValue} */
44
+ testType: TestTypeValue;
45
+ /** @type {Conditions} */
46
+ conditions: Conditions;
47
+ /** @type {DieTypeValue} */
48
+ dieType: DieTypeValue;
49
+ /** @type {RollModifierInstance} */
50
+ modifier: RollModifierInstance;
51
+ /** @type {{ min: number, max: number }} */
52
+ modifiedRange: {
53
+ min: number;
54
+ max: number;
55
+ };
56
+ /**
57
+ * Validates that the test conditions still conform to spec.
58
+ * @throws {TypeError} If the test conditions are invalid.
59
+ */
60
+ validate(): void;
61
+ }
62
+ /**
63
+ * Validates test conditions against a modified range.
64
+ *
65
+ * @private
66
+ * @param {Conditions & Record<string, any>} c - Conditions with modifiedRange
67
+ * @param {TestTypeValue} testType
68
+ * @returns {boolean}
69
+ */
70
+ export function areValidModifiedTestConditions(c: Conditions & Record<string, any>, testType: TestTypeValue): boolean;
71
+ /**
72
+ * @typedef {import("./TestType").TestTypeValue} TestTypeValue
73
+ * @typedef {import("./DieType").DieTypeValue} DieTypeValue
74
+ * @typedef {import("./RollModifier").RollModifierFunction} RollModifierFunction
75
+ * @typedef {import("./RollModifier").RollModifierInstance} RollModifierInstance
76
+ */
77
+ /**
78
+ * Computes the achievable range for a die + modifier combination.
79
+ *
80
+ * @private
81
+ * @param {DieTypeValue} dieType
82
+ * @param {RollModifierInstance} modifier
83
+ * @returns {{ min: number, max: number }}
84
+ */
85
+ export function computeModifiedRange(dieType: DieTypeValue, modifier: RollModifierInstance): {
86
+ min: number;
87
+ max: number;
88
+ };
89
+ //# sourceMappingURL=ModifiedTestConditions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModifiedTestConditions.d.ts","sourceRoot":"","sources":["../../src/entities/ModifiedTestConditions.js"],"names":[],"mappings":"4BAyBa,OAAO,YAAY,EAAE,aAAa;2BAClC,OAAO,WAAW,EAAE,YAAY;mCAChC,OAAO,gBAAgB,EAAE,oBAAoB;mCAC7C,OAAO,gBAAgB,EAAE,oBAAoB;;mBAsN5C;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;;+BAI7B,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE;+BACtC,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;qCAChD,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;8BACxC,iBAAiB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE;yBAI5F,gBAAgB,GAAG,eAAe,GAAG,gBAAgB,GAAG,sBAAsB;6CAI9E,YAAY,CAAC,OAAO,sBAAsB,CAAC;AA1MxD;;;;;GAKG;AACH;IACE;;;;;;OAMG;IACH,sBANW,aAAa,cACb,UAAU,WACV,YAAY,YACZ,oBAAoB,GAAG,oBAAoB,EAmErD;IAVC,4BAA4B;IAC5B,UADW,aAAa,CACA;IACxB,yBAAyB;IACzB,YADW,UAAU,CACO;IAC5B,2BAA2B;IAC3B,SADW,YAAY,CACD;IACtB,mCAAmC;IACnC,UADW,oBAAoB,CACZ;IACnB,2CAA2C;IAC3C,eADW;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CACb;IAG5B;;;OAGG;IACH,iBASC;CACF;AAED;;;;;;;GAOG;AACH,kDAJW,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAChC,aAAa,GACX,OAAO,CAiFnB;AAtND;;;;;GAKG;AAEH;;;;;;;GAOG;AACH,8CAJW,YAAY,YACZ,oBAAoB,GAClB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAgBxC"}
@@ -0,0 +1,265 @@
1
+ /**
2
+ * @module @platonic-dice/core/src/entities/ModifiedTestConditions
3
+ * @description
4
+ * Represents test conditions for modified rolls, where the achievable range
5
+ * is determined by both the base die type and the applied modifier.
6
+ *
7
+ * Unlike {@link TestConditions}, this class validates targets against the
8
+ * **modified range** rather than just the base die faces.
9
+ *
10
+ * @example
11
+ * // D6 with +10 modifier can reach 11-16
12
+ * const conditions = new ModifiedTestConditions(
13
+ * TestType.AtLeast,
14
+ * { target: 15 },
15
+ * DieType.D6,
16
+ * (n) => n + 10
17
+ * );
18
+ */
19
+
20
+ const { isValidDieType } = require("./DieType");
21
+ const { isValidTestType } = require("./TestType");
22
+ const { normaliseRollModifier } = require("./RollModifier");
23
+ const { numSides } = require("../utils");
24
+
25
+ /**
26
+ * @typedef {import("./TestType").TestTypeValue} TestTypeValue
27
+ * @typedef {import("./DieType").DieTypeValue} DieTypeValue
28
+ * @typedef {import("./RollModifier").RollModifierFunction} RollModifierFunction
29
+ * @typedef {import("./RollModifier").RollModifierInstance} RollModifierInstance
30
+ */
31
+
32
+ /**
33
+ * Computes the achievable range for a die + modifier combination.
34
+ *
35
+ * @private
36
+ * @param {DieTypeValue} dieType
37
+ * @param {RollModifierInstance} modifier
38
+ * @returns {{ min: number, max: number }}
39
+ */
40
+ function computeModifiedRange(dieType, modifier) {
41
+ const sides = numSides(dieType);
42
+ const minRoll = 1;
43
+ const maxRoll = sides;
44
+
45
+ // Apply modifier to both extremes
46
+ const minModified = modifier.apply(minRoll);
47
+ const maxModified = modifier.apply(maxRoll);
48
+
49
+ // Handle cases where modifier might reverse order (e.g., negative multipliers)
50
+ return {
51
+ min: Math.min(minModified, maxModified),
52
+ max: Math.max(minModified, maxModified),
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Represents a set of validated test conditions for modified rolls.
58
+ *
59
+ * This class is similar to {@link TestConditions} but validates numeric
60
+ * targets against the achievable range after applying a modifier.
61
+ */
62
+ class ModifiedTestConditions {
63
+ /**
64
+ * @param {TestTypeValue} testType - The test type.
65
+ * @param {Conditions} conditions - The test conditions object.
66
+ * @param {DieTypeValue} dieType - The base die type.
67
+ * @param {RollModifierFunction | RollModifierInstance} modifier - The modifier to apply.
68
+ * @throws {TypeError|RangeError} If the test type or conditions are invalid.
69
+ */
70
+ constructor(testType, conditions, dieType, modifier) {
71
+ if (!isValidTestType(testType)) {
72
+ throw new TypeError(`Invalid test type: ${testType}`);
73
+ }
74
+
75
+ if (!conditions || typeof conditions !== "object") {
76
+ throw new TypeError("conditions must be an object.");
77
+ }
78
+
79
+ if (!dieType) {
80
+ throw new TypeError("dieType is required.");
81
+ }
82
+
83
+ if (!modifier) {
84
+ throw new TypeError("modifier is required.");
85
+ }
86
+
87
+ // Normalize the modifier
88
+ const mod = normaliseRollModifier(modifier);
89
+
90
+ // Compute the achievable range with this modifier
91
+ const range = computeModifiedRange(dieType, mod);
92
+
93
+ // Validate conditions against the modified range
94
+ if (
95
+ !areValidModifiedTestConditions(
96
+ { ...conditions, modifiedRange: range },
97
+ testType
98
+ )
99
+ ) {
100
+ switch (testType) {
101
+ case "at_least":
102
+ case "at_most":
103
+ case "exact":
104
+ throw new RangeError(
105
+ `Invalid ${testType} condition for ${dieType} with modifier: target must be achievable (range: ${range.min}–${range.max}).`
106
+ );
107
+ case "within":
108
+ throw new RangeError(
109
+ `Invalid 'within' condition for ${dieType} with modifier: range must be achievable (${range.min}–${range.max}).`
110
+ );
111
+ case "in_list":
112
+ throw new RangeError(
113
+ `Invalid 'in_list' condition for ${dieType} with modifier: values must be achievable (${range.min}–${range.max}).`
114
+ );
115
+ case "skill":
116
+ throw new RangeError(
117
+ `Invalid 'skill' condition for ${dieType} with modifier: thresholds must be achievable (${range.min}–${range.max}).`
118
+ );
119
+ default:
120
+ throw new TypeError(`Unknown testType '${testType}'.`);
121
+ }
122
+ }
123
+
124
+ /** @type {TestTypeValue} */
125
+ this.testType = testType;
126
+ /** @type {Conditions} */
127
+ this.conditions = conditions;
128
+ /** @type {DieTypeValue} */
129
+ this.dieType = dieType;
130
+ /** @type {RollModifierInstance} */
131
+ this.modifier = mod;
132
+ /** @type {{ min: number, max: number }} */
133
+ this.modifiedRange = range;
134
+ }
135
+
136
+ /**
137
+ * Validates that the test conditions still conform to spec.
138
+ * @throws {TypeError} If the test conditions are invalid.
139
+ */
140
+ validate() {
141
+ if (
142
+ !areValidModifiedTestConditions(
143
+ { ...this.conditions, modifiedRange: this.modifiedRange },
144
+ this.testType
145
+ )
146
+ ) {
147
+ throw new TypeError("Invalid modified test conditions.");
148
+ }
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Validates test conditions against a modified range.
154
+ *
155
+ * @private
156
+ * @param {Conditions & Record<string, any>} c - Conditions with modifiedRange
157
+ * @param {TestTypeValue} testType
158
+ * @returns {boolean}
159
+ */
160
+ function areValidModifiedTestConditions(c, testType) {
161
+ if (!c.modifiedRange) return false;
162
+
163
+ const { min, max } = c.modifiedRange;
164
+
165
+ switch (testType) {
166
+ case "exact":
167
+ case "at_least":
168
+ case "at_most":
169
+ return (
170
+ typeof c.target === "number" &&
171
+ Number.isInteger(c.target) &&
172
+ c.target >= min &&
173
+ c.target <= max
174
+ );
175
+
176
+ case "within":
177
+ return (
178
+ typeof c.min === "number" &&
179
+ typeof c.max === "number" &&
180
+ Number.isInteger(c.min) &&
181
+ Number.isInteger(c.max) &&
182
+ c.min <= c.max &&
183
+ c.min >= min &&
184
+ c.max <= max
185
+ );
186
+
187
+ case "in_list":
188
+ return (
189
+ Array.isArray(c.values) &&
190
+ c.values.length > 0 &&
191
+ c.values.every(
192
+ (v) =>
193
+ typeof v === "number" && Number.isInteger(v) && v >= min && v <= max
194
+ )
195
+ );
196
+
197
+ case "skill":
198
+ // target is required
199
+ if (
200
+ typeof c.target !== "number" ||
201
+ !Number.isInteger(c.target) ||
202
+ c.target < min ||
203
+ c.target > max
204
+ ) {
205
+ return false;
206
+ }
207
+
208
+ // critical_success is optional but must be valid if present
209
+ if (c.critical_success !== undefined) {
210
+ if (
211
+ typeof c.critical_success !== "number" ||
212
+ !Number.isInteger(c.critical_success) ||
213
+ c.critical_success < min ||
214
+ c.critical_success > max ||
215
+ c.critical_success < c.target
216
+ ) {
217
+ return false;
218
+ }
219
+ }
220
+
221
+ // critical_failure is optional but must be valid if present
222
+ if (c.critical_failure !== undefined) {
223
+ if (
224
+ typeof c.critical_failure !== "number" ||
225
+ !Number.isInteger(c.critical_failure) ||
226
+ c.critical_failure < min ||
227
+ c.critical_failure > max ||
228
+ c.critical_failure > c.target
229
+ ) {
230
+ return false;
231
+ }
232
+ }
233
+
234
+ return true;
235
+
236
+ default:
237
+ return false;
238
+ }
239
+ }
240
+
241
+ /**
242
+ * @typedef {Object} BaseTestCondition
243
+ * @property {{ min: number, max: number }} modifiedRange
244
+ */
245
+
246
+ /**
247
+ * @typedef {BaseTestCondition & { target: number }} TargetConditions
248
+ * @typedef {BaseTestCondition & { min: number, max: number }} WithinConditions
249
+ * @typedef {BaseTestCondition & { values: number[] }} SpecificListConditions
250
+ * @typedef {BaseTestCondition & { target: number, critical_success?: number, critical_failure?: number }} SkillConditions
251
+ */
252
+
253
+ /**
254
+ * @typedef {TargetConditions | SkillConditions | WithinConditions | SpecificListConditions} Conditions
255
+ */
256
+
257
+ /**
258
+ * @typedef {InstanceType<typeof ModifiedTestConditions>} ModifiedTestConditionsInstance
259
+ */
260
+
261
+ module.exports = {
262
+ ModifiedTestConditions,
263
+ areValidModifiedTestConditions,
264
+ computeModifiedRange,
265
+ };
@@ -10,7 +10,10 @@ import { isValidRollType } from "./RollType.js";
10
10
  import { TestConditions } from "./TestConditions.js";
11
11
  import { areValidTestConditions } from "./TestConditions.js";
12
12
  import { normaliseTestConditions } from "./TestConditions.js";
13
+ import { ModifiedTestConditions } from "./ModifiedTestConditions.js";
14
+ import { areValidModifiedTestConditions } from "./ModifiedTestConditions.js";
15
+ import { computeModifiedRange } from "./ModifiedTestConditions.js";
13
16
  import { TestType } from "./TestType.js";
14
17
  import { isValidTestType } from "./TestType.js";
15
- export { DieType, isValidDieType, Outcome, isValidOutcome, RollModifier, isValidRollModifier, normaliseRollModifier, RollType, isValidRollType, TestConditions, areValidTestConditions, normaliseTestConditions, TestType, isValidTestType };
18
+ export { DieType, isValidDieType, Outcome, isValidOutcome, RollModifier, isValidRollModifier, normaliseRollModifier, RollType, isValidRollType, TestConditions, areValidTestConditions, normaliseTestConditions, ModifiedTestConditions, areValidModifiedTestConditions, computeModifiedRange, TestType, isValidTestType };
16
19
  //# sourceMappingURL=index.d.ts.map
@@ -26,6 +26,11 @@ const {
26
26
  areValidTestConditions,
27
27
  normaliseTestConditions,
28
28
  } = require("./TestConditions.js");
29
+ const {
30
+ ModifiedTestConditions,
31
+ areValidModifiedTestConditions,
32
+ computeModifiedRange,
33
+ } = require("./ModifiedTestConditions.js");
29
34
  const { TestType, isValidTestType } = require("./TestType.js");
30
35
 
31
36
  module.exports = {
@@ -41,6 +46,9 @@ module.exports = {
41
46
  TestConditions,
42
47
  areValidTestConditions,
43
48
  normaliseTestConditions,
49
+ ModifiedTestConditions,
50
+ areValidModifiedTestConditions,
51
+ computeModifiedRange,
44
52
  TestType,
45
53
  isValidTestType,
46
54
  };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare const _exports: typeof import("./roll") & typeof import("./rollDice") & typeof import("./rollMod") & typeof import("./rollDiceMod") & typeof import("./rollTest") & typeof import("./entities") & {
1
+ declare const _exports: typeof import("./roll") & typeof import("./rollDice") & typeof import("./rollMod") & typeof import("./rollDiceMod") & typeof import("./rollTest") & typeof import("./rollModTest") & typeof import("./analyseTest") & typeof import("./analyseModTest") & typeof import("./entities") & {
2
2
  default: any;
3
3
  };
4
4
  export = _exports;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"wBAsBU,cAAc,QAAQ,CAAC,GAChC,cAAuB,YAAY,CAAC,GACpC,cAAuB,WAAW,CAAC,GACnC,cAAuB,eAAe,CAAC,GACvC,cAAuB,YAAY,CAAC,GACpC,cAAuB,YAAY,CAAC,GACpC;IAAW,OAAO,EAAE,GAAG,CAAA;CAAE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"wBAyBU,cAAc,QAAQ,CAAC,GAChC,cAAuB,YAAY,CAAC,GACpC,cAAuB,WAAW,CAAC,GACnC,cAAuB,eAAe,CAAC,GACvC,cAAuB,YAAY,CAAC,GACpC,cAAuB,eAAe,CAAC,GACvC,cAAuB,eAAe,CAAC,GACvC,cAAuB,kBAAkB,CAAC,GAC1C,cAAuB,YAAY,CAAC,GACpC;IAAW,OAAO,EAAE,GAAG,CAAA;CAAE"}
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * Re-exports all main rolling functions and modifiers.
6
6
  *
7
7
  * @example
8
- * import { roll, rollMod, rollDice, rollDiceMod, rollTest } from "@platonic-dice/core";
8
+ * import { roll, rollMod, rollDice, rollDiceMod, rollTest, rollModTest } from "@platonic-dice/core";
9
9
  */
10
10
 
11
11
  // --- Core modules ---
@@ -14,6 +14,9 @@ const roll = require("./roll.js");
14
14
  const rollMod = require("./rollMod.js");
15
15
  const rollDiceMod = require("./rollDiceMod.js");
16
16
  const rollTest = require("./rollTest.js");
17
+ const rollModTest = require("./rollModTest.js");
18
+ const analyseTest = require("./analyseTest.js");
19
+ const analyseModTest = require("./analyseModTest.js");
17
20
 
18
21
  // --- Entities (public API) ---
19
22
  const entities = require("./entities");
@@ -25,6 +28,9 @@ const entities = require("./entities");
25
28
  * typeof import("./rollMod") &
26
29
  * typeof import("./rollDiceMod") &
27
30
  * typeof import("./rollTest") &
31
+ * typeof import("./rollModTest") &
32
+ * typeof import("./analyseTest") &
33
+ * typeof import("./analyseModTest") &
28
34
  * typeof import("./entities") &
29
35
  * { default: any }}
30
36
  */
@@ -35,6 +41,9 @@ module.exports = {
35
41
  ...rollDiceMod,
36
42
  ...entities,
37
43
  ...rollTest,
44
+ ...rollModTest,
45
+ ...analyseTest,
46
+ ...analyseModTest,
38
47
  default: undefined, // placeholder; will be overwritten
39
48
  };
40
49
 
@@ -0,0 +1,72 @@
1
+ export type DieTypeValue = import("./entities/DieType").DieTypeValue;
2
+ export type OutcomeValue = import("./entities/Outcome").OutcomeValue;
3
+ export type RollTypeValue = import("./entities/RollType").RollTypeValue;
4
+ export type RollModifierFunction = import("./entities/RollModifier").RollModifierFunction;
5
+ export type RollModifierInstance = import("./entities/RollModifier").RollModifierInstance;
6
+ export type TestTypeValue = import("./entities/TestType").TestTypeValue;
7
+ export type TestConditionsInstance = import("./entities/TestConditions").TestConditionsInstance;
8
+ /**
9
+ * Rolls a die with a modifier and evaluates the modified result against test conditions.
10
+ *
11
+ * @function rollModTest
12
+ * @param {DieTypeValue} dieType - The type of die to roll (e.g., `DieType.D20`).
13
+ * @param {RollModifierFunction|RollModifierInstance} modifier - The modifier to apply to the roll.
14
+ * Can be either:
15
+ * - A function `(n: number) => number`
16
+ * - A {@link RollModifier} instance
17
+ * @param {TestConditionsInstance|{ testType: TestTypeValue, [key: string]: any }} testConditions
18
+ * Can be:
19
+ * - A `TestConditions` instance
20
+ * - A plain object `{ testType, ...conditions }`
21
+ * @param {RollTypeValue} [rollType=undefined] - Optional roll mode (`RollType.Advantage` or `RollType.Disadvantage`).
22
+ * @param {Object} [options={}] - Optional configuration.
23
+ * @param {boolean} [options.useNaturalCrits] - If true, natural max/min rolls on the die trigger
24
+ * critical success/failure (for Skill tests) or success/failure (for other test types).
25
+ * If undefined, defaults to true for Skill test type and false for all others.
26
+ * @returns {{ base: number, modified: number, outcome: OutcomeValue }}
27
+ * - `base`: The raw die roll
28
+ * - `modified`: The roll after applying the modifier
29
+ * - `outcome`: The success/failure result based on test conditions
30
+ * @throws {TypeError} If `dieType`, `modifier`, or `testConditions` are invalid.
31
+ *
32
+ * @example
33
+ * const result = rollModTest(
34
+ * DieType.D20,
35
+ * (n) => n + 2,
36
+ * { testType: TestType.AtLeast, target: 15 }
37
+ * );
38
+ * console.log(result); // { base: 14, modified: 16, outcome: "success" }
39
+ *
40
+ * @example
41
+ * // With natural crits enabled (TTRPG style)
42
+ * const result = rollModTest(
43
+ * DieType.D20,
44
+ * (n) => n + 5,
45
+ * { testType: TestType.Skill, target: 15, critical_success: 25, critical_failure: 2 },
46
+ * undefined,
47
+ * { useNaturalCrits: true }
48
+ * );
49
+ * // If base roll is 20, outcome is always "critical_success"
50
+ * // If base roll is 1, outcome is always "critical_failure"
51
+ *
52
+ * @example
53
+ * // With advantage - compares outcomes, not just base rolls
54
+ * const result = rollModTest(
55
+ * DieType.D20,
56
+ * (n) => n + 3,
57
+ * { testType: TestType.Skill, target: 12, critical_success: 20, critical_failure: 1 },
58
+ * RollType.Advantage
59
+ * );
60
+ * // Rolls twice, returns the result with the better outcome
61
+ */
62
+ export function rollModTest(dieType: DieTypeValue, modifier: RollModifierFunction | RollModifierInstance, testConditions: TestConditionsInstance | {
63
+ testType: TestTypeValue;
64
+ [key: string]: any;
65
+ }, rollType?: RollTypeValue, options?: {
66
+ useNaturalCrits?: boolean | undefined;
67
+ }): {
68
+ base: number;
69
+ modified: number;
70
+ outcome: OutcomeValue;
71
+ };
72
+ //# sourceMappingURL=rollModTest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollModTest.d.ts","sourceRoot":"","sources":["../src/rollModTest.js"],"names":[],"mappings":"2BAoCa,OAAO,oBAAoB,EAAE,YAAY;2BACzC,OAAO,oBAAoB,EAAE,YAAY;4BACzC,OAAO,qBAAqB,EAAE,aAAa;mCAC3C,OAAO,yBAAyB,EAAE,oBAAoB;mCACtD,OAAO,yBAAyB,EAAE,oBAAoB;4BACtD,OAAO,qBAAqB,EAAE,aAAa;qCAC3C,OAAO,2BAA2B,EAAE,sBAAsB;AAyBvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qCAlDW,YAAY,YACZ,oBAAoB,GAAC,oBAAoB,kBAIzC,sBAAsB,GAAC;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,aAItE,aAAa,YAErB;IAA0B,eAAe;CAGzC,GAAU;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAsHrE"}