mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Show achievement names from Achievement.dbc in chat notifications
Previously "Achievement earned! (ID 1234)" was the only message. Now loadAchievementNameCache() lazily loads Achievement.dbc (field 4 = Title, verified against WotLK 3.3.5a binary) on first earned event and shows "Achievement earned: Level 10" or "Player has earned the achievement: ..." Falls back to ID if DBC is unavailable or entry is missing.
This commit is contained in:
parent
e12e399c0a
commit
63c8dfa304
3 changed files with 50 additions and 6 deletions
|
|
@ -28,6 +28,7 @@
|
|||
"ReputationBase0": 10, "ReputationBase1": 11,
|
||||
"ReputationBase2": 12, "ReputationBase3": 13
|
||||
},
|
||||
"Achievement": { "ID": 0, "Title": 4, "Description": 21 },
|
||||
"AreaTable": { "ID": 0, "ExploreFlag": 3 },
|
||||
"CreatureDisplayInfoExtra": {
|
||||
"ID": 0, "RaceID": 1, "SexID": 2, "SkinID": 3, "FaceID": 4,
|
||||
|
|
|
|||
|
|
@ -1979,6 +1979,11 @@ private:
|
|||
struct SpellNameEntry { std::string name; std::string rank; uint32_t schoolMask = 0; };
|
||||
std::unordered_map<uint32_t, SpellNameEntry> spellNameCache_;
|
||||
bool spellNameCacheLoaded_ = false;
|
||||
|
||||
// Achievement name cache (lazy-loaded from Achievement.dbc on first earned event)
|
||||
std::unordered_map<uint32_t, std::string> achievementNameCache_;
|
||||
bool achievementNameCacheLoaded_ = false;
|
||||
void loadAchievementNameCache();
|
||||
std::vector<TrainerTab> trainerTabs_;
|
||||
void handleTrainerList(network::Packet& packet);
|
||||
void loadSpellNameCache();
|
||||
|
|
|
|||
|
|
@ -17094,6 +17094,30 @@ void GameHandler::sendLootRoll(uint64_t objectGuid, uint32_t slot, uint8_t rollT
|
|||
// PackedTime date — uint32 bitfield (seconds since epoch)
|
||||
// uint32 realmFirst — how many on realm also got it (0 = realm first)
|
||||
// ---------------------------------------------------------------------------
|
||||
void GameHandler::loadAchievementNameCache() {
|
||||
if (achievementNameCacheLoaded_) return;
|
||||
achievementNameCacheLoaded_ = true;
|
||||
|
||||
auto* am = core::Application::getInstance().getAssetManager();
|
||||
if (!am || !am->isInitialized()) return;
|
||||
|
||||
auto dbc = am->loadDBC("Achievement.dbc");
|
||||
if (!dbc || !dbc->isLoaded() || dbc->getFieldCount() < 22) return;
|
||||
|
||||
const auto* achL = pipeline::getActiveDBCLayout()
|
||||
? pipeline::getActiveDBCLayout()->getLayout("Achievement") : nullptr;
|
||||
uint32_t titleField = achL ? achL->field("Title") : 4;
|
||||
if (titleField == 0xFFFFFFFF) titleField = 4;
|
||||
|
||||
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);
|
||||
}
|
||||
LOG_INFO("Achievement: loaded ", achievementNameCache_.size(), " names from Achievement.dbc");
|
||||
}
|
||||
|
||||
void GameHandler::handleAchievementEarned(network::Packet& packet) {
|
||||
size_t remaining = packet.getSize() - packet.getReadPos();
|
||||
if (remaining < 16) return; // guid(8) + id(4) + date(4)
|
||||
|
|
@ -17102,12 +17126,20 @@ void GameHandler::handleAchievementEarned(network::Packet& packet) {
|
|||
uint32_t achievementId = packet.readUInt32();
|
||||
/*uint32_t date =*/ packet.readUInt32(); // PackedTime — not displayed
|
||||
|
||||
loadAchievementNameCache();
|
||||
auto nameIt = achievementNameCache_.find(achievementId);
|
||||
const std::string& achName = (nameIt != achievementNameCache_.end())
|
||||
? nameIt->second : std::string();
|
||||
|
||||
// Show chat notification
|
||||
bool isSelf = (guid == playerGuid);
|
||||
if (isSelf) {
|
||||
char buf[128];
|
||||
std::snprintf(buf, sizeof(buf),
|
||||
"Achievement earned! (ID %u)", achievementId);
|
||||
char buf[256];
|
||||
if (!achName.empty()) {
|
||||
std::snprintf(buf, sizeof(buf), "Achievement earned: %s", achName.c_str());
|
||||
} else {
|
||||
std::snprintf(buf, sizeof(buf), "Achievement earned! (ID %u)", achievementId);
|
||||
}
|
||||
addSystemChatMessage(buf);
|
||||
|
||||
if (achievementEarnedCallback_) {
|
||||
|
|
@ -17127,13 +17159,19 @@ void GameHandler::handleAchievementEarned(network::Packet& packet) {
|
|||
senderName = tmp;
|
||||
}
|
||||
char buf[256];
|
||||
std::snprintf(buf, sizeof(buf),
|
||||
"%s has earned an achievement! (ID %u)", senderName.c_str(), achievementId);
|
||||
if (!achName.empty()) {
|
||||
std::snprintf(buf, sizeof(buf), "%s has earned the achievement: %s",
|
||||
senderName.c_str(), achName.c_str());
|
||||
} else {
|
||||
std::snprintf(buf, sizeof(buf), "%s has earned an achievement! (ID %u)",
|
||||
senderName.c_str(), achievementId);
|
||||
}
|
||||
addSystemChatMessage(buf);
|
||||
}
|
||||
|
||||
LOG_INFO("SMSG_ACHIEVEMENT_EARNED: guid=0x", std::hex, guid, std::dec,
|
||||
" achievementId=", achievementId, " self=", isSelf);
|
||||
" achievementId=", achievementId, " self=", isSelf,
|
||||
achName.empty() ? "" : " name=", achName);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue