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);
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());
}
return result;
@ -514,7 +518,7 @@ bool StoreLootAction::Execute(Event event)
BroadcastHelper::BroadcastLootingItem(botAI, bot, proto);
}
AI_VALUE(LootObjectStack*, "available loot")->Remove(guid);
AI_VALUE(LootObjectStack*, "available loot")->MarkCompleted(guid);
// release loot
WorldPacket* packet = new WorldPacket(CMSG_LOOT_RELEASE, 8);

View File

@ -362,6 +362,13 @@ bool LootObject::IsLootPossible(Player* bot)
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)
{
availableLoot.shrink(time(nullptr) - 30);
@ -385,7 +392,17 @@ void LootObjectStack::Remove(ObjectGuid guid)
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)
{

View File

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