Move count reducer to artigen/utils/counter.ts, implement auto-confirm-crit flag
This commit is contained in:
		
							parent
							
								
									b169ee8632
								
							
						
					
					
						commit
						14e909c89f
					
				| 
						 | 
					@ -5,7 +5,7 @@ meta {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
get {
 | 
					get {
 | 
				
			||||||
  url: http://localhost:8166/api/roll?user=[discord-user-id]&channel=[discord-channel-id]&rollstr=[artificer-roll-cmd]&documentation=All items below are optional. Flags do not need values.&nd=[no-details-flag]&snd=[super-no-details-flag]&hr=[hide-raw-roll-details-flag]&s=[spoiler-results-flag]&m-or-max=[max-roll-flag, cannot be used with n flag]&min=[[min-roll-flag, cannot be used with n or max]&n=[nominal-roll-flag, cannot be used with max or min flag]&gms=[csv-of-discord-user-ids-to-be-dmed-results]&o=[order-rolls, must be a or d]&c=[count-flag]
 | 
					  url: http://localhost:8166/api/roll?user=[discord-user-id]&channel=[discord-channel-id]&rollstr=[artificer-roll-cmd]&documentation=All items below are optional. Flags do not need values.&nd=[no-details-flag]&snd=[super-no-details-flag]&hr=[hide-raw-roll-details-flag]&s=[spoiler-results-flag]&m-or-max=[max-roll-flag, cannot be used with n flag]&min=[[min-roll-flag, cannot be used with n or max]&n=[nominal-roll-flag, cannot be used with max or min flag]&gms=[csv-of-discord-user-ids-to-be-dmed-results]&o=[order-rolls, must be a or d]&c=[count-flag]&cc=[confirm-crit-flag]
 | 
				
			||||||
  body: none
 | 
					  body: none
 | 
				
			||||||
  auth: inherit
 | 
					  auth: inherit
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -25,4 +25,5 @@ params:query {
 | 
				
			||||||
  gms: [csv-of-discord-user-ids-to-be-dmed-results]
 | 
					  gms: [csv-of-discord-user-ids-to-be-dmed-results]
 | 
				
			||||||
  o: [order-rolls, must be a or d]
 | 
					  o: [order-rolls, must be a or d]
 | 
				
			||||||
  c: [count-flag]
 | 
					  c: [count-flag]
 | 
				
			||||||
 | 
					  cc: [confirm-crit-flag]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ import { loggingEnabled } from 'artigen/utils/logFlag.ts';
 | 
				
			||||||
import { assertPrePostBalance } from 'artigen/utils/parenBalance.ts';
 | 
					import { assertPrePostBalance } from 'artigen/utils/parenBalance.ts';
 | 
				
			||||||
import { compareTotalRolls, compareTotalRollsReverse } from 'artigen/utils/sortFuncs.ts';
 | 
					import { compareTotalRolls, compareTotalRollsReverse } from 'artigen/utils/sortFuncs.ts';
 | 
				
			||||||
import { translateError } from 'artigen/utils/translateError.ts';
 | 
					import { translateError } from 'artigen/utils/translateError.ts';
 | 
				
			||||||
 | 
					import { reduceCountDetails } from 'artigen/utils/counter.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// runCmd(rollRequest)
 | 
					// runCmd(rollRequest)
 | 
				
			||||||
// runCmd handles converting rollRequest into a computer readable format for processing, and finally executes the solving
 | 
					// runCmd handles converting rollRequest into a computer readable format for processing, and finally executes the solving
 | 
				
			||||||
| 
						 | 
					@ -115,24 +116,7 @@ export const runCmd = (rollRequest: QueuedRoll): SolvedRoll => {
 | 
				
			||||||
    returnMsg.line3 = line3;
 | 
					    returnMsg.line3 = line3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Reduce counts to a single object
 | 
					    // Reduce counts to a single object
 | 
				
			||||||
    returnMsg.counts = tempCountDetails.reduce(
 | 
					    returnMsg.counts = reduceCountDetails(tempCountDetails);
 | 
				
			||||||
      (acc, cnt) => ({
 | 
					 | 
				
			||||||
        total: acc.total + cnt.total,
 | 
					 | 
				
			||||||
        successful: acc.successful + cnt.successful,
 | 
					 | 
				
			||||||
        failed: acc.failed + cnt.failed,
 | 
					 | 
				
			||||||
        rerolled: acc.rerolled + cnt.rerolled,
 | 
					 | 
				
			||||||
        dropped: acc.dropped + cnt.dropped,
 | 
					 | 
				
			||||||
        exploded: acc.exploded + cnt.exploded,
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        total: 0,
 | 
					 | 
				
			||||||
        successful: 0,
 | 
					 | 
				
			||||||
        failed: 0,
 | 
					 | 
				
			||||||
        rerolled: 0,
 | 
					 | 
				
			||||||
        dropped: 0,
 | 
					 | 
				
			||||||
        exploded: 0,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  } catch (e) {
 | 
					  } catch (e) {
 | 
				
			||||||
    // Fill in the return block
 | 
					    // Fill in the return block
 | 
				
			||||||
    const solverError = e as Error;
 | 
					    const solverError = e as Error;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,7 @@ import { tokenizeMath } from 'artigen/math/mathTokenizer.ts';
 | 
				
			||||||
import { closeInternal, internalWrapRegex, openInternal } from 'artigen/utils/escape.ts';
 | 
					import { closeInternal, internalWrapRegex, openInternal } from 'artigen/utils/escape.ts';
 | 
				
			||||||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
 | 
					import { loggingEnabled } from 'artigen/utils/logFlag.ts';
 | 
				
			||||||
import { getMatchingInternalIdx, getMatchingPostfixIdx } from 'artigen/utils/parenBalance.ts';
 | 
					import { getMatchingInternalIdx, getMatchingPostfixIdx } from 'artigen/utils/parenBalance.ts';
 | 
				
			||||||
 | 
					import { reduceCountDetails } from 'artigen/utils/counter.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tokenizeCmd expects a string[] of items that are either config.prefix/config.postfix or some text that contains math and/or dice rolls
 | 
					// tokenizeCmd expects a string[] of items that are either config.prefix/config.postfix or some text that contains math and/or dice rolls
 | 
				
			||||||
export const tokenizeCmd = (cmd: string[], modifiers: RollModifiers, topLevel: boolean, previousResults: number[] = []): [ReturnData[], CountDetails[]] => {
 | 
					export const tokenizeCmd = (cmd: string[], modifiers: RollModifiers, topLevel: boolean, previousResults: number[] = []): [ReturnData[], CountDetails[]] => {
 | 
				
			||||||
| 
						 | 
					@ -28,15 +29,12 @@ export const tokenizeCmd = (cmd: string[], modifiers: RollModifiers, topLevel: b
 | 
				
			||||||
    const openIdx = cmd.indexOf(config.prefix);
 | 
					    const openIdx = cmd.indexOf(config.prefix);
 | 
				
			||||||
    const closeIdx = getMatchingPostfixIdx(cmd, openIdx);
 | 
					    const closeIdx = getMatchingPostfixIdx(cmd, openIdx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const currentCmd = cmd.slice(openIdx + 1, closeIdx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loggingEnabled && log(LT.LOG, `Setting previous results: topLevel:${topLevel} ${topLevel ? returnData.map((rd) => rd.rollTotal) : previousResults}`);
 | 
					    loggingEnabled && log(LT.LOG, `Setting previous results: topLevel:${topLevel} ${topLevel ? returnData.map((rd) => rd.rollTotal) : previousResults}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Handle any nested commands
 | 
					    // Handle any nested commands
 | 
				
			||||||
    const [tempData, tempCounts] = tokenizeCmd(
 | 
					    const [tempData, tempCounts] = tokenizeCmd(currentCmd, modifiers, false, topLevel ? returnData.map((rd) => rd.rollTotal) : previousResults);
 | 
				
			||||||
      cmd.slice(openIdx + 1, closeIdx),
 | 
					 | 
				
			||||||
      modifiers,
 | 
					 | 
				
			||||||
      false,
 | 
					 | 
				
			||||||
      topLevel ? returnData.map((rd) => rd.rollTotal) : previousResults,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    const data = tempData[0];
 | 
					    const data = tempData[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (topLevel) {
 | 
					    if (topLevel) {
 | 
				
			||||||
| 
						 | 
					@ -55,6 +53,24 @@ export const tokenizeCmd = (cmd: string[], modifiers: RollModifiers, topLevel: b
 | 
				
			||||||
    // Store results
 | 
					    // Store results
 | 
				
			||||||
    returnData.push(data);
 | 
					    returnData.push(data);
 | 
				
			||||||
    countDetails.push(...tempCounts);
 | 
					    countDetails.push(...tempCounts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (topLevel && modifiers.confirmCrit && reduceCountDetails(tempCounts).successful) {
 | 
				
			||||||
 | 
					      loggingEnabled && log(LT.LOG, `ConfirmCrit on ${JSON.stringify(currentCmd)}`);
 | 
				
			||||||
 | 
					      let done = false;
 | 
				
			||||||
 | 
					      while (!done) {
 | 
				
			||||||
 | 
					        const [ccTempData, ccTempCounts] = tokenizeCmd(currentCmd, modifiers, false, topLevel ? returnData.map((rd) => rd.rollTotal) : previousResults);
 | 
				
			||||||
 | 
					        const ccData = ccTempData[0];
 | 
				
			||||||
 | 
					        ccData.rollPreFormat = '\nAuto-Confirming Crit: ';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loggingEnabled && log(LT.LOG, `ConfirmCrit on ${JSON.stringify(currentCmd)} | Rolled again ${JSON.stringify(ccData)} ${JSON.stringify(ccTempCounts)}`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Store CC results
 | 
				
			||||||
 | 
					        returnData.push(ccData);
 | 
				
			||||||
 | 
					        countDetails.push(...ccTempCounts);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        done = reduceCountDetails(ccTempCounts).successful === 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (topLevel) {
 | 
					  if (topLevel) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ export interface RollModifiers {
 | 
				
			||||||
  order: string;
 | 
					  order: string;
 | 
				
			||||||
  count: boolean;
 | 
					  count: boolean;
 | 
				
			||||||
  commaTotals: boolean;
 | 
					  commaTotals: boolean;
 | 
				
			||||||
 | 
					  confirmCrit: boolean;
 | 
				
			||||||
  apiWarn: string;
 | 
					  apiWarn: string;
 | 
				
			||||||
  valid: boolean;
 | 
					  valid: boolean;
 | 
				
			||||||
  error: Error;
 | 
					  error: Error;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,7 @@ export const Modifiers = Object.freeze({
 | 
				
			||||||
  GM: '-gm',
 | 
					  GM: '-gm',
 | 
				
			||||||
  Order: '-o',
 | 
					  Order: '-o',
 | 
				
			||||||
  CommaTotals: '-ct',
 | 
					  CommaTotals: '-ct',
 | 
				
			||||||
 | 
					  ConfirmCrit: '-cc',
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
 | 
					export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
 | 
				
			||||||
| 
						 | 
					@ -31,6 +32,7 @@ export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
 | 
				
			||||||
    order: '',
 | 
					    order: '',
 | 
				
			||||||
    count: false,
 | 
					    count: false,
 | 
				
			||||||
    commaTotals: false,
 | 
					    commaTotals: false,
 | 
				
			||||||
 | 
					    confirmCrit: false,
 | 
				
			||||||
    apiWarn: '',
 | 
					    apiWarn: '',
 | 
				
			||||||
    valid: false,
 | 
					    valid: false,
 | 
				
			||||||
    error: new Error(),
 | 
					    error: new Error(),
 | 
				
			||||||
| 
						 | 
					@ -66,6 +68,9 @@ export const getModifiers = (args: string[]): [RollModifiers, string[]] => {
 | 
				
			||||||
      case Modifiers.Nominal:
 | 
					      case Modifiers.Nominal:
 | 
				
			||||||
        modifiers.nominalRoll = true;
 | 
					        modifiers.nominalRoll = true;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case Modifiers.ConfirmCrit:
 | 
				
			||||||
 | 
					        modifiers.confirmCrit = true;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
      case Modifiers.GM:
 | 
					      case Modifiers.GM:
 | 
				
			||||||
        modifiers.gmRoll = true;
 | 
					        modifiers.gmRoll = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,3 +21,24 @@ export const rollCounter = (rollSet: RollSet[]): CountDetails => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return countDetails;
 | 
					  return countDetails;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const reduceCountDetails = (counts: CountDetails[]): CountDetails => {
 | 
				
			||||||
 | 
					  return counts.reduce(
 | 
				
			||||||
 | 
					    (acc, cnt) => ({
 | 
				
			||||||
 | 
					      total: acc.total + cnt.total,
 | 
				
			||||||
 | 
					      successful: acc.successful + cnt.successful,
 | 
				
			||||||
 | 
					      failed: acc.failed + cnt.failed,
 | 
				
			||||||
 | 
					      rerolled: acc.rerolled + cnt.rerolled,
 | 
				
			||||||
 | 
					      dropped: acc.dropped + cnt.dropped,
 | 
				
			||||||
 | 
					      exploded: acc.exploded + cnt.exploded,
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      total: 0,
 | 
				
			||||||
 | 
					      successful: 0,
 | 
				
			||||||
 | 
					      failed: 0,
 | 
				
			||||||
 | 
					      rerolled: 0,
 | 
				
			||||||
 | 
					      dropped: 0,
 | 
				
			||||||
 | 
					      exploded: 0,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -94,6 +94,7 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Pr
 | 
				
			||||||
          order: query.has('o') ? query.get('o')?.toLowerCase() || '' : '',
 | 
					          order: query.has('o') ? query.get('o')?.toLowerCase() || '' : '',
 | 
				
			||||||
          count: query.has('c'),
 | 
					          count: query.has('c'),
 | 
				
			||||||
          commaTotals: query.has('ct'),
 | 
					          commaTotals: query.has('ct'),
 | 
				
			||||||
 | 
					          confirmCrit: query.has('cc'),
 | 
				
			||||||
          apiWarn: hideWarn ? '' : apiWarning,
 | 
					          apiWarn: hideWarn ? '' : apiWarning,
 | 
				
			||||||
          valid: true,
 | 
					          valid: true,
 | 
				
			||||||
          error: new Error(),
 | 
					          error: new Error(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue