diff --git a/include/ui/inventory_screen.hpp b/include/ui/inventory_screen.hpp index 9d4f18ef..3453e966 100644 --- a/include/ui/inventory_screen.hpp +++ b/include/ui/inventory_screen.hpp @@ -171,11 +171,18 @@ private: void renderHeldItem(); bool bagHasAnyItems(const game::Inventory& inventory, int bagIndex) const; - // Drop confirmation + // Drop confirmation (drag-outside-window destroy) bool dropConfirmOpen_ = false; int dropBackpackIndex_ = -1; std::string dropItemName_; + // Destroy confirmation (Shift+right-click destroy) + bool destroyConfirmOpen_ = false; + uint8_t destroyBag_ = 0xFF; + uint8_t destroySlot_ = 0; + uint8_t destroyCount_ = 1; + std::string destroyItemName_; + // Pending chat item link from shift-click std::string pendingChatItemLink_; diff --git a/src/ui/inventory_screen.cpp b/src/ui/inventory_screen.cpp index c6e04f38..899944c6 100644 --- a/src/ui/inventory_screen.cpp +++ b/src/ui/inventory_screen.cpp @@ -834,6 +834,33 @@ void InventoryScreen::render(game::Inventory& inventory, uint64_t moneyCopper) { ImGui::EndPopup(); } + // Shift+right-click destroy confirmation popup + if (destroyConfirmOpen_) { + ImVec2 mousePos = ImGui::GetIO().MousePos; + ImGui::SetNextWindowPos(ImVec2(mousePos.x - 80.0f, mousePos.y - 20.0f), ImGuiCond_Always); + ImGui::OpenPopup("##DestroyItem"); + destroyConfirmOpen_ = false; + } + if (ImGui::BeginPopup("##DestroyItem", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar)) { + ImGui::TextColored(ImVec4(1.0f, 0.4f, 0.4f, 1.0f), "Destroy"); + ImGui::TextUnformatted(destroyItemName_.c_str()); + ImGui::Spacing(); + if (ImGui::Button("Yes, Destroy", ImVec2(110, 0))) { + if (gameHandler_) { + gameHandler_->destroyItem(destroyBag_, destroySlot_, destroyCount_); + } + destroyItemName_.clear(); + inventoryDirty = true; + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(70, 0))) { + destroyItemName_.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + // Draw held item at cursor renderHeldItem(); } @@ -1783,9 +1810,28 @@ void InventoryScreen::renderItemSlot(game::Inventory& inventory, const game::Ite } } + // Shift+right-click: open destroy confirmation for non-quest items + if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Right) && + !holdingItem && ImGui::GetIO().KeyShift && item.itemId != 0 && item.bindType != 4) { + destroyConfirmOpen_ = true; + destroyItemName_ = item.name; + destroyCount_ = static_cast(std::clamp( + std::max(1u, item.stackCount), 1u, 255u)); + if (kind == SlotKind::BACKPACK && backpackIndex >= 0) { + destroyBag_ = 0xFF; + destroySlot_ = static_cast(23 + backpackIndex); + } else if (kind == SlotKind::BACKPACK && isBagSlot) { + destroyBag_ = static_cast(19 + bagIndex); + destroySlot_ = static_cast(bagSlotIndex); + } else if (kind == SlotKind::EQUIPMENT) { + destroyBag_ = 0xFF; + destroySlot_ = static_cast(equipSlot); + } + } + // Right-click: bank deposit (if bank open), vendor sell (if vendor mode), or auto-equip/use // Note: InvisibleButton only tracks left-click by default, so use IsItemHovered+IsMouseClicked - if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Right) && !holdingItem && gameHandler_) { + if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Right) && !holdingItem && !ImGui::GetIO().KeyShift && gameHandler_) { LOG_WARNING("Right-click slot: kind=", (int)kind, " backpackIndex=", backpackIndex, " bagIndex=", bagIndex, " bagSlotIndex=", bagSlotIndex, @@ -2192,6 +2238,16 @@ void InventoryScreen::renderItemTooltip(const game::ItemDef& item, const game::I } } + // Destroy hint (not shown for quest items) + if (item.itemId != 0 && item.bindType != 4) { + ImGui::Spacing(); + if (ImGui::GetIO().KeyShift) { + ImGui::TextColored(ImVec4(1.0f, 0.45f, 0.45f, 0.9f), "Shift+RClick to destroy"); + } else { + ImGui::TextDisabled("Shift+RClick to destroy"); + } + } + ImGui::EndTooltip(); }