From e2de237591fd8099f08290753f5bb1b62bf57d84 Mon Sep 17 00:00:00 2001 From: Alexander Drozdov Date: Mon, 26 Jul 2021 19:34:20 +0300 Subject: [PATCH] show unique rolls from advanced text --- src/parser/advanced-mod-desc.ts | 33 ++++++-- src/parser/modifiers.ts | 4 + .../filters/create-stat-filters.ts | 19 +---- src/web/price-check/filters/unique-roll.ts | 81 ++++++------------- 4 files changed, 54 insertions(+), 83 deletions(-) diff --git a/src/parser/advanced-mod-desc.ts b/src/parser/advanced-mod-desc.ts index a9cb9fe5..bee1999f 100644 --- a/src/parser/advanced-mod-desc.ts +++ b/src/parser/advanced-mod-desc.ts @@ -158,19 +158,34 @@ export function sumStatsFromMods (mods: readonly ParsedModifier[]): LegacyItemMo }, [] as Array<{ info: ModifierInfo, stat: ParsedStat }>) if (toMerge.length === 1) { + // TODO: for some stats reduced is better (m.negate === true) + const translation = (statA.roll && Math.sign(statA.roll.min) !== Math.sign(statA.roll.max)) + ? dbStatA.stat.matchers.find(m => m.value == null && !m.negate)! + : statA.translation + out.push({ stat: dbStatA.stat, trade: dbStatA.trade, - string: statA.translation.string, + string: translation.string, type: modA.info.type, - negate: statA.translation.negate, - value: statA.roll?.value + negate: translation.negate, + value: statA.roll?.value, + bounds: statA.roll && { min: statA.roll.min, max: statA.roll.max } }) } else { - const rollValue = toMerge.reduce((sum, { stat }) => sum + stat.roll!.value, 0) + const roll = toMerge.reduce((sum, { stat }) => { + sum.value += stat.roll!.value + sum.min += stat.roll!.min + sum.max += stat.roll!.max + return sum + }, { value: 0, min: 0, max: 0 }) + + const sameSign = (Math.sign(roll.min) === Math.sign(roll.max)) + + // TODO: for some stats reduced is better (m.negate === true) const translation = - (dbStatA.stat.matchers.find(m => m.value === rollValue)) ?? - ((statA.translation.value == null) + (dbStatA.stat.matchers.find(m => m.value === roll.value)) ?? + ((sameSign && statA.translation.value == null) ? statA.translation : dbStatA.stat.matchers.find(m => m.value == null && !m.negate)) ?? ({ string: `Report bug if you see this text (${statA.translation.string})` }) @@ -181,7 +196,11 @@ export function sumStatsFromMods (mods: readonly ParsedModifier[]): LegacyItemMo string: translation.string, type: modA.info.type, negate: translation.negate, - value: rollValue + value: roll.value, + bounds: { + min: roll.min, + max: roll.max + } }) } diff --git a/src/parser/modifiers.ts b/src/parser/modifiers.ts index d3a163ef..a2e8c393 100644 --- a/src/parser/modifiers.ts +++ b/src/parser/modifiers.ts @@ -14,6 +14,10 @@ export interface LegacyItemModifier extends Stat, Pick { value?: number + bounds?: { + min: number + max: number + } type: ModifierType } diff --git a/src/web/price-check/filters/create-stat-filters.ts b/src/web/price-check/filters/create-stat-filters.ts index fc60deac..47604373 100644 --- a/src/web/price-check/filters/create-stat-filters.ts +++ b/src/web/price-check/filters/create-stat-filters.ts @@ -133,24 +133,7 @@ function filterAdjustmentForNegate ( mod: ItemModifier, filter: Writeable ) { - let negateFilter = false - - if (filter.boundMin != null && filter.boundMax != null) { // unique - const sameSign = (Math.sign(filter.boundMin) === Math.sign(filter.boundMax)) - const isNegated = mod.negate - const positiveMatcher = mod.stat.matchers.find(matcher => !matcher.negate) - if (!sameSign && isNegated && positiveMatcher) { - filter.text = positiveMatcher.string - } else { - filter.text = mod.string - negateFilter = Boolean(mod.negate) - } - } else { - filter.text = mod.string - negateFilter = Boolean(mod.negate) - } - - if (negateFilter) { + if (mod.negate) { filter.invert = true const raw = { ...filter } diff --git a/src/web/price-check/filters/unique-roll.ts b/src/web/price-check/filters/unique-roll.ts index bf619861..7e341ba2 100644 --- a/src/web/price-check/filters/unique-roll.ts +++ b/src/web/price-check/filters/unique-roll.ts @@ -1,72 +1,37 @@ -import { /* UniqueItem, */ UNIQUES } from '@/assets/data' +// import { UniqueItem, UNIQUES } from '@/assets/data' import { ParsedItem } from '@/parser' import { ItemModifier } from '@/parser/modifiers' -// import { percentRollDelta } from './util' +import { percentRollDelta } from './util' import { StatFilter } from './interfaces' -import { percentRoll } from './util' -// import { Config } from '@/web/Config' - -// function isConstantMod (mod: UniqueItem['stats'][0]): boolean { -// return mod.bounds.every(b => b.min === b.max) -// } - -// function isWithinBounds (mod: ItemModifier, { bounds }: UniqueItem['stats'][0]): boolean { -// return mod.values!.every((value, idx) => ( -// bounds[idx] !== undefined && -// value >= bounds[idx].min && -// value <= bounds[idx].max -// )) -// } +import { Config } from '@/web/Config' export function uniqueModFilterPartial ( - item: ParsedItem, + _item: ParsedItem, mod: ItemModifier, filter: Writeable ): void { - const uniqueInfo = UNIQUES.get(`${item.name} ${item.baseType!}`) - if (!uniqueInfo) return fallbackToExact(mod, filter) + // const uniqueInfo = UNIQUES.get(`${item.name} ${item.baseType!}`) - const modInfo = uniqueInfo.stats.find(stat => - stat.text === mod.stat.ref && - stat.implicit === (mod.type === 'implicit' ? true : undefined) - ) - if (!modInfo) return fallbackToExact(mod, filter) + // TODO set this info again: filter.variant = modInfo.variant - filter.variant = modInfo.variant + if (!mod.bounds || (mod.bounds.min === mod.bounds.max)) { + // TODO: add exceptions to (!mod.bounds) for items like sythesized rings, watcher's eye, unqiues with variants, etc. - // trick: mod.values = modInfo.bounds - // if (!mod.values) { - // mod.values = modInfo.bounds.map(b => getRollAsSingleNumber([b.min, b.max])) - // } + filter.defaultMin = mod.value + filter.defaultMax = mod.value + filter.min = filter.defaultMin + filter.max = filter.defaultMax + filter.roll = mod.value + if (!filter.variant) { + filter.hidden = 'Roll is not variable' + } + } else { + filter.boundMin = mod.bounds.min + filter.boundMax = mod.bounds.max - // it may be catalysts or stale data after patch - /* if (!isWithinBounds(mod, modInfo)) */ return fallbackToExact(mod, filter) - - // if (isConstantMod(modInfo)) { - // filter.defaultMin = getRollAsSingleNumber(mod.values) - // filter.defaultMax = getRollAsSingleNumber(mod.values) - // filter.min = filter.defaultMin - // filter.max = filter.defaultMax - // filter.roll = getRollAsSingleNumber(mod.values) - // if (!filter.variant) { - // filter.hidden = 'Roll is not variable' - // } - // } else { - // filter.boundMin = getRollAsSingleNumber(modInfo.bounds.map(b => b.min)) - // filter.boundMax = getRollAsSingleNumber(modInfo.bounds.map(b => b.max)) - - // const roll = getRollAsSingleNumber(mod.values) - // filter.roll = roll - // const percent = Config.store.searchStatRange * 2 - // filter.defaultMin = Math.max(percentRollDelta(roll, (filter.boundMax - filter.boundMin), -percent, Math.floor), filter.boundMin) - // filter.defaultMax = Math.min(percentRollDelta(roll, (filter.boundMax - filter.boundMin), +percent, Math.ceil), filter.boundMax) - // } -} - -function fallbackToExact (mod: ItemModifier, filter: Writeable): void { - if (mod.value) { - filter.roll = percentRoll(mod.value, 0, Math.floor, mod.stat.dp) - filter.defaultMin = filter.roll - filter.defaultMax = filter.roll + filter.roll = mod.value! + const percent = Config.store.searchStatRange * 2 + filter.defaultMin = Math.max(percentRollDelta(mod.value!, (filter.boundMax - filter.boundMin), -percent, Math.floor), filter.boundMin) + filter.defaultMax = Math.min(percentRollDelta(mod.value!, (filter.boundMax - filter.boundMin), +percent, Math.ceil), filter.boundMax) } }