Skip to content

Commit

Permalink
NPCBots: Improve gear bank sorting by involving item class, subclass,…
Browse files Browse the repository at this point in the history
… inventory type, quality and GS

(cherry picked from commit 66014b789d878080802a1c148c0c87f1f1c3c179)
  • Loading branch information
trickerer committed Nov 14, 2024
1 parent 8999adf commit da3fbac
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 26 deletions.
14 changes: 7 additions & 7 deletions src/server/game/AI/NpcBots/bot_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9112,7 +9112,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
if (slot <= BOT_SLOT_RANGED && einfo->ItemEntry[slot] == item->GetEntry())
msg << " |cffe6cc80|h[!" << LocalizedNpcText(player, BOT_TEXT_VISUALONLY) << "!]|h|r";

msg << " GS: " << uint32(CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot, item->GetTemplate()));
msg << " GS: " << uint32(CalculateItemGearScore(item->GetTemplate(), me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot));

BotWhisper(msg.str(), player);

Expand Down Expand Up @@ -9199,7 +9199,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
if (visual_only)
str << " |cffe6cc80|h[!" << LocalizedNpcText(player, BOT_TEXT_VISUALONLY) << "!]|h|r";

str << " GS: " << uint32(CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot, item->GetTemplate()));
str << " GS: " << uint32(CalculateItemGearScore(item->GetTemplate(), me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot));

AddGossipItemFor(player, GOSSIP_ICON_CHAT, str.str(), GOSSIP_SENDER_EQUIPMENT_INFO, action);

Expand Down Expand Up @@ -9264,7 +9264,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
{
std::ostringstream name;
_AddItemLink(player, item, name);
name << " GS: " << uint32(CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot, item->GetTemplate()));
name << " GS: " << uint32(CalculateItemGearScore(item->GetTemplate(), me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot));
if (BotMgr::SendEquipListItems())
BotWhisper(name.str(), player);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, name.str(), GOSSIP_SENDER_EQUIP + slot, GOSSIP_ACTION_INFO_DEF + item->GetGUID().GetCounter());
Expand All @@ -9288,7 +9288,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
{
std::ostringstream name;
_AddItemLink(player, item, name);
name << " GS: " << uint32(CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot, item->GetTemplate()));
name << " GS: " << uint32(CalculateItemGearScore(item->GetTemplate(), me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot));
if (BotMgr::SendEquipListItems())
BotWhisper(name.str(), player);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, name.str(), GOSSIP_SENDER_EQUIP + slot, GOSSIP_ACTION_INFO_DEF + item->GetGUID().GetCounter());
Expand Down Expand Up @@ -9883,7 +9883,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
else if (GetBotClass() == BOT_CLASS_WARRIOR && _canEquip(proto, BOT_SLOT_MAINHAND, true))
slot = BOT_SLOT_MAINHAND;

name << " GS: " << uint32(CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot, proto));
name << " GS: " << uint32(CalculateItemGearScore(proto, me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), slot));
AddGossipItemFor(player, GOSSIP_ICON_CHAT, name.str(), GOSSIP_SENDER_EQUIPMENT_BANK_WITHDRAW_ITEM, GOSSIP_ACTION_INFO_DEF + item->GetGUID().GetCounter());
}

Expand Down Expand Up @@ -10092,7 +10092,7 @@ bool bot_ai::OnGossipSelect(Player* player, Creature* creature/* == me*/, uint32
if (item)
{
_AddItemLink(player, item, ss);
float item_gs = CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), i, proto);
float item_gs = CalculateItemGearScore(proto, me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), i);
gs_total += item_gs;
ss << " GS: " << uint32(item_gs);
}
Expand Down Expand Up @@ -14355,7 +14355,7 @@ float bot_ai::_getItemGearStatScore(ItemTemplate const* iproto, uint8 forslot, I
for (uint8 i = 0; i != MAX_BOT_ITEM_MOD; ++i)
itemScore += istats[i] * _getStatScore(i);

float itemGearScore = CalculateItemGearScore(me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), forslot, iproto);
float itemGearScore = CalculateItemGearScore(iproto, me->GetEntry(), me->GetLevel(), GetBotClass(), GetSpec(), forslot);
itemScore += itemGearScore;

//BOT_LOG_ERROR("scripts", "_getItemGearScore total score %.3f", itemScore);
Expand Down
28 changes: 27 additions & 1 deletion src/server/game/AI/NpcBots/botdatamgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "BattlegroundQueue.h"
#include "bot_ai.h"
#include "botdatamgr.h"
#include "botgearscore.h"
#include "botlog.h"
#include "botmgr.h"
#include "botspell.h"
Expand Down Expand Up @@ -78,7 +79,32 @@ bool BotBankItemCompare::operator()(Item const* item1, Item const* item2) const
{
ItemTemplate const* proto1 = item1->GetTemplate();
ItemTemplate const* proto2 = item2->GetTemplate();
return proto1->Name1 < proto2->Name1;

if (proto1->Class == proto2->Class)
{
if (proto1->SubClass == proto2->SubClass)
{
if (proto1->InventoryType == proto2->InventoryType)
{
if (proto1->Quality == proto2->Quality)
{
float gs1 = CalculateItemGearScoreRaw(proto1);
float gs2 = CalculateItemGearScoreRaw(proto1);
if (gs1 == gs2)
{
if (proto1->Name1 == proto2->Name1)
return item1->GetGUID().GetCounter() < item2->GetGUID().GetCounter();
return proto1->Name1 < proto2->Name1;
}
return gs1 < gs2;
}
return proto1->Quality > proto2->Quality;
}
return proto1->InventoryType < proto2->InventoryType;
}
return proto1->SubClass < proto2->SubClass;
}
return proto1->Class < proto2->Class;
}

class BotBattlegroundEnterEvent : public BasicEvent
Expand Down
39 changes: 22 additions & 17 deletions src/server/game/AI/NpcBots/botgearscore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ constexpr std::pair<float, float> ItemLevelFactors[2][5] = {
}
};

void CalculateRawItemScore(ItemTemplate const* proto, float& score)
float CalculateItemGearScoreRaw(ItemTemplate const* proto)
{
auto smcit = ItemSlotMods.find(proto->InventoryType);
if (smcit == ItemSlotMods.cend())
return;
return 0.0f;

uint32 quality = proto->Quality;
float itemlvl = proto->ItemLevel;
Expand All @@ -83,33 +83,38 @@ void CalculateRawItemScore(ItemTemplate const* proto, float& score)
}

if (!(quality >= ITEM_QUALITY_UNCOMMON && quality <= ITEM_QUALITY_EPIC))
return;
return 0.0f;

auto const& p = ItemLevelFactors[size_t(itemlvl <= 120.0f)][quality];
score = floor(((itemlvl - p.first) / p.second) * slotmod * qscale * GS_scale);
return floor(((itemlvl - p.first) / p.second) * slotmod * qscale * GS_scale);
}

float CalculateItemGearScore(uint32 botentry, uint8 botlevel, uint8 botclass, uint8 botspec, uint8 slot, ItemTemplate const* proto)
float CalculateItemGearScore(ItemTemplate const* proto, uint32 botentry/* = 0*/, uint8 botlevel/* = 0*/, uint8 botclass/* = 0*/, uint8 botspec/* = 0*/, uint8 slot/* = 18*/)
{
ASSERT(slot < BOT_INVENTORY_SIZE, "Invalid bot equip slot %u!", uint32(slot));
EquipmentInfo const* einfo = BotDataMgr::GetBotEquipmentInfo(botentry);
ASSERT(einfo, "Trying to CalculateItemGearScore for bot %u with no equip info!", botentry);
EquipmentInfo const* einfo = nullptr;
if (botentry)
{
ASSERT(slot < BOT_INVENTORY_SIZE, "Invalid bot equip slot %u!", uint32(slot));
einfo = BotDataMgr::GetBotEquipmentInfo(botentry);
ASSERT(einfo, "Trying to CalculateItemGearScore for bot %u with no equip info!", botentry);
}

float itemscore = 0.0f;

if (slot > BOT_SLOT_RANGED || einfo->ItemEntry[slot] != proto->ItemId)
if (slot > BOT_SLOT_RANGED || !einfo || einfo->ItemEntry[slot] != proto->ItemId)
{
CalculateRawItemScore(proto, itemscore);
itemscore = CalculateItemGearScoreRaw(proto);

if (slot == BOT_SLOT_MAINHAND || slot == BOT_SLOT_OFFHAND)
if (botspec == BOT_SPEC_WARRIOR_FURY && botlevel >= 60 && proto->InventoryType == INVTYPE_2HWEAPON)
itemscore *= 0.5f;
else if (botclass == BOT_CLASS_HUNTER)
{
if (botspec == BOT_SPEC_WARRIOR_FURY && botlevel >= 60 && proto->InventoryType == INVTYPE_2HWEAPON)
itemscore *= 0.5f;
else if (botclass == BOT_CLASS_HUNTER)
if (proto->InventoryType == INVTYPE_WEAPON || proto->InventoryType == INVTYPE_WEAPONMAINHAND ||
proto->InventoryType == INVTYPE_WEAPONOFFHAND || proto->InventoryType == INVTYPE_THROWN)
itemscore *= 0.3164f;
else if (proto->InventoryType == INVTYPE_RANGED || proto->InventoryType == INVTYPE_RANGEDRIGHT)
itemscore *= 5.3224f;
}
else if (slot == BOT_SLOT_RANGED && botclass == BOT_CLASS_HUNTER)
itemscore *= 5.3224f;
}

return std::max<float>(itemscore, 0.0f);
Expand All @@ -124,7 +129,7 @@ std::pair<float, float> CalculateBotGearScore(uint32 botentry, uint8 botlevel, u
{
if (Item const* item = items[i])
{
float itemscore = CalculateItemGearScore(botentry, botlevel, botclass, botspec, i, item->GetTemplate());
float itemscore = CalculateItemGearScore(item->GetTemplate(), botentry, botlevel, botclass, botspec, i);
if (itemscore > 0.0f)
{
++items_count;
Expand Down
3 changes: 2 additions & 1 deletion src/server/game/AI/NpcBots/botgearscore.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class Item;

struct ItemTemplate;

float CalculateItemGearScore(uint32 botentry, uint8 botlevel, uint8 botclass, uint8 botspec, uint8 slot, ItemTemplate const* proto);
float CalculateItemGearScoreRaw(ItemTemplate const* proto);
float CalculateItemGearScore(ItemTemplate const* proto, uint32 botentry = 0, uint8 botlevel = 0, uint8 botclass = 0, uint8 botspec = 0, uint8 slot = BOT_INVENTORY_SIZE);
std::pair<float, float> CalculateBotGearScore(uint32 botentry, uint8 botlevel, uint8 botclass, uint8 botspec, Item const* const items[BOT_INVENTORY_SIZE]);

#endif

0 comments on commit da3fbac

Please sign in to comment.