mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
speed up InitEquipment
This commit is contained in:
@@ -6,9 +6,14 @@
|
||||
#include "AccountMgr.h"
|
||||
#include "AiFactory.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "ItemTemplate.h"
|
||||
#include "Log.h"
|
||||
#include "LootMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "PetDefines.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
@@ -961,7 +966,7 @@ bool PlayerbotFactory::CanEquipWeapon(ItemTemplate const* proto)
|
||||
|
||||
bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality)
|
||||
{
|
||||
if (proto->Duration & 0x80000000)
|
||||
if (proto->Duration != 0)
|
||||
return false;
|
||||
|
||||
if (proto->Quality != desiredQuality)
|
||||
@@ -1017,141 +1022,153 @@ void Shuffle(std::vector<uint32>& items)
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerbotFactory::InitEquipmentNew(bool incremental)
|
||||
{
|
||||
if (incremental)
|
||||
{
|
||||
DestroyItemsVisitor visitor(bot);
|
||||
IterateItems(&visitor, (IterateItemsMask)(ITERATE_ITEMS_IN_BAGS | ITERATE_ITEMS_IN_BANK));
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyItemsVisitor visitor(bot);
|
||||
IterateItems(&visitor, ITERATE_ALL_ITEMS);
|
||||
}
|
||||
// void PlayerbotFactory::InitEquipmentNew(bool incremental)
|
||||
// {
|
||||
// if (incremental)
|
||||
// {
|
||||
// DestroyItemsVisitor visitor(bot);
|
||||
// IterateItems(&visitor, (IterateItemsMask)(ITERATE_ITEMS_IN_BAGS | ITERATE_ITEMS_IN_BANK));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// DestroyItemsVisitor visitor(bot);
|
||||
// IterateItems(&visitor, ITERATE_ALL_ITEMS);
|
||||
// }
|
||||
|
||||
std::string const& specName = AiFactory::GetPlayerSpecName(bot);
|
||||
if (specName.empty())
|
||||
return;
|
||||
// std::string const& specName = AiFactory::GetPlayerSpecName(bot);
|
||||
// if (specName.empty())
|
||||
// return;
|
||||
|
||||
// look for upgrades
|
||||
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
{
|
||||
if (slot == EQUIPMENT_SLOT_TABARD && !bot->GetGuildId())
|
||||
continue;
|
||||
// // look for upgrades
|
||||
// for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
// {
|
||||
// if (slot == EQUIPMENT_SLOT_TABARD && !bot->GetGuildId())
|
||||
// continue;
|
||||
|
||||
bool isUpgrade = false;
|
||||
bool found = false;
|
||||
bool noItem = false;
|
||||
uint32 quality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
|
||||
uint32 attempts = 10;
|
||||
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL) {
|
||||
quality--;
|
||||
}
|
||||
// current item;
|
||||
Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
|
||||
if (oldItem)
|
||||
isUpgrade = true;
|
||||
// bool isUpgrade = false;
|
||||
// bool found = false;
|
||||
// bool noItem = false;
|
||||
// uint32 quality = urand(ITEM_QUALITY_UNCOMMON, ITEM_QUALITY_EPIC);
|
||||
// uint32 attempts = 10;
|
||||
// if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && quality > ITEM_QUALITY_NORMAL) {
|
||||
// quality--;
|
||||
// }
|
||||
// // current item;
|
||||
// Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
|
||||
// if (oldItem)
|
||||
// isUpgrade = true;
|
||||
|
||||
uint32 itemInSlot = isUpgrade ? oldItem->GetTemplate()->ItemId : 0;
|
||||
// uint32 itemInSlot = isUpgrade ? oldItem->GetTemplate()->ItemId : 0;
|
||||
|
||||
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
||||
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||
// uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
||||
// if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
// maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||
|
||||
uint32 minLevel = sPlayerbotAIConfig->randomBotMinLevel;
|
||||
if (minLevel < sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL))
|
||||
minLevel = sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL);
|
||||
// uint32 minLevel = sPlayerbotAIConfig->randomBotMinLevel;
|
||||
// if (minLevel < sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL))
|
||||
// minLevel = sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL);
|
||||
|
||||
// test
|
||||
do
|
||||
{
|
||||
if (isUpgrade)
|
||||
{
|
||||
std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, 0, itemInSlot);
|
||||
if (!ids.empty())
|
||||
Shuffle(ids);
|
||||
// // test
|
||||
// do
|
||||
// {
|
||||
// if (isUpgrade)
|
||||
// {
|
||||
// std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, 0, itemInSlot);
|
||||
// if (!ids.empty())
|
||||
// Shuffle(ids);
|
||||
|
||||
for (uint32 index = 0; index < ids.size(); ++index)
|
||||
{
|
||||
uint32 newItemId = ids[index];
|
||||
if (incremental && !IsDesiredReplacement(oldItem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// for (uint32 index = 0; index < ids.size(); ++index)
|
||||
// {
|
||||
// uint32 newItemId = ids[index];
|
||||
// if (incremental && !IsDesiredReplacement(oldItem))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
uint16 dest;
|
||||
if (!CanEquipUnseenItem(slot, dest, newItemId))
|
||||
continue;
|
||||
// uint16 dest;
|
||||
// if (!CanEquipUnseenItem(slot, dest, newItemId))
|
||||
// continue;
|
||||
|
||||
if (oldItem)
|
||||
{
|
||||
bot->RemoveItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
oldItem->DestroyForPlayer(bot);
|
||||
}
|
||||
// if (oldItem)
|
||||
// {
|
||||
// bot->RemoveItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
// oldItem->DestroyForPlayer(bot);
|
||||
// }
|
||||
|
||||
Item* newItem = bot->EquipNewItem(dest, newItemId, true);
|
||||
if (newItem)
|
||||
{
|
||||
newItem->AddToWorld();
|
||||
newItem->AddToUpdateQueueOf(bot);
|
||||
bot->AutoUnequipOffhandIfNeed();
|
||||
newItem->SetOwnerGUID(bot->GetGUID());
|
||||
EnchantItem(newItem);
|
||||
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Equip: {}, slot: {}, Old item: {}",
|
||||
bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), newItemId, slot, itemInSlot);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, quality, itemInSlot);
|
||||
if (!ids.empty())
|
||||
Shuffle(ids);
|
||||
// Item* newItem = bot->EquipNewItem(dest, newItemId, true);
|
||||
// if (newItem)
|
||||
// {
|
||||
// newItem->AddToWorld();
|
||||
// newItem->AddToUpdateQueueOf(bot);
|
||||
// bot->AutoUnequipOffhandIfNeed();
|
||||
// newItem->SetOwnerGUID(bot->GetGUID());
|
||||
// EnchantItem(newItem);
|
||||
// LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Equip: {}, slot: {}, Old item: {}",
|
||||
// bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), newItemId, slot, itemInSlot);
|
||||
// found = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// std::vector<uint32> ids = sRandomItemMgr->GetUpgradeList(bot, specName, slot, quality, itemInSlot);
|
||||
// if (!ids.empty())
|
||||
// Shuffle(ids);
|
||||
|
||||
for (uint32 index = 0; index < ids.size(); ++index)
|
||||
{
|
||||
uint32 newItemId = ids[index];
|
||||
uint16 dest;
|
||||
if (!CanEquipUnseenItem(slot, dest, newItemId))
|
||||
continue;
|
||||
// for (uint32 index = 0; index < ids.size(); ++index)
|
||||
// {
|
||||
// uint32 newItemId = ids[index];
|
||||
// uint16 dest;
|
||||
// if (!CanEquipUnseenItem(slot, dest, newItemId))
|
||||
// continue;
|
||||
|
||||
Item* newItem = bot->EquipNewItem(dest, newItemId, true);
|
||||
if (newItem)
|
||||
{
|
||||
bot->AutoUnequipOffhandIfNeed();
|
||||
newItem->SetOwnerGUID(bot->GetGUID());
|
||||
EnchantItem(newItem);
|
||||
found = true;
|
||||
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Equip: {}, slot: {}",
|
||||
bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), newItemId, slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
quality--;
|
||||
} while (!found && quality != ITEM_QUALITY_POOR);
|
||||
if (!found)
|
||||
{
|
||||
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: no item for slot {}",
|
||||
bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), slot);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Item* newItem = bot->EquipNewItem(dest, newItemId, true);
|
||||
// if (newItem)
|
||||
// {
|
||||
// bot->AutoUnequipOffhandIfNeed();
|
||||
// newItem->SetOwnerGUID(bot->GetGUID());
|
||||
// EnchantItem(newItem);
|
||||
// found = true;
|
||||
// LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Equip: {}, slot: {}",
|
||||
// bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), newItemId, slot);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// quality--;
|
||||
// } while (!found && quality != ITEM_QUALITY_POOR);
|
||||
// if (!found)
|
||||
// {
|
||||
// LOG_INFO("playerbots", "Bot {} {}:{} <{}>: no item for slot {}",
|
||||
// bot->GetGUID().ToString().c_str(), IsAlliance(bot->getRace()) ? "A" : "H", bot->getLevel(), bot->GetName(), slot);
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
{
|
||||
|
||||
// todo(yunfan): to be refactored, too much time overhead
|
||||
// DestroyItemsVisitor visitor(bot);
|
||||
// IterateItems(&visitor, ITERATE_ALL_ITEMS);
|
||||
|
||||
std::map<uint8, std::vector<uint32> > items;
|
||||
int tab = AiFactory::GetPlayerSpecTab(bot);
|
||||
// todo(yunfan): make cache for this
|
||||
|
||||
uint32 blevel = bot->getLevel();
|
||||
int32 delta = 2;
|
||||
if (blevel < 15)
|
||||
delta = 15;
|
||||
else if (blevel < 40)
|
||||
delta = 10;
|
||||
else if (blevel < 60)
|
||||
delta = 6;
|
||||
else if (blevel < 70)
|
||||
delta = 9;
|
||||
else if (blevel < 80)
|
||||
delta = 9;
|
||||
else if (blevel == 80)
|
||||
delta = 2;
|
||||
|
||||
for(uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
{
|
||||
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||
@@ -1163,46 +1180,44 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
}
|
||||
do
|
||||
{
|
||||
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
||||
for (ItemTemplateContainer::const_iterator i = itemTemplates->begin(); i != itemTemplates->end(); ++i)
|
||||
{
|
||||
uint32 itemId = i->first;
|
||||
if (sRandomItemMgr->IsTestItem(itemId)) {
|
||||
continue;
|
||||
ItemTemplateContainer const* itemTemplate = sObjectMgr->GetItemTemplateStore();
|
||||
for (uint32 requiredLevel = bot->GetLevel(); requiredLevel > std::max((int32)bot->GetLevel() - delta, 0); requiredLevel--) {
|
||||
for (InventoryType inventoryType : GetPossibleInventoryTypeListBySlot((EquipmentSlots)slot)) {
|
||||
for (uint32 itemId : sRandomItemMgr->GetCachedEquipments(requiredLevel, inventoryType)) {
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
if (proto->Class != ITEM_CLASS_WEAPON &&
|
||||
proto->Class != ITEM_CLASS_ARMOR)
|
||||
continue;
|
||||
|
||||
if (!CanEquipItem(proto, desiredQuality))
|
||||
continue;
|
||||
|
||||
if (proto->Class == ITEM_CLASS_ARMOR && (
|
||||
slot == EQUIPMENT_SLOT_HEAD ||
|
||||
slot == EQUIPMENT_SLOT_SHOULDERS ||
|
||||
slot == EQUIPMENT_SLOT_CHEST ||
|
||||
slot == EQUIPMENT_SLOT_WAIST ||
|
||||
slot == EQUIPMENT_SLOT_LEGS ||
|
||||
slot == EQUIPMENT_SLOT_FEET ||
|
||||
slot == EQUIPMENT_SLOT_WRISTS ||
|
||||
slot == EQUIPMENT_SLOT_HANDS) && !CanEquipArmor(proto))
|
||||
continue;
|
||||
|
||||
if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(proto))
|
||||
continue;
|
||||
|
||||
if (slot == EQUIPMENT_SLOT_OFFHAND && bot->getClass() == CLASS_ROGUE && proto->Class != ITEM_CLASS_WEAPON)
|
||||
continue;
|
||||
|
||||
uint16 dest = 0;
|
||||
if (CanEquipUnseenItem(slot, dest, itemId))
|
||||
items[slot].push_back(itemId);
|
||||
}
|
||||
}
|
||||
ItemTemplate const* proto = &i->second;
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
if (proto->Class != ITEM_CLASS_WEAPON &&
|
||||
proto->Class != ITEM_CLASS_ARMOR &&
|
||||
proto->Class != ITEM_CLASS_CONTAINER &&
|
||||
proto->Class != ITEM_CLASS_PROJECTILE)
|
||||
continue;
|
||||
|
||||
if (!CanEquipItem(proto, desiredQuality))
|
||||
continue;
|
||||
|
||||
if (proto->Class == ITEM_CLASS_ARMOR && (
|
||||
slot == EQUIPMENT_SLOT_HEAD ||
|
||||
slot == EQUIPMENT_SLOT_SHOULDERS ||
|
||||
slot == EQUIPMENT_SLOT_CHEST ||
|
||||
slot == EQUIPMENT_SLOT_WAIST ||
|
||||
slot == EQUIPMENT_SLOT_LEGS ||
|
||||
slot == EQUIPMENT_SLOT_FEET ||
|
||||
slot == EQUIPMENT_SLOT_WRISTS ||
|
||||
slot == EQUIPMENT_SLOT_HANDS) && !CanEquipArmor(proto))
|
||||
continue;
|
||||
|
||||
if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(proto))
|
||||
continue;
|
||||
|
||||
if (slot == EQUIPMENT_SLOT_OFFHAND && bot->getClass() == CLASS_ROGUE && proto->Class != ITEM_CLASS_WEAPON)
|
||||
continue;
|
||||
|
||||
uint16 dest = 0;
|
||||
if (CanEquipUnseenItem(slot, dest, itemId))
|
||||
items[slot].push_back(itemId);
|
||||
if (items[slot].size() >= 10) break;
|
||||
}
|
||||
} while (items[slot].size() < 10 && desiredQuality-- > ITEM_QUALITY_NORMAL);
|
||||
}
|
||||
@@ -1245,9 +1260,7 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
}
|
||||
if (oldItem)
|
||||
{
|
||||
// bot->RemoveItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
// oldItem->DestroyForPlayer(bot, false);
|
||||
}
|
||||
uint16 dest;
|
||||
if (!CanEquipUnseenItem(slot, dest, bestItemForSlot)) {
|
||||
@@ -1271,10 +1284,13 @@ bool PlayerbotFactory::IsDesiredReplacement(Item* item)
|
||||
|
||||
ItemTemplate const* proto = item->GetTemplate();
|
||||
uint32 requiredLevel = proto->RequiredLevel;
|
||||
if (!requiredLevel)
|
||||
{
|
||||
requiredLevel = sRandomItemMgr->GetMinLevelFromCache(proto->ItemId);
|
||||
if (!requiredLevel) {
|
||||
return true;
|
||||
}
|
||||
// if (!requiredLevel)
|
||||
// {
|
||||
// requiredLevel = sRandomItemMgr->GetMinLevelFromCache(proto->ItemId);
|
||||
// }
|
||||
|
||||
uint32 delta = 1 + (80 - bot->getLevel()) / 10;
|
||||
return int32(bot->getLevel() - requiredLevel) > delta;
|
||||
@@ -1295,110 +1311,110 @@ inline Item* StoreNewItemInInventorySlot(Player* player, uint32 newItemId, uint3
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PlayerbotFactory::InitSecondEquipmentSet()
|
||||
{
|
||||
if (bot->getClass() == CLASS_MAGE || bot->getClass() == CLASS_WARLOCK || bot->getClass() == CLASS_PRIEST)
|
||||
return;
|
||||
// void PlayerbotFactory::InitSecondEquipmentSet()
|
||||
// {
|
||||
// if (bot->getClass() == CLASS_MAGE || bot->getClass() == CLASS_WARLOCK || bot->getClass() == CLASS_PRIEST)
|
||||
// return;
|
||||
|
||||
std::map<uint32, std::vector<uint32>> items;
|
||||
// std::map<uint32, std::vector<uint32>> items;
|
||||
|
||||
uint32 desiredQuality = itemQuality;
|
||||
while (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
|
||||
{
|
||||
desiredQuality--;
|
||||
}
|
||||
// uint32 desiredQuality = itemQuality;
|
||||
// while (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
|
||||
// {
|
||||
// desiredQuality--;
|
||||
// }
|
||||
|
||||
ItemTemplateContainer const* itemTemplate = sObjectMgr->GetItemTemplateStore();
|
||||
do
|
||||
{
|
||||
for (auto const& itr : *itemTemplate)
|
||||
{
|
||||
ItemTemplate const* proto = &itr.second;
|
||||
if (!proto)
|
||||
continue;
|
||||
if (!CanEquipItem(proto, desiredQuality))
|
||||
continue;
|
||||
// ItemTemplateContainer const* itemTemplate = sObjectMgr->GetItemTemplateStore();
|
||||
// do
|
||||
// {
|
||||
// for (auto const& itr : *itemTemplate)
|
||||
// {
|
||||
// ItemTemplate const* proto = &itr.second;
|
||||
// if (!proto)
|
||||
// continue;
|
||||
// if (!CanEquipItem(proto, desiredQuality))
|
||||
// continue;
|
||||
|
||||
if (proto->Class == ITEM_CLASS_WEAPON)
|
||||
{
|
||||
//if (!CanEquipWeapon(proto))
|
||||
// continue;
|
||||
// if (proto->Class == ITEM_CLASS_WEAPON)
|
||||
// {
|
||||
// //if (!CanEquipWeapon(proto))
|
||||
// // continue;
|
||||
|
||||
if (sRandomItemMgr->HasStatWeight(proto->ItemId))
|
||||
{
|
||||
if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
|
||||
continue;
|
||||
}
|
||||
// if (sRandomItemMgr->HasStatWeight(proto->ItemId))
|
||||
// {
|
||||
// if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
|
||||
// continue;
|
||||
// }
|
||||
|
||||
Item* existingItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
|
||||
if (existingItem)
|
||||
{
|
||||
switch (existingItem->GetTemplate()->SubClass)
|
||||
{
|
||||
case ITEM_SUBCLASS_WEAPON_AXE:
|
||||
case ITEM_SUBCLASS_WEAPON_DAGGER:
|
||||
case ITEM_SUBCLASS_WEAPON_FIST:
|
||||
case ITEM_SUBCLASS_WEAPON_MACE:
|
||||
case ITEM_SUBCLASS_WEAPON_SWORD:
|
||||
if (proto->SubClass == ITEM_SUBCLASS_WEAPON_AXE || proto->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER || proto->SubClass == ITEM_SUBCLASS_WEAPON_FIST ||
|
||||
proto->SubClass == ITEM_SUBCLASS_WEAPON_MACE || proto->SubClass == ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE && proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST &&
|
||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD)
|
||||
{
|
||||
//if (!CanEquipArmor(proto))
|
||||
// continue;
|
||||
// Item* existingItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
|
||||
// if (existingItem)
|
||||
// {
|
||||
// switch (existingItem->GetTemplate()->SubClass)
|
||||
// {
|
||||
// case ITEM_SUBCLASS_WEAPON_AXE:
|
||||
// case ITEM_SUBCLASS_WEAPON_DAGGER:
|
||||
// case ITEM_SUBCLASS_WEAPON_FIST:
|
||||
// case ITEM_SUBCLASS_WEAPON_MACE:
|
||||
// case ITEM_SUBCLASS_WEAPON_SWORD:
|
||||
// if (proto->SubClass == ITEM_SUBCLASS_WEAPON_AXE || proto->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER || proto->SubClass == ITEM_SUBCLASS_WEAPON_FIST ||
|
||||
// proto->SubClass == ITEM_SUBCLASS_WEAPON_MACE || proto->SubClass == ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
// continue;
|
||||
// break;
|
||||
// default:
|
||||
// if (proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE && proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST &&
|
||||
// proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD)
|
||||
// continue;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD)
|
||||
// {
|
||||
// //if (!CanEquipArmor(proto))
|
||||
// // continue;
|
||||
|
||||
if (sRandomItemMgr->HasStatWeight(proto->ItemId))
|
||||
{
|
||||
if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
|
||||
continue;
|
||||
}
|
||||
// if (sRandomItemMgr->HasStatWeight(proto->ItemId))
|
||||
// {
|
||||
// if (!sRandomItemMgr->GetLiveStatWeight(bot, proto->ItemId))
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (Item* existingItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
|
||||
if (existingItem->GetTemplate()->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
// if (Item* existingItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
|
||||
// if (existingItem->GetTemplate()->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD)
|
||||
// continue;
|
||||
// }
|
||||
// else
|
||||
// continue;
|
||||
|
||||
items[proto->Class].push_back(itr.first);
|
||||
}
|
||||
} while (items[ITEM_CLASS_ARMOR].empty() && items[ITEM_CLASS_WEAPON].empty() && desiredQuality-- > ITEM_QUALITY_NORMAL);
|
||||
// items[proto->Class].push_back(itr.first);
|
||||
// }
|
||||
// } while (items[ITEM_CLASS_ARMOR].empty() && items[ITEM_CLASS_WEAPON].empty() && desiredQuality-- > ITEM_QUALITY_NORMAL);
|
||||
|
||||
for (std::map<uint32, std::vector<uint32>>::iterator i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
std::vector<uint32>& ids = i->second;
|
||||
if (ids.empty())
|
||||
{
|
||||
LOG_DEBUG("playerbots", "{}: no items to make second equipment set for slot {}", bot->GetName().c_str(), i->first);
|
||||
continue;
|
||||
}
|
||||
// for (std::map<uint32, std::vector<uint32>>::iterator i = items.begin(); i != items.end(); ++i)
|
||||
// {
|
||||
// std::vector<uint32>& ids = i->second;
|
||||
// if (ids.empty())
|
||||
// {
|
||||
// LOG_DEBUG("playerbots", "{}: no items to make second equipment set for slot {}", bot->GetName().c_str(), i->first);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
for (uint32 attempts = 0; attempts < 15; attempts++)
|
||||
{
|
||||
uint32 index = urand(0, ids.size() - 1);
|
||||
uint32 newItemId = ids[index];
|
||||
// for (uint32 attempts = 0; attempts < 15; attempts++)
|
||||
// {
|
||||
// uint32 index = urand(0, ids.size() - 1);
|
||||
// uint32 newItemId = ids[index];
|
||||
|
||||
if (Item* newItem = StoreNewItemInInventorySlot(bot, newItemId, 1))
|
||||
{
|
||||
newItem->SetOwnerGUID(bot->GetGUID());
|
||||
EnchantItem(newItem);
|
||||
newItem->AddToWorld();
|
||||
newItem->AddToUpdateQueueOf(bot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (Item* newItem = StoreNewItemInInventorySlot(bot, newItemId, 1))
|
||||
// {
|
||||
// newItem->SetOwnerGUID(bot->GetGUID());
|
||||
// EnchantItem(newItem);
|
||||
// newItem->AddToWorld();
|
||||
// newItem->AddToUpdateQueueOf(bot);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void PlayerbotFactory::InitBags()
|
||||
{
|
||||
@@ -1769,18 +1785,22 @@ void PlayerbotFactory::InitAvailableSpells()
|
||||
{
|
||||
bot->LearnDefaultSkills();
|
||||
|
||||
CreatureTemplateContainer const* creatureTemplateContainer = sObjectMgr->GetCreatureTemplates();
|
||||
for (CreatureTemplateContainer::const_iterator i = creatureTemplateContainer->begin(); i != creatureTemplateContainer->end(); ++i)
|
||||
{
|
||||
CreatureTemplate const& co = i->second;
|
||||
if (co.trainer_type != TRAINER_TYPE_TRADESKILLS && co.trainer_type != TRAINER_TYPE_CLASS)
|
||||
continue;
|
||||
if (trainerIdCache.empty()) {
|
||||
CreatureTemplateContainer const* creatureTemplateContainer = sObjectMgr->GetCreatureTemplates();
|
||||
for (CreatureTemplateContainer::const_iterator i = creatureTemplateContainer->begin(); i != creatureTemplateContainer->end(); ++i)
|
||||
{
|
||||
CreatureTemplate const& co = i->second;
|
||||
if (co.trainer_type != TRAINER_TYPE_TRADESKILLS && co.trainer_type != TRAINER_TYPE_CLASS)
|
||||
continue;
|
||||
|
||||
if (co.trainer_type == TRAINER_TYPE_CLASS && co.trainer_class != bot->getClass())
|
||||
continue;
|
||||
|
||||
uint32 trainerId = co.Entry;
|
||||
if (co.trainer_type == TRAINER_TYPE_CLASS && co.trainer_class != bot->getClass())
|
||||
continue;
|
||||
|
||||
uint32 trainerId = co.Entry;
|
||||
trainerIdCache.push_back(trainerId);
|
||||
}
|
||||
}
|
||||
for (uint32 trainerId : trainerIdCache) {
|
||||
TrainerSpellData const* trainer_spells = sObjectMgr->GetNpcTrainerSpells(trainerId);
|
||||
if (!trainer_spells)
|
||||
trainer_spells = sObjectMgr->GetNpcTrainerSpells(trainerId);
|
||||
@@ -1788,7 +1808,7 @@ void PlayerbotFactory::InitAvailableSpells()
|
||||
if (!trainer_spells)
|
||||
continue;
|
||||
|
||||
for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
|
||||
for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
|
||||
{
|
||||
TrainerSpell const* tSpell = &itr->second;
|
||||
|
||||
@@ -1825,7 +1845,6 @@ void PlayerbotFactory::InitAvailableSpells()
|
||||
bot->learnSpell(tSpell->learnedSpell[0], false);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("playerbots", "!tSpell->learnedSpell[0] {}", tSpell->spell);
|
||||
botAI->CastSpell(tSpell->spell, bot);
|
||||
}
|
||||
}
|
||||
@@ -2810,6 +2829,74 @@ void PlayerbotFactory::ApplyEnchantTemplate(uint8 spec)
|
||||
botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId);
|
||||
}
|
||||
|
||||
std::vector<InventoryType> PlayerbotFactory::GetPossibleInventoryTypeListBySlot(EquipmentSlots slot) {
|
||||
std::vector<InventoryType> ret;
|
||||
switch (slot) {
|
||||
case EQUIPMENT_SLOT_HEAD:
|
||||
ret.push_back(INVTYPE_HEAD);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_NECK:
|
||||
ret.push_back(INVTYPE_NECK);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_SHOULDERS:
|
||||
ret.push_back(INVTYPE_SHOULDERS);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_BODY:
|
||||
ret.push_back(INVTYPE_BODY);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_CHEST:
|
||||
ret.push_back(INVTYPE_CHEST);
|
||||
ret.push_back(INVTYPE_ROBE);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_WAIST:
|
||||
ret.push_back(INVTYPE_WAIST);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_LEGS:
|
||||
ret.push_back(INVTYPE_LEGS);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_FEET:
|
||||
ret.push_back(INVTYPE_FEET);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_WRISTS:
|
||||
ret.push_back(INVTYPE_WRISTS);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_HANDS:
|
||||
ret.push_back(INVTYPE_HANDS);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_FINGER1:
|
||||
case EQUIPMENT_SLOT_FINGER2:
|
||||
ret.push_back(INVTYPE_FINGER);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_TRINKET1:
|
||||
case EQUIPMENT_SLOT_TRINKET2:
|
||||
ret.push_back(INVTYPE_TRINKET);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_BACK:
|
||||
ret.push_back(INVTYPE_CLOAK);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_MAINHAND:
|
||||
ret.push_back(INVTYPE_WEAPON);
|
||||
ret.push_back(INVTYPE_2HWEAPON);
|
||||
ret.push_back(INVTYPE_WEAPONMAINHAND);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_OFFHAND:
|
||||
ret.push_back(INVTYPE_WEAPON);
|
||||
ret.push_back(INVTYPE_2HWEAPON);
|
||||
ret.push_back(INVTYPE_WEAPONOFFHAND);
|
||||
ret.push_back(INVTYPE_SHIELD);
|
||||
ret.push_back(INVTYPE_HOLDABLE);
|
||||
break;
|
||||
case EQUIPMENT_SLOT_RANGED:
|
||||
ret.push_back(INVTYPE_RANGED);
|
||||
ret.push_back(INVTYPE_RANGEDRIGHT);
|
||||
ret.push_back(INVTYPE_RELIC);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PlayerbotFactory::LoadEnchantContainer()
|
||||
{
|
||||
m_EnchantContainer.clear();
|
||||
@@ -3022,4 +3109,4 @@ bool PlayerbotFactory::NotSameArmorType(uint32 item_subclass_armor, Player* bot)
|
||||
return item_subclass_armor != ITEM_SUBCLASS_ARMOR_LEATHER;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#define _PLAYERBOT_PLAYERBOTFACTORY_H
|
||||
|
||||
#include "InventoryAction.h"
|
||||
#include "Player.h"
|
||||
|
||||
class Item;
|
||||
class Player;
|
||||
|
||||
struct ItemTemplate;
|
||||
|
||||
@@ -123,8 +123,8 @@ class PlayerbotFactory : public InventoryAction
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
void InitSecondEquipmentSet();
|
||||
void InitEquipmentNew(bool incremental);
|
||||
// void InitSecondEquipmentSet();
|
||||
// void InitEquipmentNew(bool incremental);
|
||||
bool CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality);
|
||||
bool CanEquipUnseenItem(uint8 slot, uint16& dest, uint32 item);
|
||||
void InitTradeSkills();
|
||||
@@ -166,15 +166,15 @@ class PlayerbotFactory : public InventoryAction
|
||||
void LoadEnchantContainer();
|
||||
void ApplyEnchantTemplate();
|
||||
void ApplyEnchantTemplate(uint8 spec);
|
||||
std::vector<InventoryType> GetPossibleInventoryTypeListBySlot(EquipmentSlots slot);
|
||||
static bool IsShieldTank(Player* bot);
|
||||
static bool NotSameArmorType(uint32 item_subclass_armor, Player* bot);
|
||||
EnchantContainer::const_iterator GetEnchantContainerBegin() { return m_EnchantContainer.begin(); }
|
||||
EnchantContainer::const_iterator GetEnchantContainerEnd() { return m_EnchantContainer.end(); }
|
||||
|
||||
uint32 level;
|
||||
uint32 itemQuality;
|
||||
static std::list<uint32> specialQuestIds;
|
||||
|
||||
std::vector<uint32> trainerIdCache;
|
||||
protected:
|
||||
EnchantContainer m_EnchantContainer;
|
||||
};
|
||||
|
||||
@@ -154,6 +154,7 @@ void RandomItemMgr::Init()
|
||||
{
|
||||
BuildItemInfoCache();
|
||||
// BuildEquipCache();
|
||||
BuildEquipCacheNew();
|
||||
BuildAmmoCache();
|
||||
BuildPotionCache();
|
||||
BuildFoodCache();
|
||||
@@ -441,6 +442,11 @@ bool RandomItemMgr::CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank)
|
||||
return sp || ap || tank;
|
||||
}
|
||||
|
||||
std::vector<uint32> RandomItemMgr::GetCachedEquipments(uint32 requiredLevel, uint32 inventoryType)
|
||||
{
|
||||
return equipCacheNew[requiredLevel][inventoryType];
|
||||
}
|
||||
|
||||
bool RandomItemMgr::ShouldEquipArmorForSpec(uint8 playerclass, uint8 spec, ItemTemplate const* proto)
|
||||
{
|
||||
if (proto->InventoryType == INVTYPE_TABARD)
|
||||
@@ -2139,6 +2145,23 @@ void RandomItemMgr::BuildEquipCache()
|
||||
}
|
||||
}
|
||||
|
||||
void RandomItemMgr::BuildEquipCacheNew()
|
||||
{
|
||||
LOG_INFO("playerbots", "Loading equipments cache...");
|
||||
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
||||
for (auto const& itr : *itemTemplates)
|
||||
{
|
||||
ItemTemplate const* proto = &itr.second;
|
||||
if (!proto)
|
||||
continue;
|
||||
uint32 itemId = proto->ItemId;
|
||||
if (IsTestItem(itemId)) {
|
||||
continue;
|
||||
}
|
||||
equipCacheNew[proto->RequiredLevel][proto->InventoryType].push_back(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
RandomItemList RandomItemMgr::Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality)
|
||||
{
|
||||
// return equipCache[key];
|
||||
|
||||
@@ -166,10 +166,12 @@ class RandomItemMgr
|
||||
std::vector<uint32> GetQuestIdsForItem(uint32 itemId);
|
||||
static bool IsUsedBySkill(ItemTemplate const* proto, uint32 skillId);
|
||||
bool IsTestItem(uint32 itemId) { return itemForTest.find(itemId) != itemForTest.end(); }
|
||||
std::vector<uint32> GetCachedEquipments(uint32 requiredLevel, uint32 inventoryType);
|
||||
|
||||
private:
|
||||
void BuildRandomItemCache();
|
||||
void BuildEquipCache();
|
||||
void BuildEquipCacheNew();
|
||||
void BuildItemInfoCache();
|
||||
void BuildAmmoCache();
|
||||
void BuildFoodCache();
|
||||
@@ -180,7 +182,6 @@ class RandomItemMgr
|
||||
bool CanEquipItemNew(ItemTemplate const* proto);
|
||||
void AddItemStats(uint32 mod, uint8& sp, uint8& ap, uint8& tank);
|
||||
bool CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank);
|
||||
|
||||
private:
|
||||
std::map<uint32, RandomItemCache> randomItemCache;
|
||||
std::map<RandomItemType, RandomItemPredicate*> predicates;
|
||||
@@ -197,6 +198,8 @@ class RandomItemMgr
|
||||
std::map<uint32, ItemInfoEntry> itemInfoCache;
|
||||
std::set<uint32> itemForTest;
|
||||
static std::set<uint32> itemCache;
|
||||
// equipCacheNew[RequiredLevel][InventoryType]
|
||||
std::map<uint32, std::map<uint32, std::vector<uint32>>> equipCacheNew;
|
||||
};
|
||||
|
||||
#define sRandomItemMgr RandomItemMgr::instance()
|
||||
|
||||
Reference in New Issue
Block a user