@yipe/dice 0.2.3 → 0.2.5

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.
@@ -198,7 +198,6 @@ declare class ACBuilder extends RollBuilder {
198
198
  onHit(count: number, sides: number): AttackBuilder;
199
199
  onHit(count: number, die: RollBuilder, modifier: number): AttackBuilder;
200
200
  onHit(count: number, sides: number, modifier: number): AttackBuilder;
201
- dc(_: number): never;
202
201
  get critThreshold(): number;
203
202
  critOn(threshold: number): ACBuilder;
204
203
  toExpression(): string;
@@ -198,7 +198,6 @@ declare class ACBuilder extends RollBuilder {
198
198
  onHit(count: number, sides: number): AttackBuilder;
199
199
  onHit(count: number, die: RollBuilder, modifier: number): AttackBuilder;
200
200
  onHit(count: number, sides: number, modifier: number): AttackBuilder;
201
- dc(_: number): never;
202
201
  get critThreshold(): number;
203
202
  critOn(threshold: number): ACBuilder;
204
203
  toExpression(): string;
@@ -2566,6 +2566,7 @@ var RollBuilder = class _RollBuilder {
2566
2566
  /** Apply one-pass reroll threshold (k): reroll faces 1..k once, must keep. */
2567
2567
  reroll(value) {
2568
2568
  if (isNaN(value)) throw new Error("Invalid NaN value for reroll");
2569
+ if (value === this.lastConfig.reroll) return this;
2569
2570
  const newConfigs = this.getSubRollConfigs();
2570
2571
  newConfigs[newConfigs.length - 1].reroll = value;
2571
2572
  return new this.constructor(newConfigs);
@@ -2662,19 +2663,63 @@ var RollBuilder = class _RollBuilder {
2662
2663
  return new this.constructor(newConfigs);
2663
2664
  }
2664
2665
  toExpression() {
2665
- const diceConfigs = this.subRollConfigs.filter(
2666
+ const originalDiceConfigs = this.subRollConfigs.filter(
2666
2667
  (config) => config.sides && config.sides > 0
2667
2668
  );
2669
+ const configGroups = /* @__PURE__ */ new Map();
2670
+ for (const config of originalDiceConfigs) {
2671
+ const keyConfig = { ...config };
2672
+ delete keyConfig.count;
2673
+ delete keyConfig.modifier;
2674
+ const key = JSON.stringify(keyConfig);
2675
+ const existingGroup = configGroups.get(key);
2676
+ if (existingGroup) {
2677
+ existingGroup.totalCount += config.count;
2678
+ } else {
2679
+ configGroups.set(key, { config, totalCount: config.count });
2680
+ }
2681
+ }
2682
+ const rootConfig = this.getRootDieConfig();
2683
+ const groupedConfigs = Array.from(configGroups.values());
2684
+ let rootD20Group;
2685
+ if (rootConfig && rootConfig.sides === 20) {
2686
+ const rootIndex = groupedConfigs.findIndex(
2687
+ ({ config }) => config.sides === rootConfig.sides && config.rollType === rootConfig.rollType && config.reroll === rootConfig.reroll && config.explode === rootConfig.explode && config.minimum === rootConfig.minimum && config.bestOf === rootConfig.bestOf && JSON.stringify(config.keep) === JSON.stringify(rootConfig.keep)
2688
+ );
2689
+ if (rootIndex !== -1) {
2690
+ rootD20Group = groupedConfigs.splice(rootIndex, 1)[0];
2691
+ }
2692
+ }
2693
+ const sortedDiceConfigs = groupedConfigs.map(({ config, totalCount }) => ({
2694
+ ...config,
2695
+ count: totalCount
2696
+ })).sort((a, b) => {
2697
+ const aHasPriority = a.reroll > 0 || a.minimum > 0;
2698
+ const bHasPriority = b.reroll > 0 || b.minimum > 0;
2699
+ if (aHasPriority !== bHasPriority) {
2700
+ return aHasPriority ? -1 : 1;
2701
+ }
2702
+ if (b.sides !== a.sides) return b.sides - a.sides;
2703
+ const complexity = (c) => (c.reroll > 0 ? 1 : 0) + (c.minimum > 0 ? 1 : 0) + (c.explode > 0 ? 1 : 0) + (c.bestOf > 0 ? 1 : 0) + (c.keep ? 1 : 0);
2704
+ return complexity(b) - complexity(a);
2705
+ });
2706
+ const diceConfigs = rootD20Group ? [
2707
+ { ...rootD20Group.config, count: rootD20Group.totalCount },
2708
+ ...sortedDiceConfigs
2709
+ ] : sortedDiceConfigs;
2668
2710
  const totalModifier = this.subRollConfigs.reduce(
2669
2711
  (sum, config) => sum + config.modifier,
2670
2712
  0
2671
2713
  );
2672
2714
  if (diceConfigs.length === 0) return totalModifier.toString();
2673
- const rootConfig = this.getRootDieConfig();
2715
+ const rootDieConfig = this.getRootDieConfig();
2716
+ const newRootConfig = rootDieConfig ? diceConfigs.find(
2717
+ (c) => c.sides === rootDieConfig.sides && c.rollType === rootDieConfig.rollType && c.reroll === rootDieConfig.reroll && c.explode === rootDieConfig.explode && c.minimum === rootDieConfig.minimum && c.bestOf === rootDieConfig.bestOf && c.keep === rootDieConfig.keep
2718
+ ) : void 0;
2674
2719
  const diceExpressions = diceConfigs.map(
2675
2720
  (config) => this.configToSingleExpressionWithoutModifier(
2676
2721
  config,
2677
- config === rootConfig
2722
+ config === newRootConfig
2678
2723
  )
2679
2724
  );
2680
2725
  let result = "";
@@ -3275,11 +3320,6 @@ var ACBuilder = class _ACBuilder extends RollBuilder {
3275
3320
  const damageRoll = RollBuilder.fromArgs(...args);
3276
3321
  return new AttackBuilder(this, damageRoll);
3277
3322
  }
3278
- dc(_) {
3279
- throw new Error(
3280
- "Cannot use dc() on an AttackRollBuilder. Use ac() for attack rolls instead."
3281
- );
3282
- }
3283
3323
  get critThreshold() {
3284
3324
  return this.attackConfig.critThreshold;
3285
3325
  }