Skip to content

Commit

Permalink
update talents tab
Browse files Browse the repository at this point in the history
  • Loading branch information
kayla-glick committed Aug 16, 2023
1 parent 697eeab commit 124d4d5
Show file tree
Hide file tree
Showing 33 changed files with 632 additions and 390 deletions.
1 change: 0 additions & 1 deletion ui/core/components/content_block.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Tooltip } from 'bootstrap';
import { title } from 'process';
import { Component } from './component.js';

export interface ContentBlockHeaderConfig {
Expand Down
74 changes: 26 additions & 48 deletions ui/core/components/gear_picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ export function getEmptySlotIconUrl(slot: ItemSlot): string {
}

export class ItemList<T> {

private listElem: HTMLElement;
private listItemElems: HTMLLIElement[];
private readonly player: Player<any>;
private label: string;
Expand Down Expand Up @@ -897,8 +897,8 @@ export class ItemList<T> {
const tabContent = tabContentFragment.children[0] as HTMLElement;
parent.appendChild(tabContent);

const helpIcon = tabContent.getElementsByClassName("ep-help").item(0);
tippy(helpIcon, { 'content': 'These values are computed using stat weights which can be edited using the "Stat Weights" button.' });
// const helpIcon = tabContent.getElementsByClassName("ep-help").item(0);
// tippy(helpIcon, { 'content': 'These values are computed using stat weights which can be edited using the "Stat Weights" button.' });
const show1hWeaponsSelector = makeShow1hWeaponsSelector(tabContent.getElementsByClassName('selector-modal-show-1h-weapons')[0] as HTMLElement, player.sim);
const show2hWeaponsSelector = makeShow2hWeaponsSelector(tabContent.getElementsByClassName('selector-modal-show-2h-weapons')[0] as HTMLElement, player.sim);
if (!(label == 'Items' && (slot == ItemSlot.ItemSlotMainHand || (slot == ItemSlot.ItemSlotOffHand && player.getClass() == Class.ClassWarrior)))) {
Expand All @@ -920,7 +920,7 @@ export class ItemList<T> {
filtersButton.addEventListener('click', () => new FiltersMenu(parent, player, slot));
}

const listElem = tabContent.getElementsByClassName('selector-modal-list')[0] as HTMLElement;
this.listElem = tabContent.getElementsByClassName('selector-modal-list')[0] as HTMLElement;
const initialFilters = player.sim.getFilters();
let lastFavElem: HTMLElement | null = null;

Expand All @@ -929,15 +929,14 @@ export class ItemList<T> {
const itemEP = computeEP(item);

const listItemElem = document.createElement('li');
this.listElem.appendChild(listItemElem);
listItemElem.classList.add('selector-modal-list-item');
listElem.appendChild(listItemElem);

listItemElem.dataset.idx = String(itemIdx);

listItemElem.innerHTML = `
<a class="selector-modal-list-item-link">
<div class="selector-modal-list-label-cell">
<a class="selector-modal-list-item-icon"></a>
<a class="selector-modal-list-item-name">${itemData.heroic ? itemData.name + "<span style=\"color:green\">[H]</span>" : itemData.name}</a>
<img class="selector-modal-list-item-icon" />
<label class="selector-modal-list-item-name">${itemData.heroic ? itemData.name + "<span style=\"color:green\">[H]</span>" : itemData.name}</label>
</div>
<div class="selector-modal-list-item-source-container">
</div>
Expand All @@ -950,19 +949,26 @@ export class ItemList<T> {
<div class="selector-modal-list-item-ep">
<span class="selector-modal-list-item-ep-delta"></span>
</div>
</a>
`;

if (slot == ItemSlot.ItemSlotTrinket1 || slot == ItemSlot.ItemSlotTrinket2) {
const epElem = listItemElem.getElementsByClassName('selector-modal-list-item-ep')[0] as HTMLElement;
epElem.style.display = 'none';
}

const iconElem = listItemElem.getElementsByClassName('selector-modal-list-item-icon')[0] as HTMLAnchorElement;
const anchorElem = listItemElem.children[0] as HTMLAnchorElement;
const iconElem = listItemElem.getElementsByClassName('selector-modal-list-item-icon')[0] as HTMLImageElement;
const nameElem = listItemElem.getElementsByClassName('selector-modal-list-item-name')[0] as HTMLAnchorElement;

anchorElem.addEventListener('click', (event: Event) => {
event.preventDefault();
onItemClick(itemData);
});

itemData.actionId.fill().then(filledId => {
filledId.setWowheadHref(iconElem);
filledId.setWowheadHref(nameElem);
iconElem.style.backgroundImage = `url('${filledId.iconUrl}')`;
filledId.setWowheadHref(anchorElem);
iconElem.src = filledId.iconUrl;
});

setItemQualityCssClass(nameElem, itemData.quality);
Expand All @@ -973,12 +979,6 @@ export class ItemList<T> {
} else {
sourceElem.remove();
}
const clickHandle = (event: Event) => {
event.preventDefault();
onItemClick(itemData);
}
nameElem.addEventListener('click', clickHandle);
iconElem.addEventListener('click', clickHandle);

const favoriteElem = listItemElem.getElementsByClassName('selector-modal-list-item-favorite')[0] as HTMLElement;
tippy(favoriteElem, { 'content': 'Add to Favorites' });
Expand Down Expand Up @@ -1018,14 +1018,14 @@ export class ItemList<T> {
player.sim.setFilters(TypedEvent.nextEventID(), filters);

// Reorder and update this element.
const curItemElems = Array.from(listElem.children) as Array<HTMLElement>;
const curItemElems = Array.from(this.listElem.children) as Array<HTMLElement>;
if (isFavorite) {
// Use same sorting order (based on idx) among the favorited elems.
const nextElem = curItemElems.find(elem => elem.dataset.fav == 'false' || parseInt(elem.dataset.idx!) > itemIdx);
if (nextElem) {
listElem.insertBefore(listItemElem, nextElem);
this.listElem.insertBefore(listItemElem, nextElem);
} else {
listElem.appendChild(listItemElem);
this.listElem.appendChild(listItemElem);
}

favoriteElem.classList.add('fa-solid');
Expand All @@ -1042,9 +1042,9 @@ export class ItemList<T> {
curIdx++;
}
if (curIdx == curItemElems.length) {
listElem.appendChild(listItemElem);
this.listElem.appendChild(listItemElem);
} else {
listElem.insertBefore(listItemElem, curItemElems[curIdx]);
this.listElem.insertBefore(listItemElem, curItemElems[curIdx]);
}

favoriteElem.classList.remove('fa-solid');
Expand All @@ -1066,7 +1066,7 @@ export class ItemList<T> {
favoriteElem.classList.add('fa-solid');
listItemElem.dataset.fav = 'true';
if (lastFavElem == null) {
listElem.prepend(listItemElem);
this.listElem.prepend(listItemElem);
} else {
lastFavElem.after(listItemElem)
}
Expand Down Expand Up @@ -1098,9 +1098,6 @@ export class ItemList<T> {
this.searchInput.addEventListener("keyup", ev => {
if (ev.key == "Enter") {
this.listItemElems.find(ele => {
if (ele.classList.contains("hidden")) {
return false;
}
const nameElem = ele.getElementsByClassName('selector-modal-list-item-name')[0] as HTMLElement;
nameElem.click();
return true;
Expand Down Expand Up @@ -1128,11 +1125,6 @@ export class ItemList<T> {
}

this.listItemElems.forEach((elem, index) => {
// skip items already filtered out.
if (elem.classList.contains('hidden')) {
return;
}

const idata = this.itemData[index];
if (!isRangedOrTrinket && curEP > 0 && idata.baseEP < (curEP / 2)) {
return; // If we have EPs on current item, dont sim items with less than half the EP.
Expand Down Expand Up @@ -1232,21 +1224,7 @@ export class ItemList<T> {

return true;
});

let numShown = 0;
this.listItemElems.forEach(elem => {
if (validItemElems.includes(elem)) {
elem.classList.remove('hidden');
numShown++;
if (numShown % 2 == 0) {
elem.classList.remove('odd');
} else {
elem.classList.add('odd');
}
} else {
elem.classList.add('hidden');
}
});
this.listElem.replaceChildren(...validItemElems);

Check failure on line 1227 in ui/core/components/gear_picker.ts

View workflow job for this annotation

GitHub Actions / build-and-test

Property 'replaceChildren' does not exist on type 'HTMLElement'.
}

public hideOrShowEPValues() {
Expand Down
154 changes: 154 additions & 0 deletions ui/core/components/individual_sim_ui/talents_tab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { IndividualSimUI } from "../../individual_sim_ui";
import { Player } from "../../player";
import { EventID, TypedEvent } from "../../typed_event";

import { Class, Glyphs, Spec } from "../../proto/common";
import { SavedTalents } from "../../proto/ui";

import { classGlyphsConfig, classTalentsConfig } from "../../talents/factory";
import { GlyphsPicker } from "../../talents/glyphs_picker";
import { HunterPetTalentsPicker, makePetTypeInputConfig } from "../../talents/hunter_pet";
import { TalentsPicker } from "../../talents/talents_picker";

import { EnumPicker } from "../enum_picker";
import { IconEnumPicker } from "../icon_enum_picker";
import { SavedDataManager } from "../saved_data_manager";
import { SimTab } from "../sim_tab";

import * as Mechanics from '../../constants/mechanics';

export class TalentsTab extends SimTab {
protected simUI: IndividualSimUI<Spec>;

readonly leftPanel: HTMLElement;
readonly rightPanel: HTMLElement;

constructor(parentElem: HTMLElement, simUI: IndividualSimUI<Spec>) {
super(parentElem, simUI, { identifier: 'talents-tab', title: 'Talents' });
this.simUI = simUI;

this.leftPanel = document.createElement('div');
this.leftPanel.classList.add('talents-tab-left', 'tab-panel-left');
this.rightPanel = document.createElement('div');
this.rightPanel.classList.add('talents-tab-right', 'tab-panel-right', 'within-raid-sim-hide');

this.contentContainer.appendChild(this.leftPanel);
this.contentContainer.appendChild(this.rightPanel);

this.buildTabContent();
}

protected buildTabContent() {
if (this.simUI.player.getClass() == Class.ClassHunter) {
this.buildHunterPickers();
} else {
this.buildTalentsPicker(this.leftPanel);
this.buildGlyphsPicker(this.leftPanel);
}

this.buildSavedTalentsPicker();
}

private buildTalentsPicker(parentElem: HTMLElement) {
new TalentsPicker(parentElem, this.simUI.player, {
klass: this.simUI.player.getClass(),
trees: classTalentsConfig[this.simUI.player.getClass()],
changedEvent: (player: Player<any>) => player.talentsChangeEmitter,
getValue: (player: Player<any>) => player.getTalentsString(),
setValue: (eventID: EventID, player: Player<any>, newValue: string) => {
player.setTalentsString(eventID, newValue);
},
pointsPerRow: 5,
maxPoints: Mechanics.MAX_TALENT_POINTS,
});
}

private buildGlyphsPicker(parentElem: HTMLElement) {
new GlyphsPicker(parentElem, this.simUI.player, classGlyphsConfig[this.simUI.player.getClass()]);
}

private buildHunterPickers() {
this.leftPanel.innerHTML = `
<div class="hunter-talents-pickers-container tab-content">
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item" role="presentation">
<a
class="nav-link active"
type="button"
role="tab"
data-bs-toggle="tab"
data-bs-target="#player-talents-tab"
aria-controls="#player-talents-tab"
aria-selected="true"
>
Player
</a>
</li>
<li class="nav-item" role="presentation">
<a
class="nav-link"
type="button"
role="tab"
data-bs-toggle="tab"
data-bs-target="#pet-talents-tab"
aria-controls="#pet-talents-tab"
aria-selected="false"
>
Pet</a
>
</li>
</ul>
<div id="player-talents-tab" class="tab-pane fade active show" role="tabpanel">
</div>
<div id="pet-talents-tab" class="tab-pane fade" role="tabpanel">
</div>
</div>
`

const playerTab = this.leftPanel.querySelector('#player-talents-tab') as HTMLElement;
const petTab = this.leftPanel.querySelector('#pet-talents-tab') as HTMLElement;

this.buildTalentsPicker(playerTab);
this.buildGlyphsPicker(playerTab);
this.buildHunterPetPicker(petTab);
}

private buildHunterPetPicker(parentElem: HTMLElement) {
new HunterPetTalentsPicker(parentElem, this.simUI, this.simUI.player as Player<Spec.SpecHunter>);
const petTypeToggle = new IconEnumPicker(parentElem, this.simUI.player as Player<Spec.SpecHunter>, makePetTypeInputConfig(false));
}

private buildSavedTalentsPicker() {
const savedTalentsManager = new SavedDataManager<Player<any>, SavedTalents>(this.rightPanel, this.simUI, this.simUI.player, {
label: 'Talents',
header: { title: 'Saved Talents' },
storageKey: this.simUI.getSavedTalentsStorageKey(),
getData: (player: Player<any>) => SavedTalents.create({
talentsString: player.getTalentsString(),
glyphs: player.getGlyphs(),
}),
setData: (eventID: EventID, player: Player<any>, newTalents: SavedTalents) => {
TypedEvent.freezeAllAndDo(() => {
player.setTalentsString(eventID, newTalents.talentsString);
player.setGlyphs(eventID, newTalents.glyphs || Glyphs.create());
});
},
changeEmitters: [this.simUI.player.talentsChangeEmitter, this.simUI.player.glyphsChangeEmitter],
equals: (a: SavedTalents, b: SavedTalents) => SavedTalents.equals(a, b),
toJson: (a: SavedTalents) => SavedTalents.toJson(a),
fromJson: (obj: any) => SavedTalents.fromJson(obj),
});

this.simUI.sim.waitForInit().then(() => {
savedTalentsManager.loadUserData();
this.simUI.individualConfig.presets.talents.forEach(config => {
config.isPreset = true;
savedTalentsManager.addSavedData({
name: config.name,
isPreset: true,
data: config.data,
});
});
});
}
}
Loading

0 comments on commit 124d4d5

Please sign in to comment.