feat: show item set piece count and active bonuses in item tooltip

This commit is contained in:
Kelsi 2026-03-12 12:43:53 -07:00
parent a56b50df2b
commit bc0d98adae

View file

@ -2560,32 +2560,98 @@ void InventoryScreen::renderItemTooltip(const game::ItemQueryResponseData& info,
// Item set membership
if (info.itemSetId != 0) {
// Lazy-load ItemSet.dbc name table
static std::unordered_map<uint32_t, std::string> s_setNames;
static bool s_setNamesLoaded = false;
if (!s_setNamesLoaded && assetManager_) {
s_setNamesLoaded = true;
// Lazy-load full ItemSet.dbc data (name + item IDs + bonus spells/thresholds)
struct SetEntry {
std::string name;
std::array<uint32_t, 10> itemIds{};
std::array<uint32_t, 10> spellIds{};
std::array<uint32_t, 10> thresholds{};
};
static std::unordered_map<uint32_t, SetEntry> s_setData;
static bool s_setDataLoaded = false;
if (!s_setDataLoaded && assetManager_) {
s_setDataLoaded = true;
auto dbc = assetManager_->loadDBC("ItemSet.dbc");
if (dbc && dbc->isLoaded()) {
const auto* layout = pipeline::getActiveDBCLayout()
? pipeline::getActiveDBCLayout()->getLayout("ItemSet") : nullptr;
uint32_t idF = layout ? (*layout)["ID"] : 0;
uint32_t nameF = layout ? (*layout)["Name"] : 1;
auto lf = [&](const char* k, uint32_t def) -> uint32_t {
return layout ? (*layout)[k] : def;
};
uint32_t idF = lf("ID", 0), nameF = lf("Name", 1);
static const char* itemKeys[10] = {
"Item0","Item1","Item2","Item3","Item4",
"Item5","Item6","Item7","Item8","Item9"
};
static const char* spellKeys[10] = {
"Spell0","Spell1","Spell2","Spell3","Spell4",
"Spell5","Spell6","Spell7","Spell8","Spell9"
};
static const char* thrKeys[10] = {
"Threshold0","Threshold1","Threshold2","Threshold3","Threshold4",
"Threshold5","Threshold6","Threshold7","Threshold8","Threshold9"
};
uint32_t itemFallback[10], spellFallback[10], thrFallback[10];
for (int i = 0; i < 10; ++i) {
itemFallback[i] = 18 + i;
spellFallback[i] = 28 + i;
thrFallback[i] = 38 + i;
}
for (uint32_t r = 0; r < dbc->getRecordCount(); ++r) {
uint32_t id = dbc->getUInt32(r, idF);
if (!id) continue;
std::string nm = dbc->getString(r, nameF);
if (!nm.empty()) s_setNames[id] = std::move(nm);
SetEntry e;
e.name = dbc->getString(r, nameF);
for (int i = 0; i < 10; ++i) {
e.itemIds[i] = dbc->getUInt32(r, layout ? (*layout)[itemKeys[i]] : itemFallback[i]);
e.spellIds[i] = dbc->getUInt32(r, layout ? (*layout)[spellKeys[i]] : spellFallback[i]);
e.thresholds[i] = dbc->getUInt32(r, layout ? (*layout)[thrKeys[i]] : thrFallback[i]);
}
s_setData[id] = std::move(e);
}
}
}
auto setIt = s_setNames.find(info.itemSetId);
const char* setName = (setIt != s_setNames.end()) ? setIt->second.c_str() : nullptr;
auto setIt = s_setData.find(info.itemSetId);
ImGui::Spacing();
if (setName)
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "%s", setName);
else
if (setIt != s_setData.end()) {
const SetEntry& se = setIt->second;
// Count equipped pieces
int equipped = 0, total = 0;
for (int i = 0; i < 10; ++i) {
if (se.itemIds[i] == 0) continue;
++total;
if (inventory) {
for (int s = 0; s < game::Inventory::NUM_EQUIP_SLOTS; s++) {
const auto& eSlot = inventory->getEquipSlot(static_cast<game::EquipSlot>(s));
if (!eSlot.empty() && eSlot.item.itemId == se.itemIds[i]) { ++equipped; break; }
}
}
}
if (total > 0) {
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f),
"%s (%d/%d)", se.name.empty() ? "Set" : se.name.c_str(), equipped, total);
} else {
if (!se.name.empty())
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "%s", se.name.c_str());
}
// Show set bonuses: gray if not reached, green if active
if (gameHandler_) {
for (int i = 0; i < 10; ++i) {
if (se.spellIds[i] == 0 || se.thresholds[i] == 0) continue;
const std::string& bname = gameHandler_->getSpellName(se.spellIds[i]);
bool active = (equipped >= static_cast<int>(se.thresholds[i]));
ImVec4 col = active ? ImVec4(0.5f, 1.0f, 0.5f, 1.0f)
: ImVec4(0.55f, 0.55f, 0.55f, 1.0f);
if (!bname.empty())
ImGui::TextColored(col, "(%u) %s", se.thresholds[i], bname.c_str());
else
ImGui::TextColored(col, "(%u) Set Bonus", se.thresholds[i]);
}
}
} else {
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "Set (id %u)", info.itemSetId);
}
}
if (info.startQuestId != 0) {