Skip to content

Commit

Permalink
Logic to find identical-or-better items, UI WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
xpdota committed Sep 19, 2024
1 parent a5e0e29 commit 33d6483
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 6 deletions.
18 changes: 18 additions & 0 deletions packages/common-ui/styles/common.less
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,24 @@ gear-set-viewer {
//box-shadow: 0 0 3px 3px var(--stat-color) inset;
}
}

.item-name-holder-view {
display: flex;
flex-direction: row;

span.item-name {
flex-basis: 1px;
flex-grow: 99;
overflow: hidden;
text-overflow: ellipsis;
}

span.item-alts {
flex-basis: fit-content;
flex-shrink: 0;
flex-grow: 0;
}
}
}

.food-view-table {
Expand Down
47 changes: 47 additions & 0 deletions packages/core/src/gear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -944,3 +944,50 @@ export type ItemSingleStatDetail = {
};


/**
* Returns true if 'candidateItem' has identical or better stats than 'baseItem'.
*
* In order to be true, every stat must be identical or greater.
*
* @param candidateItem
* @param baseItem
*/
export function isSameOrBetterItem(candidateItem: GearItem, baseItem: GearItem): boolean {
// TODO: consider materia slots
// Ultimate weapons are equivalent to savage raid but with an extra materia slot. So an ultimate weapon should
// be considered an acceptable replacement for a savage weapon, but not the other way around.


// Phase 1: Raw stats
const candidateStats = candidateItem.stats;
const baseStats = baseItem.stats;
for (const [statKey, baseValue] of Object.entries(baseStats)) {
const candidateValue = candidateStats[statKey] as number;
if (candidateValue < baseValue) {
return false;
}
}
// Phase 2: Materia
// The logic here is to just check that every materia slot in the base item:
// 1. Exists in the candidate item,
// 2. is at least the same grade, and
// 3. is high grade if the source slot is also high grade
for (const baseSlot of baseItem.materiaSlots) {
const index = baseItem.materiaSlots.indexOf(baseSlot);
if (index in candidateItem.materiaSlots) {
const candidateSlot = candidateItem.materiaSlots[index];
if (candidateSlot.maxGrade < baseSlot.maxGrade) {
return false;
}
else if (baseSlot.allowsHighGrade && !candidateSlot.allowsHighGrade) {
return false;
}
}
else {
// Not enough slots
return false;
}
}

return true;
}
25 changes: 23 additions & 2 deletions packages/core/src/sheet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ // TODO: get back to fixing this at some point
/* eslint-disable @typescript-eslint/no-explicit-any */ // TODO: get back to fixing this at some point
import {
CURRENT_MAX_LEVEL,
defaultItemDisplaySettings,
Expand Down Expand Up @@ -36,7 +36,7 @@ import {
SimExport,
Substat
} from "@xivgear/xivmath/geartypes";
import {CharacterGearSet} from "./gear";
import {CharacterGearSet, isSameOrBetterItem} from "./gear";
import {DataManager, makeDataManager} from "./datamanager";
import {Inactivitytimer} from "./util/inactivitytimer";
import {writeProxy} from "./util/proxies";
Expand Down Expand Up @@ -837,4 +837,25 @@ export class GearPlanSheet {
}
this._sets.forEach(set => set.forceRecalc());
}

/**
* Get items that could replace the given item - either identical or better.
*
* @param thisItem
*/
getAltItemsFor(thisItem: GearItem): GearItem[] {
// Ignore this for relics - consider them to be incompatible until we can
// figure out a good way to do this.
if (thisItem.isCustomRelic) {
return [];
}
return this.dataManager.allItems.filter(otherItem => {
// Cannot be the same item
return otherItem.id !== thisItem.id
// Must be same slot
&& otherItem.occGearSlotName === thisItem.occGearSlotName
// Must be better or same stats
&& isSameOrBetterItem(otherItem, thisItem);
});
}
}
19 changes: 15 additions & 4 deletions packages/frontend/src/scripts/components/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,8 @@ export class GearItemsViewTable extends CustomTable<GearSlotItem, EquipmentSet>
const item = {
slot: slot,
item: equippedItem,
slotId: slotId
slotId: slotId,
alts: sheet.getAltItemsFor(equippedItem)
};
slotItem = equippedItem;
data.push(item);
Expand Down Expand Up @@ -786,10 +787,20 @@ export class GearItemsViewTable extends CustomTable<GearSlotItem, EquipmentSet>
shortName: "itemname",
displayName: headingText,
getter: item => {
return item.item.name;
return item;
},
renderer: (name: string) => {
return document.createTextNode(shortenItemName(name));
renderer: (item) => {
const name = item.item.name;
const itemNameSpan = quickElement('span', ['item-name'], [shortenItemName(name)]);
const out = quickElement('div', ['item-name-holder-view'], [itemNameSpan]);
if (item.alts.length > 0) {
const altSpan = quickElement('span', ['item-alts'], [`(+${item.alts.length} others)`]);
altSpan.addEventListener('click', () => {
console.log("Alts", item.alts);
});
out.appendChild(altSpan);
}
return out;
},
// initialWidth: 300,
},
Expand Down

0 comments on commit 33d6483

Please sign in to comment.