mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
feat(Core/Loot): Make bag space for incoming quest items
This commit is contained in:
parent
d35e0da5d9
commit
952fdc54a1
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "LootAction.h"
|
#include "LootAction.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "Bag.h"
|
#include "Bag.h"
|
||||||
#include "ChatHelper.h"
|
#include "ChatHelper.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
@ -379,6 +381,12 @@ bool StoreLootAction::Execute(Event event)
|
|||||||
// bot->GetSession()->HandleLootMoneyOpcode(packet);
|
// bot->GetSession()->HandleLootMoneyOpcode(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// one make-room destroy per loot packet — CanStoreNewItem after a junk
|
||||||
|
// destroy can still report full while CMSG_AUTOSTORE_LOOT_ITEM is
|
||||||
|
// queued, so a multi-quest-item packet would otherwise destroy more
|
||||||
|
// junk than necessary
|
||||||
|
bool destroyedThisPacket = false;
|
||||||
|
|
||||||
for (uint8 i = 0; i < items; ++i)
|
for (uint8 i = 0; i < items; ++i)
|
||||||
{
|
{
|
||||||
uint32 itemid;
|
uint32 itemid;
|
||||||
@ -404,7 +412,9 @@ bool StoreLootAction::Execute(Event event)
|
|||||||
if (!proto)
|
if (!proto)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!botAI->HasActivePlayerMaster() && AI_VALUE(uint8, "bag space") > 80)
|
// bags >80%: skip non-stackable junk (quest items exempt)
|
||||||
|
if (!botAI->HasActivePlayerMaster() && AI_VALUE(uint8, "bag space") > 80 &&
|
||||||
|
!bot->HasQuestForItem(itemid))
|
||||||
{
|
{
|
||||||
uint32 maxStack = proto->GetMaxStackSize();
|
uint32 maxStack = proto->GetMaxStackSize();
|
||||||
if (maxStack == 1)
|
if (maxStack == 1)
|
||||||
@ -440,6 +450,55 @@ bool StoreLootAction::Execute(Event event)
|
|||||||
GuildTaskMgr::instance().CheckItemTask(itemid, itemcount, ref->GetSource(), bot);
|
GuildTaskMgr::instance().CheckItemTask(itemid, itemcount, ref->GetSource(), bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bags full + quest item: make room by dropping cheapest junk
|
||||||
|
if (!destroyedThisPacket && bot->HasQuestForItem(itemid))
|
||||||
|
{
|
||||||
|
ItemPosCountVec dest;
|
||||||
|
InventoryResult can =
|
||||||
|
bot->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, itemcount);
|
||||||
|
if (can == EQUIP_ERR_INVENTORY_FULL || can == EQUIP_ERR_BAG_FULL)
|
||||||
|
{
|
||||||
|
// picked by usage, not quality — high-level bots have no grays
|
||||||
|
Item* victim = nullptr;
|
||||||
|
uint32 minPrice = std::numeric_limits<uint32>::max();
|
||||||
|
auto consider = [&](uint8 bag, uint8 slot)
|
||||||
|
{
|
||||||
|
Item* it = bot->GetItemByPos(bag, slot);
|
||||||
|
if (!it)
|
||||||
|
return;
|
||||||
|
ItemTemplate const* tpl = it->GetTemplate();
|
||||||
|
if (!tpl)
|
||||||
|
return;
|
||||||
|
if (bot->HasQuestForItem(tpl->ItemId))
|
||||||
|
return;
|
||||||
|
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", tpl->ItemId);
|
||||||
|
if (usage != ITEM_USAGE_NONE && usage != ITEM_USAGE_VENDOR &&
|
||||||
|
usage != ITEM_USAGE_BAD_EQUIP && usage != ITEM_USAGE_BROKEN_EQUIP)
|
||||||
|
return;
|
||||||
|
if (tpl->SellPrice < minPrice)
|
||||||
|
{
|
||||||
|
minPrice = tpl->SellPrice;
|
||||||
|
victim = it;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot)
|
||||||
|
consider(INVENTORY_SLOT_BAG_0, slot);
|
||||||
|
for (uint8 bag = INVENTORY_SLOT_BAG_START; bag < INVENTORY_SLOT_BAG_END; ++bag)
|
||||||
|
{
|
||||||
|
Bag* pBag = bot->GetBagByPos(bag);
|
||||||
|
if (!pBag)
|
||||||
|
continue;
|
||||||
|
for (uint32 slot = 0; slot < pBag->GetBagSize(); ++slot)
|
||||||
|
consider(bag, static_cast<uint8>(slot));
|
||||||
|
}
|
||||||
|
if (victim)
|
||||||
|
{
|
||||||
|
bot->DestroyItem(victim->GetBagSlot(), victim->GetSlot(), true);
|
||||||
|
destroyedThisPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WorldPacket* packet = new WorldPacket(CMSG_AUTOSTORE_LOOT_ITEM, 1);
|
WorldPacket* packet = new WorldPacket(CMSG_AUTOSTORE_LOOT_ITEM, 1);
|
||||||
*packet << itemindex;
|
*packet << itemindex;
|
||||||
bot->GetSession()->QueuePacket(packet);
|
bot->GetSession()->QueuePacket(packet);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user