Skip to content

Commit d3d2ed6

Browse files
committed
feat: Show important scenario attributes in result
1 parent 7acc530 commit d3d2ed6

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed

locales/en/translation.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
"Infusions: ": "Infusions: ",
121121
"Invalid Format.": "Invalid Format.",
122122
"Jump to sharing section": "Jump to sharing section",
123+
"Key Scenario Attributes": "Key Scenario Attributes",
123124
"Life Siphon": "Life Siphon",
124125
"Lifesteal frequency:": "Lifesteal frequency:",
125126
"Lock any gear slots to a specific type to work with what you already have or share gear between multiple builds.": "Lock any gear slots to a specific type to work with what you already have or share gear between multiple builds.",

src/components/sections/results/ResultDetails.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import OtherAttributes from './OtherAttributes';
2121
import OutputDistribution from './OutputDistribution';
2222
import OutputInfusions from './OutputInfusions';
2323
import ResultCharacter from './ResultCharacter';
24+
import ScenarioAttributeSummary from './ScenarioAttributeSummary';
2425
import SpecialDurations from './SpecialDurations';
2526
import TemplateHelperSections from './TemplateHelperSections';
2627

@@ -89,6 +90,7 @@ const ResultDetails = () => {
8990
<MultiplierBreakdown character={character} />
9091
</Grid>
9192
</Grid>
93+
<ScenarioAttributeSummary character={character} />
9294
<AppliedModifiers character={character} />
9395
<TemplateHelperSections character={character} />
9496
</ErrorBoundary>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import DataSaverOnIcon from '@mui/icons-material/DataSaverOn';
2+
import { Grid, Table, TableBody, TableCell, TableRow, Typography } from '@mui/material';
3+
import { Trans } from 'react-i18next';
4+
import { allAttributePercentKeys } from '../../../assets/modifierdata/metadata';
5+
import type { Character } from '../../../state/optimizer/types/optimizerTypes';
6+
7+
const roundOne = (num: number) => Math.round(num * 10) / 10;
8+
const roundTwo = (num: number) => Math.round(num * 100) / 100;
9+
10+
const ScenarioAttributeSummary = ({ character }: { character: Character }) => {
11+
if (character.results.scenarioAttributeSummary) {
12+
return (
13+
<>
14+
<Typography variant="h6">
15+
<DataSaverOnIcon color="info" fontSize="small" sx={{ marginRight: '0.5ch' }} />
16+
<Trans>Key Scenario Attributes</Trans>
17+
</Typography>
18+
<Grid container spacing={2} mb={2}>
19+
{Object.entries(character.results.scenarioAttributeSummary).map(
20+
([attribute, entries]) => (
21+
<Grid size={{ xs: 12, sm: 8, md: 4 }}>
22+
<Table padding="none" sx={{ mb: 0 }}>
23+
<TableBody>
24+
{entries.map(([value, amount]) => (
25+
<TableRow hover key={value}>
26+
<TableCell>
27+
<Typography sx={{ fontSize: '18px', color: '#AAAAAA' }}>
28+
{allAttributePercentKeys.includes(attribute)
29+
? `${(value * 100).toFixed(2)}%`
30+
: roundOne(value)}{' '}
31+
{attribute}
32+
</Typography>
33+
</TableCell>
34+
<TableCell align="right">{roundTwo(amount * 100)}%</TableCell>
35+
</TableRow>
36+
))}
37+
</TableBody>
38+
</Table>
39+
</Grid>
40+
),
41+
)}
42+
</Grid>
43+
</>
44+
);
45+
}
46+
};
47+
48+
export default ScenarioAttributeSummary;

src/state/optimizer/optimizerCore.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import type {
2626
OptimizerCoreSettings,
2727
Results,
2828
Scenario,
29+
ScenarioAttributeSummary,
2930
ScenarioProcessed,
3031
} from './types/optimizerTypes';
3132
import { iteratePartitions } from './utils/combinatorics';
@@ -976,6 +977,29 @@ export class OptimizerCore {
976977
};
977978
}
978979

980+
if (character.scenarios.length > 1) {
981+
const scenarioAttributeSummary: ScenarioAttributeSummary = {};
982+
let hasData = false;
983+
984+
const attrs = ['Critical Chance', 'Condition Duration'] as const;
985+
for (const attr of attrs) {
986+
const map = new Map<number, number>();
987+
scenarios.forEach((scenario) =>
988+
map.set(
989+
scenario.attributes[attr],
990+
(map.get(scenario.attributes[attr]) ?? 0) + scenario.fraction,
991+
),
992+
);
993+
if (map.size > 1) {
994+
scenarioAttributeSummary[attr] = [...map.entries()].sort((a, b) => a[0] - b[0]);
995+
hasData = true;
996+
}
997+
}
998+
if (hasData) {
999+
results.scenarioAttributeSummary = scenarioAttributeSummary;
1000+
}
1001+
}
1002+
9791003
// out of combat hero panel simulation (overrides both baseAttributes and modifiers)
9801004
if (settings.unbuffedBaseAttributes && settings.unbuffedModifiers) {
9811005
const unbuffedScenario: Scenario = {

src/state/optimizer/types/optimizerTypes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ interface CoefficientHelperValue {
161161
}
162162
export type EffectiveDistributionKey = DistributionNameInternal | 'Other' | 'Siphon';
163163
type GainLossKey = 'Power' | 'Precision' | 'Ferocity' | 'Condition Damage' | 'Expertise';
164+
165+
export type ScenarioAttributeSummary = Partial<Record<AttributeName, [number, number][]>>;
164166
export interface Results {
165167
value: number;
166168
indicators: Record<IndicatorName, number>;
@@ -170,6 +172,7 @@ export interface Results {
170172
damageBreakdown?: Partial<Record<EffectiveDistributionKey, number>>;
171173
coefficientHelper?: Partial<Record<DistributionNameInternal, CoefficientHelperValue>>;
172174
unbuffedAttributes?: Attributes;
175+
scenarioAttributeSummary?: ScenarioAttributeSummary;
173176
}
174177
export interface CharacterUnprocessed {
175178
id?: string;

0 commit comments

Comments
 (0)