@yipe/dice 0.2.13 → 0.2.15

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.
@@ -2659,14 +2659,6 @@ var RollBuilder = class _RollBuilder {
2659
2659
  const scaleInt = Math.floor(scale);
2660
2660
  if (scaleInt !== scale) throw new Error("Scale must be an integer");
2661
2661
  if (scaleInt <= 0) throw new Error("Scale must be > 0");
2662
- if (scaleInt > 1) {
2663
- const configs = this.getSubRollConfigs();
2664
- if (configs.length === 1 && configs[0].keep && configs[0].count === 1) {
2665
- const config = configs[0];
2666
- const newConfig = { ...config, count: scaleInt };
2667
- return new _RollBuilder([newConfig]);
2668
- }
2669
- }
2670
2662
  const newConfigs = this.getSubRollConfigs().map((config) => {
2671
2663
  if (!config.sides || config.sides <= 0) return config;
2672
2664
  return { ...config, count: config.count * scaleInt };
@@ -2676,6 +2668,9 @@ var RollBuilder = class _RollBuilder {
2676
2668
  doubleDice() {
2677
2669
  return this.scaleDice(2);
2678
2670
  }
2671
+ alwaysHits() {
2672
+ return new AlwaysHitBuilder(this);
2673
+ }
2679
2674
  copy() {
2680
2675
  return new this.constructor(this.getSubRollConfigs());
2681
2676
  }
@@ -2939,17 +2934,6 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
2939
2934
  }
2940
2935
  return `max${this.count}(?d?)`;
2941
2936
  }
2942
- findDieInAST(node) {
2943
- if (node.type === "die") return node;
2944
- if (node.child) return this.findDieInAST(node.child);
2945
- if (node.children) {
2946
- for (const child of node.children) {
2947
- const result = this.findDieInAST(child.node || child);
2948
- if (result) return result;
2949
- }
2950
- }
2951
- return null;
2952
- }
2953
2937
  toAST() {
2954
2938
  if (this.diceCount && this.diceSides) {
2955
2939
  const sumChild = {
@@ -2991,6 +2975,80 @@ var MaxOfRollBuilder = class _MaxOfRollBuilder extends RollBuilder {
2991
2975
  return new _MaxOfRollBuilder(this.innerRoll.copy(), this.count);
2992
2976
  }
2993
2977
  };
2978
+ var AlwaysHitBuilder = class _AlwaysHitBuilder extends RollBuilder {
2979
+ constructor(baseRoll, attackConfig) {
2980
+ super(baseRoll.getSubRollConfigs());
2981
+ __publicField(this, "attackConfig");
2982
+ if (attackConfig) {
2983
+ this.attackConfig = { ...attackConfig };
2984
+ } else {
2985
+ this.attackConfig = { critThreshold: 20 };
2986
+ }
2987
+ }
2988
+ onHit(...args) {
2989
+ const damageRoll = RollBuilder.fromArgs(...args);
2990
+ return new AttackBuilder(this, damageRoll);
2991
+ }
2992
+ get critThreshold() {
2993
+ return this.attackConfig.critThreshold;
2994
+ }
2995
+ // TODO - move this to AC Builder… or if we create a DC builder that has critOn, throw an error?
2996
+ critOn(critThreshold) {
2997
+ const newConfig = { critThreshold };
2998
+ return new _AlwaysHitBuilder(this, newConfig);
2999
+ }
3000
+ // Legacy expressions
3001
+ toExpression() {
3002
+ const configs = this.getSubRollConfigs();
3003
+ return new RollBuilder(configs).toExpression();
3004
+ }
3005
+ toPMF() {
3006
+ const rollType = this.rollType;
3007
+ const rerollOne = this.baseReroll > 0;
3008
+ return d20RollPMF(rollType, rerollOne);
3009
+ }
3010
+ copy() {
3011
+ const baseCopy = new RollBuilder(this.getSubRollConfigs());
3012
+ const critThreshold = this.critThreshold;
3013
+ const newConfig = { critThreshold };
3014
+ return new _AlwaysHitBuilder(baseCopy, newConfig);
3015
+ }
3016
+ };
3017
+ var AlwaysCritBuilder = class extends RollBuilder {
3018
+ constructor(baseRoll, attackConfig) {
3019
+ super(baseRoll.getSubRollConfigs());
3020
+ __publicField(this, "attackConfig");
3021
+ if (attackConfig) {
3022
+ this.attackConfig = { ...attackConfig };
3023
+ } else {
3024
+ this.attackConfig = { critThreshold: 20 };
3025
+ }
3026
+ }
3027
+ get critThreshold() {
3028
+ return this.attackConfig.critThreshold;
3029
+ }
3030
+ // TODO - move this to AC Builder… or if we create a DC builder that has critOn, throw an error?
3031
+ critOn(critThreshold) {
3032
+ const newConfig = { critThreshold };
3033
+ return new AlwaysHitBuilder(this, newConfig);
3034
+ }
3035
+ // Legacy expressions
3036
+ toExpression() {
3037
+ const configs = this.getSubRollConfigs();
3038
+ return new RollBuilder(configs).toExpression();
3039
+ }
3040
+ toPMF() {
3041
+ const rollType = this.rollType;
3042
+ const rerollOne = this.baseReroll > 0;
3043
+ return d20RollPMF(rollType, rerollOne);
3044
+ }
3045
+ copy() {
3046
+ const baseCopy = new RollBuilder(this.getSubRollConfigs());
3047
+ const critThreshold = this.critThreshold;
3048
+ const newConfig = { critThreshold };
3049
+ return new AlwaysHitBuilder(baseCopy, newConfig);
3050
+ }
3051
+ };
2994
3052
 
2995
3053
  // src/builder/factory.ts
2996
3054
  var rollFn = (count, sidesOrDie, modifier) => {
@@ -3543,11 +3601,25 @@ var AttackBuilder = class _AttackBuilder {
3543
3601
  return `${checkPart} * ${effectPart}`;
3544
3602
  }
3545
3603
  resolveProbabilities(check, eps = 0) {
3546
- const ac = check.attackConfig.ac;
3604
+ if (check instanceof AlwaysCritBuilder) {
3605
+ return { pSuccess: 1, pHit: 0, pCrit: 1, pMiss: 0 };
3606
+ }
3547
3607
  const rollType = check.rollType;
3548
3608
  const rerollOne = check.baseReroll > 0;
3549
3609
  const critThreshold = check.critThreshold;
3550
3610
  const d202 = d20RollPMF(rollType, rerollOne);
3611
+ if (check instanceof AlwaysHitBuilder) {
3612
+ let pCrit = 0;
3613
+ for (const [r, rec] of d202) {
3614
+ const pr = typeof rec === "number" ? rec : rec.p;
3615
+ if (pr <= 0) continue;
3616
+ if (r >= critThreshold) pCrit += pr;
3617
+ }
3618
+ const pHit = 1 - pCrit;
3619
+ const pMiss = 0;
3620
+ return { pSuccess: 1, pHit, pCrit, pMiss };
3621
+ }
3622
+ const ac = check.attackConfig.ac;
3551
3623
  const staticMod = this.check.modifier;
3552
3624
  const bonusDicePMFs = this.check.getBonusDicePMFs(this.check, eps);
3553
3625
  const bonusPMF = bonusDicePMFs.length ? PMF.convolveMany(bonusDicePMFs, eps) : PMF.delta(0, eps);
@@ -3833,6 +3905,8 @@ RollBuilder.prototype.dc = function(saveDC) {
3833
3905
  };
3834
3906
 
3835
3907
  exports.ACBuilder = ACBuilder;
3908
+ exports.AlwaysCritBuilder = AlwaysCritBuilder;
3909
+ exports.AlwaysHitBuilder = AlwaysHitBuilder;
3836
3910
  exports.DCBuilder = DCBuilder;
3837
3911
  exports.HalfRollBuilder = HalfRollBuilder;
3838
3912
  exports.MaxOfRollBuilder = MaxOfRollBuilder;