Skip to content

Commit

Permalink
Standardize scalesWith across character UI (#2460)
Browse files Browse the repository at this point in the history
* Standardize scalesWith across character UI

* unify scaling stats by removing minTotal in buildTC

* remove test in gi-solver-tc

* format

* add ScalesWith

* alert variant
  • Loading branch information
frzyc authored Sep 27, 2024
1 parent 007622f commit c585a9e
Show file tree
Hide file tree
Showing 32 changed files with 364 additions and 451 deletions.
5 changes: 5 additions & 0 deletions libs/gi/consts/src/artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,8 @@ export type ArtifactRarity = (typeof allArtifactRarityKeys)[number]

const allArtifactSetCount = [1, 2, 3, 4, 5] as const
export type SetNum = (typeof allArtifactSetCount)[number]

export const allMainSubStatKeys = Array.from(
new Set([...allSubstatKeys, ...allMainStatKeys] as const)
)
export type MainSubStatKey = (typeof allMainSubStatKeys)[number]
24 changes: 2 additions & 22 deletions libs/gi/db/src/Database/DataManagers/BuildTcDataManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type {
ArtifactSetKey,
ArtifactSlotKey,
MainStatKey,
SubstatKey,
WeaponKey,
} from '@genshin-optimizer/gi/consts'
import {
Expand All @@ -26,17 +25,6 @@ import type { ArtCharDatabase } from '../ArtCharDatabase'
import { DataManager } from '../DataManager'
import type { IGO, ImportResult } from '../exim'

export type MinTotalStatKey = Exclude<SubstatKey, 'hp_' | 'atk_' | 'def_'>
export const minTotalStatKeys: MinTotalStatKey[] = [
'atk',
'hp',
'def',
'eleMas',
'enerRech_',
'critRate_',
'critDMG_',
]

export class BuildTcDataManager extends DataManager<
string,
'buildTcs',
Expand Down Expand Up @@ -148,7 +136,6 @@ export function initCharTC(weaponKey: WeaponKey): BuildTc {
optimization: {
distributedSubstats: 45,
maxSubstats: initBuildTcOptimizationMaxSubstats(),
minTotal: {},
},
}
}
Expand Down Expand Up @@ -259,22 +246,15 @@ function validateBuildTcOptimization(
optimization: unknown
): BuildTc['optimization'] | undefined {
if (typeof optimization !== 'object') return undefined
let { distributedSubstats, maxSubstats, minTotal } =
let { distributedSubstats, maxSubstats } =
optimization as BuildTc['optimization']
if (typeof distributedSubstats !== 'number') distributedSubstats = 20
if (typeof maxSubstats !== 'object')
maxSubstats = initBuildTcOptimizationMaxSubstats()
maxSubstats = objKeyMap([...allSubstatKeys], (k) =>
typeof maxSubstats[k] === 'number' ? maxSubstats[k] : 0
)
if (typeof minTotal !== 'object') minTotal = {}
minTotal = Object.fromEntries(
Object.entries(minTotal).filter(
([k, v]) => minTotalStatKeys.includes(k) && typeof v === 'number'
)
)

return { distributedSubstats, maxSubstats, minTotal }
return { distributedSubstats, maxSubstats }
}
function initBuildTcOptimizationMaxSubstats(): BuildTc['optimization']['maxSubstats'] {
return objKeyMap(
Expand Down
7 changes: 3 additions & 4 deletions libs/gi/db/src/Database/DataManagers/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { cachedArtifact, validateArtifact } from './ArtifactDataManager'
import type { MinTotalStatKey } from './BuildTcDataManager'
import { initCharTC, minTotalStatKeys, toBuildTc } from './BuildTcDataManager'
import { initCharTC, toBuildTc } from './BuildTcDataManager'
import {
MAX_DESC_LENGTH,
MAX_NAME_LENGTH,
Expand All @@ -12,6 +11,7 @@ import type {
ArtSetExclusion,
ArtSetExclusionKey,
GeneratedBuild,
OptConfig,
StatFilterSetting,
StatFilters,
} from './OptConfigDataManager'
Expand Down Expand Up @@ -48,7 +48,6 @@ export {
initCustomTarget,
initialWeapon,
maxBuildsToShowList,
minTotalStatKeys,
toBuildTc,
validateArtifact,
validateCustomMultiTarget,
Expand All @@ -61,7 +60,7 @@ export type {
LoadoutDataExportSetting,
LoadoutDatum,
LoadoutExportSetting,
MinTotalStatKey,
OptConfig,
StatFilterSetting,
StatFilters,
Team,
Expand Down
7 changes: 0 additions & 7 deletions libs/gi/db/src/Interfaces/BuildTc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,5 @@ export type BuildTc = {
optimization: {
distributedSubstats: number
maxSubstats: Record<SubstatKey, number>
/** NB: this is in total raw value, not substat count
* This includes stats from other sources
* e.g. `{enerRech_: 0.3}`
*/
minTotal: Partial<
Record<Exclude<SubstatKey, 'hp_' | 'atk_' | 'def_'>, number>
>
}
}
4 changes: 0 additions & 4 deletions libs/gi/localization/assets/locales/en/page_character.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,6 @@
"scalesWith": "The selected Optimization target and constraints scales with: ",
"distribute": ". The solver will only distribute stats to these substats.",
"feasibilty": "There may be additional leftover substats that should be distributed to non-scaling stats to ensure the solution is feasible."
},
"constraint": {
"title": "Stat Constraints",
"add": "Add a Stat Constraint"
}
},
"tabTeambuff": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@
"build_other": "<0>{{count}}</0> Builds",
"thread_one": "<0>{{count}}</0> Thread",
"thread_other": "<0>{{count}}</0> Threads",
"optAlert": {
"scalesWith": "The selected Optimization target and constraints scales with: "
},
"targetSelector": {
"selectOptTarget": "Select an Optimization Target",
"selectGraphTarget": "Select a Graph Target",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { iconInlineProps } from '@genshin-optimizer/common/svgicons'
import { StatIcon } from '@genshin-optimizer/gi/svgicons'
import {
ArtifactStatWithUnit,
OptTargetContext,
} from '@genshin-optimizer/gi/ui'
import { Alert } from '@mui/material'
import { useContext } from 'react'
import { Trans, useTranslation } from 'react-i18next'

export default function ScalesWith() {
const { t } = useTranslation('page_character_optimize')
const { scalesWith } = useContext(OptTargetContext)
return (
!!scalesWith.size && (
<Alert severity="info" variant="standard">
<Trans t={t} i18nKey="optAlert.scalesWith">
The selected Optimization target and constraints scales with:{' '}
</Trans>
{new Intl.ListFormat()
.format(Array(scalesWith.size).fill('\u200B'))
.split(/([^\u200B]+)/)
.map((str, i) =>
str === '\u200B'
? ((k) => (
<strong key={k}>
<StatIcon statKey={k} iconProps={iconInlineProps} />
<ArtifactStatWithUnit statKey={k} />
</strong>
))([...scalesWith][i / 2])
: str
)}
</Alert>
)
)
}
54 changes: 18 additions & 36 deletions libs/gi/page-team/src/CharacterDisplay/Tabs/TabOptimize/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from '@genshin-optimizer/gi/db-ui'
import type { OptProblemInput } from '@genshin-optimizer/gi/solver'
import { GOSolver, mergeBuilds, mergePlot } from '@genshin-optimizer/gi/solver'
import { compactArtifacts, dynamicData } from '@genshin-optimizer/gi/solver-tc'
import { compactArtifacts } from '@genshin-optimizer/gi/solver-tc'
import { getCharStat } from '@genshin-optimizer/gi/stats'
import {
AdResponsive,
Expand All @@ -46,18 +46,18 @@ import {
GraphContext,
HitModeToggle,
NoArtWarning,
OptimizationTargetContext,
ReactionToggle,
getTeamData,
resolveInfo,
statFilterToNumNode,
useGlobalError,
useNumWorkers,
useTeamData,
} from '@genshin-optimizer/gi/ui'
import type { UIData } from '@genshin-optimizer/gi/uidata'
import { uiDataForTeam } from '@genshin-optimizer/gi/uidata'
import type { NumNode } from '@genshin-optimizer/gi/wr'
import { mergeData, optimize } from '@genshin-optimizer/gi/wr'
import { dynamicData, mergeData, optimize } from '@genshin-optimizer/gi/wr'
import {
CheckBox,
CheckBoxOutlineBlank,
Expand Down Expand Up @@ -112,6 +112,7 @@ import OptimizationTargetSelector from './Components/OptimizationTargetSelector'
import StatFilterCard from './Components/StatFilterCard'
import UseEquipped from './Components/UseEquipped'
import { UseTeammateArt } from './Components/UseTeammateArt'
import ScalesWith from './ScalesWith'

const audio = new Audio('assets/notification.mp3')
export default function TabBuild() {
Expand Down Expand Up @@ -339,25 +340,7 @@ export default function TabBuild() {
) as NumNode | undefined
if (!unoptimizedOptimizationTargetNode) return
const targetNode = unoptimizedOptimizationTargetNode
const valueFilter: { value: NumNode; minimum: number }[] = Object.entries(
statFilters
)
.flatMap(([pathStr, settings]) =>
settings
.filter((setting) => !setting.disabled)
.map((setting) => {
const filterNode: NumNode = objPathValue(
workerData.display ?? {},
JSON.parse(pathStr)
)
const infoResolved =
filterNode?.info && resolveInfo(filterNode.info)
const minimum =
infoResolved?.unit === '%' ? setting.value / 100 : setting.value // TODO: Conversion
return { value: filterNode, minimum: minimum }
})
)
.filter((x) => x.value && x.minimum > -Infinity)
const valueFilter = statFilterToNumNode(workerData, statFilters)

setChartData(undefined)

Expand Down Expand Up @@ -768,6 +751,7 @@ export default function TabBuild() {
</span>
</BootstrapTooltip>
</ButtonGroup>
<ScalesWith />
{!!characterKey && (
<BuildAlert
{...{ status: buildStatus, characterName, maxBuildsToShow }}
Expand Down Expand Up @@ -845,25 +829,23 @@ export default function TabBuild() {
</CardThemed>
)}

<OptimizationTargetContext.Provider value={optimizationTarget}>
{graphBuilds && (
<BuildList
builds={graphBuilds}
compareData={compareData}
disabled={!!generatingBuilds}
getLabel={getGraphBuildLabel}
setBuilds={setGraphBuilds}
mainStatAssumptionLevel={mainStatAssumptionLevel}
/>
)}
{graphBuilds && (
<BuildList
builds={builds}
builds={graphBuilds}
compareData={compareData}
disabled={!!generatingBuilds}
getLabel={getNormBuildLabel}
getLabel={getGraphBuildLabel}
setBuilds={setGraphBuilds}
mainStatAssumptionLevel={mainStatAssumptionLevel}
/>
</OptimizationTargetContext.Provider>
)}
<BuildList
builds={builds}
compareData={compareData}
disabled={!!generatingBuilds}
getLabel={getNormBuildLabel}
mainStatAssumptionLevel={mainStatAssumptionLevel}
/>
</Box>
)
}
Expand Down
Loading

0 comments on commit c585a9e

Please sign in to comment.