From 93f886fc02e11378faeb857a6d3e1aa0361442a3 Mon Sep 17 00:00:00 2001 From: David Cole <40234707+DavidArthurCole@users.noreply.github.com> Date: Fri, 19 Jul 2024 09:16:26 -0400 Subject: [PATCH] Fix issue with filter options --- main.go | 143 ++++++----------------------------- www/index.html | 110 ++++++++++++++++++++++----- www/templates/FullFilter.vue | 68 ++++++++++++++++- 3 files changed, 180 insertions(+), 141 deletions(-) diff --git a/main.go b/main.go index 2110a86..5766287 100644 --- a/main.go +++ b/main.go @@ -14,7 +14,6 @@ import ( "path/filepath" "regexp" "runtime" - "strconv" "strings" "sync" "time" @@ -58,7 +57,6 @@ var ( _latestMennoData = MennoData{} _possibleTargets = []PossibleTarget{} _possibleArtifacts = []PossibleArtifact{} - _topLevelMaps = map[string][]FilterValueOption{} ) const ( @@ -438,28 +436,6 @@ func initPossibleArtifacts() { _possibleArtifacts = possibleArtifacts } -func artifactDisplayText(drop PossibleArtifact) string { - displayName := drop.DisplayName - lDisplayName := strings.ToLower(displayName) - level := drop.Level - levelInc := int32(1) - if strings.Contains(lDisplayName, "stone") && !strings.Contains(lDisplayName, "fragment") { - levelInc = 2 - } - return displayName + " (T" + strconv.FormatInt(int64(level+levelInc), 10) + ")" -} - -func dropPath(drop PossibleArtifact) string { - addendum := int32(0) - if strings.Contains(drop.ProtoName, "_STONE") { - addendum = 1 - } - fixedName := strings.ReplaceAll(drop.ProtoName, "_FRAGMENT", "") - fixedName = strings.ReplaceAll(fixedName, "ORNATE_GUSSET", "GUSSET") - fixedName = strings.ReplaceAll(fixedName, "VIAL_MARTIAN_DUST", "VIAL_OF_MARTIAN_DUST") - return "artifacts/" + fixedName + "/" + fixedName + "_" + strconv.FormatInt(int64(drop.Level+1+addendum), 10) + ".png" -} - func main() { if _devMode { log.Info("starting app in dev mode") @@ -631,106 +607,33 @@ func main() { _storage.SetFilterWarningRead(flag) }) - ui.MustBind("getFilterValueOptions", func(topLevel string) []FilterValueOption { + ui.MustBind("getMaxQuality", func() float32 { + maxQuality := float32(0) + for _, mission := range _eiAfxConfigMissions { + for _, duration := range mission.GetDurations() { + compedMaxQuality := float32(duration.GetMaxQuality()) + (duration.GetLevelQualityBump() * float32(len(mission.LevelMissionRequirements))) + if compedMaxQuality > maxQuality { + maxQuality = compedMaxQuality + } + } + } + return maxQuality + }) - if _topLevelMaps[topLevel] != nil { - return _topLevelMaps[topLevel] + ui.MustBind("getAfxConfigs", func() []PossibleArtifact { + if len(_possibleArtifacts) == 0 { + initPossibleArtifacts() } - options := []FilterValueOption{} - switch strings.ToLower(topLevel) { - case "ship": - { - shipNames := []string{ - "Chicken One", "Chicken Nine", "Chicken Heavy", - "BCR", "Quintillion Chicken", "Cornish-Hen Corvette", - "Galeggtica", "Defihent", "Voyegger", "Henerprise", "Atreggies Henliner", - } - for index := 0; index < len(shipNames); index++ { - options = append(options, FilterValueOption{ - Text: shipNames[index], - Value: strconv.FormatInt(int64(index), 10), - }) - } - } - case "duration": - { - durationNames := []string{ - "Short", "Standard", "Extended", "Tutorial", - } - for index := 0; index < len(durationNames); index++ { - options = append(options, FilterValueOption{ - Text: durationNames[index], - StyleClass: "text-duration-" + strconv.FormatInt(int64(index), 10), - Value: strconv.FormatInt(int64(index), 10), - }) - } - } - case "level": - { - for index := 0; index < 10; index++ { - options = append(options, FilterValueOption{ - Text: strconv.FormatInt(int64(index), 10) + "★", - Value: strconv.FormatInt(int64(index), 10), - }) - } - } - case "target": - { - for _, target := range _possibleTargets { - options = append(options, FilterValueOption{ - Text: target.DisplayName, - Value: strconv.FormatInt(int64(target.Id), 10), - ImagePath: target.ImageString, - }) - } - } - case "drops": - { - options = append(options, FilterValueOption{ - Text: "Any Legendary", - Value: "%_%_3_%", - Rarity: 3, - ImagePath: "icon_help.webp", - }) - options = append(options, FilterValueOption{ - Text: "Any Epic", - Value: "%_%_2_%", - Rarity: 2, - ImagePath: "icon_help.webp", - }) - options = append(options, FilterValueOption{ - Text: "Any Rare", - Value: "%_%_1_%", - Rarity: 1, - ImagePath: "icon_help.webp", - }) - for _, drop := range _possibleArtifacts { - options = append(options, FilterValueOption{ - Text: artifactDisplayText(drop), - Value: strconv.FormatInt(int64(drop.Name), 10) + "_" + strconv.FormatInt(int64(drop.Level), 10) + "_" + strconv.FormatInt(int64(drop.Rarity), 10) + "_" + strconv.FormatFloat(drop.BaseQuality, 'f', -1, 64), - Rarity: drop.Rarity, - ImagePath: dropPath(drop), - }) - } - } - case "dubcap": - fallthrough - case "buggedcap": - { - options = append(options, FilterValueOption{ - Text: "True", - Value: "true", - }) - options = append(options, FilterValueOption{ - Text: "False", - Value: "false", - }) - } - default: + return _possibleArtifacts + }) + + ui.MustBind("getPossibleTargets", func() []PossibleTarget { + if len(_possibleTargets) == 0 { + initPossibleArtifacts() } - _topLevelMaps[topLevel] = options - return options + + return _possibleTargets }) w := &worker{ diff --git a/www/index.html b/www/index.html index cd2b70f..ef26b2e 100644 --- a/www/index.html +++ b/www/index.html @@ -659,7 +659,7 @@

Known issues

@handle-filter-change="handleFilterChange" @handle-or-filter-change="handleOrFilterChange" @remove-and-shift="removeAndShift" @remove-or-and-shift="removeOrAndShift" @open-target-filter-menu="openTargetFilterMenu" @open-drop-filter-menu="openDropFilterMenu" - @add-or="addOr" @change-filter-value="changeFilterValue" + @add-or="addOr" @change-filter-value="changeFilterValue" > @@ -958,7 +958,7 @@

Known issues

@handle-filter-change="handleFilterChange" @handle-or-filter-change="handleOrFilterChange" @remove-and-shift="removeAndShift" @remove-or-and-shift="removeOrAndShift" @open-target-filter-menu="openTargetFilterMenu" @open-drop-filter-menu="openDropFilterMenu" - @add-or="addOr" @change-filter-value="changeFilterValue" + @add-or="addOr" @change-filter-value="changeFilterValue" > @@ -1017,7 +1017,7 @@

Known issues

:lifetime-show-per-ship="lifetimeShowDropsPerShip" :data="lifetimeData" :show-expected-drops="lifetimeShowExpectedTotals" > -
+

Lifetime data is being compiled, please wait... @@ -1275,9 +1275,9 @@

Known issues

const targetFilterSelectedIndex = Vue.ref(null); const targetFilterSelectedOrIndex = Vue.ref(null); const targetFilterMenuOpen = Vue.ref(false); - const openTargetFilterMenu = async (index, orIndex) => { + const openTargetFilterMenu = (index, orIndex) => { window.removeEventListener('focus', handleFocus, true); - tSelectListRef().value = await window.getFilterValueOptions('target'); + tSelectListRef().value = getFilterValueOptions('target'); tSelectedIndexRef().value = index; tSelectedOrIndexRef().value = orIndex ?? null; tFilterMenuOpenRef().value = true; @@ -1297,8 +1297,8 @@

Known issues

el.classList.add('hidden'); }; const targetSearchTerm = Vue.ref(""); - Vue.watch(targetSearchTerm, async () => { - targetSelectList.value = (await window.getFilterValueOptions('target')).filter(target => target.text.toLowerCase().includes(targetSearchTerm.value.toLowerCase())); + Vue.watch(targetSearchTerm, () => { + targetSelectList.value = getFilterValueOptions('target').filter(target => target.text.toLowerCase().includes(targetSearchTerm.value.toLowerCase())); }); const selectTargetFilter = (target) => { const newValue = target.value.toString().split('.')[0]; @@ -1322,9 +1322,9 @@

Known issues

const dropFilterSelectedIndex = Vue.ref(null); const dropFilterSelectedOrIndex = Vue.ref(null); const dropFilterMenuOpen = Vue.ref(false); - const openDropFilterMenu = async (index, orIndex) => { + const openDropFilterMenu = (index, orIndex) => { window.removeEventListener('focus', handleFocus, true); - dropSelectList.value = await window.getFilterValueOptions('drops'); + dropSelectList.value = getFilterValueOptions('drops'); dropFilterSelectedIndex.value = index; dropFilterSelectedOrIndex.value = orIndex ?? null; dropFilterMenuOpen.value = true; @@ -1346,8 +1346,8 @@

Known issues

el.classList.add('hidden'); }; const dropSearchTerm = Vue.ref(""); - Vue.watch(dropSearchTerm, async () => { - dropSelectList.value = (await window.getFilterValueOptions('drops')).filter(drop => drop.text.toLowerCase().includes(dropSearchTerm.value.toLowerCase())); + Vue.watch(dropSearchTerm, () => { + dropSelectList.value = getFilterValueOptions('drops').filter(drop => drop.text.toLowerCase().includes(dropSearchTerm.value.toLowerCase())); }); const selectDropFilter = (drop) => { const newValue = drop.value.toString().split('.')[0]; @@ -1487,7 +1487,7 @@

Known issues

const lifetimeTargetFilterMenuOpen = Vue.ref(false); const lifetimeTargetSearchTerm = Vue.ref(""); Vue.watch(lifetimeTargetSearchTerm, async () => { - lifetimeTargetSelectList.value = (await window.getFilterValueOptions('target')).filter(target => target.text.toLowerCase().includes(lifetimeTargetSearchTerm.value.toLowerCase())); + lifetimeTargetSelectList.value = getFilterValueOptions('target').filter(target => target.text.toLowerCase().includes(lifetimeTargetSearchTerm.value.toLowerCase())); }); const lifetimeSortMethod = Vue.ref('default'); @@ -2130,6 +2130,9 @@

Known issues

filterHasChanged.value = true; }); + const possibleTargets = Vue.ref(null); + const maxQuality = Vue.ref(""); + const artifactConfigs = Vue.ref(null); const durationConfigs = Vue.ref(null); const mennoDataAutoRefresh = Vue.ref(false); const mennoProgress = Vue.ref(""); @@ -2263,7 +2266,7 @@

Known issues

orDataFilterRef().value = newOrDataFilter; }; - const handleFilterChange = async (event) => { + const handleFilterChange = (event) => { const targetEl = event.target ?? document.getElementById(event); const targetId = targetEl.id; if(targetEl.oldValue == null || targetEl.type == 'date') { @@ -2273,15 +2276,15 @@

Known issues

updateValueStyling(targetEl, false); if(targetId.indexOf(filterTopSelector.value) > -1) { const index = parseInt(targetId.split("-").pop()); - if((await window.getFilterValueOptions(targetEl.value)).indexOf(opRef().value[index]) == -1) opRef().value[index] = null; - if((await window.getFilterValueOptions(targetEl.value)).indexOf(valRef().value[index]) == -1) { + if(getFilterValueOptions(targetEl.value).indexOf(opRef().value[index]) == -1) opRef().value[index] = null; + if(getFilterValueOptions(targetEl.value).indexOf(valRef().value[index]) == -1) { valRef().value[index] = null; dValRef().value[index] = null; } } }; - const handleOrFilterChange = async (event) => { + const handleOrFilterChange = (event) => { const targetEl = event.target ?? document.getElementById(event); const targetId = targetEl.id; const index = parseInt(targetId.split("-")[isLifetime.value ? 3 : 2]); @@ -2289,8 +2292,8 @@

Known issues

updateFilterNoReCount(); updateValueStyling(targetEl, true); if(targetId.indexOf(filterTopSelector.value) > -1) { - if((await window.getFilterValueOptions(targetEl.value)).indexOf(ofOpRef().value[index][orIndex]) == -1) ofOpRef().value[index][orIndex] = null; - if((await window.getFilterValueOptions(targetEl.value)).indexOf(ofValRef().value[index][orIndex]) == -1) { + if(getFilterValueOptions(targetEl.value).indexOf(ofOpRef().value[index][orIndex]) == -1) ofOpRef().value[index][orIndex] = null; + if(getFilterValueOptions(targetEl.value).indexOf(ofValRef().value[index][orIndex]) == -1) { ofValRef().value[index][orIndex] = null; ofDValRef().value[index][orIndex] = null; } @@ -2399,6 +2402,71 @@

Known issues

return currentState; } + function artifactDisplayText(artifact){ + const displayName = artifact.displayName; + const level = artifact.level; + var displayText = displayName; + if(level != '%') displayText += " (T" + (level + ((displayName.toLowerCase().indexOf('stone') > -1 && displayName.toLowerCase().indexOf('fragment') == -1) ? 2 : 1)) + ")"; + return displayText; + } + const dropPath = (drop) => { + const addendum = (drop.protoName.indexOf('_STONE') > -1 ? 1 : 0); + const fixedName = drop.protoName.replaceAll("_FRAGMENT", "").replaceAll("ORNATE_GUSSET", "GUSSET").replaceAll("VIAL_MARTIAN_DUST", "VIAL_OF_MARTIAN_DUST"); + return "artifacts/" + fixedName + "/" + fixedName + "_" + (drop.level + 1 + addendum) + ".png"; + }; + const dropRarityPath = (drop) => { + switch(drop.rarity){ + case 0: return ""; + case 1: return "images/rare.gif"; + case 2: return "images/epic.gif"; + case 3: return "images/legendary.gif"; + default: return ""; + } + } + + const getFilterValueOptions = (topLevel) => { + switch(topLevel){ + case 'ship': return Array.from({ length: 11 }, (_, index) => ({ + text: Array.of( + 'Chicken One', 'Chicken Nine', 'Chicken Heavy', + 'BCR', 'Quintillion Chicken', 'Cornish-Hen Corvette', + 'Galeggtica', 'Defihent', 'Voyegger', 'Henerprise', 'Atreggies Henliner' + )[index], + value: index, + })); + case 'duration': return Array.from({ length: 4 }, (_, index) => ({ + text: Array.of('Short', 'Standard', 'Extended', 'Tutorial')[index], + value: index, + styleClass: 'text-duration-' + index + })); + case 'level': return Array.from({ length: 9 }, (_, index) => ({ + text: index + '★', + value: index + })); + case 'target': return possibleTargets.value.map(target => ({ + text: target.displayName, + value: target.id, + imagePath: target.imageString + })); + case 'drops': { + const filteredConfigs = artifactConfigs.value.filter(a => a.baseQuality <= maxQuality.value).map(artifact => ({ + text: artifactDisplayText(artifact), + value: artifact.name + "_" + artifact.level + "_" + artifact.rarity + "_" + artifact.baseQuality, + rarity: artifact.rarity, + imagePath: dropPath(artifact), + rarityGif: dropRarityPath(artifact), + })) + filteredConfigs.unshift({text: 'Any Legendary', value: '%_%_3_%', rarity: 3, styleClass: 'text-legendary', imagePath: 'icon_help.webp'}); + filteredConfigs.unshift({text: 'Any Epic', value: '%_%_2_%', rarity: 2, styleClass: 'text-epic', imagePath: 'icon_help.webp'}); + filteredConfigs.unshift({text: 'Any Rare', value: '%_%_1_%', rarity: 1, styleClass: 'text-rare', imagePath: 'icon_help.webp'}); + return filteredConfigs; + } + case 'buggedcap': + case 'dubcap': return [{ text: 'True', value: 'true' },{ text: 'False', value: 'false' }]; + default: return []; + } + } + const testMissionAgainstFilter = async(mission, filter) => { var filterPassed = true; if(filter.topLevel != null && filter.op != null && filter.val != null){ @@ -2715,7 +2783,10 @@

Known issues

startInFullscreen.value = await window.getStartInFullscreen(); //Load configs + artifactConfigs.value = await window.getAfxConfigs(); + maxQuality.value = await window.getMaxQuality(); durationConfigs.value = await window.getDurationConfigs(); + possibleTargets.value = await window.getPossibleTargets(); //Load Menno data if (await window.isMennoRefreshNeeded()) { @@ -2727,7 +2798,7 @@

Known issues

secondsSinceLastMennoUpdate.value = await window.secondsSinceLastMennoUpdate(); //Cache the filter value options ahead of time - ['ship', 'duration', 'level', 'target', 'drops'].forEach(async (i) => _ = await window.window.getFilterValueOptions(i)); + ['ship', 'duration', 'level', 'target', 'drops'].forEach((i) => _ = getFilterValueOptions(i)); }); const isLifetime = Vue.computed(() => activeTab.value == UITab.LifetimeData); @@ -2975,6 +3046,7 @@

Known issues

generateFilterConditionsArr, changeFilterValue, filterModVals, + getFilterValueOptions, //Self-update appReleaseNotes, diff --git a/www/templates/FullFilter.vue b/www/templates/FullFilter.vue index 986d5f0..58e85d7 100644 --- a/www/templates/FullFilter.vue +++ b/www/templates/FullFilter.vue @@ -16,7 +16,7 @@ @handle-filter-change="handleFilterChange"> @@ -69,7 +69,7 @@ @@ -129,8 +129,72 @@ filterArray: Array, modVals: Object, isLifetime: Boolean, + getFilterValueOptions: Function }, methods: { + artifactDisplayText(artifact) { + const displayName = artifact.displayName; + const level = artifact.level; + let displayText = displayName; + if(level != '%') displayText += " (T" + (level + ((displayName.toLowerCase().indexOf('stone') > -1 && displayName.toLowerCase().indexOf('fragment') == -1) ? 2 : 1)) + ")"; + return displayText; + }, + dropPath(drop) { + const addendum = (drop.protoName.indexOf('_STONE') > -1 ? 1 : 0); + const fixedName = drop.protoName.replaceAll("_FRAGMENT", "").replaceAll("ORNATE_GUSSET", "GUSSET").replaceAll("VIAL_MARTIAN_DUST", "VIAL_OF_MARTIAN_DUST"); + return "artifacts/" + fixedName + "/" + fixedName + "_" + (drop.level + 1 + addendum) + ".png"; + }, + dropRarityPath(drop) { + switch(drop.rarity){ + case 0: return ""; + case 1: return "images/rare.gif"; + case 2: return "images/epic.gif"; + case 3: return "images/legendary.gif"; + default: return ""; + } + }, + getFilterValueOptions(topLevel) { + switch(topLevel){ + case 'ship': return Array.from({ length: 11 }, (_, index) => ({ + text: Array.of( + 'Chicken One', 'Chicken Nine', 'Chicken Heavy', + 'BCR', 'Quintillion Chicken', 'Cornish-Hen Corvette', + 'Galeggtica', 'Defihent', 'Voyegger', 'Henerprise', 'Atreggies Henliner' + )[index], + value: index, + })); + case 'duration': return Array.from({ length: 4 }, (_, index) => ({ + text: Array.of('Short', 'Standard', 'Extended', 'Tutorial')[index], + value: index, + styleClass: 'text-duration-' + index + })); + case 'level': return Array.from({ length: 9 }, (_, index) => ({ + text: index + '★', + value: index + })); + case 'target': return possibleTargets.value.map(target => ({ + text: target.displayName, + value: target.id, + imagePath: target.imageString + })); + case 'drops': { + const filteredConfigs = artifactConfigs.value.filter(a => a.baseQuality <= maxQuality.value).map(artifact => ({ + text: this.artifactDisplayText(artifact), + value: artifact.name + "_" + artifact.level + "_" + artifact.rarity + "_" + artifact.baseQuality, + rarity: artifact.rarity, + imagePath: this.dropPath(artifact), + rarityGif: this.dropRarityPath(artifact), + })) + filteredConfigs.unshift({text: 'Any Legendary', value: '%_%_3_%', rarity: 3, styleClass: 'text-legendary', imagePath: 'icon_help.webp'}); + filteredConfigs.unshift({text: 'Any Epic', value: '%_%_2_%', rarity: 2, styleClass: 'text-epic', imagePath: 'icon_help.webp'}); + filteredConfigs.unshift({text: 'Any Rare', value: '%_%_1_%', rarity: 1, styleClass: 'text-rare', imagePath: 'icon_help.webp'}); + return filteredConfigs; + } + case 'buggedcap': + case 'dubcap': return [{ text: 'True', value: 'true' },{ text: 'False', value: 'false' }]; + default: return []; + } + }, removeAndShift(index) { this.$emit('removeAndShift', index); },