feat: parse item set ID and display set name in item tooltip via ItemSet.dbc

This commit is contained in:
Kelsi 2026-03-12 12:35:56 -07:00
parent d48e4fb7c3
commit 48f12d9ca8
6 changed files with 66 additions and 2 deletions

View file

@ -100,5 +100,15 @@
},
"SpellItemEnchantment": {
"ID": 0, "Name": 8
},
"ItemSet": {
"ID": 0, "Name": 1,
"Item0": 18, "Item1": 19, "Item2": 20, "Item3": 21, "Item4": 22,
"Item5": 23, "Item6": 24, "Item7": 25, "Item8": 26, "Item9": 27,
"Spell0": 28, "Spell1": 29, "Spell2": 30, "Spell3": 31, "Spell4": 32,
"Spell5": 33, "Spell6": 34, "Spell7": 35, "Spell8": 36, "Spell9": 37,
"Threshold0": 38, "Threshold1": 39, "Threshold2": 40, "Threshold3": 41,
"Threshold4": 42, "Threshold5": 43, "Threshold6": 44, "Threshold7": 45,
"Threshold8": 46, "Threshold9": 47
}
}

View file

@ -98,5 +98,15 @@
},
"SpellItemEnchantment": {
"ID": 0, "Name": 8
},
"ItemSet": {
"ID": 0, "Name": 1,
"Item0": 10, "Item1": 11, "Item2": 12, "Item3": 13, "Item4": 14,
"Item5": 15, "Item6": 16, "Item7": 17, "Item8": 18, "Item9": 19,
"Spell0": 20, "Spell1": 21, "Spell2": 22, "Spell3": 23, "Spell4": 24,
"Spell5": 25, "Spell6": 26, "Spell7": 27, "Spell8": 28, "Spell9": 29,
"Threshold0": 30, "Threshold1": 31, "Threshold2": 32, "Threshold3": 33,
"Threshold4": 34, "Threshold5": 35, "Threshold6": 36, "Threshold7": 37,
"Threshold8": 38, "Threshold9": 39
}
}

View file

@ -101,5 +101,15 @@
},
"SpellItemEnchantment": {
"ID": 0, "Name": 8
},
"ItemSet": {
"ID": 0, "Name": 1,
"Item0": 18, "Item1": 19, "Item2": 20, "Item3": 21, "Item4": 22,
"Item5": 23, "Item6": 24, "Item7": 25, "Item8": 26, "Item9": 27,
"Spell0": 28, "Spell1": 29, "Spell2": 30, "Spell3": 31, "Spell4": 32,
"Spell5": 33, "Spell6": 34, "Spell7": 35, "Spell8": 36, "Spell9": 37,
"Threshold0": 38, "Threshold1": 39, "Threshold2": 40, "Threshold3": 41,
"Threshold4": 42, "Threshold5": 43, "Threshold6": 44, "Threshold7": 45,
"Threshold8": 46, "Threshold9": 47
}
}

View file

@ -1597,6 +1597,7 @@ struct ItemQueryResponseData {
// Gem socket slots (WotLK/TBC): 0=no socket; color mask: 1=Meta,2=Red,4=Yellow,8=Blue
std::array<uint32_t, 3> socketColor{};
uint32_t socketBonus = 0; // enchantmentId of socket bonus; 0=none
uint32_t itemSetId = 0; // ItemSet.dbc entry; 0=not part of a set
bool valid = false;
};

View file

@ -2936,8 +2936,11 @@ bool ItemQueryResponseParser::parse(network::Packet& packet, ItemQueryResponseDa
// TotemCategory(4) = 48 bytes before sockets
constexpr size_t kPreSocketSkip = 48;
if (packet.getReadPos() + kPreSocketSkip + 28 <= packet.getSize()) {
for (size_t i = 0; i < kPreSocketSkip / 4; ++i)
packet.readUInt32();
// LockID(0), Material(1), Sheath(2), RandomProperty(3), RandomSuffix(4), Block(5)
for (size_t i = 0; i < 6; ++i) packet.readUInt32();
data.itemSetId = packet.readUInt32(); // ItemSet(6)
// MaxDurability(7), Area(8), Map(9), BagFamily(10), TotemCategory(11)
for (size_t i = 0; i < 5; ++i) packet.readUInt32();
// 3 socket slots: socketColor (4 bytes each)
data.socketColor[0] = packet.readUInt32();
data.socketColor[1] = packet.readUInt32();

View file

@ -2536,6 +2536,36 @@ 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;
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;
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);
}
}
}
auto setIt = s_setNames.find(info.itemSetId);
const char* setName = (setIt != s_setNames.end()) ? setIt->second.c_str() : nullptr;
ImGui::Spacing();
if (setName)
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "%s", setName);
else
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "Set (id %u)", info.itemSetId);
}
if (info.startQuestId != 0) {
ImGui::TextColored(ImVec4(1.0f, 0.82f, 0.0f, 1.0f), "Begins a Quest");
}