Optimize loot

This commit is contained in:
Yunfan Li 2025-07-21 11:37:27 +08:00
parent d6b7693b8b
commit 4875651e79
2 changed files with 37 additions and 44 deletions

View File

@ -6,6 +6,8 @@
#include "LootObjectStack.h" #include "LootObjectStack.h"
#include "LootMgr.h" #include "LootMgr.h"
#include "Object.h"
#include "ObjectAccessor.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Unit.h" #include "Unit.h"
@ -287,7 +289,7 @@ bool LootObject::IsLootPossible(Player* bot)
if (reqItem && !bot->HasItemCount(reqItem, 1)) if (reqItem && !bot->HasItemCount(reqItem, 1))
return false; return false;
if (abs(worldObj->GetPositionZ() - bot->GetPositionZ()) > INTERACTION_DISTANCE -2.0f) if (abs(worldObj->GetPositionZ() - bot->GetPositionZ()) > INTERACTION_DISTANCE - 2.0f)
return false; return false;
Creature* creature = botAI->GetCreature(guid); Creature* creature = botAI->GetCreature(guid);
@ -318,28 +320,16 @@ bool LootObject::IsLootPossible(Player* bot)
if (reqSkillValue > skillValue) if (reqSkillValue > skillValue)
return false; return false;
if (skillId == SKILL_MINING && if (skillId == SKILL_MINING && !bot->HasItemCount(756, 1) && !bot->HasItemCount(778, 1) &&
!bot->HasItemCount(756, 1) && !bot->HasItemCount(1819, 1) && !bot->HasItemCount(1893, 1) && !bot->HasItemCount(1959, 1) &&
!bot->HasItemCount(778, 1) && !bot->HasItemCount(2901, 1) && !bot->HasItemCount(9465, 1) && !bot->HasItemCount(20723, 1) &&
!bot->HasItemCount(1819, 1) && !bot->HasItemCount(40772, 1) && !bot->HasItemCount(40892, 1) && !bot->HasItemCount(40893, 1))
!bot->HasItemCount(1893, 1) &&
!bot->HasItemCount(1959, 1) &&
!bot->HasItemCount(2901, 1) &&
!bot->HasItemCount(9465, 1) &&
!bot->HasItemCount(20723, 1) &&
!bot->HasItemCount(40772, 1) &&
!bot->HasItemCount(40892, 1) &&
!bot->HasItemCount(40893, 1))
{ {
return false; // Bot is missing a mining pick return false; // Bot is missing a mining pick
} }
if (skillId == SKILL_SKINNING && if (skillId == SKILL_SKINNING && !bot->HasItemCount(7005, 1) && !bot->HasItemCount(40772, 1) &&
!bot->HasItemCount(7005, 1) && !bot->HasItemCount(40893, 1) && !bot->HasItemCount(12709, 1) && !bot->HasItemCount(19901, 1))
!bot->HasItemCount(40772, 1) &&
!bot->HasItemCount(40893, 1) &&
!bot->HasItemCount(12709, 1) &&
!bot->HasItemCount(19901, 1))
{ {
return false; // Bot is missing a skinning knife return false; // Bot is missing a skinning knife
} }
@ -376,42 +366,45 @@ void LootObjectStack::Clear() { availableLoot.clear(); }
bool LootObjectStack::CanLoot(float maxDistance) bool LootObjectStack::CanLoot(float maxDistance)
{ {
std::vector<LootObject> ordered = OrderByDistance(maxDistance); LootObject nearest = GetNearest(maxDistance);
return !ordered.empty(); return !nearest.IsEmpty();
} }
LootObject LootObjectStack::GetLoot(float maxDistance) LootObject LootObjectStack::GetLoot(float maxDistance)
{ {
std::vector<LootObject> ordered = OrderByDistance(maxDistance); LootObject nearest = GetNearest(maxDistance);
return ordered.empty() ? LootObject() : *ordered.begin(); return nearest.IsEmpty() ? LootObject() : nearest;
} }
std::vector<LootObject> LootObjectStack::OrderByDistance(float maxDistance)
LootObject LootObjectStack::GetNearest(float maxDistance)
{ {
availableLoot.shrink(time(nullptr) - 30); availableLoot.shrink(time(nullptr) - 30);
std::map<float, LootObject> sortedMap; LootObject nearest;
float nearestDistance = std::numeric_limits<float>::max();
LootTargetList safeCopy(availableLoot); LootTargetList safeCopy(availableLoot);
for (LootTargetList::iterator i = safeCopy.begin(); i != safeCopy.end(); i++) for (LootTargetList::iterator i = safeCopy.begin(); i != safeCopy.end(); i++)
{ {
ObjectGuid guid = i->guid; ObjectGuid guid = i->guid;
LootObject lootObject(bot, guid);
if (!lootObject.IsLootPossible(bot)) // Ensure loot object is valid
continue;
WorldObject* worldObj = lootObject.GetWorldObject(bot); WorldObject* worldObj = ObjectAccessor::GetWorldObject(*bot, guid);
if (!worldObj) // Prevent null pointer dereference if (!worldObj)
{
continue; continue;
}
float distance = bot->GetDistance(worldObj); float distance = bot->GetDistance(worldObj);
if (!maxDistance || distance <= maxDistance)
sortedMap[distance] = lootObject; if (distance >= nearestDistance || (maxDistance && distance > maxDistance))
continue;
LootObject lootObject(bot, guid);
if (!lootObject.IsLootPossible(bot))
continue;
nearestDistance = distance;
nearest = lootObject;
} }
std::vector<LootObject> result; return nearest;
for (auto& [_, lootObject] : sortedMap)
result.push_back(lootObject);
return result;
} }

View File

@ -78,7 +78,7 @@ public:
LootObject GetLoot(float maxDistance = 0); LootObject GetLoot(float maxDistance = 0);
private: private:
std::vector<LootObject> OrderByDistance(float maxDistance = 0); LootObject GetNearest(float maxDistance = 0);
Player* bot; Player* bot;
LootTargetList availableLoot; LootTargetList availableLoot;