fix(Core/Loot): Prevent re-loot of same corpse via completed-guid set

This commit is contained in:
bash 2026-05-08 22:17:52 +02:00
parent edd27ee8e1
commit cfd5012b13
3 changed files with 28 additions and 3 deletions

View File

@ -79,7 +79,11 @@ bool OpenLootAction::Execute(Event /*event*/)
bool result = DoLoot(lootObject); bool result = DoLoot(lootObject);
if (result) if (result)
{ {
AI_VALUE(LootObjectStack*, "available loot")->Remove(lootObject.guid); // MarkCompleted (not Remove) — "add all loot" reads
// "nearest corpses" without a lootable filter, so a plain
// Remove lets the same corpse re-enter the stack on the next
// tick. The completed set blocks re-add for ~5 min.
AI_VALUE(LootObjectStack*, "available loot")->MarkCompleted(lootObject.guid);
context->GetValue<LootObject>("loot target")->Set(LootObject()); context->GetValue<LootObject>("loot target")->Set(LootObject());
} }
return result; return result;
@ -514,7 +518,7 @@ bool StoreLootAction::Execute(Event event)
BroadcastHelper::BroadcastLootingItem(botAI, bot, proto); BroadcastHelper::BroadcastLootingItem(botAI, bot, proto);
} }
AI_VALUE(LootObjectStack*, "available loot")->Remove(guid); AI_VALUE(LootObjectStack*, "available loot")->MarkCompleted(guid);
// release loot // release loot
WorldPacket* packet = new WorldPacket(CMSG_LOOT_RELEASE, 8); WorldPacket* packet = new WorldPacket(CMSG_LOOT_RELEASE, 8);

View File

@ -362,6 +362,13 @@ bool LootObject::IsLootPossible(Player* bot)
bool LootObjectStack::Add(ObjectGuid guid) bool LootObjectStack::Add(ObjectGuid guid)
{ {
// expire old completed entries so a despawn/respawn with a reused
// guid can still be looted later
completedLoot.shrink(time(nullptr) - 300);
if (completedLoot.find(guid) != completedLoot.end())
return false;
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT)
{ {
availableLoot.shrink(time(nullptr) - 30); availableLoot.shrink(time(nullptr) - 30);
@ -385,7 +392,17 @@ void LootObjectStack::Remove(ObjectGuid guid)
availableLoot.erase(i); availableLoot.erase(i);
} }
void LootObjectStack::Clear() { availableLoot.clear(); } void LootObjectStack::MarkCompleted(ObjectGuid guid)
{
Remove(guid);
completedLoot.insert(guid);
}
void LootObjectStack::Clear()
{
availableLoot.clear();
completedLoot.clear();
}
bool LootObjectStack::CanLoot(float maxDistance) bool LootObjectStack::CanLoot(float maxDistance)
{ {

View File

@ -76,6 +76,7 @@ public:
bool Add(ObjectGuid guid); bool Add(ObjectGuid guid);
void Remove(ObjectGuid guid); void Remove(ObjectGuid guid);
void MarkCompleted(ObjectGuid guid);
void Clear(); void Clear();
bool CanLoot(float maxDistance); bool CanLoot(float maxDistance);
LootObject GetLoot(float maxDistance = 0); LootObject GetLoot(float maxDistance = 0);
@ -85,6 +86,9 @@ private:
Player* bot; Player* bot;
LootTargetList availableLoot; LootTargetList availableLoot;
// Guids we already opened loot on; blocks "add all loot" from
// re-adding the same corpse before it despawns.
LootTargetList completedLoot;
}; };
#endif #endif