@yipe/dice 0.2.19 → 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 +228 -18
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.d.cts +35 -8
- package/dist/builder/index.d.ts +35 -8
- package/dist/builder/index.js +228 -19
- package/dist/builder/index.js.map +1 -1
- package/package.json +1 -1
package/dist/builder/index.cjs
CHANGED
|
@@ -3340,9 +3340,15 @@ var RollBuilder = class _RollBuilder {
|
|
|
3340
3340
|
this.subRollConfigs = countOrConfigs.map((c) => ({ ...c }));
|
|
3341
3341
|
}
|
|
3342
3342
|
}
|
|
3343
|
+
create(configs) {
|
|
3344
|
+
return new _RollBuilder(configs);
|
|
3345
|
+
}
|
|
3343
3346
|
get lastConfig() {
|
|
3344
3347
|
return this.subRollConfigs[this.subRollConfigs.length - 1];
|
|
3345
3348
|
}
|
|
3349
|
+
hasHiddenState() {
|
|
3350
|
+
return false;
|
|
3351
|
+
}
|
|
3346
3352
|
getSubRollConfigs() {
|
|
3347
3353
|
return this.subRollConfigs.map((c) => ({ ...c }));
|
|
3348
3354
|
}
|
|
@@ -3376,6 +3382,11 @@ var RollBuilder = class _RollBuilder {
|
|
|
3376
3382
|
}
|
|
3377
3383
|
if (isNaN(count)) throw new Error("Invalid NaN value for count argument");
|
|
3378
3384
|
if (sidesOrDie instanceof _RollBuilder) {
|
|
3385
|
+
if (sidesOrDie.hasHiddenState()) {
|
|
3386
|
+
throw new Error(
|
|
3387
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
3388
|
+
);
|
|
3389
|
+
}
|
|
3379
3390
|
const subRollConfigs = sidesOrDie.getSubRollConfigs();
|
|
3380
3391
|
if (subRollConfigs.length === 0) {
|
|
3381
3392
|
const result = new _RollBuilder(0);
|
|
@@ -3416,12 +3427,17 @@ var RollBuilder = class _RollBuilder {
|
|
|
3416
3427
|
if (sides === 0) return this;
|
|
3417
3428
|
const newConfigs = this.getSubRollConfigs();
|
|
3418
3429
|
newConfigs[newConfigs.length - 1].sides = sides;
|
|
3419
|
-
return
|
|
3430
|
+
return this.create(newConfigs);
|
|
3420
3431
|
}
|
|
3421
3432
|
plus(modOrRoll, die) {
|
|
3422
3433
|
if (typeof modOrRoll === "number" && isNaN(modOrRoll))
|
|
3423
3434
|
throw new Error("Invalid NaN value for modOrRoll");
|
|
3424
3435
|
if (die instanceof _RollBuilder && typeof modOrRoll === "number") {
|
|
3436
|
+
if (die.hasHiddenState()) {
|
|
3437
|
+
throw new Error(
|
|
3438
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
3439
|
+
);
|
|
3440
|
+
}
|
|
3425
3441
|
const count = modOrRoll;
|
|
3426
3442
|
const subRollConfigs = die.getSubRollConfigs();
|
|
3427
3443
|
if (subRollConfigs.length === 0) return this;
|
|
@@ -3446,7 +3462,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3446
3462
|
if (modOrRoll === 0) return this;
|
|
3447
3463
|
const newConfigs = this.getSubRollConfigs();
|
|
3448
3464
|
newConfigs[newConfigs.length - 1].modifier += modOrRoll;
|
|
3449
|
-
return
|
|
3465
|
+
return this.create(newConfigs);
|
|
3450
3466
|
}
|
|
3451
3467
|
return this.add(modOrRoll);
|
|
3452
3468
|
}
|
|
@@ -3464,7 +3480,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3464
3480
|
if (value === this.lastConfig.reroll) return this;
|
|
3465
3481
|
const newConfigs = this.getSubRollConfigs();
|
|
3466
3482
|
newConfigs[newConfigs.length - 1].reroll = value;
|
|
3467
|
-
return
|
|
3483
|
+
return this.create(newConfigs);
|
|
3468
3484
|
}
|
|
3469
3485
|
/** Set finite explode count for max-face explosions (Infinity allowed). */
|
|
3470
3486
|
explode(count = Infinity) {
|
|
@@ -3475,7 +3491,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3475
3491
|
if (count < 0) throw new Error("Explode count must be >= 0");
|
|
3476
3492
|
const newConfigs = this.getSubRollConfigs();
|
|
3477
3493
|
newConfigs[newConfigs.length - 1].explode = count;
|
|
3478
|
-
return
|
|
3494
|
+
return this.create(newConfigs);
|
|
3479
3495
|
}
|
|
3480
3496
|
/** Apply per-die minimum value (min > 0). */
|
|
3481
3497
|
minimum(val) {
|
|
@@ -3486,7 +3502,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3486
3502
|
if (val < 0) throw new Error("Minimum value must be >= 0");
|
|
3487
3503
|
const newConfigs = this.getSubRollConfigs();
|
|
3488
3504
|
newConfigs[newConfigs.length - 1].minimum = val + 1;
|
|
3489
|
-
return
|
|
3505
|
+
return this.create(newConfigs);
|
|
3490
3506
|
}
|
|
3491
3507
|
bestOf(count) {
|
|
3492
3508
|
if (count !== void 0 && isNaN(count))
|
|
@@ -3495,40 +3511,83 @@ var RollBuilder = class _RollBuilder {
|
|
|
3495
3511
|
if (count <= 0) throw new Error("Best of count must be > 0");
|
|
3496
3512
|
const newConfigs = this.getSubRollConfigs();
|
|
3497
3513
|
newConfigs[newConfigs.length - 1].bestOf = count;
|
|
3498
|
-
return
|
|
3514
|
+
return this.create(newConfigs);
|
|
3499
3515
|
}
|
|
3500
3516
|
keepHighest(total, count) {
|
|
3501
3517
|
if (isNaN(total) || isNaN(count))
|
|
3502
3518
|
throw new Error("Invalid NaN value for keepHighest");
|
|
3503
3519
|
const newConfigs = this.getSubRollConfigs();
|
|
3504
3520
|
newConfigs[newConfigs.length - 1].keep = { total, count, mode: "highest" };
|
|
3505
|
-
return
|
|
3521
|
+
return this.create(newConfigs);
|
|
3506
3522
|
}
|
|
3507
3523
|
keepLowest(total, count) {
|
|
3508
3524
|
if (isNaN(total) || isNaN(count))
|
|
3509
3525
|
throw new Error("Invalid NaN value for keepLowest");
|
|
3510
3526
|
const newConfigs = this.getSubRollConfigs();
|
|
3511
3527
|
newConfigs[newConfigs.length - 1].keep = { total, count, mode: "lowest" };
|
|
3512
|
-
return
|
|
3528
|
+
return this.create(newConfigs);
|
|
3529
|
+
}
|
|
3530
|
+
keepHighestAll(total, count) {
|
|
3531
|
+
if (isNaN(total) || isNaN(count))
|
|
3532
|
+
throw new Error("Invalid NaN value for keepHighestAll");
|
|
3533
|
+
const currentAST = this.toAST();
|
|
3534
|
+
const trialPool = {
|
|
3535
|
+
type: "sum",
|
|
3536
|
+
count: total,
|
|
3537
|
+
child: currentAST
|
|
3538
|
+
};
|
|
3539
|
+
const keepNode = {
|
|
3540
|
+
type: "keep",
|
|
3541
|
+
mode: "highest",
|
|
3542
|
+
count,
|
|
3543
|
+
child: trialPool
|
|
3544
|
+
};
|
|
3545
|
+
const currentExpr = this.toExpression();
|
|
3546
|
+
const expression = `${total}kh${count}(${currentExpr})`;
|
|
3547
|
+
return new PooledRollBuilder(keepNode, expression);
|
|
3548
|
+
}
|
|
3549
|
+
keepLowestAll(total, count) {
|
|
3550
|
+
if (isNaN(total) || isNaN(count))
|
|
3551
|
+
throw new Error("Invalid NaN value for keepLowestAll");
|
|
3552
|
+
const currentAST = this.toAST();
|
|
3553
|
+
const trialPool = {
|
|
3554
|
+
type: "sum",
|
|
3555
|
+
count: total,
|
|
3556
|
+
child: currentAST
|
|
3557
|
+
};
|
|
3558
|
+
const keepNode = {
|
|
3559
|
+
type: "keep",
|
|
3560
|
+
mode: "lowest",
|
|
3561
|
+
count,
|
|
3562
|
+
child: trialPool
|
|
3563
|
+
};
|
|
3564
|
+
const currentExpr = this.toExpression();
|
|
3565
|
+
const expression = `${total}kl${count}(${currentExpr})`;
|
|
3566
|
+
return new PooledRollBuilder(keepNode, expression);
|
|
3513
3567
|
}
|
|
3514
3568
|
withAdvantage() {
|
|
3515
3569
|
const newConfigs = this.getSubRollConfigs();
|
|
3516
3570
|
newConfigs[newConfigs.length - 1].rollType = "advantage";
|
|
3517
|
-
return
|
|
3571
|
+
return this.create(newConfigs);
|
|
3518
3572
|
}
|
|
3519
3573
|
withDisadvantage() {
|
|
3520
3574
|
const configs = this.getSubRollConfigs();
|
|
3521
3575
|
configs[configs.length - 1].rollType = "disadvantage";
|
|
3522
|
-
return
|
|
3576
|
+
return this.create(configs);
|
|
3523
3577
|
}
|
|
3524
3578
|
add(anotherRoll) {
|
|
3525
3579
|
if (anotherRoll === void 0) return this;
|
|
3580
|
+
if (anotherRoll.hasHiddenState()) {
|
|
3581
|
+
throw new Error(
|
|
3582
|
+
"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)."
|
|
3583
|
+
);
|
|
3584
|
+
}
|
|
3526
3585
|
const configs = [...this.subRollConfigs, ...anotherRoll.subRollConfigs];
|
|
3527
|
-
return
|
|
3586
|
+
return this.create(configs);
|
|
3528
3587
|
}
|
|
3529
3588
|
withBonus(anotherRoll) {
|
|
3530
3589
|
const configs = [...this.subRollConfigs, ...anotherRoll.subRollConfigs];
|
|
3531
|
-
return
|
|
3590
|
+
return this.create(configs);
|
|
3532
3591
|
}
|
|
3533
3592
|
addRoll(count = 1) {
|
|
3534
3593
|
if (isNaN(count)) throw new Error("Invalid NaN value for count");
|
|
@@ -3540,7 +3599,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3540
3599
|
isSubtraction: count < 0
|
|
3541
3600
|
}
|
|
3542
3601
|
];
|
|
3543
|
-
return
|
|
3602
|
+
return this.create(configs);
|
|
3544
3603
|
}
|
|
3545
3604
|
scaleDice(scale) {
|
|
3546
3605
|
const scaleInt = Math.floor(scale);
|
|
@@ -3550,7 +3609,7 @@ var RollBuilder = class _RollBuilder {
|
|
|
3550
3609
|
if (!config.sides || config.sides <= 0) return config;
|
|
3551
3610
|
return { ...config, count: config.count * scaleInt };
|
|
3552
3611
|
});
|
|
3553
|
-
return
|
|
3612
|
+
return this.create(newConfigs);
|
|
3554
3613
|
}
|
|
3555
3614
|
doubleDice() {
|
|
3556
3615
|
return this.scaleDice(2);
|
|
@@ -3562,12 +3621,12 @@ var RollBuilder = class _RollBuilder {
|
|
|
3562
3621
|
return new AlwaysCritBuilder(this);
|
|
3563
3622
|
}
|
|
3564
3623
|
copy() {
|
|
3565
|
-
return
|
|
3624
|
+
return this.create(this.getSubRollConfigs());
|
|
3566
3625
|
}
|
|
3567
3626
|
withElvenAccuracy() {
|
|
3568
3627
|
const newConfigs = this.getSubRollConfigs();
|
|
3569
3628
|
newConfigs[newConfigs.length - 1].rollType = "elven accuracy";
|
|
3570
|
-
return
|
|
3629
|
+
return this.create(newConfigs);
|
|
3571
3630
|
}
|
|
3572
3631
|
toExpression() {
|
|
3573
3632
|
const originalDiceConfigs = this.subRollConfigs.filter(
|
|
@@ -3781,6 +3840,19 @@ var HalfRollBuilder = class _HalfRollBuilder extends RollBuilder {
|
|
|
3781
3840
|
super(0);
|
|
3782
3841
|
this.innerRoll = innerRoll;
|
|
3783
3842
|
}
|
|
3843
|
+
hasHiddenState() {
|
|
3844
|
+
return this.innerRoll.hasHiddenState();
|
|
3845
|
+
}
|
|
3846
|
+
// No need to override create if we don't expose RollBuilder methods that use it,
|
|
3847
|
+
// but HalfRollBuilder extends RollBuilder so it does.
|
|
3848
|
+
// However, HalfRollBuilder seems to just wrap another roll.
|
|
3849
|
+
// If we call .plus() on HalfRollBuilder, it returns a HalfRollBuilder?
|
|
3850
|
+
// No, RollBuilder.plus returns RollBuilder.
|
|
3851
|
+
// The inheritance here is a bit tricky.
|
|
3852
|
+
// Existing code for HalfRollBuilder doesn't seem to implement plus/etc.
|
|
3853
|
+
// So .plus() on a HalfRollBuilder would return a RollBuilder (base class).
|
|
3854
|
+
// Which is fine.
|
|
3855
|
+
// The only issue is if we want it to return HalfRollBuilder, but it doesn't seem designed for that.
|
|
3784
3856
|
get lastConfig() {
|
|
3785
3857
|
return this.innerRoll.lastConfig;
|
|
3786
3858
|
}
|
|
@@ -3812,6 +3884,9 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
|
|
|
3812
3884
|
this.diceCount = diceCount;
|
|
3813
3885
|
this.diceSides = diceSides;
|
|
3814
3886
|
}
|
|
3887
|
+
hasHiddenState() {
|
|
3888
|
+
return this.innerRoll.hasHiddenState();
|
|
3889
|
+
}
|
|
3815
3890
|
get lastConfig() {
|
|
3816
3891
|
return this.innerRoll.lastConfig;
|
|
3817
3892
|
}
|
|
@@ -3867,6 +3942,11 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
|
|
|
3867
3942
|
};
|
|
3868
3943
|
var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
3869
3944
|
constructor(baseRoll, attackConfig) {
|
|
3945
|
+
if (baseRoll.hasHiddenState()) {
|
|
3946
|
+
throw new Error(
|
|
3947
|
+
"Cannot create AlwaysHitBuilder from a roll with hidden state."
|
|
3948
|
+
);
|
|
3949
|
+
}
|
|
3870
3950
|
super(baseRoll.getSubRollConfigs());
|
|
3871
3951
|
__publicField(this, "attackConfig");
|
|
3872
3952
|
if (attackConfig) {
|
|
@@ -3875,6 +3955,9 @@ var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
|
3875
3955
|
this.attackConfig = { critThreshold: 20 };
|
|
3876
3956
|
}
|
|
3877
3957
|
}
|
|
3958
|
+
create(configs) {
|
|
3959
|
+
return new RollBuilder(configs);
|
|
3960
|
+
}
|
|
3878
3961
|
onHit(...args) {
|
|
3879
3962
|
const damageRoll = RollBuilder.fromArgs(...args);
|
|
3880
3963
|
return new AttackBuilder(this, damageRoll);
|
|
@@ -3909,6 +3992,11 @@ var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
|
|
|
3909
3992
|
};
|
|
3910
3993
|
var AlwaysCritBuilder = class _AlwaysCritBuilder extends RollBuilder {
|
|
3911
3994
|
constructor(baseRoll, attackConfig, fromAlwaysHit = false) {
|
|
3995
|
+
if (baseRoll.hasHiddenState()) {
|
|
3996
|
+
throw new Error(
|
|
3997
|
+
"Cannot create AlwaysCritBuilder from a roll with hidden state."
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
3912
4000
|
super(baseRoll.getSubRollConfigs());
|
|
3913
4001
|
__publicField(this, "attackConfig");
|
|
3914
4002
|
__publicField(this, "fromAlwaysHit");
|
|
@@ -3919,6 +4007,9 @@ var AlwaysCritBuilder = class _AlwaysCritBuilder extends RollBuilder {
|
|
|
3919
4007
|
}
|
|
3920
4008
|
this.fromAlwaysHit = fromAlwaysHit || baseRoll instanceof AlwaysHitBuilder;
|
|
3921
4009
|
}
|
|
4010
|
+
create(configs) {
|
|
4011
|
+
return new RollBuilder(configs);
|
|
4012
|
+
}
|
|
3922
4013
|
onHit(...args) {
|
|
3923
4014
|
const damageRoll = RollBuilder.fromArgs(...args);
|
|
3924
4015
|
return new AttackBuilder(this, damageRoll);
|
|
@@ -3955,7 +4046,13 @@ var ParsedRollBuilder = class _ParsedRollBuilder extends RollBuilder {
|
|
|
3955
4046
|
this.originalExpression = expression;
|
|
3956
4047
|
this.cachedPMF = parse(expression, 0);
|
|
3957
4048
|
}
|
|
3958
|
-
|
|
4049
|
+
hasHiddenState() {
|
|
4050
|
+
return true;
|
|
4051
|
+
}
|
|
4052
|
+
create(configs) {
|
|
4053
|
+
return new RollBuilder(configs);
|
|
4054
|
+
}
|
|
4055
|
+
toPMF(_eps = 0) {
|
|
3959
4056
|
return this.cachedPMF;
|
|
3960
4057
|
}
|
|
3961
4058
|
toExpression() {
|
|
@@ -3975,10 +4072,122 @@ var ParsedRollBuilder = class _ParsedRollBuilder extends RollBuilder {
|
|
|
3975
4072
|
);
|
|
3976
4073
|
}
|
|
3977
4074
|
};
|
|
4075
|
+
var PooledRollBuilder = class _PooledRollBuilder extends RollBuilder {
|
|
4076
|
+
constructor(baseAST, baseExpression, configs = []) {
|
|
4077
|
+
super(configs.length > 0 ? configs : 0);
|
|
4078
|
+
this.baseAST = baseAST;
|
|
4079
|
+
this.baseExpression = baseExpression;
|
|
4080
|
+
}
|
|
4081
|
+
create(configs) {
|
|
4082
|
+
return new _PooledRollBuilder(this.baseAST, this.baseExpression, configs);
|
|
4083
|
+
}
|
|
4084
|
+
hasHiddenState() {
|
|
4085
|
+
return true;
|
|
4086
|
+
}
|
|
4087
|
+
d(_sides) {
|
|
4088
|
+
throw new Error("Cannot add dice to a pooled roll. The pool is finalized.");
|
|
4089
|
+
}
|
|
4090
|
+
reroll(_value) {
|
|
4091
|
+
throw new Error("Cannot set reroll on a pooled roll.");
|
|
4092
|
+
}
|
|
4093
|
+
explode(_count = Infinity) {
|
|
4094
|
+
throw new Error("Cannot set explode on a pooled roll.");
|
|
4095
|
+
}
|
|
4096
|
+
minimum(_val) {
|
|
4097
|
+
throw new Error("Cannot set minimum on a pooled roll.");
|
|
4098
|
+
}
|
|
4099
|
+
bestOf(_count) {
|
|
4100
|
+
throw new Error("Cannot set bestOf on a pooled roll.");
|
|
4101
|
+
}
|
|
4102
|
+
keepHighest(_total, _count) {
|
|
4103
|
+
throw new Error(
|
|
4104
|
+
"Cannot use keepHighest on a pooled roll. Use keepHighestAll again if you want nested pooling."
|
|
4105
|
+
);
|
|
4106
|
+
}
|
|
4107
|
+
keepLowest(_total, _count) {
|
|
4108
|
+
throw new Error(
|
|
4109
|
+
"Cannot use keepLowest on a pooled roll. Use keepLowestAll again if you want nested pooling."
|
|
4110
|
+
);
|
|
4111
|
+
}
|
|
4112
|
+
withAdvantage() {
|
|
4113
|
+
throw new Error("Cannot set advantage on a pooled roll.");
|
|
4114
|
+
}
|
|
4115
|
+
withDisadvantage() {
|
|
4116
|
+
throw new Error("Cannot set disadvantage on a pooled roll.");
|
|
4117
|
+
}
|
|
4118
|
+
withElvenAccuracy() {
|
|
4119
|
+
throw new Error("Cannot set elven accuracy on a pooled roll.");
|
|
4120
|
+
}
|
|
4121
|
+
toAST() {
|
|
4122
|
+
const configsAST = super.toAST();
|
|
4123
|
+
const isZero = configsAST.type === "constant" && configsAST.value === 0;
|
|
4124
|
+
if (isZero) {
|
|
4125
|
+
return this.baseAST;
|
|
4126
|
+
}
|
|
4127
|
+
const children = [
|
|
4128
|
+
{ node: this.baseAST, sign: 1 },
|
|
4129
|
+
{ node: configsAST, sign: 1 }
|
|
4130
|
+
];
|
|
4131
|
+
return { type: "add", children };
|
|
4132
|
+
}
|
|
4133
|
+
toExpression() {
|
|
4134
|
+
const configsExpression = super.toExpression();
|
|
4135
|
+
if (configsExpression === "0") {
|
|
4136
|
+
return this.baseExpression;
|
|
4137
|
+
}
|
|
4138
|
+
if (configsExpression.startsWith("-")) {
|
|
4139
|
+
return `${this.baseExpression} - ${configsExpression.substring(1)}`;
|
|
4140
|
+
}
|
|
4141
|
+
return `${this.baseExpression} + ${configsExpression}`;
|
|
4142
|
+
}
|
|
4143
|
+
copy() {
|
|
4144
|
+
return new _PooledRollBuilder(
|
|
4145
|
+
this.baseAST,
|
|
4146
|
+
this.baseExpression,
|
|
4147
|
+
this.getSubRollConfigs()
|
|
4148
|
+
);
|
|
4149
|
+
}
|
|
4150
|
+
scaleDice(scale) {
|
|
4151
|
+
const scaleInt = Math.floor(scale);
|
|
4152
|
+
if (scaleInt !== scale) throw new Error("Scale must be an integer");
|
|
4153
|
+
if (scaleInt <= 0) throw new Error("Scale must be > 0");
|
|
4154
|
+
const newBaseAST = {
|
|
4155
|
+
type: "sum",
|
|
4156
|
+
count: scaleInt,
|
|
4157
|
+
child: this.baseAST
|
|
4158
|
+
};
|
|
4159
|
+
const newBaseExpr = scaleInt === 1 ? this.baseExpression : `${scaleInt}(${this.baseExpression})`;
|
|
4160
|
+
return new _PooledRollBuilder(
|
|
4161
|
+
newBaseAST,
|
|
4162
|
+
newBaseExpr,
|
|
4163
|
+
this.getSubRollConfigs()
|
|
4164
|
+
);
|
|
4165
|
+
}
|
|
4166
|
+
times(count) {
|
|
4167
|
+
if (isNaN(count)) throw new Error("Invalid NaN value for times");
|
|
4168
|
+
if (Math.floor(count) !== count)
|
|
4169
|
+
throw new Error("times() requires an integer");
|
|
4170
|
+
if (count < 0) throw new Error("times() requires a non-negative integer");
|
|
4171
|
+
const currentAST = this.toAST();
|
|
4172
|
+
const currentExpr = this.toExpression();
|
|
4173
|
+
const sumNode = {
|
|
4174
|
+
type: "sum",
|
|
4175
|
+
count,
|
|
4176
|
+
child: currentAST
|
|
4177
|
+
};
|
|
4178
|
+
const newExpr = count === 1 ? currentExpr : `${count}(${currentExpr})`;
|
|
4179
|
+
return new _PooledRollBuilder(sumNode, newExpr);
|
|
4180
|
+
}
|
|
4181
|
+
};
|
|
3978
4182
|
|
|
3979
4183
|
// src/builder/factory.ts
|
|
3980
4184
|
var rollFn = (count, sidesOrDie, modifier) => {
|
|
3981
4185
|
if (sidesOrDie instanceof RollBuilder) {
|
|
4186
|
+
if (sidesOrDie.hasHiddenState()) {
|
|
4187
|
+
throw new Error(
|
|
4188
|
+
"Cannot use a roll with hidden state (like a pooled roll) as a die type."
|
|
4189
|
+
);
|
|
4190
|
+
}
|
|
3982
4191
|
const subRollConfigs = sidesOrDie.getSubRollConfigs();
|
|
3983
4192
|
if (subRollConfigs.length === 0) return new RollBuilder(0).plus(modifier);
|
|
3984
4193
|
const absCount = Math.abs(count);
|
|
@@ -4755,7 +4964,7 @@ var SaveBuilder = class _SaveBuilder {
|
|
|
4755
4964
|
const { pSuccess: psuccess = 0, pFail: pfail = 1 } = resolveProbabilities(
|
|
4756
4965
|
this.check
|
|
4757
4966
|
);
|
|
4758
|
-
const failPMF = this.failureEffect ? pmfFromRollBuilder(this.failureEffect) : PMF.delta(0);
|
|
4967
|
+
const failPMF = this.failureEffect ? this.failureEffect instanceof ParsedRollBuilder ? this.failureEffect.toPMF(eps) : pmfFromRollBuilder(this.failureEffect) : PMF.delta(0);
|
|
4759
4968
|
const onSuccess = this.saveOutcome ?? "half";
|
|
4760
4969
|
let successPMF = PMF.delta(0, eps);
|
|
4761
4970
|
if (onSuccess === "half") successPMF = failPMF.scaleDamage(0.5, "floor");
|
|
@@ -4887,6 +5096,7 @@ exports.DCBuilder = DCBuilder;
|
|
|
4887
5096
|
exports.HalfRollBuilder = HalfRollBuilder;
|
|
4888
5097
|
exports.MaxOfRollBuilder = MaxOfRollBuilder;
|
|
4889
5098
|
exports.ParsedRollBuilder = ParsedRollBuilder;
|
|
5099
|
+
exports.PooledRollBuilder = PooledRollBuilder;
|
|
4890
5100
|
exports.RollBuilder = RollBuilder;
|
|
4891
5101
|
exports.SaveBuilder = SaveBuilder;
|
|
4892
5102
|
exports.builderPMFCache = builderPMFCache;
|