Update aoe_loot.cpp

This commit is contained in:
TerraByte
2025-05-03 20:57:11 -05:00
committed by GitHub
parent c822378bbf
commit b4fb75dbeb

View File

@@ -48,7 +48,6 @@ void AoeLootCommandScript::ProcessLootRelease(ObjectGuid lguid, Player* player,
{ {
player->SetLootGUID(ObjectGuid::Empty); player->SetLootGUID(ObjectGuid::Empty);
player->SendLootRelease(lguid); player->SendLootRelease(lguid);
player->RemoveUnitFlag(UNIT_FLAG_LOOTING); player->RemoveUnitFlag(UNIT_FLAG_LOOTING);
if (!player->IsInWorld()) if (!player->IsInWorld())
@@ -67,22 +66,15 @@ void AoeLootCommandScript::ProcessLootRelease(ObjectGuid lguid, Player* player,
loot = &go->loot; loot = &go->loot;
// GameObject handling remains unchanged
// ...
} }
else if (lguid.IsCorpse()) // ONLY remove insignia at BG else if (lguid.IsCorpse()) // ONLY remove insignia at BG
{ {
Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid); Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid);
// Remove distance check for corpses
if (!corpse) if (!corpse)
return; return;
loot = &corpse->loot; loot = &corpse->loot;
// Clear loot and remove lootable flag
loot->clear();
corpse->RemoveFlag(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE);
} }
else if (lguid.IsItem()) else if (lguid.IsItem())
{ {
@@ -90,23 +82,25 @@ void AoeLootCommandScript::ProcessLootRelease(ObjectGuid lguid, Player* player,
if (!pItem) if (!pItem)
return; return;
// Item handling remains unchanged
// ...
} }
else // Must be a creature else // Must be a creature
{ {
Creature* creature = player->GetMap()->GetCreature(lguid); Creature* creature = player->GetMap()->GetCreature(lguid);
// Check if this is pickpocketing (creature alive) or corpse looting (creature dead) // Skip distance check for dead creatures (corpses)
// Keep distance check for pickpocketing (live creatures)
bool isPickpocketing = creature && creature->IsAlive() && player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING; bool isPickpocketing = creature && creature->IsAlive() && player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING;
// For pickpocketing, keep distance check // Only check distance for pickpocketing, not for corpse looting
// For corpse looting, skip distance check if (isPickpocketing && !creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
if (!creature || (isPickpocketing && !creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))) {
player->SendLootError(lguid, LOOT_ERROR_TOO_FAR);
return; return;
}
loot = &creature->loot; loot = &creature->loot;
if (loot->isLooted()) if (loot->isLooted())
{ {
// skip pickpocketing loot for speed, skinning timer reduction is no-op in fact // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
@@ -247,22 +241,22 @@ bool AoeLootCommandScript::ProcessLootSlot(Player* player, ObjectGuid lguid, uin
// Keep distance check for pickpocketing (live creatures) // Keep distance check for pickpocketing (live creatures)
bool isPickpocketing = creature && creature->IsAlive() && player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING; bool isPickpocketing = creature && creature->IsAlive() && player->IsClass(CLASS_ROGUE, CLASS_CONTEXT_ABILITY) && creature->loot.loot_type == LOOT_PICKPOCKETING;
bool lootAllowed = creature && creature->IsAlive() == isPickpocketing;
// Only check distance for pickpocketing, not for corpse looting // Only check distance for pickpocketing, not for corpse looting
if (!lootAllowed || (isPickpocketing && !creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))) if (isPickpocketing && !creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
{ {
player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL); player->SendLootError(lguid, LOOT_ERROR_TOO_FAR);
return false; return false;
} }
loot = &creature->loot; loot = &creature->loot;
} }
sScriptMgr->OnPlayerAfterCreatureLoot(player); sScriptMgr->OnPlayerAfterCreatureLoot(player);
if (!loot) if (!loot)
return false; return false;
// Check if the item is already looted // Check if the item is already looted
QuestItem* qitem = nullptr; QuestItem* qitem = nullptr;
QuestItem* ffaitem = nullptr; QuestItem* ffaitem = nullptr;
QuestItem* conditem = nullptr; QuestItem* conditem = nullptr;
@@ -276,6 +270,14 @@ bool AoeLootCommandScript::ProcessLootSlot(Player* player, ObjectGuid lguid, uin
return false; return false;
} }
// Skip items being rolled on
if (item->is_blocked)
return false;
// Skip already looted items
if (item->is_looted)
return false;
InventoryResult msg; InventoryResult msg;
LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg); LootItem* lootItem = player->StoreLootItem(lootSlot, loot, msg);
if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE) if (msg != EQUIP_ERR_OK && lguid.IsItem() && loot->loot_type != LOOT_CORPSE)
@@ -323,9 +325,46 @@ bool AoeLootCommandScript::HandleStartAoeLootCommand(ChatHandler* handler, Optio
continue; continue;
// Check if creature is valid for looting by this player // Check if creature is valid for looting by this player
if (!player->isAllowedToLoot(creature))
{
if (debugMode)
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not your loot", creature->GetGUID().ToString());
continue;
}
if (!creature->hasLootRecipient() || !creature->isTappedBy(player)) if (!creature->hasLootRecipient() || !creature->isTappedBy(player))
continue; continue;
// Get player's group and check loot permissions based on group loot method
Group* group = player->GetGroup();
if (group)
{
Loot* loot = &creature->loot;
LootMethod lootMethod = group->GetLootMethod();
// For Round Robin loot, check if this player is the designated looter
if (lootMethod == ROUND_ROBIN)
{
if (loot->roundRobinPlayer && loot->roundRobinPlayer != player->GetGUID())
{
if (debugMode)
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not your turn (Round Robin)", creature->GetGUID().ToString());
continue;
}
}
// For Master Loot, check if this player is the master looter
else if (lootMethod == MASTER_LOOT)
{
if (group->GetMasterLooterGuid() != player->GetGUID())
{
if (debugMode)
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not master looter", creature->GetGUID().ToString());
continue;
}
}
}
// Skip if corpse is not lootable // Skip if corpse is not lootable
if (!creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE)) if (!creature->HasDynamicFlag(UNIT_DYNFLAG_LOOTABLE))
{ {
@@ -334,14 +373,6 @@ bool AoeLootCommandScript::HandleStartAoeLootCommand(ChatHandler* handler, Optio
continue; continue;
} }
// Additional permission check for instances
if (player->GetMap()->Instanceable() && !player->isAllowedToLoot(creature))
{
if (debugMode)
LOG_DEBUG("module.aoe_loot", "AOE Loot: Skipping creature {} - not your loot", creature->GetGUID().ToString());
continue;
}
validCorpses.push_back(creature); validCorpses.push_back(creature);
} }
@@ -367,7 +398,6 @@ bool AoeLootCommandScript::HandleStartAoeLootCommand(ChatHandler* handler, Optio
{ {
uint8 lootSlot = loot->items.size() + i; uint8 lootSlot = loot->items.size() + i;
ProcessLootSlot(player, lguid, lootSlot); ProcessLootSlot(player, lguid, lootSlot);
if (debugMode) if (debugMode)
LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item in slot {}", lootSlot); LOG_DEBUG("module.aoe_loot", "AOE Loot: looted quest item in slot {}", lootSlot);
} }
@@ -378,7 +408,6 @@ bool AoeLootCommandScript::HandleStartAoeLootCommand(ChatHandler* handler, Optio
{ {
player->SetLootGUID(lguid); player->SetLootGUID(lguid);
ProcessLootSlot(player, lguid, lootSlot); ProcessLootSlot(player, lguid, lootSlot);
if (debugMode && lootSlot < loot->items.size()) if (debugMode && lootSlot < loot->items.size())
{ {
LOG_DEBUG("module.aoe_loot", "AOE Loot: looted item from slot {} (ID: {}) from {}", lootSlot, loot->items[lootSlot].itemid, lguid.ToString()); LOG_DEBUG("module.aoe_loot", "AOE Loot: looted item from slot {} (ID: {}) from {}", lootSlot, loot->items[lootSlot].itemid, lguid.ToString());
@@ -390,7 +419,6 @@ bool AoeLootCommandScript::HandleStartAoeLootCommand(ChatHandler* handler, Optio
{ {
uint32 goldAmount = loot->gold; uint32 goldAmount = loot->gold;
ProcessLootMoney(player, creature); ProcessLootMoney(player, creature);
if (debugMode) if (debugMode)
{ {
LOG_DEBUG("module.aoe_loot", "AOE Loot: Looted {} copper from {}", goldAmount, lguid.ToString()); LOG_DEBUG("module.aoe_loot", "AOE Loot: Looted {} copper from {}", goldAmount, lguid.ToString());