@yipe/dice 0.2.20 → 0.2.21
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/dist/builder/index.cjs +227 -17
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.d.cts +34 -8
- package/dist/builder/index.d.ts +34 -8
- package/dist/builder/index.js +227 -18
- package/dist/builder/index.js.map +1 -1
- package/package.json +1 -1
package/dist/builder/index.d.cts
CHANGED
|
@@ -112,7 +112,9 @@ declare const defaultConfig: RollConfig;
|
|
|
112
112
|
declare class RollBuilder {
|
|
113
113
|
protected readonly subRollConfigs: readonly RollConfig[];
|
|
114
114
|
constructor(countOrConfigs?: number | readonly RollConfig[]);
|
|
115
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
115
116
|
protected get lastConfig(): RollConfig;
|
|
117
|
+
hasHiddenState(): boolean;
|
|
116
118
|
getSubRollConfigs(): readonly RollConfig[];
|
|
117
119
|
static fromConfig(config: Partial<RollConfig>): RollBuilder;
|
|
118
120
|
static fromConfigs(configs: Partial<RollConfig>[]): RollBuilder;
|
|
@@ -131,6 +133,8 @@ declare class RollBuilder {
|
|
|
131
133
|
bestOf(count: number | undefined): RollBuilder;
|
|
132
134
|
keepHighest(total: number, count: number): RollBuilder;
|
|
133
135
|
keepLowest(total: number, count: number): RollBuilder;
|
|
136
|
+
keepHighestAll(total: number, count: number): PooledRollBuilder;
|
|
137
|
+
keepLowestAll(total: number, count: number): PooledRollBuilder;
|
|
134
138
|
withAdvantage(): RollBuilder;
|
|
135
139
|
withDisadvantage(): RollBuilder;
|
|
136
140
|
add(anotherRoll: RollBuilder | undefined): RollBuilder;
|
|
@@ -168,6 +172,7 @@ declare class RollBuilder {
|
|
|
168
172
|
declare class HalfRollBuilder extends RollBuilder {
|
|
169
173
|
private readonly innerRoll;
|
|
170
174
|
constructor(innerRoll: RollBuilder);
|
|
175
|
+
hasHiddenState(): boolean;
|
|
171
176
|
get lastConfig(): any;
|
|
172
177
|
getSubRollConfigs(): readonly RollConfig[];
|
|
173
178
|
toExpression(): string;
|
|
@@ -181,6 +186,7 @@ declare class MaxOfRollBuilder extends RollBuilder {
|
|
|
181
186
|
private readonly diceCount?;
|
|
182
187
|
private readonly diceSides?;
|
|
183
188
|
constructor(innerRoll: RollBuilder, count: number, diceCount?: number, diceSides?: number);
|
|
189
|
+
hasHiddenState(): boolean;
|
|
184
190
|
get lastConfig(): any;
|
|
185
191
|
getSubRollConfigs(): readonly RollConfig[];
|
|
186
192
|
toExpression(): string;
|
|
@@ -191,6 +197,7 @@ declare class MaxOfRollBuilder extends RollBuilder {
|
|
|
191
197
|
declare class AlwaysHitBuilder extends RollBuilder {
|
|
192
198
|
readonly attackConfig: CritConfig;
|
|
193
199
|
constructor(baseRoll: RollBuilder, attackConfig?: CritConfig);
|
|
200
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
194
201
|
onHit(val: number): AttackBuilder;
|
|
195
202
|
onHit(val: string): AttackBuilder;
|
|
196
203
|
onHit(val: RollBuilder): AttackBuilder;
|
|
@@ -213,6 +220,7 @@ declare class AlwaysCritBuilder extends RollBuilder {
|
|
|
213
220
|
constructor(baseRoll: RollBuilder, attackConfig?: CritConfig & {
|
|
214
221
|
ac?: number;
|
|
215
222
|
}, fromAlwaysHit?: boolean);
|
|
223
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
216
224
|
onHit(val: number): AttackBuilder;
|
|
217
225
|
onHit(val: string): AttackBuilder;
|
|
218
226
|
onHit(val: RollBuilder): AttackBuilder;
|
|
@@ -226,22 +234,40 @@ declare class AlwaysCritBuilder extends RollBuilder {
|
|
|
226
234
|
toPMF(): PMF;
|
|
227
235
|
copy(): AlwaysCritBuilder;
|
|
228
236
|
}
|
|
229
|
-
/**
|
|
230
|
-
* A RollBuilder that wraps a pre-computed PMF from a parsed string expression.
|
|
231
|
-
* This is used to support string-based damage expressions in onHit/onCrit/onMiss.
|
|
232
|
-
* The builder is not fully composable (e.g., you can't call .plus() on it),
|
|
233
|
-
* but it can be used anywhere a RollBuilder is expected for terminal damage.
|
|
234
|
-
*/
|
|
235
237
|
declare class ParsedRollBuilder extends RollBuilder {
|
|
236
238
|
private readonly cachedPMF;
|
|
237
239
|
private readonly originalExpression;
|
|
238
240
|
constructor(expression: string);
|
|
239
|
-
|
|
241
|
+
hasHiddenState(): boolean;
|
|
242
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
243
|
+
toPMF(_eps?: number): PMF;
|
|
240
244
|
toExpression(): string;
|
|
241
245
|
toAST(): ExpressionNode;
|
|
242
246
|
copy(): ParsedRollBuilder;
|
|
243
247
|
doubleDice(): ParsedRollBuilder;
|
|
244
248
|
}
|
|
249
|
+
declare class PooledRollBuilder extends RollBuilder {
|
|
250
|
+
private readonly baseAST;
|
|
251
|
+
private readonly baseExpression;
|
|
252
|
+
constructor(baseAST: ExpressionNode, baseExpression: string, configs?: readonly RollConfig[]);
|
|
253
|
+
protected create(configs: readonly RollConfig[]): PooledRollBuilder;
|
|
254
|
+
hasHiddenState(): boolean;
|
|
255
|
+
d(_sides: number | undefined): RollBuilder;
|
|
256
|
+
reroll(_value: number): RollBuilder;
|
|
257
|
+
explode(_count?: number | undefined): RollBuilder;
|
|
258
|
+
minimum(_val: number | undefined): RollBuilder;
|
|
259
|
+
bestOf(_count: number | undefined): RollBuilder;
|
|
260
|
+
keepHighest(_total: number, _count: number): RollBuilder;
|
|
261
|
+
keepLowest(_total: number, _count: number): RollBuilder;
|
|
262
|
+
withAdvantage(): RollBuilder;
|
|
263
|
+
withDisadvantage(): RollBuilder;
|
|
264
|
+
withElvenAccuracy(): RollBuilder;
|
|
265
|
+
toAST(): ExpressionNode;
|
|
266
|
+
toExpression(): string;
|
|
267
|
+
copy(): PooledRollBuilder;
|
|
268
|
+
scaleDice(scale: number): RollBuilder;
|
|
269
|
+
times(count: number): PooledRollBuilder;
|
|
270
|
+
}
|
|
245
271
|
|
|
246
272
|
type ActionEffect = RollBuilder;
|
|
247
273
|
declare class AttackBuilder implements CheckBuilder {
|
|
@@ -359,4 +385,4 @@ declare const flat: (n: number) => RollBuilder;
|
|
|
359
385
|
declare const roll: RollFactory;
|
|
360
386
|
declare const builderPMFCache: LRUCache<string, PMF>;
|
|
361
387
|
|
|
362
|
-
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, type AttackConfig, type AttackResolution, type CheckBuilder, DCBuilder, HalfRollBuilder, type KeepMode, MaxOfRollBuilder, ParsedRollBuilder, type Resolution, RollBuilder, type RollConfig, type RollFactory, type RollType, SaveBuilder, type SaveOutcome, type SaveResolution, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
|
388
|
+
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, type AttackConfig, type AttackResolution, type CheckBuilder, DCBuilder, HalfRollBuilder, type KeepMode, MaxOfRollBuilder, ParsedRollBuilder, PooledRollBuilder, type Resolution, RollBuilder, type RollConfig, type RollFactory, type RollType, SaveBuilder, type SaveOutcome, type SaveResolution, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
package/dist/builder/index.d.ts
CHANGED
|
@@ -112,7 +112,9 @@ declare const defaultConfig: RollConfig;
|
|
|
112
112
|
declare class RollBuilder {
|
|
113
113
|
protected readonly subRollConfigs: readonly RollConfig[];
|
|
114
114
|
constructor(countOrConfigs?: number | readonly RollConfig[]);
|
|
115
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
115
116
|
protected get lastConfig(): RollConfig;
|
|
117
|
+
hasHiddenState(): boolean;
|
|
116
118
|
getSubRollConfigs(): readonly RollConfig[];
|
|
117
119
|
static fromConfig(config: Partial<RollConfig>): RollBuilder;
|
|
118
120
|
static fromConfigs(configs: Partial<RollConfig>[]): RollBuilder;
|
|
@@ -131,6 +133,8 @@ declare class RollBuilder {
|
|
|
131
133
|
bestOf(count: number | undefined): RollBuilder;
|
|
132
134
|
keepHighest(total: number, count: number): RollBuilder;
|
|
133
135
|
keepLowest(total: number, count: number): RollBuilder;
|
|
136
|
+
keepHighestAll(total: number, count: number): PooledRollBuilder;
|
|
137
|
+
keepLowestAll(total: number, count: number): PooledRollBuilder;
|
|
134
138
|
withAdvantage(): RollBuilder;
|
|
135
139
|
withDisadvantage(): RollBuilder;
|
|
136
140
|
add(anotherRoll: RollBuilder | undefined): RollBuilder;
|
|
@@ -168,6 +172,7 @@ declare class RollBuilder {
|
|
|
168
172
|
declare class HalfRollBuilder extends RollBuilder {
|
|
169
173
|
private readonly innerRoll;
|
|
170
174
|
constructor(innerRoll: RollBuilder);
|
|
175
|
+
hasHiddenState(): boolean;
|
|
171
176
|
get lastConfig(): any;
|
|
172
177
|
getSubRollConfigs(): readonly RollConfig[];
|
|
173
178
|
toExpression(): string;
|
|
@@ -181,6 +186,7 @@ declare class MaxOfRollBuilder extends RollBuilder {
|
|
|
181
186
|
private readonly diceCount?;
|
|
182
187
|
private readonly diceSides?;
|
|
183
188
|
constructor(innerRoll: RollBuilder, count: number, diceCount?: number, diceSides?: number);
|
|
189
|
+
hasHiddenState(): boolean;
|
|
184
190
|
get lastConfig(): any;
|
|
185
191
|
getSubRollConfigs(): readonly RollConfig[];
|
|
186
192
|
toExpression(): string;
|
|
@@ -191,6 +197,7 @@ declare class MaxOfRollBuilder extends RollBuilder {
|
|
|
191
197
|
declare class AlwaysHitBuilder extends RollBuilder {
|
|
192
198
|
readonly attackConfig: CritConfig;
|
|
193
199
|
constructor(baseRoll: RollBuilder, attackConfig?: CritConfig);
|
|
200
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
194
201
|
onHit(val: number): AttackBuilder;
|
|
195
202
|
onHit(val: string): AttackBuilder;
|
|
196
203
|
onHit(val: RollBuilder): AttackBuilder;
|
|
@@ -213,6 +220,7 @@ declare class AlwaysCritBuilder extends RollBuilder {
|
|
|
213
220
|
constructor(baseRoll: RollBuilder, attackConfig?: CritConfig & {
|
|
214
221
|
ac?: number;
|
|
215
222
|
}, fromAlwaysHit?: boolean);
|
|
223
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
216
224
|
onHit(val: number): AttackBuilder;
|
|
217
225
|
onHit(val: string): AttackBuilder;
|
|
218
226
|
onHit(val: RollBuilder): AttackBuilder;
|
|
@@ -226,22 +234,40 @@ declare class AlwaysCritBuilder extends RollBuilder {
|
|
|
226
234
|
toPMF(): PMF;
|
|
227
235
|
copy(): AlwaysCritBuilder;
|
|
228
236
|
}
|
|
229
|
-
/**
|
|
230
|
-
* A RollBuilder that wraps a pre-computed PMF from a parsed string expression.
|
|
231
|
-
* This is used to support string-based damage expressions in onHit/onCrit/onMiss.
|
|
232
|
-
* The builder is not fully composable (e.g., you can't call .plus() on it),
|
|
233
|
-
* but it can be used anywhere a RollBuilder is expected for terminal damage.
|
|
234
|
-
*/
|
|
235
237
|
declare class ParsedRollBuilder extends RollBuilder {
|
|
236
238
|
private readonly cachedPMF;
|
|
237
239
|
private readonly originalExpression;
|
|
238
240
|
constructor(expression: string);
|
|
239
|
-
|
|
241
|
+
hasHiddenState(): boolean;
|
|
242
|
+
protected create(configs: readonly RollConfig[]): RollBuilder;
|
|
243
|
+
toPMF(_eps?: number): PMF;
|
|
240
244
|
toExpression(): string;
|
|
241
245
|
toAST(): ExpressionNode;
|
|
242
246
|
copy(): ParsedRollBuilder;
|
|
243
247
|
doubleDice(): ParsedRollBuilder;
|
|
244
248
|
}
|
|
249
|
+
declare class PooledRollBuilder extends RollBuilder {
|
|
250
|
+
private readonly baseAST;
|
|
251
|
+
private readonly baseExpression;
|
|
252
|
+
constructor(baseAST: ExpressionNode, baseExpression: string, configs?: readonly RollConfig[]);
|
|
253
|
+
protected create(configs: readonly RollConfig[]): PooledRollBuilder;
|
|
254
|
+
hasHiddenState(): boolean;
|
|
255
|
+
d(_sides: number | undefined): RollBuilder;
|
|
256
|
+
reroll(_value: number): RollBuilder;
|
|
257
|
+
explode(_count?: number | undefined): RollBuilder;
|
|
258
|
+
minimum(_val: number | undefined): RollBuilder;
|
|
259
|
+
bestOf(_count: number | undefined): RollBuilder;
|
|
260
|
+
keepHighest(_total: number, _count: number): RollBuilder;
|
|
261
|
+
keepLowest(_total: number, _count: number): RollBuilder;
|
|
262
|
+
withAdvantage(): RollBuilder;
|
|
263
|
+
withDisadvantage(): RollBuilder;
|
|
264
|
+
withElvenAccuracy(): RollBuilder;
|
|
265
|
+
toAST(): ExpressionNode;
|
|
266
|
+
toExpression(): string;
|
|
267
|
+
copy(): PooledRollBuilder;
|
|
268
|
+
scaleDice(scale: number): RollBuilder;
|
|
269
|
+
times(count: number): PooledRollBuilder;
|
|
270
|
+
}
|
|
245
271
|
|
|
246
272
|
type ActionEffect = RollBuilder;
|
|
247
273
|
declare class AttackBuilder implements CheckBuilder {
|
|
@@ -359,4 +385,4 @@ declare const flat: (n: number) => RollBuilder;
|
|
|
359
385
|
declare const roll: RollFactory;
|
|
360
386
|
declare const builderPMFCache: LRUCache<string, PMF>;
|
|
361
387
|
|
|
362
|
-
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, type AttackConfig, type AttackResolution, type CheckBuilder, DCBuilder, HalfRollBuilder, type KeepMode, MaxOfRollBuilder, ParsedRollBuilder, type Resolution, RollBuilder, type RollConfig, type RollFactory, type RollType, SaveBuilder, type SaveOutcome, type SaveResolution, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
|
388
|
+
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, type AttackConfig, type AttackResolution, type CheckBuilder, DCBuilder, HalfRollBuilder, type KeepMode, MaxOfRollBuilder, ParsedRollBuilder, PooledRollBuilder, type Resolution, RollBuilder, type RollConfig, type RollFactory, type RollType, SaveBuilder, type SaveOutcome, type SaveResolution, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
package/dist/builder/index.js
CHANGED
|
@@ -3338,9 +3338,15 @@ var RollBuilder = class _RollBuilder {
|
|
|
3338
3338
|
this.subRollConfigs = countOrConfigs.map((c) => ({ ...c }));
|
|
3339
3339
|
}
|
|
3340
3340
|
}
|
|
3341
|
+
create(configs) {
|
|
3342
|
+
return new _RollBuilder(configs);
|
|
3343
|
+
}
|
|
3341
3344
|
get lastConfig() {
|
|
3342
3345
|
return this.subRollConfigs[this.subRollConfigs.length - 1];
|
|
3343
3346
|
}
|
|
3347
|
+
hasHiddenState() {
|
|
3348
|
+
return false;
|
|
3349
|
+
}
|
|
3344
3350
|
getSubRollConfigs() {
|
|
3345
3351
|
return this.subRollConfigs.map((c) => ({ ...c }));
|
|
3346
3352
|
}
|
|
@@ -3374,6 +3380,11 @@ var RollBuilder = class _RollBuilder {
|
|
|
3374
3380
|
}
|
|
3375
3381
|
if (isNaN(count)) throw new Error("Invalid NaN value for count argument");
|
|
3376
3382
|
if (sidesOrDie instanceof _RollBuilder) {
|
|
3383
|
+
if (sidesOrDie.hasHiddenState()) {
|
|
3384
|
+
throw new Error(
|
|
3385
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
3386
|
+
);
|
|
3387
|
+
}
|
|
3377
3388
|
const subRollConfigs = sidesOrDie.getSubRollConfigs();
|
|
3378
3389
|
if (subRollConfigs.length === 0) {
|
|
3379
3390
|
const result = new _RollBuilder(0);
|
|
@@ -3414,12 +3425,17 @@ var RollBuilder = class _RollBuilder {
|
|
|
3414
3425
|
if (sides === 0) return this;
|
|
3415
3426
|
const newConfigs = this.getSubRollConfigs();
|
|
3416
3427
|
newConfigs[newConfigs.length - 1].sides = sides;
|
|
3417
|
-
return
|
|
3428
|
+
return this.create(newConfigs);
|
|
3418
3429
|
}
|
|
3419
3430
|
plus(modOrRoll, die) {
|
|
3420
3431
|
if (typeof modOrRoll === "number" && isNaN(modOrRoll))
|
|
3421
3432
|
throw new Error("Invalid NaN value for modOrRoll");
|
|
3422
3433
|
if (die instanceof _RollBuilder && typeof modOrRoll === "number") {
|
|
3434
|
+
if (die.hasHiddenState()) {
|
|
3435
|
+
throw new Error(
|
|
3436
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
3437
|
+
);
|
|
3438
|
+
}
|
|
3423
3439
|
const count = modOrRoll;
|
|
3424
3440
|
const subRollConfigs = die.getSubRollConfigs();
|
|
3425
3441
|
if (subRollConfigs.length === 0) return this;
|
|
@@ -3444,7 +3460,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3444
3460
|
if (modOrRoll === 0) return this;
|
|
3445
3461
|
const newConfigs = this.getSubRollConfigs();
|
|
3446
3462
|
newConfigs[newConfigs.length - 1].modifier += modOrRoll;
|
|
3447
|
-
return
|
|
3463
|
+
return this.create(newConfigs);
|
|
3448
3464
|
}
|
|
3449
3465
|
return this.add(modOrRoll);
|
|
3450
3466
|
}
|
|
@@ -3462,7 +3478,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3462
3478
|
if (value === this.lastConfig.reroll) return this;
|
|
3463
3479
|
const newConfigs = this.getSubRollConfigs();
|
|
3464
3480
|
newConfigs[newConfigs.length - 1].reroll = value;
|
|
3465
|
-
return
|
|
3481
|
+
return this.create(newConfigs);
|
|
3466
3482
|
}
|
|
3467
3483
|
/** Set finite explode count for max-face explosions (Infinity allowed). */
|
|
3468
3484
|
explode(count = Infinity) {
|
|
@@ -3473,7 +3489,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3473
3489
|
if (count < 0) throw new Error("Explode count must be >= 0");
|
|
3474
3490
|
const newConfigs = this.getSubRollConfigs();
|
|
3475
3491
|
newConfigs[newConfigs.length - 1].explode = count;
|
|
3476
|
-
return
|
|
3492
|
+
return this.create(newConfigs);
|
|
3477
3493
|
}
|
|
3478
3494
|
/** Apply per-die minimum value (min > 0). */
|
|
3479
3495
|
minimum(val) {
|
|
@@ -3484,7 +3500,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3484
3500
|
if (val < 0) throw new Error("Minimum value must be >= 0");
|
|
3485
3501
|
const newConfigs = this.getSubRollConfigs();
|
|
3486
3502
|
newConfigs[newConfigs.length - 1].minimum = val + 1;
|
|
3487
|
-
return
|
|
3503
|
+
return this.create(newConfigs);
|
|
3488
3504
|
}
|
|
3489
3505
|
bestOf(count) {
|
|
3490
3506
|
if (count !== void 0 && isNaN(count))
|
|
@@ -3493,40 +3509,83 @@ var RollBuilder = class _RollBuilder {
|
|
|
3493
3509
|
if (count <= 0) throw new Error("Best of count must be > 0");
|
|
3494
3510
|
const newConfigs = this.getSubRollConfigs();
|
|
3495
3511
|
newConfigs[newConfigs.length - 1].bestOf = count;
|
|
3496
|
-
return
|
|
3512
|
+
return this.create(newConfigs);
|
|
3497
3513
|
}
|
|
3498
3514
|
keepHighest(total, count) {
|
|
3499
3515
|
if (isNaN(total) || isNaN(count))
|
|
3500
3516
|
throw new Error("Invalid NaN value for keepHighest");
|
|
3501
3517
|
const newConfigs = this.getSubRollConfigs();
|
|
3502
3518
|
newConfigs[newConfigs.length - 1].keep = { total, count, mode: "highest" };
|
|
3503
|
-
return
|
|
3519
|
+
return this.create(newConfigs);
|
|
3504
3520
|
}
|
|
3505
3521
|
keepLowest(total, count) {
|
|
3506
3522
|
if (isNaN(total) || isNaN(count))
|
|
3507
3523
|
throw new Error("Invalid NaN value for keepLowest");
|
|
3508
3524
|
const newConfigs = this.getSubRollConfigs();
|
|
3509
3525
|
newConfigs[newConfigs.length - 1].keep = { total, count, mode: "lowest" };
|
|
3510
|
-
return
|
|
3526
|
+
return this.create(newConfigs);
|
|
3527
|
+
}
|
|
3528
|
+
keepHighestAll(total, count) {
|
|
3529
|
+
if (isNaN(total) || isNaN(count))
|
|
3530
|
+
throw new Error("Invalid NaN value for keepHighestAll");
|
|
3531
|
+
const currentAST = this.toAST();
|
|
3532
|
+
const trialPool = {
|
|
3533
|
+
type: "sum",
|
|
3534
|
+
count: total,
|
|
3535
|
+
child: currentAST
|
|
3536
|
+
};
|
|
3537
|
+
const keepNode = {
|
|
3538
|
+
type: "keep",
|
|
3539
|
+
mode: "highest",
|
|
3540
|
+
count,
|
|
3541
|
+
child: trialPool
|
|
3542
|
+
};
|
|
3543
|
+
const currentExpr = this.toExpression();
|
|
3544
|
+
const expression = `${total}kh${count}(${currentExpr})`;
|
|
3545
|
+
return new PooledRollBuilder(keepNode, expression);
|
|
3546
|
+
}
|
|
3547
|
+
keepLowestAll(total, count) {
|
|
3548
|
+
if (isNaN(total) || isNaN(count))
|
|
3549
|
+
throw new Error("Invalid NaN value for keepLowestAll");
|
|
3550
|
+
const currentAST = this.toAST();
|
|
3551
|
+
const trialPool = {
|
|
3552
|
+
type: "sum",
|
|
3553
|
+
count: total,
|
|
3554
|
+
child: currentAST
|
|
3555
|
+
};
|
|
3556
|
+
const keepNode = {
|
|
3557
|
+
type: "keep",
|
|
3558
|
+
mode: "lowest",
|
|
3559
|
+
count,
|
|
3560
|
+
child: trialPool
|
|
3561
|
+
};
|
|
3562
|
+
const currentExpr = this.toExpression();
|
|
3563
|
+
const expression = `${total}kl${count}(${currentExpr})`;
|
|
3564
|
+
return new PooledRollBuilder(keepNode, expression);
|
|
3511
3565
|
}
|
|
3512
3566
|
withAdvantage() {
|
|
3513
3567
|
const newConfigs = this.getSubRollConfigs();
|
|
3514
3568
|
newConfigs[newConfigs.length - 1].rollType = "advantage";
|
|
3515
|
-
return
|
|
3569
|
+
return this.create(newConfigs);
|
|
3516
3570
|
}
|
|
3517
3571
|
withDisadvantage() {
|
|
3518
3572
|
const configs = this.getSubRollConfigs();
|
|
3519
3573
|
configs[configs.length - 1].rollType = "disadvantage";
|
|
3520
|
-
return
|
|
3574
|
+
return this.create(configs);
|
|
3521
3575
|
}
|
|
3522
3576
|
add(anotherRoll) {
|
|
3523
3577
|
if (anotherRoll === void 0) return this;
|
|
3578
|
+
if (anotherRoll.hasHiddenState()) {
|
|
3579
|
+
throw new Error(
|
|
3580
|
+
"Cannot add a roll with hidden state (like a pooled roll) to a standard roll. Try adding the standard roll to the pooled roll instead: pool.plus(roll)."
|
|
3581
|
+
);
|
|
3582
|
+
}
|
|
3524
3583
|
const configs = [...this.subRollConfigs, ...anotherRoll.subRollConfigs];
|
|
3525
|
-
return
|
|
3584
|
+
return this.create(configs);
|
|
3526
3585
|
}
|
|
3527
3586
|
withBonus(anotherRoll) {
|
|
3528
3587
|
const configs = [...this.subRollConfigs, ...anotherRoll.subRollConfigs];
|
|
3529
|
-
return
|
|
3588
|
+
return this.create(configs);
|
|
3530
3589
|
}
|
|
3531
3590
|
addRoll(count = 1) {
|
|
3532
3591
|
if (isNaN(count)) throw new Error("Invalid NaN value for count");
|
|
@@ -3538,7 +3597,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3538
3597
|
isSubtraction: count < 0
|
|
3539
3598
|
}
|
|
3540
3599
|
];
|
|
3541
|
-
return
|
|
3600
|
+
return this.create(configs);
|
|
3542
3601
|
}
|
|
3543
3602
|
scaleDice(scale) {
|
|
3544
3603
|
const scaleInt = Math.floor(scale);
|
|
@@ -3548,7 +3607,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3548
3607
|
if (!config.sides || config.sides <= 0) return config;
|
|
3549
3608
|
return { ...config, count: config.count * scaleInt };
|
|
3550
3609
|
});
|
|
3551
|
-
return
|
|
3610
|
+
return this.create(newConfigs);
|
|
3552
3611
|
}
|
|
3553
3612
|
doubleDice() {
|
|
3554
3613
|
return this.scaleDice(2);
|
|
@@ -3560,12 +3619,12 @@ var RollBuilder = class _RollBuilder {
|
|
|
3560
3619
|
return new AlwaysCritBuilder(this);
|
|
3561
3620
|
}
|
|
3562
3621
|
copy() {
|
|
3563
|
-
return
|
|
3622
|
+
return this.create(this.getSubRollConfigs());
|
|
3564
3623
|
}
|
|
3565
3624
|
withElvenAccuracy() {
|
|
3566
3625
|
const newConfigs = this.getSubRollConfigs();
|
|
3567
3626
|
newConfigs[newConfigs.length - 1].rollType = "elven accuracy";
|
|
3568
|
-
return
|
|
3627
|
+
return this.create(newConfigs);
|
|
3569
3628
|
}
|
|
3570
3629
|
toExpression() {
|
|
3571
3630
|
const originalDiceConfigs = this.subRollConfigs.filter(
|
|
@@ -3779,6 +3838,19 @@ var HalfRollBuilder = class _HalfRollBuilder extends RollBuilder {
|
|
|
3779
3838
|
super(0);
|
|
3780
3839
|
this.innerRoll = innerRoll;
|
|
3781
3840
|
}
|
|
3841
|
+
hasHiddenState() {
|
|
3842
|
+
return this.innerRoll.hasHiddenState();
|
|
3843
|
+
}
|
|
3844
|
+
// No need to override create if we don't expose RollBuilder methods that use it,
|
|
3845
|
+
// but HalfRollBuilder extends RollBuilder so it does.
|
|
3846
|
+
// However, HalfRollBuilder seems to just wrap another roll.
|
|
3847
|
+
// If we call .plus() on HalfRollBuilder, it returns a HalfRollBuilder?
|
|
3848
|
+
// No, RollBuilder.plus returns RollBuilder.
|
|
3849
|
+
// The inheritance here is a bit tricky.
|
|
3850
|
+
// Existing code for HalfRollBuilder doesn't seem to implement plus/etc.
|
|
3851
|
+
// So .plus() on a HalfRollBuilder would return a RollBuilder (base class).
|
|
3852
|
+
// Which is fine.
|
|
3853
|
+
// The only issue is if we want it to return HalfRollBuilder, but it doesn't seem designed for that.
|
|
3782
3854
|
get lastConfig() {
|
|
3783
3855
|
return this.innerRoll.lastConfig;
|
|
3784
3856
|
}
|
|
@@ -3810,6 +3882,9 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
|
|
|
3810
3882
|
this.diceCount = diceCount;
|
|
3811
3883
|
this.diceSides = diceSides;
|
|
3812
3884
|
}
|
|
3885
|
+
hasHiddenState() {
|
|
3886
|
+
return this.innerRoll.hasHiddenState();
|
|
3887
|
+
}
|
|
3813
3888
|
get lastConfig() {
|
|
3814
3889
|
return this.innerRoll.lastConfig;
|
|
3815
3890
|
}
|
|
@@ -3865,6 +3940,11 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
|
|
|
3865
3940
|
};
|
|
3866
3941
|
var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
3867
3942
|
constructor(baseRoll, attackConfig) {
|
|
3943
|
+
if (baseRoll.hasHiddenState()) {
|
|
3944
|
+
throw new Error(
|
|
3945
|
+
"Cannot create AlwaysHitBuilder from a roll with hidden state."
|
|
3946
|
+
);
|
|
3947
|
+
}
|
|
3868
3948
|
super(baseRoll.getSubRollConfigs());
|
|
3869
3949
|
__publicField(this, "attackConfig");
|
|
3870
3950
|
if (attackConfig) {
|
|
@@ -3873,6 +3953,9 @@ var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
|
3873
3953
|
this.attackConfig = { critThreshold: 20 };
|
|
3874
3954
|
}
|
|
3875
3955
|
}
|
|
3956
|
+
create(configs) {
|
|
3957
|
+
return new RollBuilder(configs);
|
|
3958
|
+
}
|
|
3876
3959
|
onHit(...args) {
|
|
3877
3960
|
const damageRoll = RollBuilder.fromArgs(...args);
|
|
3878
3961
|
return new AttackBuilder(this, damageRoll);
|
|
@@ -3907,6 +3990,11 @@ var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
|
3907
3990
|
};
|
|
3908
3991
|
var AlwaysCritBuilder = class _AlwaysCritBuilder extends RollBuilder {
|
|
3909
3992
|
constructor(baseRoll, attackConfig, fromAlwaysHit = false) {
|
|
3993
|
+
if (baseRoll.hasHiddenState()) {
|
|
3994
|
+
throw new Error(
|
|
3995
|
+
"Cannot create AlwaysCritBuilder from a roll with hidden state."
|
|
3996
|
+
);
|
|
3997
|
+
}
|
|
3910
3998
|
super(baseRoll.getSubRollConfigs());
|
|
3911
3999
|
__publicField(this, "attackConfig");
|
|
3912
4000
|
__publicField(this, "fromAlwaysHit");
|
|
@@ -3917,6 +4005,9 @@ var AlwaysCritBuilder = class _AlwaysCritBuilder extends RollBuilder {
|
|
|
3917
4005
|
}
|
|
3918
4006
|
this.fromAlwaysHit = fromAlwaysHit || baseRoll instanceof AlwaysHitBuilder;
|
|
3919
4007
|
}
|
|
4008
|
+
create(configs) {
|
|
4009
|
+
return new RollBuilder(configs);
|
|
4010
|
+
}
|
|
3920
4011
|
onHit(...args) {
|
|
3921
4012
|
const damageRoll = RollBuilder.fromArgs(...args);
|
|
3922
4013
|
return new AttackBuilder(this, damageRoll);
|
|
@@ -3953,7 +4044,13 @@ var ParsedRollBuilder = class _ParsedRollBuilder extends RollBuilder {
|
|
|
3953
4044
|
this.originalExpression = expression;
|
|
3954
4045
|
this.cachedPMF = parse(expression, 0);
|
|
3955
4046
|
}
|
|
3956
|
-
|
|
4047
|
+
hasHiddenState() {
|
|
4048
|
+
return true;
|
|
4049
|
+
}
|
|
4050
|
+
create(configs) {
|
|
4051
|
+
return new RollBuilder(configs);
|
|
4052
|
+
}
|
|
4053
|
+
toPMF(_eps = 0) {
|
|
3957
4054
|
return this.cachedPMF;
|
|
3958
4055
|
}
|
|
3959
4056
|
toExpression() {
|
|
@@ -3973,10 +4070,122 @@ var ParsedRollBuilder = class _ParsedRollBuilder extends RollBuilder {
|
|
|
3973
4070
|
);
|
|
3974
4071
|
}
|
|
3975
4072
|
};
|
|
4073
|
+
var PooledRollBuilder = class _PooledRollBuilder extends RollBuilder {
|
|
4074
|
+
constructor(baseAST, baseExpression, configs = []) {
|
|
4075
|
+
super(configs.length > 0 ? configs : 0);
|
|
4076
|
+
this.baseAST = baseAST;
|
|
4077
|
+
this.baseExpression = baseExpression;
|
|
4078
|
+
}
|
|
4079
|
+
create(configs) {
|
|
4080
|
+
return new _PooledRollBuilder(this.baseAST, this.baseExpression, configs);
|
|
4081
|
+
}
|
|
4082
|
+
hasHiddenState() {
|
|
4083
|
+
return true;
|
|
4084
|
+
}
|
|
4085
|
+
d(_sides) {
|
|
4086
|
+
throw new Error("Cannot add dice to a pooled roll. The pool is finalized.");
|
|
4087
|
+
}
|
|
4088
|
+
reroll(_value) {
|
|
4089
|
+
throw new Error("Cannot set reroll on a pooled roll.");
|
|
4090
|
+
}
|
|
4091
|
+
explode(_count = Infinity) {
|
|
4092
|
+
throw new Error("Cannot set explode on a pooled roll.");
|
|
4093
|
+
}
|
|
4094
|
+
minimum(_val) {
|
|
4095
|
+
throw new Error("Cannot set minimum on a pooled roll.");
|
|
4096
|
+
}
|
|
4097
|
+
bestOf(_count) {
|
|
4098
|
+
throw new Error("Cannot set bestOf on a pooled roll.");
|
|
4099
|
+
}
|
|
4100
|
+
keepHighest(_total, _count) {
|
|
4101
|
+
throw new Error(
|
|
4102
|
+
"Cannot use keepHighest on a pooled roll. Use keepHighestAll again if you want nested pooling."
|
|
4103
|
+
);
|
|
4104
|
+
}
|
|
4105
|
+
keepLowest(_total, _count) {
|
|
4106
|
+
throw new Error(
|
|
4107
|
+
"Cannot use keepLowest on a pooled roll. Use keepLowestAll again if you want nested pooling."
|
|
4108
|
+
);
|
|
4109
|
+
}
|
|
4110
|
+
withAdvantage() {
|
|
4111
|
+
throw new Error("Cannot set advantage on a pooled roll.");
|
|
4112
|
+
}
|
|
4113
|
+
withDisadvantage() {
|
|
4114
|
+
throw new Error("Cannot set disadvantage on a pooled roll.");
|
|
4115
|
+
}
|
|
4116
|
+
withElvenAccuracy() {
|
|
4117
|
+
throw new Error("Cannot set elven accuracy on a pooled roll.");
|
|
4118
|
+
}
|
|
4119
|
+
toAST() {
|
|
4120
|
+
const configsAST = super.toAST();
|
|
4121
|
+
const isZero = configsAST.type === "constant" && configsAST.value === 0;
|
|
4122
|
+
if (isZero) {
|
|
4123
|
+
return this.baseAST;
|
|
4124
|
+
}
|
|
4125
|
+
const children = [
|
|
4126
|
+
{ node: this.baseAST, sign: 1 },
|
|
4127
|
+
{ node: configsAST, sign: 1 }
|
|
4128
|
+
];
|
|
4129
|
+
return { type: "add", children };
|
|
4130
|
+
}
|
|
4131
|
+
toExpression() {
|
|
4132
|
+
const configsExpression = super.toExpression();
|
|
4133
|
+
if (configsExpression === "0") {
|
|
4134
|
+
return this.baseExpression;
|
|
4135
|
+
}
|
|
4136
|
+
if (configsExpression.startsWith("-")) {
|
|
4137
|
+
return `${this.baseExpression} - ${configsExpression.substring(1)}`;
|
|
4138
|
+
}
|
|
4139
|
+
return `${this.baseExpression} + ${configsExpression}`;
|
|
4140
|
+
}
|
|
4141
|
+
copy() {
|
|
4142
|
+
return new _PooledRollBuilder(
|
|
4143
|
+
this.baseAST,
|
|
4144
|
+
this.baseExpression,
|
|
4145
|
+
this.getSubRollConfigs()
|
|
4146
|
+
);
|
|
4147
|
+
}
|
|
4148
|
+
scaleDice(scale) {
|
|
4149
|
+
const scaleInt = Math.floor(scale);
|
|
4150
|
+
if (scaleInt !== scale) throw new Error("Scale must be an integer");
|
|
4151
|
+
if (scaleInt <= 0) throw new Error("Scale must be > 0");
|
|
4152
|
+
const newBaseAST = {
|
|
4153
|
+
type: "sum",
|
|
4154
|
+
count: scaleInt,
|
|
4155
|
+
child: this.baseAST
|
|
4156
|
+
};
|
|
4157
|
+
const newBaseExpr = scaleInt === 1 ? this.baseExpression : `${scaleInt}(${this.baseExpression})`;
|
|
4158
|
+
return new _PooledRollBuilder(
|
|
4159
|
+
newBaseAST,
|
|
4160
|
+
newBaseExpr,
|
|
4161
|
+
this.getSubRollConfigs()
|
|
4162
|
+
);
|
|
4163
|
+
}
|
|
4164
|
+
times(count) {
|
|
4165
|
+
if (isNaN(count)) throw new Error("Invalid NaN value for times");
|
|
4166
|
+
if (Math.floor(count) !== count)
|
|
4167
|
+
throw new Error("times() requires an integer");
|
|
4168
|
+
if (count < 0) throw new Error("times() requires a non-negative integer");
|
|
4169
|
+
const currentAST = this.toAST();
|
|
4170
|
+
const currentExpr = this.toExpression();
|
|
4171
|
+
const sumNode = {
|
|
4172
|
+
type: "sum",
|
|
4173
|
+
count,
|
|
4174
|
+
child: currentAST
|
|
4175
|
+
};
|
|
4176
|
+
const newExpr = count === 1 ? currentExpr : `${count}(${currentExpr})`;
|
|
4177
|
+
return new _PooledRollBuilder(sumNode, newExpr);
|
|
4178
|
+
}
|
|
4179
|
+
};
|
|
3976
4180
|
|
|
3977
4181
|
// src/builder/factory.ts
|
|
3978
4182
|
var rollFn = (count, sidesOrDie, modifier) => {
|
|
3979
4183
|
if (sidesOrDie instanceof RollBuilder) {
|
|
4184
|
+
if (sidesOrDie.hasHiddenState()) {
|
|
4185
|
+
throw new Error(
|
|
4186
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
4187
|
+
);
|
|
4188
|
+
}
|
|
3980
4189
|
const subRollConfigs = sidesOrDie.getSubRollConfigs();
|
|
3981
4190
|
if (subRollConfigs.length === 0) return new RollBuilder(0).plus(modifier);
|
|
3982
4191
|
const absCount = Math.abs(count);
|
|
@@ -4878,6 +5087,6 @@ RollBuilder.prototype.dc = function(saveDC) {
|
|
|
4878
5087
|
return new DCBuilder(this).dc(saveDC);
|
|
4879
5088
|
};
|
|
4880
5089
|
|
|
4881
|
-
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, DCBuilder, HalfRollBuilder, MaxOfRollBuilder, ParsedRollBuilder, RollBuilder, SaveBuilder, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
|
5090
|
+
export { ACBuilder, AlwaysCritBuilder, AlwaysHitBuilder, DCBuilder, HalfRollBuilder, MaxOfRollBuilder, ParsedRollBuilder, PooledRollBuilder, RollBuilder, SaveBuilder, builderPMFCache, d, d10, d100, d12, d20, d4, d6, d8, defaultConfig, flat, hd20, roll };
|
|
4882
5091
|
//# sourceMappingURL=index.js.map
|
|
4883
5092
|
//# sourceMappingURL=index.js.map
|