further improve roll safety, no doubling up on drop/keep
This commit is contained in:
		
							parent
							
								
									e69806c443
								
							
						
					
					
						commit
						2f2a8f67e0
					
				| 
						 | 
					@ -286,6 +286,9 @@ export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll
 | 
				
			||||||
      case 'YouNeedAD':
 | 
					      case 'YouNeedAD':
 | 
				
			||||||
        errorMsg = 'Formatting Error: Missing die size and count config';
 | 
					        errorMsg = 'Formatting Error: Missing die size and count config';
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'DoubleSeparator':
 | 
				
			||||||
 | 
					        errorMsg = `Formatting Error: \`${errorDetails}\` should only be specified once per roll, remove all but one and repeat roll`;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      case 'FormattingError':
 | 
					      case 'FormattingError':
 | 
				
			||||||
        errorMsg = 'Formatting Error: Cannot use Keep and Drop at the same time, remove all but one and repeat roll';
 | 
					        errorMsg = 'Formatting Error: Cannot use Keep and Drop at the same time, remove all but one and repeat roll';
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
| 
						 | 
					@ -307,22 +310,25 @@ export const parseRoll = (fullCmd: string, modifiers: RollModifiers): SolvedRoll
 | 
				
			||||||
            errorMsg += 'Die Size and Die Count';
 | 
					            errorMsg += 'Die Size and Die Count';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'drop':
 | 
					          case 'drop':
 | 
				
			||||||
            errorMsg += 'Drop (d or dl)';
 | 
					            errorMsg += 'Drop (`d` or `dl`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'keep':
 | 
					          case 'keep':
 | 
				
			||||||
            errorMsg += 'Keep (k or kh)';
 | 
					            errorMsg += 'Keep (`k` or `kh`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'dropHigh':
 | 
					          case 'dropHigh':
 | 
				
			||||||
            errorMsg += 'Drop Highest (dh)';
 | 
					            errorMsg += 'Drop Highest (`dh`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'keepLow':
 | 
					          case 'keepLow':
 | 
				
			||||||
            errorMsg += 'Keep Lowest (kl)';
 | 
					            errorMsg += 'Keep Lowest (`kl`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'reroll':
 | 
					          case 'reroll':
 | 
				
			||||||
            errorMsg += 'Reroll (r)';
 | 
					            errorMsg += 'Reroll (`r`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          case 'critScore':
 | 
					          case 'critScore':
 | 
				
			||||||
            errorMsg += 'Crit Score (cs)';
 | 
					            errorMsg += 'Crit Score (`cs`)';
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'critFail':
 | 
				
			||||||
 | 
					            errorMsg += 'Crit Fail (`cf`)';
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
          default:
 | 
					          default:
 | 
				
			||||||
            errorMsg += `Unhandled - ${errorDetails}`;
 | 
					            errorMsg += `Unhandled - ${errorDetails}`;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,10 @@ const loopCountCheck = (loopCount: number): void => {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const throwDoubleSepError = (sep: string): void => {
 | 
				
			||||||
 | 
					  throw new Error(`DoubleSeparator_${sep}`);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// roll(rollStr, maximizeRoll, nominalRoll) returns RollSet
 | 
					// roll(rollStr, maximizeRoll, nominalRoll) returns RollSet
 | 
				
			||||||
// roll parses and executes the rollStr, if needed it will also make the roll the maximum or average
 | 
					// roll parses and executes the rollStr, if needed it will also make the roll the maximum or average
 | 
				
			||||||
export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolean): RollSet[] => {
 | 
					export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolean): RollSet[] => {
 | 
				
			||||||
| 
						 | 
					@ -193,22 +197,38 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
 | 
				
			||||||
      switch (tSep) {
 | 
					      switch (tSep) {
 | 
				
			||||||
        case 'dl':
 | 
					        case 'dl':
 | 
				
			||||||
        case 'd':
 | 
					        case 'd':
 | 
				
			||||||
 | 
					          if (rollConf.drop.on) {
 | 
				
			||||||
 | 
					            // Ensure we do not override existing settings
 | 
				
			||||||
 | 
					            throwDoubleSepError(tSep);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          // Configure Drop (Lowest)
 | 
					          // Configure Drop (Lowest)
 | 
				
			||||||
          rollConf.drop.on = true;
 | 
					          rollConf.drop.on = true;
 | 
				
			||||||
          rollConf.drop.count = tNum;
 | 
					          rollConf.drop.count = tNum;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 'kh':
 | 
					        case 'kh':
 | 
				
			||||||
        case 'k':
 | 
					        case 'k':
 | 
				
			||||||
 | 
					          if (rollConf.keep.on) {
 | 
				
			||||||
 | 
					            // Ensure we do not override existing settings
 | 
				
			||||||
 | 
					            throwDoubleSepError(tSep);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          // Configure Keep (Highest)
 | 
					          // Configure Keep (Highest)
 | 
				
			||||||
          rollConf.keep.on = true;
 | 
					          rollConf.keep.on = true;
 | 
				
			||||||
          rollConf.keep.count = tNum;
 | 
					          rollConf.keep.count = tNum;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 'dh':
 | 
					        case 'dh':
 | 
				
			||||||
 | 
					          if (rollConf.dropHigh.on) {
 | 
				
			||||||
 | 
					            // Ensure we do not override existing settings
 | 
				
			||||||
 | 
					            throwDoubleSepError(tSep);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          // Configure Drop (Highest)
 | 
					          // Configure Drop (Highest)
 | 
				
			||||||
          rollConf.dropHigh.on = true;
 | 
					          rollConf.dropHigh.on = true;
 | 
				
			||||||
          rollConf.dropHigh.count = tNum;
 | 
					          rollConf.dropHigh.count = tNum;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 'kl':
 | 
					        case 'kl':
 | 
				
			||||||
 | 
					          if (rollConf.keepLow.on) {
 | 
				
			||||||
 | 
					            // Ensure we do not override existing settings
 | 
				
			||||||
 | 
					            throwDoubleSepError(tSep);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          // Configure Keep (Lowest)
 | 
					          // Configure Keep (Lowest)
 | 
				
			||||||
          rollConf.keepLow.on = true;
 | 
					          rollConf.keepLow.on = true;
 | 
				
			||||||
          rollConf.keepLow.count = tNum;
 | 
					          rollConf.keepLow.count = tNum;
 | 
				
			||||||
| 
						 | 
					@ -381,13 +401,6 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Filter rollConf num lists to only include valid numbers
 | 
					 | 
				
			||||||
  const validNumFilter = (curNum: number) => curNum <= rollConf.dieSize && curNum > 0;
 | 
					 | 
				
			||||||
  rollConf.reroll.nums = rollConf.reroll.nums.filter(validNumFilter);
 | 
					 | 
				
			||||||
  rollConf.critScore.range = rollConf.critScore.range.filter(validNumFilter);
 | 
					 | 
				
			||||||
  rollConf.critFail.range = rollConf.critFail.range.filter(validNumFilter);
 | 
					 | 
				
			||||||
  rollConf.exploding.nums = rollConf.exploding.nums.filter(validNumFilter);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Verify the parse, throwing errors for every invalid config
 | 
					  // Verify the parse, throwing errors for every invalid config
 | 
				
			||||||
  if (rollConf.dieCount < 0) {
 | 
					  if (rollConf.dieCount < 0) {
 | 
				
			||||||
    throw new Error('NoZerosAllowed_base');
 | 
					    throw new Error('NoZerosAllowed_base');
 | 
				
			||||||
| 
						 | 
					@ -395,6 +408,7 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
 | 
				
			||||||
  if (rollConf.dieCount === 0 || rollConf.dieSize === 0) {
 | 
					  if (rollConf.dieCount === 0 || rollConf.dieSize === 0) {
 | 
				
			||||||
    throw new Error('NoZerosAllowed_base');
 | 
					    throw new Error('NoZerosAllowed_base');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Since only one drop or keep option can be active, count how many are active to throw the right error
 | 
					  // Since only one drop or keep option can be active, count how many are active to throw the right error
 | 
				
			||||||
  let dkdkCnt = 0;
 | 
					  let dkdkCnt = 0;
 | 
				
			||||||
  [rollConf.drop.on, rollConf.keep.on, rollConf.dropHigh.on, rollConf.keepLow.on].forEach((e) => {
 | 
					  [rollConf.drop.on, rollConf.keep.on, rollConf.dropHigh.on, rollConf.keepLow.on].forEach((e) => {
 | 
				
			||||||
| 
						 | 
					@ -406,6 +420,7 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
 | 
				
			||||||
  if (dkdkCnt > 1) {
 | 
					  if (dkdkCnt > 1) {
 | 
				
			||||||
    throw new Error('FormattingError_dk');
 | 
					    throw new Error('FormattingError_dk');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rollConf.drop.on && rollConf.drop.count === 0) {
 | 
					  if (rollConf.drop.on && rollConf.drop.count === 0) {
 | 
				
			||||||
    throw new Error('NoZerosAllowed_drop');
 | 
					    throw new Error('NoZerosAllowed_drop');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -421,6 +436,14 @@ export const roll = (rollStr: string, maximizeRoll: boolean, nominalRoll: boolea
 | 
				
			||||||
  if (rollConf.reroll.on && rollConf.reroll.nums.includes(0)) {
 | 
					  if (rollConf.reroll.on && rollConf.reroll.nums.includes(0)) {
 | 
				
			||||||
    throw new Error('NoZerosAllowed_reroll');
 | 
					    throw new Error('NoZerosAllowed_reroll');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Filter rollConf num lists to only include valid numbers
 | 
				
			||||||
 | 
					  const validNumFilter = (curNum: number) => curNum <= rollConf.dieSize && curNum > 0;
 | 
				
			||||||
 | 
					  rollConf.reroll.nums = rollConf.reroll.nums.filter(validNumFilter);
 | 
				
			||||||
 | 
					  rollConf.critScore.range = rollConf.critScore.range.filter(validNumFilter);
 | 
				
			||||||
 | 
					  rollConf.critFail.range = rollConf.critFail.range.filter(validNumFilter);
 | 
				
			||||||
 | 
					  rollConf.exploding.nums = rollConf.exploding.nums.filter(validNumFilter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (rollConf.reroll.on && rollConf.reroll.nums.length === rollConf.dieSize) {
 | 
					  if (rollConf.reroll.on && rollConf.reroll.nums.length === rollConf.dieSize) {
 | 
				
			||||||
    throw new Error('NoRerollOnAllSides');
 | 
					    throw new Error('NoRerollOnAllSides');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue