Skip to content

Commit

Permalink
Add non-stacking buff back to NO4 in a smarter way (#2592)
Browse files Browse the repository at this point in the history
* Add infrastructure for strikethrough on fields

* Add non-stacking buffs for NO4

* Modify strikethrough to be a separate info field

* Move nonstacking to its own namespace

* Fix format

* Fix format
  • Loading branch information
nguyentvan7 authored Jan 10, 2025
1 parent 2c28359 commit dd6dac4
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 14 deletions.
21 changes: 17 additions & 4 deletions libs/gi/sheets/src/Artifacts/NoblesseOblige/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import type { ArtifactSetKey } from '@genshin-optimizer/gi/consts'
import type { Data } from '@genshin-optimizer/gi/wr'
import { equal, greaterEq, input, percent } from '@genshin-optimizer/gi/wr'
import { cond, st, stg } from '../../SheetUtil'
import {
equalStr,
greaterEq,
greaterEqStr,
input,
percent,
} from '@genshin-optimizer/gi/wr'
import { cond, nonStackBuff, st, stg } from '../../SheetUtil'
import { ArtifactSheet, setHeaderTemplate } from '../ArtifactSheet'
import type { SetEffectSheet } from '../IArtifactSheet'
import { dataObjForArtifactSheet } from '../dataUtil'
Expand All @@ -12,11 +18,12 @@ const setHeader = setHeaderTemplate(key)
const set2 = greaterEq(input.artSet.NoblesseOblige, 2, percent(0.2))

const [condSet4Path, condSet4] = cond(key, 'set4')
const set4 = greaterEq(
const set4TallyWrite = greaterEqStr(
input.artSet.NoblesseOblige,
4,
equal(condSet4, 'on', percent(0.2))
equalStr(condSet4, 'on', input.charKey)
)
const [set4, set4Inactive] = nonStackBuff('no4', 'atk_', percent(0.2))

export const data: Data = dataObjForArtifactSheet(key, {
premod: {
Expand All @@ -26,6 +33,9 @@ export const data: Data = dataObjForArtifactSheet(key, {
premod: {
atk_: set4,
},
nonStacking: {
no4: set4TallyWrite,
},
},
})

Expand All @@ -45,6 +55,9 @@ const sheet: SetEffectSheet = {
{
node: set4,
},
{
node: set4Inactive,
},
{
text: stg('duration'),
value: 12,
Expand Down
25 changes: 24 additions & 1 deletion libs/gi/sheets/src/SheetUtil.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ import type {
WeaponKey,
} from '@genshin-optimizer/gi/consts'
import { Translate } from '@genshin-optimizer/gi/i18n'
import type { Info, NumNode, ReadNode, StrNode } from '@genshin-optimizer/gi/wr'
import type {
Info,
NonStackBuff,
NumNode,
ReadNode,
StrNode,
} from '@genshin-optimizer/gi/wr'
import {
customStringRead,
equal,
infoMut,
input,
nonStacking,
unequal,
} from '@genshin-optimizer/gi/wr'
import type { ReactNode } from 'react'

Expand Down Expand Up @@ -80,3 +88,18 @@ export function activeCharBuff(
equal(input.activeCharKey, buffTargetKey, node),
]
}

export function nonStackBuff(
buffName: NonStackBuff,
path: string,
buffNode: NumNode
) {
return [
equal(nonStacking[buffName], input.charKey, buffNode),
unequal(nonStacking[buffName], input.charKey, buffNode, {
path,
isTeamBuff: true,
strikethrough: true,
}),
]
}
3 changes: 2 additions & 1 deletion libs/gi/ui/src/components/FieldDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export function NodeFieldDisplay({
[setFormulaData, data, calcRes]
)
if (!calcRes && !compareCalcRes) return null
const { multi } = calcRes?.info ?? compareCalcRes?.info ?? {}
const { multi, strikethrough } = calcRes?.info ?? compareCalcRes?.info ?? {}

const multiDisplay = multi && <span>{multi}&#215;</span>
const calcValue = calcRes?.value ?? 0
Expand Down Expand Up @@ -198,6 +198,7 @@ export function NodeFieldDisplay({
gap: 1,
boxShadow: emphasize ? '0px 0px 0px 2px red inset' : undefined,
py: 0.25,
textDecoration: strikethrough ? 'line-through' : undefined,
}}
component={component}
>
Expand Down
9 changes: 7 additions & 2 deletions libs/gi/ui/src/util/getCalcDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { Translate } from '@genshin-optimizer/gi/i18n'
import type { CalcResult } from '@genshin-optimizer/gi/uidata'
import type { Info, InfoExtra, KeyMapPrefix } from '@genshin-optimizer/gi/wr'
import { Typography } from '@mui/material'
import { useContext, type ReactNode } from 'react'
import { SillyContext } from '../context'
import { resolveInfo } from './resolveInfo'
Expand Down Expand Up @@ -220,11 +221,15 @@ function computeFormulaDisplay(

components.filter((c) => c)
result.formula = (
<>
<Typography
sx={{
textDecoration: info.strikethrough ? 'line-through' : undefined,
}}
>
{components.map((x, i) => (
<span key={i}>{x}</span>
))}
</>
</Typography>
)

return result
Expand Down
3 changes: 3 additions & 0 deletions libs/gi/uidata/src/uiData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
deepNodeClone,
input,
mergeData,
nonStacking,
resetData,
setReadNodeKeys,
tally,
Expand Down Expand Up @@ -537,6 +538,8 @@ export function uiDataForTeam(
const newNode = customRead(path)
if (path[0] === 'teamBuff' && path[1] === 'tally')
newNode.accu = objPathValue(tally, path.slice(2))?.accu
if (path[0] === 'teamBuff' && path[1] === 'nonStacking')
newNode.accu = objPathValue(nonStacking, path.slice(2))?.accu
layeredAssignment(customReadNodes, path, newNode)
return newNode
}
Expand Down
12 changes: 9 additions & 3 deletions libs/gi/wr/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
} from '@genshin-optimizer/gi/db'
import type { ICharacter } from '@genshin-optimizer/gi/good'
import { getMainStatValue } from '@genshin-optimizer/gi/util'
import { input, tally } from './formula'
import { input, nonStacking, tally } from './formula'
import type { Data, Info, NumNode, ReadNode, StrNode } from './type'
import { constant, data, infoMut, none, percent, prod, sum } from './utils'

Expand All @@ -41,7 +41,7 @@ export function inferInfoMut(data: Data, source?: Info['source']): Data {
| undefined
if (reference)
x.info = { ...x.info, ...reference.info, prefix: undefined, source }
else if (path[0] !== 'tally')
else if (path[0] !== 'tally' && path[0] !== 'nonStacking')
console.error(
`Detect ${source} buff into non-existant key path ${path}`
)
Expand Down Expand Up @@ -246,7 +246,13 @@ export function mergeData(data: Data[]): Data {
if (data.length <= 1) return data[0]
if (data[0].operation) {
if (path[0] === 'teamBuff') path = path.slice(1)
const base = path[0] === 'tally' ? ((path = path.slice(1)), tally) : input
const base =
path[0] === 'tally'
? tally
: path[0] === 'nonStacking'
? nonStacking
: input
if (path[0] === 'tally' || path[0] === 'nonStacking') path = path.slice(1)
/*eslint prefer-const: ["error", {"destructuring": "all"}]*/
let { accu, type } =
(objPathValue(base, path) as ReadNode<number | string> | undefined) ??
Expand Down
9 changes: 8 additions & 1 deletion libs/gi/wr/src/formula.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const asConst = true as const,

const allElements = allElementWithPhyKeys
const allTalents = ['auto', 'skill', 'burst'] as const
const allNonstackBuffs = ['no4'] as const
export type NonStackBuff = (typeof allNonstackBuffs)[number]
const allMoves = [
'normal',
'charged',
Expand Down Expand Up @@ -587,6 +589,11 @@ const tally = {
ele: sum(...allElements.map((ele) => min(_tally[ele], 1))),
}

const nonStacking = setReadNodeKeys(
objKeyMap(allNonstackBuffs, () => stringRead('small')),
['nonStacking']
)

/**
* List of `input` nodes, rearranged to conform to the needs of the
* UI code. This is a separate list so that the evolution of the UIs
Expand All @@ -604,4 +611,4 @@ export const infusionNode = stringPrio(
input.infusion.overridableSelf
)

export { common, customBonus, input, tally, target, uiInput }
export { common, customBonus, input, nonStacking, tally, target, uiInput }
8 changes: 6 additions & 2 deletions libs/gi/wr/src/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {
AmplifyingReactionsKey,
TransformativeReactionsKey,
} from '@genshin-optimizer/gi/keymap'
import type { input, uiInput } from './formula'
import type { input, NonStackBuff, uiInput } from './formula'

export type NumNode =
| ComputeNode
Expand Down Expand Up @@ -54,6 +54,7 @@ export type Info = {
fixed?: number
isTeamBuff?: boolean
multi?: number
strikethrough?: boolean
}
export type Variant =
| ElementWithPhyKey
Expand Down Expand Up @@ -179,7 +180,10 @@ interface DynamicNumInput<T = NumNode> {
[key: string]: DisplaySub
}
conditional?: NodeData<T>
teamBuff?: Input & { tally?: NodeData }
teamBuff?: Input & {
tally?: NodeData<NumNode>
nonStacking?: Record<NonStackBuff, StrNode>
}
}
export interface NodeData<T = NumNode> {
[key: string]: typeof key extends 'operation' ? never : NodeData<T> | T
Expand Down

0 comments on commit dd6dac4

Please sign in to comment.