diff --git a/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-chromium-linux.txt b/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-chromium-linux.txt index a06ac6f4..dfc260d0 100644 --- a/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-chromium-linux.txt +++ b/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-chromium-linux.txt @@ -1 +1 @@ -4 star gear:Physical Resistance: 0 rollsAttack: 2 rolls, strength: 88%Physical Attack: 2 rolls, strength: 50%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 2 rolls, strength: 88%Physical Attack: 3 rolls, strength: 11%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 3 rolls, strength: 36%Physical Attack: 2 rolls, strength: 50%Volt Attack: 0 rolls \ No newline at end of file +4 star gear:Physical Resistance: 0 rollsAttack: 2 rollsAverage strength of each roll: 88%. Total weighting: 185%Physical Attack: 2 rollsAverage strength of each roll: 50%. Total weighting: 140%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 2 rollsAverage strength of each roll: 88%. Total weighting: 185%Physical Attack: 3 rollsAverage strength of each roll: 11%. Total weighting: 140%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 3 rollsAverage strength of each roll: 36%. Total weighting: 185%Physical Attack: 2 rollsAverage strength of each roll: 50%. Total weighting: 140%Volt Attack: 0 rolls \ No newline at end of file diff --git a/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-firefox-linux.txt b/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-firefox-linux.txt index a06ac6f4..dfc260d0 100644 --- a/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-firefox-linux.txt +++ b/e2e-tests/gear-comparer.spec.ts-snapshots/import-gear-ocr-fills-in-correct-gear-1-firefox-linux.txt @@ -1 +1 @@ -4 star gear:Physical Resistance: 0 rollsAttack: 2 rolls, strength: 88%Physical Attack: 2 rolls, strength: 50%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 2 rolls, strength: 88%Physical Attack: 3 rolls, strength: 11%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 3 rolls, strength: 36%Physical Attack: 2 rolls, strength: 50%Volt Attack: 0 rolls \ No newline at end of file +4 star gear:Physical Resistance: 0 rollsAttack: 2 rollsAverage strength of each roll: 88%. Total weighting: 185%Physical Attack: 2 rollsAverage strength of each roll: 50%. Total weighting: 140%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 2 rollsAverage strength of each roll: 88%. Total weighting: 185%Physical Attack: 3 rollsAverage strength of each roll: 11%. Total weighting: 140%Volt Attack: 0 rollsor5 star gear:Physical Resistance: 0 rollsAttack: 3 rollsAverage strength of each roll: 36%. Total weighting: 185%Physical Attack: 2 rollsAverage strength of each roll: 50%. Total weighting: 140%Volt Attack: 0 rolls \ No newline at end of file diff --git a/example-images/titan-stats/stat-weightings-1.png b/example-images/titan-stats/stat-weightings-1.png new file mode 100644 index 00000000..32f50c83 Binary files /dev/null and b/example-images/titan-stats/stat-weightings-1.png differ diff --git a/example-images/titan-stats/stat-weightings-2.png b/example-images/titan-stats/stat-weightings-2.png new file mode 100644 index 00000000..d48662c0 Binary files /dev/null and b/example-images/titan-stats/stat-weightings-2.png differ diff --git a/src/features/GearRollBreakdown.tsx b/src/features/GearRollBreakdown.tsx index f7ef4fd2..d0710784 100644 --- a/src/features/GearRollBreakdown.tsx +++ b/src/features/GearRollBreakdown.tsx @@ -28,13 +28,17 @@ export const GearRollBreakdown = ({ gearSnap }: GearRollBreakdownProps) => { {`${y.randomStatId}: `} {pluralize('roll', y.rollCombination.numberOfRolls, true)} - {!!y.rollCombination.rollStrength && ( - <> - , strength:{' '} + {!!y.rollCombination.numberOfRolls && ( +
+ Average strength of each roll:{' '} - + . Total weighting:{' '} + +
)}
diff --git a/src/models/gear.ts b/src/models/gear.ts index 2d9251d7..bd71ed99 100644 --- a/src/models/gear.ts +++ b/src/models/gear.ts @@ -201,15 +201,8 @@ export class Gear implements Persistable { const rollBreakdown = gearStatRollCombinations[0].randomStatRollCombinations; const highestStatName = rollBreakdown.reduce((prev, current) => - current.rollCombination.numberOfRolls > - prev.rollCombination.numberOfRolls || - (current.rollCombination.numberOfRolls === - prev.rollCombination.numberOfRolls && - ((current.rollCombination.rollStrength && - prev.rollCombination.rollStrength && - current.rollCombination.rollStrength >= - prev.rollCombination.rollStrength) || - current.rollCombination.rollStrength === undefined)) + current.rollCombination.totalRollWeight >= + prev.rollCombination.totalRollWeight ? current : prev ).randomStatId; diff --git a/src/models/random-stat-roll-combination.ts b/src/models/random-stat-roll-combination.ts index 41507502..999e7577 100644 --- a/src/models/random-stat-roll-combination.ts +++ b/src/models/random-stat-roll-combination.ts @@ -1,8 +1,26 @@ export interface RollCombination { numberOfRolls: number; - rollStrength: number | undefined; + + /** The average strength of each roll between the min roll value and the max roll value. + * + * i.e. For one roll, if rolled the min roll value, the strength is 0. If rolled the max roll value, the strength is 1. + * + * e.g. if min roll value is 100, max roll value is 200, and a roll is 150, then the strength of that roll is 0.5. */ + rollStrength: number; + + /** This is the sum of (the strength of each roll between 0 and the max roll value). + * + * This value is used to compare which stat rolled "higher" + * + * Slightly different calculation from the `rollStrength` property in that the `rollStrength` property normalizes the strength to be relative to the range of the min roll value and the max roll value, instead of 0 and the max roll value. + * + * e.g. max roll value = 100. First roll is 50, strength is 0.5. Second roll is 75, strength is 0.75. Total weight is 0.5 + 0.75 = 1.25 + * + * Note that since we are unlikely to know the value of each roll, this is calculated by using the average strength of a single roll multiplied by the number of rolls + */ + totalRollWeight: number; } export function zeroRollCombination(): RollCombination { - return { numberOfRolls: 0, rollStrength: undefined }; + return { numberOfRolls: 0, rollStrength: 0, totalRollWeight: 0 }; } diff --git a/src/models/random-stat.ts b/src/models/random-stat.ts index a2f09b48..06e28b57 100644 --- a/src/models/random-stat.ts +++ b/src/models/random-stat.ts @@ -138,17 +138,34 @@ export class RandomStat implements Persistable { const combinations: RollCombination[] = []; for (let n = smallestNumOfRolls; n <= largestNumOfRolls; n++) { // (value - defaultValue - n * minValue) / (maxValue - minValue) / n - const rollStrength = BigNumber(value) - .minus(BigNumber(randomStatDefaultValue)) - .minus(BigNumber(randomStatMinRollValue).multipliedBy(n)) - .dividedBy( - BigNumber(randomStatMaxRollValue).minus( - BigNumber(randomStatMinRollValue) - ) - ) - .dividedBy(n) - .toNumber(); - combinations.push({ numberOfRolls: n, rollStrength }); + // Need to check if minValue === maxValue to prevent div by 0 in the case of % value stats, e.g. ele atk%, where every roll is fixed (minValue = maxValue). This also means % stats always have roll strength = 1 + const rollStrength = + randomStatMinRollValue >= randomStatMaxRollValue + ? 1 + : BigNumber(value) + .minus(BigNumber(randomStatDefaultValue)) + .minus(BigNumber(randomStatMinRollValue).multipliedBy(n)) + .dividedBy( + BigNumber(randomStatMaxRollValue).minus( + BigNumber(randomStatMinRollValue) + ) + ) + .dividedBy(n) + .toNumber(); + + // (value - defaultValue) / n / maxValue * n + // a.k.a. work out the average of one roll, divided by the max roll value, multiplied by the number of rolls + const totalRollWeight = + n === 0 + ? 0 + : BigNumber(value) + .minus(randomStatDefaultValue) + .div(n) + .div(randomStatMaxRollValue) + .times(n) + .toNumber(); + + combinations.push({ numberOfRolls: n, rollStrength, totalRollWeight }); } return combinations;