Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial SRO light cone sheet with targeted buff #2531

Merged
merged 4 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libs/pando/ui-sheet/src/types/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import type { ReactNode } from 'react'
export type Header = {
icon: ReactNode
text: ReactNode
additional: ReactNode
additional?: ReactNode
}
1 change: 1 addition & 0 deletions libs/sr/formula-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './char'
export * from './lightCone'
export * from './relic'
8 changes: 8 additions & 0 deletions libs/sr/formula-ui/src/lightCone/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { UISheetElement } from '@genshin-optimizer/pando/ui-sheet'
import type { LightConeKey } from '@genshin-optimizer/sr/consts'
import PastSelfInMirror from './sheets/PastSelfInMirror'

export const lightConeUiSheets: Partial<Record<LightConeKey, UISheetElement>> =
{
PastSelfInMirror,
}
74 changes: 74 additions & 0 deletions libs/sr/formula-ui/src/lightCone/sheets/PastSelfInMirror.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { ImgIcon } from '@genshin-optimizer/common/ui'
import type { UISheetElement } from '@genshin-optimizer/pando/ui-sheet'
import { lightConeAsset } from '@genshin-optimizer/sr/assets'
import type { LightConeKey } from '@genshin-optimizer/sr/consts'
import { buffs, conditionals } from '@genshin-optimizer/sr/formula'
import { mappedStats } from '@genshin-optimizer/sr/stats'
import { StatDisplay } from '@genshin-optimizer/sr/ui'
import { trans } from '../../util'
import { SuperImposeWrapper } from '../util'

const key: LightConeKey = 'PastSelfInMirror'

const [chg, _ch] = trans('lightcone', key)
const dm = mappedStats.lightCone[key]
const icon = lightConeAsset(key, 'cover')
const cond = conditionals[key]
const buff = buffs[key]
const sheet: UISheetElement = {
title: chg('passive.name'),
img: icon,
documents: [
{
type: 'text',
text: chg('passive.description'), // TODO: getInterpolateObject for lightcone
},
{
type: 'conditional',
conditional: {
targeted: true,
header: {
icon: <ImgIcon src={icon} sx={{ width: 'auto' }} size={2} />,
text: chg('passive.name'),
},
metadata: cond.useUltimate,
label: 'Wearer use their Ultimate',
fields: [
{
title: <StatDisplay statKey="dmg_" />,
fieldRef: buff.cond_dmg_.tag,
},
// TODO: translate DM "Duration"
{
title: 'Duration',
fieldValue: (
<SuperImposeWrapper>
{(superimpose) => dm.duration[superimpose]}
</SuperImposeWrapper>
),
},
{
// TODO: should only show when wearer brEffect_ > dm.brEffect_thresh_[superimpose]
title: 'Skill POint recovered',
fieldValue: 1,
},
frzyc marked this conversation as resolved.
Show resolved Hide resolved
],
},
},
{
type: 'fields',
fields: [
{
title: 'Energy regen at start of each wave',
fieldValue: (
<SuperImposeWrapper>
{(superimpose) => dm.enerRegn[superimpose]}
</SuperImposeWrapper>
),
},
],
},
],
}

export default sheet
13 changes: 13 additions & 0 deletions libs/sr/formula-ui/src/lightCone/util.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { own } from '@genshin-optimizer/sr/formula'
import { useSrCalcContext } from '@genshin-optimizer/sr/ui'
import type { ReactNode } from 'react'

export function SuperImposeWrapper({
children,
}: {
children: (superimpose: number) => ReactNode
}) {
const calc = useSrCalcContext()
const superimpose = calc?.compute(own.lightCone.superimpose).val ?? 1
return children(superimpose)
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const sheet: UISheet<'2' | '4'> = {
title: <StatDisplay statKey="brEffect_" />,
fieldRef: buff.set4_brEffect_.tag,
},
/// TODO: translate DM "Duration"
// TODO: translate DM "Duration"
{ title: 'Duration', fieldValue: dm['4'].duration },
],
},
Expand Down
24 changes: 2 additions & 22 deletions libs/sr/formula/src/data/lightCone/sheets/PastSelfInMirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import type { LightConeKey } from '@genshin-optimizer/sr/consts'
import { allStats, mappedStats } from '@genshin-optimizer/sr/stats'
import {
allBoolConditionals,
allListConditionals,
allNumConditionals,
enemyDebuff,
own,
ownBuff,
register,
registerBuff,
teamBuff,
Expand All @@ -20,35 +16,19 @@ const dm = mappedStats.lightCone[key]
const lcCount = own.common.count.sheet(key)
const { superimpose } = own.lightCone

// TODO: Add conditionals
const { boolConditional } = allBoolConditionals(key)
const { listConditional } = allListConditionals(key, ['val1', 'val2'])
const { numConditional } = allNumConditionals(key, true, 0, 2)
const { useUltimate } = allBoolConditionals(key)

const sheet = register(
key,
// Handles base stats and passive buffs
entriesForLightCone(key, data_gen),

// TODO: Add formulas/buffs
// Conditional buffs
registerBuff(
'cond_dmg_',
ownBuff.premod.dmg_.add(
boolConditional.ifOn(
cmpGE(lcCount, 1, subscript(superimpose, dm.cond_dmg_))
)
)
),
registerBuff(
'team_dmg_',
teamBuff.premod.dmg_.add(
cmpGE(lcCount, 1, listConditional.map({ val1: 1, val2: 2 }))
cmpGE(lcCount, 1, useUltimate.ifOn(subscript(superimpose, dm.dmg_)))
)
),
registerBuff(
'enemy_defIgn_',
enemyDebuff.common.defIgn_.add(cmpGE(lcCount, 1, numConditional))
)
)
export default sheet
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const dm = mappedStats.relic[key]

const relicCount = own.common.count.sheet(key)

// TODO: how do we do a directional targeted buff? since this requires a character equipped with 4-set to trigger a ult on ally to buff team
const { useUltimateOnAlly } = allBoolConditionals(key)

const sheet = register(
Expand Down
40 changes: 2 additions & 38 deletions libs/sr/formula/src/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2413,25 +2413,11 @@ export const conditionals = {
},
},
PastSelfInMirror: {
boolConditional: {
useUltimate: {
sheet: 'PastSelfInMirror',
name: 'boolConditional',
name: 'useUltimate',
type: 'bool',
},
listConditional: {
sheet: 'PastSelfInMirror',
name: 'listConditional',
type: 'list',
list: ['val1', 'val2'],
},
numConditional: {
sheet: 'PastSelfInMirror',
name: 'numConditional',
type: 'num',
int_only: true,
min: 0,
max: 2,
},
},
PatienceIsAllYouNeed: {
boolConditional: {
Expand Down Expand Up @@ -14931,28 +14917,6 @@ export const buffs = {
name: 'cond_dmg_',
},
},
enemy_defIgn_: {
sheet: 'PastSelfInMirror',
name: 'enemy_defIgn_',
tag: {
et: 'display',
qt: 'common',
q: 'defIgn_',
sheet: 'PastSelfInMirror',
name: 'enemy_defIgn_',
},
},
team_dmg_: {
sheet: 'PastSelfInMirror',
name: 'team_dmg_',
tag: {
et: 'display',
qt: 'premod',
q: 'dmg_',
sheet: 'PastSelfInMirror',
name: 'team_dmg_',
},
},
},
PatienceIsAllYouNeed: {
cond_dmg_: {
Expand Down
16 changes: 15 additions & 1 deletion libs/sr/page-team/src/ComboEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
ModalWrapper,
} from '@genshin-optimizer/common/ui'
import { useDatabaseContext } from '@genshin-optimizer/sr/db-ui'
import type { Tag } from '@genshin-optimizer/sr/formula'
import { type Tag } from '@genshin-optimizer/sr/formula'
import {
Box,
Button,
Expand All @@ -18,6 +18,7 @@ import {
import { useContext } from 'react'
import { BonusStats } from './BonusStats'
import { PresetContext, useTeamContext } from './context'
import { LightConeSheetsDisplay } from './LightConeSheetsDisplay'
import { OptimizationTargetSelector } from './Optimize/OptimizationTargetSelector'
import { RelicSheetsDisplay } from './RelicSheetsDisplay'

Expand Down Expand Up @@ -108,6 +109,7 @@ function Team({
/>
<BonusStats />
<RelicConditionals />
<LightConeConditionals />
</Stack>
</CardContent>
</CardThemed>
Expand All @@ -126,3 +128,15 @@ function RelicConditionals() {
</>
)
}
function LightConeConditionals() {
const [show, onShow, onHide] = useBoolState()
return (
<>
{/* TODO: translation */}
<Button onClick={onShow}>Light Cone Conditionals</Button>
<ModalWrapper open={show} onClose={onHide}>
<LightConeSheetsDisplay />
</ModalWrapper>
</>
)
}
61 changes: 61 additions & 0 deletions libs/sr/page-team/src/LightConeSheetDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { CardThemed, NextImage } from '@genshin-optimizer/common/ui'
import type { UISheetElement } from '@genshin-optimizer/pando/ui-sheet'
import { DocumentDisplay } from '@genshin-optimizer/pando/ui-sheet'
import { lightConeAsset } from '@genshin-optimizer/sr/assets'
import type { LightConeKey } from '@genshin-optimizer/sr/consts'
import { lightConeUiSheets } from '@genshin-optimizer/sr/formula-ui'
import { LightConeName } from '@genshin-optimizer/sr/ui'
import {
Box,
CardContent,
CardHeader,
Divider,
Stack,
Typography,
} from '@mui/material'

export function LightConeSheetDisplay({ lcKey }: { lcKey: LightConeKey }) {
const lcSheet = lightConeUiSheets[lcKey]
if (!lcSheet) return null
return (
frzyc marked this conversation as resolved.
Show resolved Hide resolved
<CardThemed>
<CardContent>
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
<Box
component={NextImage ? NextImage : 'img'}
alt="Light Cone Cover Image"
src={lightConeAsset(lcKey, 'cover')}
sx={{
maxHeight: '5em',
width: 'auto',
}}
/>
<Typography variant="h6">
<LightConeName lcKey={lcKey} />
</Typography>
</Box>
<LightConeUiSheetElement uiSheetElement={lcSheet} />
</CardContent>
</CardThemed>
)
}
function LightConeUiSheetElement({
uiSheetElement,
}: {
uiSheetElement: UISheetElement
}) {
const { documents, title } = uiSheetElement
return (
<CardThemed bgt="light">
<CardHeader title={title} titleTypographyProps={{ variant: 'h6' }} />
<Divider />
<CardContent>
<Stack spacing={1}>
{documents.map((doc, i) => (
<DocumentDisplay key={i} document={doc} />
))}
frzyc marked this conversation as resolved.
Show resolved Hide resolved
</Stack>
</CardContent>
</CardThemed>
)
}
22 changes: 22 additions & 0 deletions libs/sr/page-team/src/LightConeSheetsDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { CardThemed } from '@genshin-optimizer/common/ui'
import type { LightConeKey } from '@genshin-optimizer/sr/consts'
import { CardContent, Grid } from '@mui/material'
import { LightConeSheetDisplay } from './LightConeSheetDisplay'

// TODO: hardcoded to LightConeSheetsDisplay.tsx for now. Can be expanded to all lightcones with sheets
const cones: LightConeKey[] = ['PastSelfInMirror'] as const
export function LightConeSheetsDisplay() {
return (
<CardThemed bgt="dark">
<CardContent>
<Grid container columns={3} spacing={1}>
{cones.map((lcKey) => (
<Grid item xs={1} key={lcKey}>
<LightConeSheetDisplay lcKey={lcKey} />
</Grid>
))}
</Grid>
</CardContent>
</CardThemed>
)
}
14 changes: 9 additions & 5 deletions libs/sr/page-team/src/RelicSheetDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export function RelicSheetDisplay({ setKey }: { setKey: RelicSetKey }) {
}}
/>
<Box>
<RelicSetName setKey={setKey} />
<Typography variant="h6">
<RelicSetName setKey={setKey} />
</Typography>
{/* TODO: translate */}
<Typography>
<SqBadge>{isCavernRelic(setKey) ? 'Cavern' : 'Planar'}</SqBadge>
Expand All @@ -56,12 +58,14 @@ export function RelicUiSheetElement({
const { documents, title } = uiSheetElement
return (
<CardThemed bgt="light">
<CardHeader title={title} />
<CardHeader title={title} titleTypographyProps={{ variant: 'h6' }} />
<Divider />
<CardContent>
{documents.map((doc, i) => (
<DocumentDisplay key={i} document={doc} />
))}
<Stack spacing={1}>
{documents.map((doc, i) => (
<DocumentDisplay key={i} document={doc} />
))}
</Stack>
</CardContent>
</CardThemed>
)
Expand Down
Loading
Loading