remove most references to charms, and remove it from frontend

This commit is contained in:
TimHasert 2023-08-20 23:24:17 +02:00
parent 093fdb10ce
commit e9c47f55ce
7 changed files with 16 additions and 510 deletions

View File

@ -45,7 +45,6 @@
<div id="navbar-container">
<ul class="navbar">
<li class="navbar-option" data-selection="0">Search</li>
<li class="navbar-option" data-selection="1">Charms</li>
<li class="navbar-option" data-selection="2">Equipment</li>
</ul>
</div>
@ -71,29 +70,21 @@
</li>
<li>
<select name="armor-rarity" id="armor-rarity">
<optgroup label="High Rank">
<option value="7">Armor RARE7</option>
<option value="6">Armor RARE6</option>
<option value="5">Armor RARE5</option>
<option value="4">Armor RARE4</option>
</optgroup>
<optgroup label="Low Rank">
<option value="3">Armor RARE3</option>
<option value="2">Armor RARE2</option>
<option value="1">Armor RARE1</option>
</optgroup>
</select>
</li>
<li>
<select name="deco-rarity" id="deco-rarity">
<optgroup label="High Rank">
<option value="7">Deco RARE7</option>
<option value="6">Deco RARE6</option>
</optgroup>
<optgroup label="Low Rank">
<option value="5">Deco RARE5</option>
<option value="4">Deco RARE4</option>
</optgroup>
</select>
</li>
<li>
@ -125,76 +116,6 @@
<div id="search-results"></div>
</div>
<!-- charms -->
<div class="panel" id="charms-container" data-panel-number="1">
<!-- charm picker -->
<div id="charm-picker">
<ul>
<li>Add Charm</li>
<li>
<select
class="charm-skill-pick"
name="charm-skill-1-name"
id="charm-skill-1-name"
></select>
</li>
<li>
<select
class="charm-points-pick"
name="charm-skill-1-points"
id="charm-skill-1-points"
></select>
</li>
<li>
<select
class="charm-skill-pick"
name="charm-skill-2-name"
id="charm-skill-2-name"
></select>
</li>
<li>
<select
class="charm-points-pick"
name="charm-skill-2-points"
id="charm-skill-2-points"
></select>
</li>
<li>
<select name="charm-slots" id="charm-slots">
<option value="0">0 Slots</option>
<option value="1">1 Slots</option>
<option value="2">2 Slots</option>
<option value="3">3 Slots</option>
</select>
</li>
<li><button id="charm-add">Add</button></li>
<li><button id="charm-import">Import</button></li>
<li><button id="charm-export">Export</button></li>
</ul>
<a href="" id="charm-download" style="display: none"></a>
<input
type="file"
id="charm-upload"
accept=".csv"
style="display: none"
/>
</div>
<!-- charm table -->
<div id="charm-table-container">
<table id="charm-table">
<tr>
<th>Skill</th>
<th>Points</th>
<th>Skill</th>
<th>Points</th>
<th>Slots</th>
<th>Delete</th>
</tr>
</table>
</div>
</div>
<!-- eq settings -->
<div class="panel" id="eq-settings-container" data-panel-number="2">
<div id="eq-container"></div>

View File

@ -1,6 +1,5 @@
import { getArms, getChest, getDecorations, getHead, getLegs, getSkillActivationMap, getSkillCategories, getSkillNameMap, getWaist } from '../../data-provider/data-provider.module'
import StaticSkillData from '../../data-provider/models/skills/StaticSkillData'
import { renderCharmPicker } from '../ui/charms.component'
import { renderEqSettings } from '../ui/eq-settings.component'
import { initiateNavbar } from '../ui/navbar.component'
import { renderSkillPicker } from '../ui/picker.component'
@ -20,7 +19,7 @@ const main = async () => {
]
const decorations = await getDecorations()
// load skill data and render skill picker and charms with it
// load skill data and render skill picker with it
const skillData: StaticSkillData = {
skillName: await getSkillNameMap(),
skillActivation: await getSkillActivationMap(),
@ -29,7 +28,6 @@ const main = async () => {
// render ui
renderSkillPicker(skillData.skillActivation, skillData.skillCategories)
renderCharmPicker(skillData.skillName, skillData.skillActivation, skillData.skillCategories)
renderEqSettings(armor)
// initialize search controls

View File

@ -188,54 +188,6 @@ ul {
padding: 0 0.4em;
}
/* charms */
#charm-picker {
padding-bottom: 0.4em;
border-width: 0 0 1px 0;
border-style: solid;
border-color: var(--color-border);
}
#charm-import {
margin-left: 2em;
}
.charm-skill-pick {
width: 10em;
}
.charm-points-pick {
width: 3em;
}
#charm-table {
margin-top: 2em;
}
#charm-table tr,
td,
th {
width: 6em;
text-align: center;
font-size: 1.1em;
}
#charm-table tr {
border-width: 1px 0;
border-color: var(--color-border);
border-style: solid;
}
#charm-table th {
background-color: var(--color-highlight);
}
.charm-delete {
cursor: pointer;
user-select: none;
}
/* eq-settings */
#eq-container {

View File

@ -1,237 +0,0 @@
import SkillActivationMap from '../../data-provider/models/skills/SkillActivationMap'
import SkillNameMap from '../../data-provider/models/skills/SkillNameMap'
import Charm from '../../data-provider/models/equipment/Charm'
import Skill from '../../data-provider/models/skills/Skill'
import UserCharmList from '../../data-provider/models/user/UserCharmList'
import { htmlToElement } from '../../helper/html.helper'
import Slots from '../../data-provider/models/equipment/Slots'
import EquipmentCategory from '../../data-provider/models/equipment/EquipmentCategory'
import GameID from '../../data-provider/models/GameId'
import { range } from '../../helper/range.helper'
import EquipmentSkills from '../../data-provider/models/equipment/EquipmentSkills'
const saveToStorage = (skillNames: SkillNameMap) => {
window.localStorage.setItem('charms', UserCharmList.Instance.serialize(skillNames))
}
const getFromStorage = () => {
return window.localStorage.getItem('charms')
}
const validSkill = (id: GameID, points: Skill) => {
return points !== 0 && id !== -1
}
const removeTableElement = (index: number) => {
const ele = document.getElementsByClassName(`charm-${index}`)[0]
ele.remove()
}
const populateCharmsFromCSV = (csv: string, skillNames: SkillNameMap) => {
UserCharmList.Instance.deserialize(csv, skillNames)
UserCharmList.Instance.get().forEach((charm, i) => {
addTableElement(charm, i, skillNames)
})
}
const purgeTable = () => {
const entries = document.getElementsByClassName('charm-table-ele')
for (const entry of Array.from(entries)) {
entry.remove()
}
}
const addTableElement = (charm: Charm, index: number, skillNames: SkillNameMap) => {
const ele = htmlToElement(`<tr class="charm-table-ele charm-${index}" data-index="${index}"></tr>`)
// get real table elements
for (const skill of Array.from(charm.skills.keys())) {
ele.appendChild(htmlToElement(`<td>${skillNames.get(skill)}</td>`))
ele.appendChild(htmlToElement(`<td>${charm.skills.get(skill)}</td>`))
}
// get placeholder table elements
const amountOfSkills = Array.from(charm.skills.keys()).length
// eslint-disable-next-line no-unused-vars
for (const _ in range(amountOfSkills, 2)) {
ele.appendChild(htmlToElement('<td></td>'))
ele.appendChild(htmlToElement('<td></td>'))
}
// get slots and delete
ele.appendChild(htmlToElement(`<td>${charm.slots}</td>`))
const d = htmlToElement('<td class="charm-delete">X</td>')
d.addEventListener('click', () => removeCharm(index, skillNames))
ele.appendChild(d)
// add final element
const tbody = document.getElementById('charm-table')!.children[0]
tbody.appendChild(ele)
}
const addCharm = (charm: Charm, skillNames: SkillNameMap) => {
const i = UserCharmList.Instance.add(charm)
addTableElement(charm, i - 1, skillNames)
saveToStorage(skillNames)
}
const removeCharm = (index: number, skillNames: SkillNameMap) => {
UserCharmList.Instance.remove(index)
removeTableElement(index)
saveToStorage(skillNames)
}
const onExportClick = (skillNames: SkillNameMap) => {
const str = UserCharmList.Instance.serialize(skillNames)
const blob = new Blob([str], { type: 'text/plain' })
const a = document.getElementById('charm-download') as HTMLAnchorElement
const url = window.URL.createObjectURL(blob)
a.href = url
a.download = 'charms.csv'
a.click()
}
const onImportClick = (e: MouseEvent) => {
e.preventDefault()
const inp = document.getElementById('charm-upload') as HTMLInputElement
inp.click()
}
const onFileUploaded = (skillNames: SkillNameMap) => {
const inp = document.getElementById('charm-upload') as HTMLInputElement
if (!inp.files) {
return
}
const file = inp.files[0]
file.text().then((text) => {
try {
UserCharmList.Instance.deserialize(text, skillNames)
saveToStorage(skillNames)
purgeTable()
UserCharmList.Instance.get().forEach((charm, i) => {
addTableElement(charm, i, skillNames)
})
} catch {
alert('Could not process file')
}
})
}
const onAddClick = (skillNames: SkillNameMap) => {
// parse data
const slots = parseInt((document.getElementById('charm-slots') as HTMLSelectElement).value)
const skills = [1, 2].map((x) => {
return {
id: parseInt((document.getElementById(`charm-skill-${x}-name`) as HTMLSelectElement).value),
points: parseInt((document.getElementById(`charm-skill-${x}-points`) as HTMLSelectElement).value),
}
})
// return if charm invalid
if (slots === 0 && !skills.some(s => validSkill(s.id, s.points))) {
return
}
// map to model
const skillsMap = new EquipmentSkills(skills
.filter(s => validSkill(s.id, s.points))
.map(s => [s.id, s.points]))
const charm: Charm = {
name: UserCharmList.getCharmName(skillsMap, slots as Slots, skillNames),
slots: slots as Slots,
category: EquipmentCategory.CHARM,
rarity: 0,
skills: skillsMap,
}
// add
addCharm(charm, skillNames)
}
const attachControlListeners = (skillNames: SkillNameMap) => {
document.getElementById('charm-add')!.addEventListener('click', () => onAddClick(skillNames))
document.getElementById('charm-export')!.addEventListener('click', () => onExportClick(skillNames))
document.getElementById('charm-import')!.addEventListener('click', (e) => onImportClick(e))
document.getElementById('charm-upload')!.addEventListener('change', () => onFileUploaded(skillNames))
}
const populatePointsPickers = () => {
const pickers = document.getElementsByClassName('charm-points-pick')
for (const picker of Array.from(pickers)) {
for (const amount of range(-10, 11).reverse()) {
picker.appendChild(htmlToElement(`
<option ${amount === 0 ? 'selected="selected"' : ''} value="${amount}">${amount}</option>
`))
}
}
}
const populateSkillsPickers = (
skillNames: SkillNameMap,
skillActivation: SkillActivationMap,
skillCategories: string[],
) => {
const pickers = document.getElementsByClassName('charm-skill-pick')
for (const picker of Array.from(pickers)) {
// make optgroup for each category
const optGroups = skillCategories.map((category, i) => {
return htmlToElement(`
<optgroup label="${category}" data-category="${i}"></optgroup>
`)
})
// append skill options to optgroup
skillActivation.forEach((activationList) => {
// continue if skill cant be activated -- Torso Up
if (activationList.length === 0) {
return
}
const dummyActivation = activationList[0]
const category = dummyActivation.category
const skill = dummyActivation.requiredSkill
const name = skillNames.get(skill)
const ele = htmlToElement(`
<option value="${skill}" data-skill="${skill}">${name}</option>
`)
optGroups[category].appendChild(ele)
})
// add default
optGroups.unshift(htmlToElement(`
<option value="-1" data-skill="-1">None</option>
`))
// add elements and select default
picker.append(...optGroups)
picker.getElementsByTagName('option')[0].selected = true
}
}
const populateCharmPicker = (
skillNames: SkillNameMap,
skillActivation: SkillActivationMap,
skillCategories: string[],
) => {
populatePointsPickers()
populateSkillsPickers(skillNames, skillActivation, skillCategories)
}
export const renderCharmPicker = (
skillNames: SkillNameMap,
skillActivation: SkillActivationMap,
skillCategories: string[],
) => {
populateCharmPicker(skillNames, skillActivation, skillCategories)
attachControlListeners(skillNames)
const savedCharms = getFromStorage()
if (savedCharms) {
populateCharmsFromCSV(savedCharms, skillNames)
}
}

View File

@ -1,4 +1,3 @@
import UserCharmList from '../../data-provider/models/user/UserCharmList'
import ArmorSet from '../../searcher/models/ArmorSet'
import SearchConstraints from '../../searcher/models/SearchConstraints'
import StaticEquipmentData from '../../data-provider/models/equipment/StaticEquipmentData'
@ -63,7 +62,7 @@ const searchLogic = (equData: StaticEquipmentData, skillData: StaticSkillData) =
const result = search(
equData.armor,
equData.decorations,
UserCharmList.Instance.get(),
[],
searchParams,
skillData,
)
@ -80,8 +79,6 @@ const moreSkillsLogic = async (equData: StaticEquipmentData, skillData: StaticSk
return
}
const charms = UserCharmList.Instance.get()
const aquirableSkills: SkillActivation[] = []
const outputIterator = moreSkillsIterator(skillData.skillActivation)
@ -111,7 +108,7 @@ const moreSkillsLogic = async (equData: StaticEquipmentData, skillData: StaticSk
const innerR = search(
equData.armor,
equData.decorations,
charms,
[],
newParams,
skillData,
)

View File

@ -52,7 +52,6 @@ const getExpandedView = (set: ArmorSet, skillData: StaticSkillData, searchParams
<th style="width: 6%">Arms</th>
<th style="width: 6%">Waist</th>
<th style="width: 6%">Legs</th>
<th style="width: 6%">Charm</th>
<th style="width: 6%">Deco</th>
<th style="width: 6%">Total</th>
<th>Active</th>
@ -74,7 +73,6 @@ const getExpandedView = (set: ArmorSet, skillData: StaticSkillData, searchParams
for (const p of set.getPieces()) {
r.append(htmlToElement(`<td>${p.skills.get(sId) ? p.skills.get(sId)! : ''}</td>`))
}
r.append(htmlToElement(`<td>${set.charm.skills.get(sId) ? set.charm.skills.get(sId)! : ''}</td>`))
r.append(htmlToElement(`<td>${computedDecoValue || ''}</td>`))
r.append(htmlToElement(`<td>${sVal}</td>`))
const possibleAct = set.evaluation!.activations.find(a => a.requiredSkill === sId)
@ -85,7 +83,7 @@ const getExpandedView = (set: ArmorSet, skillData: StaticSkillData, searchParams
// build slot list
const slotRow = document.createElement('tr')
slotRow.appendChild(htmlToElement('<td>Slots</td>'))
const rawSlowList = [searchParams.weaponSlots, ...set.getPieces().map(x => x.slots), set.charm.slots]
const rawSlowList = [searchParams.weaponSlots, ...set.getPieces().map(x => x.slots)]
rawSlowList.forEach(s => slotRow.appendChild(htmlToElement(`<td>${s}</td>`)))
// append elements to table
@ -187,7 +185,6 @@ const getSetElement = (set: ArmorSet, skillData: StaticSkillData, searchParams:
<td>${set.arms.name}</td>
<td>${set.waist.name}</td>
<td>${set.legs.name}</td>
<td>${set.charm.name}</td>
</tr>`)
const row2 = htmlToElement(`
<tr class="result-set-row result-set-row2">
@ -276,7 +273,7 @@ export const renderResults = (sets: ArmorSet[], skillData: StaticSkillData, sear
// build table and table header
const table = htmlToElement('<table class="results-table" id="results-table"></table>')
const header = htmlToElement('<tr><th>Head</th><th>Torso</th><th>Arms</th><th>Waist</th><th>Legs</th><th>Charm</th></tr>')
const header = htmlToElement('<tr><th>Head</th><th>Torso</th><th>Arms</th><th>Waist</th><th>Legs</th></tr>')
resultContainer.appendChild(table)
table.appendChild(header)

View File

@ -1,122 +0,0 @@
import { range } from '../../../helper/range.helper'
import SkillNameMap from '../skills/SkillNameMap'
import Charm from '../equipment/Charm'
import EquipmentCategory from '../equipment/EquipmentCategory'
import EquipmentSkills from '../equipment/EquipmentSkills'
import Slots from '../equipment/Slots'
export default class UserCharmList {
// eslint-disable-next-line no-use-before-define
private static _instance: UserCharmList
private list: Charm[]
private constructor () {
this.list = []
}
public static get Instance () {
return this._instance || (this._instance = new this())
}
public static getCharmName (
skills: EquipmentSkills,
slots: Slots,
skillNames: SkillNameMap,
): string {
const skillStrings = Array.from(skills.entries()).map(
(s) => `${skillNames.get(s[0])}:${s[1]}`,
)
const slotString = slots !== 0 ? `${slots} Slots` : ''
return [...skillStrings, slotString].join(' ').trim()
}
/** get the list of charms */
get () {
return this.list
}
/** adds a given charm to list */
add (charm: Charm): number {
return this.list.push(charm)
}
/** removes charm at specified index from list */
remove (index: number) {
this.list = this.list.filter((_, i) => i !== index)
}
/** serializes charm list as csv */
serialize (skillNames: SkillNameMap): string {
return this.list
.map((charm) => {
const s = []
const skillArray = Array.from(charm.skills.entries())
skillArray.forEach(([sId, sVal]) => {
s.push(`${skillNames.get(sId)},${sVal},`)
})
const amountOfSkills = skillArray.length
// eslint-disable-next-line no-unused-vars
for (const _ in range(amountOfSkills, 2)) {
s.push(',,')
}
s.push(`${charm.slots}`)
return s.join('')
})
.join('\n')
}
/** populate charm list from csv */
deserialize (csv: string, skillNames: SkillNameMap): Charm[] {
const newList = []
for (const charm of csv.split('\n')) {
const spl = charm.split(',')
const slots = parseInt(spl[4])
const skills = [
[0, 1],
[2, 3],
]
.filter(([_, j]) => !isNaN(parseInt(spl[j])))
.map(([i, j]) => {
const name = spl[i]
const id = Array.from(skillNames.entries()).find(([_, n]) => {
return n === name
})![0]
// build skill model
const skill = {
name,
points: parseInt(spl[j]),
id,
}
return skill
})
const skillMap: EquipmentSkills = new EquipmentSkills(
skills.map((skill) => {
return [skill.id, skill.points]
}),
)
const newCharm: Charm = {
name: UserCharmList.getCharmName(skillMap, slots as Slots, skillNames),
category: EquipmentCategory.CHARM,
slots: slots as Slots,
rarity: 0,
skills: skillMap,
}
newList.push(newCharm)
}
this.list = newList
return newList
}
}