diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 30149c40..bf2c3915 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1252,6 +1252,7 @@ public: }; const std::vector& getQuestLog() const { return questLog_; } void abandonQuest(uint32_t questId); + void shareQuestWithParty(uint32_t questId); // CMSG_PUSHQUESTTOPARTY bool requestQuestQuery(uint32_t questId, bool force = false); bool isQuestTracked(uint32_t questId) const { return trackedQuestIds_.count(questId) > 0; } void setQuestTracked(uint32_t questId, bool tracked) { diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 611319d9..3431e927 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -16096,6 +16096,28 @@ void GameHandler::abandonQuest(uint32_t questId) { gossipPois_.end()); } +void GameHandler::shareQuestWithParty(uint32_t questId) { + if (state != WorldState::IN_WORLD || !socket) { + addSystemChatMessage("Cannot share quest: not in world."); + return; + } + if (!isInGroup()) { + addSystemChatMessage("You must be in a group to share a quest."); + return; + } + network::Packet pkt(wireOpcode(Opcode::CMSG_PUSHQUESTTOPARTY)); + pkt.writeUInt32(questId); + socket->send(pkt); + // Local feedback: find quest title + for (const auto& q : questLog_) { + if (q.questId == questId && !q.title.empty()) { + addSystemChatMessage("Sharing quest: " + q.title); + return; + } + } + addSystemChatMessage("Quest shared."); +} + void GameHandler::handleQuestRequestItems(network::Packet& packet) { QuestRequestItemsData data; if (!QuestRequestItemsParser::parse(packet, data)) { diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index f6a1fa76..511977d0 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -6833,6 +6833,11 @@ void GameScreen::renderQuestObjectiveTracker(game::GameHandler& gameHandler) { gameHandler.setQuestTracked(q.questId, true); } } + if (gameHandler.isInGroup() && !q.complete) { + if (ImGui::MenuItem("Share Quest")) { + gameHandler.shareQuestWithParty(q.questId); + } + } if (!q.complete) { ImGui::Separator(); if (ImGui::MenuItem("Abandon Quest")) { diff --git a/src/ui/quest_log_screen.cpp b/src/ui/quest_log_screen.cpp index d89f6ab4..c343baa5 100644 --- a/src/ui/quest_log_screen.cpp +++ b/src/ui/quest_log_screen.cpp @@ -377,6 +377,11 @@ void QuestLogScreen::render(game::GameHandler& gameHandler, InventoryScreen& inv if (ImGui::MenuItem(tracked ? "Untrack" : "Track")) { gameHandler.setQuestTracked(q.questId, !tracked); } + if (gameHandler.isInGroup() && !q.complete) { + if (ImGui::MenuItem("Share Quest")) { + gameHandler.shareQuestWithParty(q.questId); + } + } if (!q.complete) { ImGui::Separator(); if (ImGui::MenuItem("Abandon Quest")) { @@ -559,12 +564,19 @@ void QuestLogScreen::render(game::GameHandler& gameHandler, InventoryScreen& inv } } - // Track / Abandon buttons + // Track / Share / Abandon buttons ImGui::Separator(); bool isTracked = gameHandler.isQuestTracked(sel.questId); if (ImGui::Button(isTracked ? "Untrack" : "Track", ImVec2(100.0f, 0.0f))) { gameHandler.setQuestTracked(sel.questId, !isTracked); } + if (gameHandler.isInGroup() && !sel.complete) { + ImGui::SameLine(); + if (ImGui::Button("Share", ImVec2(80.0f, 0.0f))) { + gameHandler.shareQuestWithParty(sel.questId); + } + if (ImGui::IsItemHovered()) ImGui::SetTooltip("Share this quest with your party"); + } if (!sel.complete) { ImGui::SameLine(); if (ImGui::Button("Abandon Quest", ImVec2(150.0f, 0.0f))) {