Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
14 changes: 8 additions & 6 deletions libs/zzz/dm/src/dm/character/character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,15 @@ export const charactersDetailedJSONData = Object.fromEntries(
coreStats: Object.values(raw.ExtraLevel).map(
({ Extra }) =>
Object.fromEntries(
Object.values(Extra).map(({ Name, Value }) => [
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably time to expand this to a proper block of code with variable names and if statements

coreStatMap[Name],
isPercentStat(coreStatMap[Name])
Object.values(Extra).map(({ Name, Value, Format }) => [
`${coreStatMap[Name]}${Format.includes('%') && !isPercentStat(coreStatMap[Name]) ? '_' : ''}`,
Format.includes('%') && !isPercentStat(coreStatMap[Name])
? Value / PERCENT_SCALING
: coreStatMap[Name] === 'enerRegen'
? Value / FLAT_SCALING
: Value,
: isPercentStat(coreStatMap[Name])
? Value / PERCENT_SCALING
: coreStatMap[Name] === 'enerRegen'
? Value / FLAT_SCALING
: Value,
])
Comment on lines +235 to 244
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Somnia: Guard unknown core stat names; compute finalKey once.

Current code may crash if Extra.Name isn’t in coreStatMap (isPercentStat(undefined)). Also duplicates percent logic.

-              Object.values(Extra).map(({ Name, Value, Format }) => [
-                `${coreStatMap[Name]}${Format.includes('%') && !isPercentStat(coreStatMap[Name]) ? '_' : ''}`,
-                Format.includes('%') && !isPercentStat(coreStatMap[Name])
-                  ? Value / PERCENT_SCALING
-                  : isPercentStat(coreStatMap[Name])
-                    ? Value / PERCENT_SCALING
-                    : coreStatMap[Name] === 'enerRegen'
-                      ? Value / FLAT_SCALING
-                      : Value,
-              ])
+              Object.values(Extra)
+                .map(({ Name, Value, Format }) => {
+                  const baseKey = coreStatMap[Name]
+                  if (!baseKey) return null
+                  const percentFmt = Format.includes('%')
+                  const finalKey =
+                    percentFmt && !isPercentStat(baseKey) ? (baseKey + '_') : baseKey
+                  const finalVal =
+                    percentFmt || isPercentStat(baseKey)
+                      ? Value / PERCENT_SCALING
+                      : baseKey === 'enerRegen'
+                        ? Value / FLAT_SCALING
+                        : Value
+                  return [finalKey, finalVal]
+                })
+                .filter((e): e is [string, number] => !!e)
🤖 Prompt for AI Agents
In libs/zzz/dm/src/dm/character/character.ts around lines 235 to 244, guard
against Extra.Name entries that are not keys in coreStatMap and avoid
recomputing percent checks: first resolve const coreKey = coreStatMap[Name]; if
coreKey is undefined, skip/return null for this map entry (or filter later) to
prevent calling isPercentStat(undefined); compute the finalKey once, e.g. const
finalKey = `${coreKey}${Format.includes('%') && !isPercentStat(coreKey) ? '_' :
''}`; then compute the value with a single set of conditionals (use a single
isPercent = Format.includes('%') || isPercentStat(coreKey) and apply
PERCENT_SCALING or FLAT_SCALING as appropriate) so percent logic isn’t
duplicated; ensure to filter out any null results before turning the array into
an object.

) as Partial<
Record<(typeof coreStatMap)[keyof typeof coreStatMap], number>
Expand Down
137 changes: 122 additions & 15 deletions libs/zzz/formula-ui/src/char/sheets/Lucia.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,132 @@
import type { CharacterKey } from '@genshin-optimizer/zzz/consts'
import { Lucia } from '@genshin-optimizer/zzz/formula'
import { trans } from '../../util'
import { createBaseSheet } from '../sheetUtil'
import { st, trans } from '../../util'
import { createBaseSheet, fieldForBuff } from '../sheetUtil'

const key: CharacterKey = 'Lucia'
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [, ch] = trans('char', key)
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const cond = Lucia.conditionals
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const buff = Lucia.buffs
const formula = Lucia.formulas

const sheet = createBaseSheet(key)
const sheet = createBaseSheet(key, {
perSkillAbility: {
special: {
EXSpecialAttackSymphonyOfTheReaperDaybreak: [
{
type: 'conditional',
conditional: {
label: ch('exSpecialCond'),
metadata: cond.darkbreaker,
fields: [fieldForBuff(buff.exSpecial_sheerForce)],
},
},
{
type: 'fields',
fields: [
{
title: ch('harmony.flat_dmg'),
fieldRef: buff.exSpecial_harmony_dmg_.tag,
},
],
},
],
},
chain: {
UltimateChargeGreatArmor: [
{
type: 'fields',
fields: [
{
title: st('heal'),
fieldRef: formula.ult_heal.tag,
},
],
},
],
},
},
core: [
{
type: 'conditional',
conditional: {
label: ch('coreCond.etherVeil'),
metadata: cond.etherVeil,
fields: [fieldForBuff(buff.core_hp_)],
},
},
{
type: 'conditional',
conditional: {
label: ch('coreCond.dreamersNurseryRhyme'),
metadata: cond.dreamersNurseryRhyme,
fields: [fieldForBuff(buff.core_common_dmg_)],
},
},
],
ability: [
{
type: 'conditional',
conditional: {
label: ch('exSpecialCond'),
metadata: cond.darkbreaker,
fields: [fieldForBuff(buff.ability_crit_dmg_)],
},
},
],
m1: [
{
type: 'conditional',
conditional: {
label: ch('coreCond.dreamersNurseryRhyme'),
metadata: cond.dreamersNurseryRhyme,
fields: [fieldForBuff(buff.m1_resIgn_)],
},
},
],
m2: [
{
type: 'conditional',
conditional: {
label: ch('coreCond.etherVeil'),
metadata: cond.etherVeil,
fields: [
{
title: ch('harmony.dmg_'),
fieldRef: buff.m2_harmony_dmg_.tag,
},
],
},
},
{
type: 'conditional',
conditional: {
label: ch('exSpecialCond'),
metadata: cond.darkbreaker,
fields: [fieldForBuff(buff.m2_sheer_dmg_)],
},
},
],
m6: [
{
type: 'conditional',
conditional: {
label: ch('coreCond.etherVeil'),
metadata: cond.etherVeil,
fields: [
fieldForBuff(buff.m6_atk_),
{
title: ch('harmony.crit_'),
fieldRef: buff.m6_harmony_crit_.tag,
},
{
title: ch('harmony.crit_dmg_'),
fieldRef: buff.m6_harmony_crit_dmg_.tag,
},
],
},
},
],
})

export default sheet
86 changes: 71 additions & 15 deletions libs/zzz/formula-ui/src/char/sheets/Manato.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,81 @@
import type { CharacterKey } from '@genshin-optimizer/zzz/consts'
import { Manato } from '@genshin-optimizer/zzz/formula'
import { trans } from '../../util'
import { createBaseSheet } from '../sheetUtil'
import { st, trans } from '../../util'
import { createBaseSheet, fieldForBuff } from '../sheetUtil'

const key: CharacterKey = 'Manato'
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [, ch] = trans('char', key)
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const cond = Manato.conditionals
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const buff = Manato.buffs

const sheet = createBaseSheet(key)
const sheet = createBaseSheet(key, {
core: [
{
type: 'fields',
fields: [fieldForBuff(buff.core_hpSheerForce)],
},
{
type: 'conditional',
conditional: {
label: ch('coreCond.consumingHp'),
metadata: cond.consumingHp_consecutiveStrikes,
fields: [
fieldForBuff(buff.core_basic_crit_dmg_),
fieldForBuff(buff.core_assistFollowUp_crit_dmg_),
],
},
},
{
type: 'conditional',
conditional: {
label: ch('coreCond.moltenEdge'),
metadata: cond.moltenEdge,
fields: [
fieldForBuff(buff.core_crit_),
fieldForBuff(buff.core_fire_dmg_),
],
},
},
],
m1: [
{
type: 'conditional',
conditional: {
label: ch('m1Cond'),
metadata: cond.hpTallied,
fields: [
fieldForBuff(buff.m1_assistFollowUp_fire_dmg_),
fieldForBuff(buff.m1_basic_fire_dmg_),
],
},
},
],
m2: [
{
type: 'conditional',
conditional: {
label: ch('coreCond.moltenEdge'),
metadata: cond.moltenEdge,
fields: [fieldForBuff(buff.m2_fire_resIgn_)],
},
},
],
m4: [
{
type: 'fields',
fields: [fieldForBuff(buff.m4_hp_)],
},
],
m6: [
{
type: 'conditional',
conditional: {
label: st('uponHit.1', { val1: '$t(skills.assistFollowUp)' }),
metadata: cond.assistFollowUpHitsEnemy,
fields: [fieldForBuff(buff.m6_fire_dmg_)],
},
},
],
})

export default sheet
102 changes: 87 additions & 15 deletions libs/zzz/formula-ui/src/char/sheets/Yidhari.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,97 @@
import type { CharacterKey } from '@genshin-optimizer/zzz/consts'
import { Yidhari } from '@genshin-optimizer/zzz/formula'
import { trans } from '../../util'
import { createBaseSheet } from '../sheetUtil'
import { st, trans } from '../../util'
import { createBaseSheet, fieldForBuff } from '../sheetUtil'

const key: CharacterKey = 'Yidhari'
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [, ch] = trans('char', key)
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const cond = Yidhari.conditionals
// TODO: Cleanup
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const buff = Yidhari.buffs
const formula = Yidhari.formulas

const sheet = createBaseSheet(key)
const sheet = createBaseSheet(key, {
perSkillAbility: {
chain: {
EtherVeilWellspring: [
{
type: 'conditional',
conditional: {
label: ch('etherVeilCond'),
metadata: cond.etherVeil,
fields: [fieldForBuff(buff.etherVeil_hp_)],
},
},
],
},
},
core: [
{
type: 'fields',
fields: [fieldForBuff(buff.core_hpSheerForce)],
},
{
type: 'conditional',
conditional: {
label: ch('coreCond'),
metadata: cond.missingHp,
fields: [fieldForBuff(buff.core_common_dmg_)],
},
},
],
ability: [
{
type: 'conditional',
conditional: {
label: ch('coreCond'),
metadata: cond.missingHp,
fields: [fieldForBuff(buff.ability_crit_dmg_)],
},
},
],
m1: [
{
type: 'fields',
fields: [
fieldForBuff(buff.m1_basic_ice_resIgn_),
fieldForBuff(buff.m1_exSpecial_ice_resIgn_),
],
},
],
m2: [
{
type: 'fields',
fields: [fieldForBuff(buff.m2_crit_dmg_)],
},
],
m4: [
{
type: 'conditional',
conditional: {
label: ch('etherVeilCond'),
metadata: cond.etherVeil,
fields: [fieldForBuff(buff.m4_hp_)],
},
},
],
m6: [
{
type: 'conditional',
conditional: {
label: ch('eruditionCond'),
metadata: cond.erudition,
fields: [fieldForBuff(buff.m6_sheer_dmg_)],
},
},
{
type: 'fields',
fields: [
{
title: st('heal'),
fieldRef: formula.m6_heal.tag,
},
],
},
],
})

export default sheet
6 changes: 3 additions & 3 deletions libs/zzz/formula-ui/src/wengine/sheets/DreamlitHearth.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { UISheetElement } from '@genshin-optimizer/game-opt/sheet-ui'
import { wengineAsset } from '@genshin-optimizer/zzz/assets'
import type { WengineKey } from '@genshin-optimizer/zzz/consts'
import { buffs, conditionals } from '@genshin-optimizer/zzz/formula'
import { DreamlitHearth } from '@genshin-optimizer/zzz/formula'
import { tagToTagField, trans } from '../../util'
import { PhaseWrapper } from '../components'

const key: WengineKey = 'DreamlitHearth'
const [chg, ch] = trans('wengine', key)
const icon = wengineAsset(key, 'icon')
const cond = conditionals[key]
const buff = buffs[key]
const cond = DreamlitHearth.conditionals
const buff = DreamlitHearth.buffs

const sheet: UISheetElement = {
title: chg('phase'),
Expand Down
Loading