mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Add Achievements tab to character screen with search filter
This commit is contained in:
parent
c9ea61aba7
commit
c9cfa864bf
2 changed files with 58 additions and 0 deletions
|
|
@ -1215,6 +1215,13 @@ public:
|
|||
using AchievementEarnedCallback = std::function<void(uint32_t achievementId, const std::string& name)>;
|
||||
void setAchievementEarnedCallback(AchievementEarnedCallback cb) { achievementEarnedCallback_ = std::move(cb); }
|
||||
const std::unordered_set<uint32_t>& getEarnedAchievements() const { return earnedAchievements_; }
|
||||
/// Returns the name of an achievement by ID, or empty string if unknown.
|
||||
const std::string& getAchievementName(uint32_t id) const {
|
||||
auto it = achievementNameCache_.find(id);
|
||||
if (it != achievementNameCache_.end()) return it->second;
|
||||
static const std::string kEmpty;
|
||||
return kEmpty;
|
||||
}
|
||||
|
||||
// Server-triggered music callback — fires when SMSG_PLAY_MUSIC is received.
|
||||
// The soundId corresponds to a SoundEntries.dbc record. The receiver is
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,57 @@ void InventoryScreen::renderCharacterScreen(game::GameHandler& gameHandler) {
|
|||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Achievements")) {
|
||||
const auto& earned = gameHandler.getEarnedAchievements();
|
||||
if (earned.empty()) {
|
||||
ImGui::Spacing();
|
||||
ImGui::TextDisabled("No achievements earned yet.");
|
||||
} else {
|
||||
static char achieveFilter[128] = {};
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
ImGui::InputTextWithHint("##achsearch", "Search achievements...",
|
||||
achieveFilter, sizeof(achieveFilter));
|
||||
ImGui::Separator();
|
||||
|
||||
char filterLower[128];
|
||||
for (size_t i = 0; i < sizeof(achieveFilter); ++i)
|
||||
filterLower[i] = static_cast<char>(tolower(static_cast<unsigned char>(achieveFilter[i])));
|
||||
|
||||
ImGui::BeginChild("##AchList", ImVec2(0, 0), false);
|
||||
// Sort by ID for stable ordering
|
||||
std::vector<uint32_t> sortedIds(earned.begin(), earned.end());
|
||||
std::sort(sortedIds.begin(), sortedIds.end());
|
||||
int shown = 0;
|
||||
for (uint32_t id : sortedIds) {
|
||||
const std::string& name = gameHandler.getAchievementName(id);
|
||||
const char* displayName = name.empty() ? nullptr : name.c_str();
|
||||
if (displayName == nullptr) continue; // skip unknown achievements
|
||||
|
||||
// Apply filter
|
||||
if (filterLower[0] != '\0') {
|
||||
// simple case-insensitive substring match
|
||||
std::string lower;
|
||||
lower.reserve(name.size());
|
||||
for (char c : name) lower += static_cast<char>(tolower(static_cast<unsigned char>(c)));
|
||||
if (lower.find(filterLower) == std::string::npos) continue;
|
||||
}
|
||||
|
||||
ImGui::PushID(static_cast<int>(id));
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.84f, 0.0f, 1.0f), "[Achievement]");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", displayName);
|
||||
ImGui::PopID();
|
||||
++shown;
|
||||
}
|
||||
if (shown == 0 && filterLower[0] != '\0') {
|
||||
ImGui::TextDisabled("No achievements match the filter.");
|
||||
}
|
||||
ImGui::Text("Total: %d", static_cast<int>(earned.size()));
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue