FULLY SUPPORT GROUPS FOIASHFOIASHFOIASFDH :D
This commit is contained in:
		
							parent
							
								
									ad0aef6c94
								
							
						
					
					
						commit
						d989e9d473
					
				| 
						 | 
				
			
			@ -6,6 +6,7 @@ type RollType = '' | 'roll20' | 'fate' | 'cwod' | 'ova';
 | 
			
		|||
// RollSet is used to preserve all information about a calculated roll
 | 
			
		||||
export interface RollSet {
 | 
			
		||||
  type: RollType;
 | 
			
		||||
  rollGrpIdx?: number;
 | 
			
		||||
  origIdx: number;
 | 
			
		||||
  roll: number;
 | 
			
		||||
  size: number;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
import { log, LogTypes as LT } from '@Log4Deno';
 | 
			
		||||
 | 
			
		||||
import { FormattedRoll, RollModifiers } from 'artigen/dice/dice.d.ts';
 | 
			
		||||
import { executeRoll } from 'artigen/dice/executeRoll.ts';
 | 
			
		||||
import { ExecutedRoll, FormattedRoll, RollModifiers } from 'artigen/dice/dice.d.ts';
 | 
			
		||||
 | 
			
		||||
import { loopCountCheck } from 'artigen/managers/loopManager.ts';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -9,23 +8,21 @@ import { rollCounter } from 'artigen/utils/counter.ts';
 | 
			
		|||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
 | 
			
		||||
import { createRollDistMap } from 'artigen/utils/rollDist.ts';
 | 
			
		||||
 | 
			
		||||
// generateFormattedRoll(rollConf, modifiers) returns one SolvedStep
 | 
			
		||||
// generateFormattedRoll(executedRoll, modifiers) returns one SolvedStep
 | 
			
		||||
// generateFormattedRoll handles creating and formatting the completed rolls into the SolvedStep format
 | 
			
		||||
export const generateFormattedRoll = (rollConf: string, modifiers: RollModifiers): FormattedRoll => {
 | 
			
		||||
export const formatRoll = (executedRoll: ExecutedRoll, modifiers: RollModifiers): FormattedRoll => {
 | 
			
		||||
  let tempTotal = 0;
 | 
			
		||||
  let tempDetails = '[';
 | 
			
		||||
  let tempCrit = false;
 | 
			
		||||
  let tempFail = false;
 | 
			
		||||
  let tempComplex = false;
 | 
			
		||||
 | 
			
		||||
  // Generate the roll, passing flags thru
 | 
			
		||||
  const executedRoll = executeRoll(rollConf, modifiers);
 | 
			
		||||
 | 
			
		||||
  // Loop thru all parts of the roll to document everything that was done to create the total roll
 | 
			
		||||
  loggingEnabled && log(LT.LOG, `Formatting roll ${JSON.stringify(executedRoll)}`);
 | 
			
		||||
  executedRoll.rollSet.forEach((e) => {
 | 
			
		||||
    loopCountCheck();
 | 
			
		||||
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `Formatting roll ${rollConf} | ${JSON.stringify(e)}`);
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `At ${JSON.stringify(e)}`);
 | 
			
		||||
    let preFormat = '';
 | 
			
		||||
    let postFormat = '';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,25 +208,22 @@ export const handleGroup = (
 | 
			
		|||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `In single-mode ${JSON.stringify(commaParts)} ${groupModifiers} ${JSON.stringify(groupConf)}`);
 | 
			
		||||
    if (groupModifiers.trim()) {
 | 
			
		||||
      // Handle special case where the group modifiers are applied across the dice rolled
 | 
			
		||||
      // ex from roll20 docs: {4d6+3d8}k4 - Roll 4 d6's and 3 d8's, out of those 7 dice the highest 4 are kept and summed up.
 | 
			
		||||
      // TODO AAAAAAAAAAAAAAAAA
 | 
			
		||||
      retData = <ReturnData> {};
 | 
			
		||||
    } else {
 | 
			
		||||
      // why did you put this in a group, that was entirely pointless
 | 
			
		||||
      loggingEnabled && log(LT.LOG, `Solving commaPart: ${commaParts[0]}`);
 | 
			
		||||
      const [tempData, tempCounts, tempDists] = tokenizeMath(commaParts[0], modifiers, previousResults, prevGrpReturnData);
 | 
			
		||||
      const data = tempData[0];
 | 
			
		||||
    const [tempData, tempCounts, tempDists] = tokenizeMath(
 | 
			
		||||
      commaParts[0],
 | 
			
		||||
      modifiers,
 | 
			
		||||
      previousResults,
 | 
			
		||||
      prevGrpReturnData,
 | 
			
		||||
      groupModifiers.trim() ? groupConf : null,
 | 
			
		||||
    );
 | 
			
		||||
    const data = tempData[0];
 | 
			
		||||
 | 
			
		||||
      loggingEnabled && log(LT.LOG, `Solved Math for Group is back ${JSON.stringify(data)} | ${JSON.stringify(tempCounts)} ${JSON.stringify(tempDists)}`);
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `Solved Math for Group is back ${JSON.stringify(data)} | ${JSON.stringify(tempCounts)} ${JSON.stringify(tempDists)}`);
 | 
			
		||||
 | 
			
		||||
      countDetails.push(...tempCounts);
 | 
			
		||||
      rollDists.push(...tempDists);
 | 
			
		||||
      data.initConfig = `{${data.initConfig}}`;
 | 
			
		||||
      data.rollDetails = `{${data.rollDetails}}`;
 | 
			
		||||
      retData = data;
 | 
			
		||||
    }
 | 
			
		||||
    countDetails.push(...tempCounts);
 | 
			
		||||
    rollDists.push(...tempDists);
 | 
			
		||||
    data.initConfig = `{${data.initConfig}}${groupModifiers.trim() ? groupModifiers.replaceAll(' ', '') : ''}`;
 | 
			
		||||
    data.rollDetails = `{${data.rollDetails}}`;
 | 
			
		||||
    retData = data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Handle merging back any nested groups to prevent an internalGrp marker from sneaking out
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,8 +4,8 @@ import { ReturnData } from 'artigen/artigen.d.ts';
 | 
			
		|||
 | 
			
		||||
import { MathConf, SolvedStep } from 'artigen/math/math.d.ts';
 | 
			
		||||
 | 
			
		||||
import { CountDetails, RollDistributionMap, RollModifiers } from 'artigen/dice/dice.d.ts';
 | 
			
		||||
import { generateFormattedRoll } from 'artigen/dice/generateFormattedRoll.ts';
 | 
			
		||||
import { CountDetails, ExecutedRoll, GroupConf, RollDistributionMap, RollModifiers, RollSet } from 'artigen/dice/dice.d.ts';
 | 
			
		||||
import { formatRoll } from 'artigen/dice/generateFormattedRoll.ts';
 | 
			
		||||
 | 
			
		||||
import { loopCountCheck } from 'artigen/managers/loopManager.ts';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +15,8 @@ import { closeInternalGrp, cmdSplitRegex, internalWrapRegex, mathSplitRegex, ope
 | 
			
		|||
import { legalMathOperators } from 'artigen/utils/legalMath.ts';
 | 
			
		||||
import { loggingEnabled } from 'artigen/utils/logFlag.ts';
 | 
			
		||||
import { assertParenBalance } from 'artigen/utils/parenBalance.ts';
 | 
			
		||||
import { executeRoll } from 'artigen/dice/executeRoll.ts';
 | 
			
		||||
import { compareOrigIdx, compareRolls } from 'artigen/utils/sortFuncs.ts';
 | 
			
		||||
 | 
			
		||||
// minusOps are operators that will cause a negative sign to collapse into a number (in cases like + - 1)
 | 
			
		||||
const minusOps = ['(', '^', '**', '*', '/', '%', '+', '-'];
 | 
			
		||||
| 
						 | 
				
			
			@ -25,9 +27,11 @@ export const tokenizeMath = (
 | 
			
		|||
  modifiers: RollModifiers,
 | 
			
		||||
  previousResults: number[],
 | 
			
		||||
  groupResults: ReturnData[],
 | 
			
		||||
  groupConf: GroupConf | null = null,
 | 
			
		||||
): [ReturnData[], CountDetails[], RollDistributionMap[]] => {
 | 
			
		||||
  const countDetails: CountDetails[] = [];
 | 
			
		||||
  const rollDists: RollDistributionMap[] = [];
 | 
			
		||||
  const executedRolls: Map<number, ExecutedRoll> = new Map();
 | 
			
		||||
 | 
			
		||||
  loggingEnabled && log(LT.LOG, `Parsing roll ${cmd} | ${JSON.stringify(modifiers)} | ${JSON.stringify(previousResults)}`);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,10 +181,15 @@ export const tokenizeMath = (
 | 
			
		|||
      }
 | 
			
		||||
    } else if (![...allOps, ...legalMathOperators].includes(curMathConfStr)) {
 | 
			
		||||
      // If nothing else has handled it by now, try it as a roll
 | 
			
		||||
      const formattedRoll = generateFormattedRoll(curMathConfStr, modifiers);
 | 
			
		||||
      mathConf[i] = formattedRoll.solvedStep;
 | 
			
		||||
      countDetails.push(formattedRoll.countDetails);
 | 
			
		||||
      rollDists.push(formattedRoll.rollDistributions);
 | 
			
		||||
      const executedRoll = executeRoll(curMathConfStr, modifiers);
 | 
			
		||||
      if (groupConf) {
 | 
			
		||||
        executedRolls.set(i, executedRoll);
 | 
			
		||||
      } else {
 | 
			
		||||
        const formattedRoll = formatRoll(executedRoll, modifiers);
 | 
			
		||||
        mathConf[i] = formattedRoll.solvedStep;
 | 
			
		||||
        countDetails.push(formattedRoll.countDetails);
 | 
			
		||||
        rollDists.push(formattedRoll.rollDistributions);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Identify if we are in a state where the current number is a negative number
 | 
			
		||||
| 
						 | 
				
			
			@ -203,6 +212,103 @@ export const tokenizeMath = (
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Handle applying the group config
 | 
			
		||||
  if (groupConf) {
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `Applying groupConf to executedRolls | ${JSON.stringify(groupConf)} ${JSON.stringify(executedRolls.entries().toArray())}`);
 | 
			
		||||
    // Merge all rollSets into one array, adding the idx into each rollSet to allow separating them back out
 | 
			
		||||
    const allRollSets: RollSet[] = [];
 | 
			
		||||
    const executedRollArr = executedRolls.entries().toArray();
 | 
			
		||||
    executedRollArr.forEach(([rollGroupIdx, executedRoll]) => {
 | 
			
		||||
      executedRoll.rollSet.forEach((roll) => (roll.rollGrpIdx = rollGroupIdx));
 | 
			
		||||
      allRollSets.push(...executedRoll.rollSet);
 | 
			
		||||
    });
 | 
			
		||||
    loggingEnabled && log(LT.LOG, `raw rollSets: ${JSON.stringify(allRollSets)}`);
 | 
			
		||||
 | 
			
		||||
    // Handle drop or keep operations
 | 
			
		||||
    if (groupConf.drop.on || groupConf.keep.on || groupConf.dropHigh.on || groupConf.keepLow.on) {
 | 
			
		||||
      allRollSets.sort(compareRolls);
 | 
			
		||||
      let dropCount = 0;
 | 
			
		||||
 | 
			
		||||
      // For normal drop and keep, simple subtraction is enough to determine how many to drop
 | 
			
		||||
      // Protections are in to prevent the dropCount from going below 0 or more than the valid rolls to drop
 | 
			
		||||
      if (groupConf.drop.on) {
 | 
			
		||||
        dropCount = groupConf.drop.count;
 | 
			
		||||
        if (dropCount > allRollSets.length) {
 | 
			
		||||
          dropCount = allRollSets.length;
 | 
			
		||||
        }
 | 
			
		||||
      } else if (groupConf.keep.on) {
 | 
			
		||||
        dropCount = allRollSets.length - groupConf.keep.count;
 | 
			
		||||
        if (dropCount < 0) {
 | 
			
		||||
          dropCount = 0;
 | 
			
		||||
        }
 | 
			
		||||
      } // For inverted drop and keep, order must be flipped to greatest to least before the simple subtraction can determine how many to drop
 | 
			
		||||
      // Protections are in to prevent the dropCount from going below 0 or more than the valid rolls to drop
 | 
			
		||||
      else if (groupConf.dropHigh.on) {
 | 
			
		||||
        allRollSets.reverse();
 | 
			
		||||
        dropCount = groupConf.dropHigh.count;
 | 
			
		||||
        if (dropCount > allRollSets.length) {
 | 
			
		||||
          dropCount = allRollSets.length;
 | 
			
		||||
        }
 | 
			
		||||
      } else if (groupConf.keepLow.on) {
 | 
			
		||||
        allRollSets.reverse();
 | 
			
		||||
        dropCount = allRollSets.length - groupConf.keepLow.count;
 | 
			
		||||
        if (dropCount < 0) {
 | 
			
		||||
          dropCount = 0;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let i = 0;
 | 
			
		||||
      while (dropCount > 0 && i < allRollSets.length) {
 | 
			
		||||
        loopCountCheck();
 | 
			
		||||
 | 
			
		||||
        loggingEnabled && log(LT.LOG, `Handling group dropping | Dropping ${dropCount}, looking at ${JSON.stringify(allRollSets[i])}`);
 | 
			
		||||
 | 
			
		||||
        if (!allRollSets[i].dropped && !allRollSets[i].rerolled) {
 | 
			
		||||
          allRollSets[i].dropped = true;
 | 
			
		||||
          allRollSets[i].success = false;
 | 
			
		||||
          allRollSets[i].fail = false;
 | 
			
		||||
          allRollSets[i].matchLabel = '';
 | 
			
		||||
          dropCount--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        i++;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      allRollSets.sort(compareOrigIdx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle marking new successes/fails
 | 
			
		||||
    if (groupConf.success.on || groupConf.fail.on) {
 | 
			
		||||
      allRollSets.forEach((rs) => {
 | 
			
		||||
        loopCountCheck();
 | 
			
		||||
 | 
			
		||||
        if (!rs.dropped && !rs.rerolled) {
 | 
			
		||||
          if (groupConf.success.on && groupConf.success.range.includes(rs.roll)) {
 | 
			
		||||
            rs.success = true;
 | 
			
		||||
            rs.matchLabel = 'S';
 | 
			
		||||
          }
 | 
			
		||||
          if (groupConf.fail.on && groupConf.fail.range.includes(rs.roll)) {
 | 
			
		||||
            rs.fail = true;
 | 
			
		||||
            rs.matchLabel = 'F';
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handle separating the rollSets back out, recalculating the success/fail count, assigning them to the correct mathConf slots
 | 
			
		||||
    executedRollArr.forEach(([rollGroupIdx, executedRoll]) => {
 | 
			
		||||
      // Update flags on executedRoll
 | 
			
		||||
      executedRoll.countSuccessOverride = executedRoll.countSuccessOverride || groupConf.success.on;
 | 
			
		||||
      executedRoll.countFailOverride = executedRoll.countFailOverride || groupConf.fail.on;
 | 
			
		||||
      executedRoll.rollSet = allRollSets.filter((rs) => rs.rollGrpIdx === rollGroupIdx);
 | 
			
		||||
 | 
			
		||||
      const formattedRoll = formatRoll(executedRoll, modifiers);
 | 
			
		||||
      mathConf[rollGroupIdx] = formattedRoll.solvedStep;
 | 
			
		||||
      countDetails.push(formattedRoll.countDetails);
 | 
			
		||||
      rollDists.push(formattedRoll.rollDistributions);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Now that mathConf is parsed, send it into the solver
 | 
			
		||||
  const tempSolved = mathSolver(mathConf);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue