Skip to content

Commit

Permalink
ZO: Partial implementation of disc filters (#2643)
Browse files Browse the repository at this point in the history
* Partial implementation of disc filters

* Partial implementation of disc filters

* Filter implementation that actually works

* Partial implementation of disc filters

* Filter implementation that actually works

* Added excluded filter

* Added % to stats that contain _

* Resolve lint issues

* Added filter locations, but as a tentative, fixed some lint errors

* fix typecheck

* Location filter is working, changed the way we get sets

* Resolve issues with lines throwing an error on filter
  • Loading branch information
failchon authored Jan 31, 2025
1 parent 1a673dd commit 7627ec7
Show file tree
Hide file tree
Showing 41 changed files with 1,441 additions and 88 deletions.
15 changes: 11 additions & 4 deletions libs/common/database-ui/src/hooks/useDataEntryBase.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
'use client'
import type { DataEntryBase } from '@genshin-optimizer/common/database'
import type {
Database,
DataEntryBase,
} from '@genshin-optimizer/common/database'
import { useEffect, useState } from 'react'
export function useDataEntryBase<A extends string, B extends string, C, D>(
entry: DataEntryBase<A, B, C, D>
) {
export function useDataEntryBase<
A extends string,
B extends string,
C,
D,
E extends Database
>(entry: DataEntryBase<A, B, C, D, E>) {
const [data, setData] = useState(() => entry?.get())

useEffect(() => {
Expand Down
1 change: 1 addition & 0 deletions libs/zzz/db-ui/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './useCharacter'
export * from './useDisc'
export * from './useDiscDisplay'
6 changes: 6 additions & 0 deletions libs/zzz/db-ui/src/hooks/useDiscDisplay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useDataEntryBase } from '@genshin-optimizer/common/database-ui'
import { useDatabaseContext } from '../context'
export function useDisplayDisc() {
const { database } = useDatabaseContext()
return useDataEntryBase(database.displayDisc)
}
80 changes: 40 additions & 40 deletions libs/zzz/db/src/Database/DataEntries/DisplayDiscEntry.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { clamp, validateArr } from '@genshin-optimizer/common/util'

import type {
DiscMainStatKey,
DiscRarityKey,
DiscSetKey,
DiscSlotKey,
DiscSubStatKey,
LocationKey,
RelicMainStatKey,
RelicRarityKey,
RelicSetKey,
RelicSlotKey,
RelicSubStatKey,
} from '@genshin-optimizer/sr/consts'
} from '@genshin-optimizer/zzz/consts'
import {
allDiscRarityKeys,
allDiscSetKeys,
allDiscSlotKeys,
allDiscSubStatKeys,
allLocationKeys,
allRelicRarityKeys,
allRelicSetKeys,
allRelicSlotKeys,
allRelicSubStatKeys,
} from '@genshin-optimizer/sr/consts'

} from '@genshin-optimizer/zzz/consts'
import { DataEntry } from '../DataEntry'
import type { ZzzDatabase } from '../Database'

Expand All @@ -25,16 +25,16 @@ export const discSortKeys = [
'efficiency',
'mefficiency',
] as const
export type RelicSortKey = (typeof discSortKeys)[number]
export type DiscSortKey = (typeof discSortKeys)[number]

export type FilterOption = {
discSetKeys: RelicSetKey[]
rarity: RelicRarityKey[]
discSetKeys: DiscSetKey[]
rarity: DiscRarityKey[]
levelLow: number
levelHigh: number
slotKeys: RelicSlotKey[]
mainStatKeys: RelicMainStatKey[]
substats: RelicSubStatKey[]
slotKeys: DiscSlotKey[]
mainStatKeys: DiscMainStatKey[]
substats: DiscSubStatKey[]
locations: LocationKey[]
showEquipped: boolean
showInventory: boolean
Expand All @@ -45,54 +45,54 @@ export type FilterOption = {
lines: Array<1 | 2 | 3 | 4>
}

export type IDisplayRelic = {
export type IDisplayDisc = {
filterOption: FilterOption
ascending: boolean
sortType: RelicSortKey
effFilter: RelicSubStatKey[]
sortType: DiscSortKey
effFilter: DiscSubStatKey[]
}

export function initialFilterOption(): FilterOption {
return {
discSetKeys: [],
rarity: [...allRelicRarityKeys],
rarity: [...allDiscRarityKeys],
levelLow: 0,
levelHigh: 15,
slotKeys: [...allRelicSlotKeys],
slotKeys: [...allDiscSlotKeys],
mainStatKeys: [],
substats: [],
locations: [],
showEquipped: true,
showInventory: true,
locked: ['locked', 'unlocked'],
rvLow: 0,
rvHigh: 900, // TODO: Figure out RVs for SRO
rvHigh: 900, // TODO: Figure out RVs for ZZZ
useMaxRV: false,
lines: [1, 2, 3, 4],
}
}

function initialState(): IDisplayRelic {
function initialState(): IDisplayDisc {
return {
filterOption: initialFilterOption(),
ascending: false,
sortType: discSortKeys[0],
effFilter: [...allRelicSubStatKeys],
effFilter: [...allDiscSubStatKeys],
}
}

export class DisplayRelicEntry extends DataEntry<
export class DisplayDiscEntry extends DataEntry<
'display_disc',
'display_disc',
IDisplayRelic,
IDisplayRelic
IDisplayDisc,
IDisplayDisc
> {
constructor(database: ZzzDatabase) {
super(database, 'display_disc', initialState, 'display_disc')
}
override validate(obj: unknown): IDisplayRelic | undefined {
override validate(obj: unknown): IDisplayDisc | undefined {
if (typeof obj !== 'object') return undefined
let { filterOption, ascending, sortType, effFilter } = obj as IDisplayRelic
let { filterOption, ascending, sortType, effFilter } = obj as IDisplayDisc

if (typeof filterOption !== 'object') filterOption = initialFilterOption()
else {
Expand All @@ -113,24 +113,24 @@ export class DisplayRelicEntry extends DataEntry<
useMaxRV,
lines,
} = filterOption
discSetKeys = validateArr(discSetKeys, allRelicSetKeys, [])
rarity = validateArr(rarity, allRelicRarityKeys)
discSetKeys = validateArr(discSetKeys, allDiscSetKeys, [])
rarity = validateArr(rarity, allDiscRarityKeys)

if (typeof levelLow !== 'number') levelLow = 0
else levelLow = clamp(levelLow, 0, 15)
if (typeof levelHigh !== 'number') levelHigh = 0
else levelHigh = clamp(levelHigh, 0, 15)

slotKeys = validateArr(slotKeys, allRelicSlotKeys)
slotKeys = validateArr(slotKeys, allDiscSlotKeys)
mainStatKeys = validateArr(mainStatKeys, mainStatKeys, [])
substats = validateArr(substats, allRelicSubStatKeys, [])
substats = validateArr(substats, allDiscSubStatKeys, [])
locations = validateArr(locations, allLocationKeys, [])
if (typeof showEquipped !== 'boolean') showEquipped = true
if (typeof showInventory !== 'boolean') showInventory = true
locked = validateArr(locked, ['locked', 'unlocked'])

if (typeof rvLow !== 'number') rvLow = 0
if (typeof rvHigh !== 'number') rvHigh = 900 // TODO: Figure out RVs for SRO
if (typeof rvHigh !== 'number') rvHigh = 900 // TODO: Figure out RVs for ZZZ

if (typeof useMaxRV !== 'boolean') useMaxRV = false

Expand Down Expand Up @@ -158,19 +158,19 @@ export class DisplayRelicEntry extends DataEntry<
if (typeof ascending !== 'boolean') ascending = false
if (!discSortKeys.includes(sortType)) sortType = discSortKeys[0]

effFilter = validateArr(effFilter, allRelicSubStatKeys)
effFilter = validateArr(effFilter, allDiscSubStatKeys)

return {
filterOption,
ascending,
sortType,
effFilter,
} as IDisplayRelic
} as IDisplayDisc
}
override set(
value:
| Partial<IDisplayRelic>
| ((v: IDisplayRelic) => Partial<IDisplayRelic> | void)
| Partial<IDisplayDisc>
| ((v: IDisplayDisc) => Partial<IDisplayDisc> | void)
| { action: 'reset' }
): boolean {
if ('action' in value) {
Expand Down
11 changes: 7 additions & 4 deletions libs/zzz/db/src/Database/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { DBStorage } from '@genshin-optimizer/common/database'
import { Database, SandboxStorage } from '@genshin-optimizer/common/database'
import type { IZenlessObjectDescription, IZZZDatabase } from '../Interfaces'
import { zzzSource } from '../Interfaces'
import { DBMetaEntry, DisplayRelicEntry } from './DataEntries/'
import { DBMetaEntry, DisplayDiscEntry } from './DataEntries/'
import { DiscDataManager } from './DataManagers/'
import { CharacterDataManager } from './DataManagers/CharacterDataManager'
import type { ImportResult } from './exim'
Expand All @@ -12,7 +12,7 @@ export class ZzzDatabase extends Database {
discs: DiscDataManager
chars: CharacterDataManager
dbMeta: DBMetaEntry
displayRelic: DisplayRelicEntry
displayDisc: DisplayDiscEntry
dbIndex: 1 | 2 | 3 | 4
dbVer: number

Expand All @@ -33,18 +33,21 @@ export class ZzzDatabase extends Database {

// Handle DataEntries
this.dbMeta = new DBMetaEntry(this)
this.displayRelic = new DisplayRelicEntry(this)
this.displayDisc = new DisplayDiscEntry(this)

this.discs.followAny(() => {
this.dbMeta.set({ lastEdit: Date.now() })
})
this.displayDisc.follow(() => {
this.dbMeta.set({ lastEdit: Date.now() })
})
}
get dataManagers() {
// IMPORTANT: it must be chars, wengines, discs in order, to respect import order
return [this.discs, this.chars] as const
}
get dataEntries() {
return [this.dbMeta, this.displayRelic] as const
return [this.dbMeta, this.displayDisc] as const
}

clear() {
Expand Down
58 changes: 29 additions & 29 deletions libs/zzz/localization/assets/locales/en/disc.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"editor": {
"title": "Relic Editor",
"title": "Disc Editor",
"rarity": "Rarity",
"level": "Level",
"unknownPieceName": "Unknown Piece Name",
"unknownSetName": "Unknown Set Name",
"curSubEff": "Current Roll Value",
"curSubEffDesc": "Every 3 relic upgrades, you get a substat roll. <strong>Roll Value</strong> calculates how high the substat rolled as a percentage.",
"curSubEffDesc": "Every 3 disc upgrades, you get a substat roll. <strong>Roll Value</strong> calculates how high the substat rolled as a percentage.",
"maxSubEff": "Max. Roll Value",
"maxSubEffDesc": "The <strong>Maximum Substats Roll Value</strong> of a relic calculates the RV if the remaining upgrades rolled their maximum values.",
"maxSubEffDesc": "The <strong>Maximum Substats Roll Value</strong> of a disc calculates the RV if the remaining upgrades rolled their maximum values.",
"substat": {
"selectSub": "Select Value",
"error": {
Expand All @@ -24,22 +24,22 @@
"substatFormat": "Substat {{value}}",
"nextRolls": "Next rolls:"
},
"preview": "Relic Preview",
"dupeRelic": "Duplicate relic detected",
"updateRelic": "Upgraded relic detected",
"preview": "Disc Preview",
"dupeDisc": "Duplicate disc detected",
"updateDisc": "Upgraded disc detected",
"beforeEdit": "Before Edit",
"btnSave": "Save Relic",
"btnAdd": "Add Relic",
"btnSave": "Save Disc",
"btnAdd": "Add Disc",
"btnClear": "Clear",
"btnRandom": "Randomize",
"btnUpdate": "Update Relic",
"clearPrompt": "There is a relic being edited. Are you sure you want to clear the editor?",
"btnUpdate": "Update Disc",
"clearPrompt": "There is a disc being edited. Are you sure you want to clear the editor?",
"delete": "Delete",
"confirmDelete": "Are you sure you want to delete this relic?"
"confirmDelete": "Are you sure you want to delete this disc?"
},
"slot": "Slot",
"setEffectNum": "{{setNum}}-Set",
"relicFilter": "Relic Filter",
"discFilter": "Disc Filter",
"efficiencyFilter": {
"title": "Substats to use in Roll Value calculation"
},
Expand All @@ -49,41 +49,41 @@
"currentlyEquipped": "Currently Equipped"
},
"button": {
"unequipRelic": "Unequip Relic",
"unequipRelics": "Unequip Relics",
"deleteRelics": "Delete Relics",
"lockRelics": "Lock Relics",
"unlockRelics": "Unlock Relics"
"unequipDisc": "Unequip Disc",
"unequipDiscs": "Unequip Discs",
"deleteDiscs": "Delete Discs",
"lockDiscs": "Lock Discs",
"unlockDiscs": "Unlock Discs"
},
"buttonHint": "Note: the red buttons above only apply to <1>filtered relics</1>",
"buttonHint": "Note: the red buttons above only apply to <1>filtered discs</1>",
"sortMap": {
"level": "Level",
"efficiency": "Current Roll Value",
"mefficiency": "Maximum Roll Value"
},
"mainStat": "Main Stat",
"showingNum_one": "Showing <1>{{count}}</1> out of {{value}} Relic",
"showingNum_other": "Showing <1>{{count}}</1> out of {{value}} Relics",
"showingNum_one": "Showing <1>{{count}}</1> out of {{value}} Disc",
"showingNum_other": "Showing <1>{{count}}</1> out of {{value}} Discs",
"resetFilters": "Reset Filters",
"edit": "Edit Relic",
"edit": "Edit Disc",
"autocompleteLabels": {
"mainStats": "Main Stats",
"substats": "Sub-Stats",
"set": "Relic Set",
"sets": "Relic Sets"
"set": "Disc Set",
"sets": "Disc Sets"
},
"substat_one": "{{count}} substat",
"substat_other": "{{count}} substats",
"sub_one": "{{count}} sub",
"sub_other": "{{count}} subs",
"addNew": "Add New Disc",
"showDupes": "Show Duplicates",
"noDupAlert": "There are no duplicate relics in your inventory.",
"cantDeleteLock": "Cannot delete relic because it is locked",
"equippedRelics": "All Equipped Relics",
"unequippedRelics": "All Unequipped Relics",
"locationsTooltip": "Disable \"All Equipped Relics\" to filter by specific characters",
"noRelics": "Looks like you haven't added any relics yet. If you want, there are <1>automatic scanners</1> that can speed up the import process!",
"noDupAlert": "There are no duplicate discs in your inventory.",
"cantDeleteLock": "Cannot delete disc because it is locked",
"equippedDiscs": "All Equipped Discs",
"unequippedDiscs": "All Unequipped Discs",
"locationsTooltip": "Disable \"All Equipped Discs\" to filter by specific characters",
"noDiscs": "Looks like you haven't added any discs yet. If you want, there are <1>automatic scanners</1> that can speed up the import process!",
"subheadings": {
"general": "General",
"inventory": "Inventory",
Expand Down
20 changes: 20 additions & 0 deletions libs/zzz/localization/assets/locales/en/discNames_gen.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7627ec7

Please sign in to comment.