diff --git a/conf/mod_aoe_loot.conf.dist b/conf/mod_aoe_loot.conf.dist index cde12d5..610c6b1 100644 --- a/conf/mod_aoe_loot.conf.dist +++ b/conf/mod_aoe_loot.conf.dist @@ -48,11 +48,20 @@ AOELoot.DefaultLootThreshold = 2 # AOELoot.Debug # Description: Enables debugging mode. +# Values: 0 = Disabled +# 1 = Enabled # Default: 0 (Disabled) -# 1 - (Enabled) AOELoot.Debug = 0 +# AOELoot.QuestItemsAsRegular +# Description: Treat quest items as regular loot instead of processing them separately +# Values: 0 = Process quest items separately (default behavior) +# 1 = Treat quest items as regular loot +# Default: 0 (Process separately) + +AOELoot.QuestItemsAsRegular = 0 + # Chat Commands # .aoeloot off If module is enabled, disables AoE looting for player # .aoeloot on If module is enabled, reenables AoE looting for player diff --git a/src/aoe_loot.cpp b/src/aoe_loot.cpp index a93ff20..14da0da 100644 --- a/src/aoe_loot.cpp +++ b/src/aoe_loot.cpp @@ -715,14 +715,23 @@ bool AoeLootCommandScript::TriggerAoeLootCommand(ChatHandler* handler, Optional< } } - // Process quest items separately if they exist - for (uint8 i = 0; i < loot->quest_items.size(); ++i) + // Handle quest items based on configuration + if (ShouldProcessQuestItemsSeparately()) { - uint8 questLootSlot = loot->items.size() + i; - ProcessSingleLootSlot(player, lguid, questLootSlot); - if (debugMode) + // Process quest items separately (default behavior) + ProcessQuestItemsForPlayer(player, lguid, loot); + } + else + { + // Treat quest items as regular loot (like quest loot party mod) + for (uint8 i = 0; i < loot->quest_items.size(); ++i) { - LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item in slot {}", questLootSlot); + uint8 questLootSlot = loot->items.size() + i; + ProcessSingleLootSlot(player, lguid, questLootSlot); + if (debugMode) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item (as regular) in slot {}", questLootSlot); + } } } @@ -975,6 +984,86 @@ LootMethod AoeLootGroupScript::GetLootMethodFromConfig(uint32 configValue) } } +// Quest item processing functions +bool AoeLootCommandScript::ShouldProcessQuestItemsSeparately() +{ + return !sConfigMgr->GetOption("AOELoot.QuestItemsAsRegular", false); +} + +bool AoeLootCommandScript::IsQuestItemForPlayer(Player* player, uint32 itemId) +{ + if (!player) + return false; + + const ItemTemplate* itemTemplate = sObjectMgr->GetItemTemplate(itemId); + if (!itemTemplate) + return false; + + // Check if this item starts a quest or is a quest item + if (itemTemplate->StartQuest != 0) + return true; + + // Check if player has quests requiring this item + for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) + { + uint32 questId = player->GetQuestSlotQuestId(slot); + if (questId == 0) + continue; + + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + continue; + + // Check quest objectives for this item + for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) + { + if (quest->RequiredItemId[i] == itemId) + { + // Check if player still needs this item for the quest + uint32 currentCount = player->GetItemCount(itemId, true); + uint32 requiredCount = quest->RequiredItemCount[i]; + + if (currentCount < requiredCount) + { + return true; + } + } + } + } + + return false; +} + +bool AoeLootCommandScript::ProcessQuestItemsForPlayer(Player* player, ObjectGuid lguid, Loot* loot) +{ + if (!player || !loot) + return false; + + bool processedAny = false; + bool debugMode = sConfigMgr->GetOption("AOELoot.Debug", false); + + for (uint8 i = 0; i < loot->quest_items.size(); ++i) + { + LootItem& questItem = loot->quest_items[i]; + + // Check if this quest item is for the current player + if (IsQuestItemForPlayer(player, questItem.itemid)) + { + uint8 questLootSlot = loot->items.size() + i; + ProcessSingleLootSlot(player, lguid, questLootSlot); + processedAny = true; + + if (debugMode) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item {} from slot {} for player {}", + questItem.itemid, questLootSlot, player->GetName()); + } + } + } + + return processedAny; +} + // Add script registrations void AddSC_AoeLoot() { diff --git a/src/aoe_loot.h b/src/aoe_loot.h index 4dd884b..a9f8547 100644 --- a/src/aoe_loot.h +++ b/src/aoe_loot.h @@ -11,6 +11,8 @@ #include "ChatCommand.h" #include "ChatCommandArgs.h" #include "AccountMgr.h" +#include "ObjectMgr.h" +#include "QuestDef.h" #include #include #include @@ -49,6 +51,11 @@ public: static bool ProcessCreatureGold(Player* player, Creature* creature); static void ReleaseAndCleanupLoot(ObjectGuid lguid, Player* player, Loot* loot); + // Quest item processing functions + static bool IsQuestItemForPlayer(Player* player, uint32 itemId); + static bool ShouldProcessQuestItemsSeparately(); + static bool ProcessQuestItemsForPlayer(Player* player, ObjectGuid lguid, Loot* loot); + // Renamed validation functions static bool ValidateLootingDistance(Player* player, ObjectGuid lguid, float maxDistance = 0.0f); static bool IsAoeLootEnabledForPlayer(Player* player);