From bbf4806fe89b507be61c8c9bdca4ad0a1a7d37ea Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 11 Mar 2026 21:19:47 -0700 Subject: [PATCH] Add item search filter to vendor window --- include/ui/game_screen.hpp | 3 +++ src/ui/game_screen.cpp | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/ui/game_screen.hpp b/include/ui/game_screen.hpp index d81b69a3..4d41ea86 100644 --- a/include/ui/game_screen.hpp +++ b/include/ui/game_screen.hpp @@ -362,6 +362,9 @@ private: char mailBodyBuffer_[2048] = ""; int mailComposeMoney_[3] = {0, 0, 0}; // gold, silver, copper + // Vendor search filter + char vendorSearchFilter_[128] = ""; + // Auction house UI state char auctionSearchName_[256] = ""; int auctionLevelMin_ = 0; diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index e94d790a..19d55fda 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -7862,6 +7862,10 @@ void GameScreen::renderVendorWindow(game::GameHandler& gameHandler) { if (vendor.items.empty()) { ImGui::TextDisabled("This vendor has nothing for sale."); } else { + ImGui::SetNextItemWidth(-1.0f); + ImGui::InputTextWithHint("##VendorSearch", "Search...", vendorSearchFilter_, sizeof(vendorSearchFilter_)); + ImGui::Spacing(); + if (ImGui::BeginTable("VendorTable", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupColumn("##icon", ImGuiTableColumnFlags_WidthFixed, 22.0f); ImGui::TableSetupColumn("Item", ImGuiTableColumnFlags_WidthStretch); @@ -7870,15 +7874,31 @@ void GameScreen::renderVendorWindow(game::GameHandler& gameHandler) { ImGui::TableSetupColumn("Buy", ImGuiTableColumnFlags_WidthFixed, 50.0f); ImGui::TableHeadersRow(); + std::string vendorFilter(vendorSearchFilter_); + // Lowercase filter for case-insensitive match + for (char& c : vendorFilter) c = static_cast(std::tolower(static_cast(c))); + for (int vi = 0; vi < static_cast(vendor.items.size()); ++vi) { const auto& item = vendor.items[vi]; - ImGui::TableNextRow(); - ImGui::PushID(vi); // Proactively ensure vendor item info is loaded gameHandler.ensureItemInfo(item.itemId); auto* info = gameHandler.getItemInfo(item.itemId); + // Apply search filter + if (!vendorFilter.empty()) { + std::string nameLC = info && info->valid ? info->name : ("Item " + std::to_string(item.itemId)); + for (char& c : nameLC) c = static_cast(std::tolower(static_cast(c))); + if (nameLC.find(vendorFilter) == std::string::npos) { + ImGui::PushID(vi); + ImGui::PopID(); + continue; + } + } + + ImGui::TableNextRow(); + ImGui::PushID(vi); + // Icon column ImGui::TableSetColumnIndex(0); {