From 856281b34edd2794a09f1e0c69be787fd5d28aab Mon Sep 17 00:00:00 2001 From: TerraByte Date: Tue, 1 Apr 2025 04:03:10 -0500 Subject: [PATCH] Update aoe_loot.cpp --- mod-aoe-loot/src/aoe_loot.cpp | 123 ++++++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 37 deletions(-) diff --git a/mod-aoe-loot/src/aoe_loot.cpp b/mod-aoe-loot/src/aoe_loot.cpp index baa25de..e12f10f 100644 --- a/mod-aoe-loot/src/aoe_loot.cpp +++ b/mod-aoe-loot/src/aoe_loot.cpp @@ -1,11 +1,16 @@ #include "aoe_loot.h" +#include "ScriptMgr.h" #include "LootMgr.h" #include "WorldSession.h" // Include for HandleAutostoreLootItemOpcode -#include "WorldPacket.h" // Include for WorldPacket +#include "WorldPacket.h" #include "Player.h" +#include "PlayerScript.h" #include "Chat.h" +#include "WorldObjectScript.h" #include "Creature.h" #include "Config.h" +#include "Log.h" +#include "Map.h" void AOELootPlayer::OnPlayerLogin(Player* player) @@ -21,74 +26,118 @@ bool AOELootServer::CanPacketReceive(WorldSession* session, WorldPacket& packet) { if (packet.GetOpcode() == CMSG_LOOT) { + // Check if AoE Loot is enabled in the config if (!sConfigMgr->GetOption("AOELoot.Enable", true)) - return true; + return false; + // Grab the player from the session Player* player = session->GetPlayer(); - if (player->GetGroup() && !sConfigMgr->GetOption("AOELoot.Group", true)) - return true; - - float range = sConfigMgr->GetOption("AOELoot.Range", 55.0); + // Set AoE Loot range from config + float range = sConfigMgr->GetOption("AOELoot.Range", 120.0); + // Create a list of creature corpses within the specified range std::list lootcreature; player->GetDeadCreatureListInGrid(lootcreature, range); - ObjectGuid mainGuid; - packet >> mainGuid; - + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: Found {} nearby corpses within range.", lootcreature.size()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Found {} nearby corpses within range.", lootcreature.size())); + } + // Cycle through the list of corpses for (auto* creature : lootcreature) { + // Check if the creature is valid. + if (!creature) + continue; - if (creature->GetGUID() == mainGuid) - { - continue; // Skip AOE loot for the main mob + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: Processing creature with {}", creature->GetGUID().ToString()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Processing creature with {}", creature->GetGUID().ToString())); } + + // Check if the player is allowed to loot the creature if (!player->GetMap()->Instanceable() && !player->isAllowedToLoot(creature)) continue; + player->SetLootGUID(creature->GetGUID()); + + // Get the loot object from the creature Loot* loot = &creature->loot; - if (sConfigMgr->GetOption("AOELoot.Debug", true)){ - LOG_DEBUG("module.aoe_loot", "Quest Items Size for {}: {}", creature->GetAIName(), loot->quest_items.size()); - ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Quest Items Size for {}: {}", creature->GetAIName(), loot->quest_items.size())); - } - // Process quest items - for (size_t i = 0; i < loot->quest_items.size(); ++i) + + // Get the max slots of loot from creature. Uses: hasLootFor(Player* player). + uint32 maxSlots = loot->GetMaxSlotInLootFor(player); + + if (sConfigMgr->GetOption("AOELoot.Debug", true)) { - player->SetLootGUID(creature->GetGUID()); - WorldPacket autostorePacket(CMSG_AUTOSTORE_LOOT_ITEM, 1); - autostorePacket << i; // Use the index i as the slot for this creature - session->HandleAutostoreLootItemOpcode(autostorePacket); + LOG_DEBUG("module.aoe_loot", "Max Slots for {}: {}", creature->GetAIName(), maxSlots); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Max Slots for {}: {}", creature->GetAIName(), maxSlots)); } - if (sConfigMgr->GetOption("AOELoot.Debug", true)){ - LOG_DEBUG("module.aoe_loot", "Regular Items Size for {}: {}", creature->GetAIName(), loot->items.size()); - ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Regular Items Size for {}: {}", creature->GetAIName(), loot->items.size())); - } - // Process regular items - for (size_t i = 0; i < loot->items.size(); ++i) + // Cycle through the loot slots + for (uint32 i = 0; i < maxSlots; ++i) { - player->SetLootGUID(creature->GetGUID()); + // Create a packet to autostore the loot item WorldPacket autostorePacket(CMSG_AUTOSTORE_LOOT_ITEM, 1); - autostorePacket << i; // Use the index i as the slot for this creature - session->HandleAutostoreLootItemOpcode(autostorePacket); + // Set the slot index in the packet + autostorePacket << i; + // Send the packet to autostore the loot item in the specified slot + LootItem* lootItem = loot->LootItemInSlot(i, player); + if (lootItem) + { + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "Loot Item ID: {} Count: {} Slot: {} Creature: {}", lootItem->itemid, static_cast(lootItem->count), i, creature->GetAIName()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: (Slot {}): Found item (ID: {}) Count: {} on {}", i, lootItem->itemid, static_cast(lootItem->count), creature->GetAIName())); + } + if (lootItem->needs_quest) // Check if it's a quest item + { + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "Loot Item ID: {} Count: {} Slot: {} Creature: {}", lootItem->itemid, static_cast(lootItem->count), i, creature->GetAIName()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot (Slot {} - Quest): Attempting to loot item (ID: {}) Count: {} on {}", i, lootItem->itemid, static_cast(lootItem->count), creature->GetAIName())); + } + } + // Send the loot packet info to the session opcode handler to be given to the player character + session->HandleAutostoreLootItemOpcode(autostorePacket); + } } - if (sConfigMgr->GetOption("AOELoot.Debug", true)){ - LOG_DEBUG("module.aoe_loot", "Gold Amount for {}: {}", creature->GetAIName(), loot->gold); - ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Found {} gold on nearby corpse.", loot->gold)); + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: Gold Amount for {}: {}", creature->GetAIName(), loot->gold); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Found {} gold on {}", loot->gold, creature->GetAIName())); } + // Process gold + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: Found {} gold on creature with {}", loot->gold, creature->GetAIName()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: Found {} gold on creature with {}", loot->gold, creature->GetAIName())); + } if (creature->loot.gold > 0) { player->SetLootGUID(creature->GetGUID()); - WorldPacket moneyPacket(CMSG_LOOT_MONEY, 0); // Create a dummy packet + // Create a dummy packet for money loot + WorldPacket moneyPacket(CMSG_LOOT_MONEY, 0); + // Send the packet to loot money session->HandleLootMoneyOpcode(moneyPacket); } - + + // Check if the loot is empty if (loot->empty()) { + if (sConfigMgr->GetOption("AOELoot.Debug", true)) + { + LOG_DEBUG("module.aoe_loot", "AOE Loot: All loot removed from corpse for {}", creature->GetAIName()); + ChatHandler(player->GetSession()).PSendSysMessage(fmt::format("AOE Loot: All loot removed from corpse for {}", creature->GetAIName())); + } + // Cleanup the loot object from the corpse creature->AllLootRemovedFromCorpse(); + // Remove the lootable flag from the creature + creature->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE); + creature->RemoveFromWorld(); } - } return true; }