mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: show achievement description and point value in tooltip
Hovering an earned achievement now shows its point value (gold badge), description text from Achievement.dbc field 21, and the earn date. loadAchievementNameCache() also populates achievementDescCache_ and achievementPointsCache_ in a single DBC pass; Points field (39) added to the WotLK Achievement DBC layout.
This commit is contained in:
parent
bc0d98adae
commit
d44f5e6560
4 changed files with 44 additions and 4 deletions
|
|
@ -31,7 +31,7 @@
|
|||
"ReputationBase0": 10, "ReputationBase1": 11,
|
||||
"ReputationBase2": 12, "ReputationBase3": 13
|
||||
},
|
||||
"Achievement": { "ID": 0, "Title": 4, "Description": 21 },
|
||||
"Achievement": { "ID": 0, "Title": 4, "Description": 21, "Points": 39 },
|
||||
"AreaTable": { "ID": 0, "MapID": 1, "ParentAreaNum": 2, "ExploreFlag": 3 },
|
||||
"CreatureDisplayInfoExtra": {
|
||||
"ID": 0, "RaceID": 1, "SexID": 2, "SkinID": 3, "FaceID": 4,
|
||||
|
|
|
|||
|
|
@ -1429,6 +1429,18 @@ public:
|
|||
static const std::string kEmpty;
|
||||
return kEmpty;
|
||||
}
|
||||
/// Returns the description of an achievement by ID, or empty string if unknown.
|
||||
const std::string& getAchievementDescription(uint32_t id) const {
|
||||
auto it = achievementDescCache_.find(id);
|
||||
if (it != achievementDescCache_.end()) return it->second;
|
||||
static const std::string kEmpty;
|
||||
return kEmpty;
|
||||
}
|
||||
/// Returns the point value of an achievement by ID, or 0 if unknown.
|
||||
uint32_t getAchievementPoints(uint32_t id) const {
|
||||
auto it = achievementPointsCache_.find(id);
|
||||
return (it != achievementPointsCache_.end()) ? it->second : 0u;
|
||||
}
|
||||
|
||||
// Server-triggered music callback — fires when SMSG_PLAY_MUSIC is received.
|
||||
// The soundId corresponds to a SoundEntries.dbc record. The receiver is
|
||||
|
|
@ -2590,8 +2602,10 @@ private:
|
|||
std::unordered_map<uint32_t, SpellNameEntry> spellNameCache_;
|
||||
bool spellNameCacheLoaded_ = false;
|
||||
|
||||
// Achievement name cache (lazy-loaded from Achievement.dbc on first earned event)
|
||||
// Achievement caches (lazy-loaded from Achievement.dbc on first earned event)
|
||||
std::unordered_map<uint32_t, std::string> achievementNameCache_;
|
||||
std::unordered_map<uint32_t, std::string> achievementDescCache_;
|
||||
std::unordered_map<uint32_t, uint32_t> achievementPointsCache_;
|
||||
bool achievementNameCacheLoaded_ = false;
|
||||
void loadAchievementNameCache();
|
||||
// Set of achievement IDs earned by the player (populated from SMSG_ALL_ACHIEVEMENT_DATA)
|
||||
|
|
|
|||
|
|
@ -20303,12 +20303,23 @@ void GameHandler::loadAchievementNameCache() {
|
|||
? pipeline::getActiveDBCLayout()->getLayout("Achievement") : nullptr;
|
||||
uint32_t titleField = achL ? achL->field("Title") : 4;
|
||||
if (titleField == 0xFFFFFFFF) titleField = 4;
|
||||
uint32_t descField = achL ? achL->field("Description") : 0xFFFFFFFF;
|
||||
uint32_t ptsField = achL ? achL->field("Points") : 0xFFFFFFFF;
|
||||
|
||||
uint32_t fieldCount = dbc->getFieldCount();
|
||||
for (uint32_t i = 0; i < dbc->getRecordCount(); ++i) {
|
||||
uint32_t id = dbc->getUInt32(i, 0);
|
||||
if (id == 0) continue;
|
||||
std::string title = dbc->getString(i, titleField);
|
||||
if (!title.empty()) achievementNameCache_[id] = std::move(title);
|
||||
if (descField != 0xFFFFFFFF && descField < fieldCount) {
|
||||
std::string desc = dbc->getString(i, descField);
|
||||
if (!desc.empty()) achievementDescCache_[id] = std::move(desc);
|
||||
}
|
||||
if (ptsField != 0xFFFFFFFF && ptsField < fieldCount) {
|
||||
uint32_t pts = dbc->getUInt32(i, ptsField);
|
||||
if (pts > 0) achievementPointsCache_[id] = pts;
|
||||
}
|
||||
}
|
||||
LOG_INFO("Achievement: loaded ", achievementNameCache_.size(), " names from Achievement.dbc");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17559,7 +17559,22 @@ void GameScreen::renderAchievementWindow(game::GameHandler& gameHandler) {
|
|||
ImGui::TextUnformatted(display.c_str());
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Achievement ID: %u", id);
|
||||
// Points badge
|
||||
uint32_t pts = gameHandler.getAchievementPoints(id);
|
||||
if (pts > 0) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.0f, 1.0f),
|
||||
"%u Achievement Point%s", pts, pts == 1 ? "" : "s");
|
||||
ImGui::Separator();
|
||||
}
|
||||
// Description
|
||||
const std::string& desc = gameHandler.getAchievementDescription(id);
|
||||
if (!desc.empty()) {
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + 320.0f);
|
||||
ImGui::TextUnformatted(desc.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::Spacing();
|
||||
}
|
||||
// Earn date
|
||||
uint32_t packed = gameHandler.getAchievementDate(id);
|
||||
if (packed != 0) {
|
||||
// WoW PackedTime: year[31:25] month[24:21] day[20:17] weekday[16:14] hour[13:9] minute[8:3]
|
||||
|
|
@ -17573,7 +17588,7 @@ void GameScreen::renderAchievementWindow(game::GameHandler& gameHandler) {
|
|||
"Jul","Aug","Sep","Oct","Nov","Dec"
|
||||
};
|
||||
const char* mname = (month >= 1 && month <= 12) ? kMonths[month - 1] : "?";
|
||||
ImGui::Text("Earned: %s %d, %d %02d:%02d", mname, day, year, hour, minute);
|
||||
ImGui::TextDisabled("Earned: %s %d, %d %02d:%02d", mname, day, year, hour, minute);
|
||||
}
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue