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