diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index 14fe51f4..0586ea7c 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -53,8 +53,9 @@ uint32 PlayerbotFactory::tradeSkills[] = std::list PlayerbotFactory::classQuestIds; std::list PlayerbotFactory::specialQuestIds; -PlayerbotFactory::PlayerbotFactory(Player* bot, uint32 level, uint32 itemQuality, uint32 gearScoreLimit) : level(level), itemQuality(itemQuality), gearScoreLimit(gearScoreLimit), InventoryAction(GET_PLAYERBOT_AI(bot), "factory") +PlayerbotFactory::PlayerbotFactory(Player* bot, uint32 level, uint32 itemQuality, uint32 gearScoreLimit) : level(level), itemQuality(itemQuality), gearScoreLimit(gearScoreLimit), bot(bot) { + botAI = GET_PLAYERBOT_AI(bot); } void PlayerbotFactory::Init() @@ -201,9 +202,11 @@ void PlayerbotFactory::Randomize(bool incremental) InitTalentsTree(); // bot->SaveToDB(false, false); sRandomPlayerbotMgr->SetValue(bot->GetGUID().GetCounter(), "specNo", 0); - sPlayerbotDbStore->Reset(botAI); - // botAI->DoSpecificAction("auto talents"); - botAI->ResetStrategies(false); // fix wrong stored strategy + if (botAI) { + sPlayerbotDbStore->Reset(botAI); + // botAI->DoSpecificAction("auto talents"); + botAI->ResetStrategies(false); // fix wrong stored strategy + } if (pmo) pmo->finish(); @@ -3099,8 +3102,35 @@ void PlayerbotFactory::ApplyEnchantTemplate() void PlayerbotFactory::ApplyEnchantTemplate(uint8 spec) { for (EnchantContainer::const_iterator itr = GetEnchantContainerBegin(); itr != GetEnchantContainerEnd(); ++itr) - if ((*itr).ClassId == bot->getClass() && (*itr).SpecId == spec) - botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId); + if ((*itr).ClassId == bot->getClass() && (*itr).SpecId == spec) { + uint32 spellid = (*itr).SpellId; + uint32 slot = (*itr).SlotId; + Item* pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if (!pItem || !pItem->IsInWorld() || !pItem->GetOwner() || !pItem->GetOwner()->IsInWorld() || !pItem->GetOwner()->GetSession()) + return; + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); + if (!spellInfo) + return; + + uint32 enchantid = spellInfo->Effects[0].MiscValue; + if (!enchantid) + { + // LOG_ERROR("playerbots", "{}: Invalid enchantid ", enchantid, " report to devs", bot->GetName().c_str()); + return; + } + + if (!((1 << pItem->GetTemplate()->SubClass) & spellInfo->EquippedItemSubClassMask) && !((1 << pItem->GetTemplate()->InventoryType) & spellInfo->EquippedItemInventoryTypeMask)) + { + // LOG_ERROR("playerbots", "{}: items could not be enchanted, wrong item type equipped", bot->GetName().c_str()); + return; + } + + bot->ApplyEnchantment(pItem, PERM_ENCHANTMENT_SLOT, false); + pItem->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchantid, 0, 0); + bot->ApplyEnchantment(pItem, PERM_ENCHANTMENT_SLOT, true); + } + // botAI->EnchantItemT((*itr).SpellId, (*itr).SlotId); } std::vector PlayerbotFactory::GetPossibleInventoryTypeListBySlot(EquipmentSlots slot) { @@ -3385,3 +3415,82 @@ bool PlayerbotFactory::NotSameArmorType(uint32 item_subclass_armor, Player* bot) } return false; } + +void PlayerbotFactory::IterateItems(IterateItemsVisitor* visitor, IterateItemsMask mask) +{ + if (mask & ITERATE_ITEMS_IN_BAGS) + IterateItemsInBags(visitor); + + if (mask & ITERATE_ITEMS_IN_EQUIP) + IterateItemsInEquip(visitor); + + if (mask == ITERATE_ITEMS_IN_BANK) + IterateItemsInBank(visitor); +} + +void PlayerbotFactory::IterateItemsInBags(IterateItemsVisitor* visitor) +{ + for (uint32 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + if (Item *pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (!visitor->Visit(pItem)) + return; + + for (uint32 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) + if (Item *pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + if (!visitor->Visit(pItem)) + return; + + for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) + if (Bag *pBag = (Bag*)bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + for(uint32 j = 0; j < pBag->GetBagSize(); ++j) + if (Item* pItem = pBag->GetItemByPos(j)) + if (!visitor->Visit(pItem)) + return; +} + +void PlayerbotFactory::IterateItemsInEquip(IterateItemsVisitor* visitor) +{ + for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; slot++) + { + Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if (!pItem) + continue; + + if (!visitor->Visit(pItem)) + return; + } +} + +void PlayerbotFactory::IterateItemsInBank(IterateItemsVisitor* visitor) +{ + for (uint8 slot = BANK_SLOT_ITEM_START; slot < BANK_SLOT_ITEM_END; slot++) + { + Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if(!pItem) + continue; + + if (!visitor->Visit(pItem)) + return; + } + + for (uint32 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i) + { + if (Bag* pBag = (Bag*)bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) + { + if (pBag) + { + for (uint32 j = 0; j < pBag->GetBagSize(); ++j) + { + if (Item* pItem = pBag->GetItemByPos(j)) + { + if(!pItem) + continue; + + if (!visitor->Visit(pItem)) + return; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/PlayerbotFactory.h b/src/PlayerbotFactory.h index f8bf8360..4f585c31 100644 --- a/src/PlayerbotFactory.h +++ b/src/PlayerbotFactory.h @@ -7,6 +7,7 @@ #include "InventoryAction.h" #include "Player.h" +#include "PlayerbotAI.h" class Item; @@ -100,7 +101,7 @@ enum PriorizedConsumables #define MAX_CONSUM_ID 28 -class PlayerbotFactory : public InventoryAction +class PlayerbotFactory { public: PlayerbotFactory(Player* bot, uint32 level, uint32 itemQuality = 0, uint32 gearScoreLimit = 0); @@ -172,6 +173,10 @@ class PlayerbotFactory : public InventoryAction std::vector GetPossibleInventoryTypeListBySlot(EquipmentSlots slot); static bool IsShieldTank(Player* bot); static bool NotSameArmorType(uint32 item_subclass_armor, Player* bot); + void IterateItems(IterateItemsVisitor* visitor, IterateItemsMask mask = ITERATE_ITEMS_IN_BAGS); + void IterateItemsInBags(IterateItemsVisitor* visitor); + void IterateItemsInEquip(IterateItemsVisitor* visitor); + void IterateItemsInBank(IterateItemsVisitor* visitor); EnchantContainer::const_iterator GetEnchantContainerBegin() { return m_EnchantContainer.begin(); } EnchantContainer::const_iterator GetEnchantContainerEnd() { return m_EnchantContainer.end(); } uint32 level; @@ -181,6 +186,8 @@ class PlayerbotFactory : public InventoryAction std::vector trainerIdCache; protected: EnchantContainer m_EnchantContainer; + Player* bot; + PlayerbotAI* botAI; }; #endif diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index 964fa027..7440ccc3 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -5,6 +5,7 @@ #include "CharacterCache.h" #include "CharacterPackets.h" #include "Common.h" +#include "Define.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "PlayerbotAIConfig.h" @@ -16,6 +17,7 @@ #include "SharedDefines.h" #include "WorldSession.h" #include "ChannelMgr.h" +#include #include #include @@ -666,14 +668,10 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg if (!strcmp(cmd, "initself")) { if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { - OnBotLogin(master); + // OnBotLogin(master); PlayerbotFactory factory(master, master->getLevel(), ITEM_QUALITY_EPIC); factory.Randomize(false); - // LogoutPlayerBot(master->GetGUID()); - // DisablePlayerBot(master->GetGUID()); - // sPlayerbotsMgr->AddPlayerbotData(master, false); - // sRandomPlayerbotMgr->OnPlayerLogin(master); - messages.push_back("initself ok. please logout to refresh."); + messages.push_back("initself ok"); return messages; } else { messages.push_back("ERROR: Only GM can use this command."); @@ -681,6 +679,50 @@ std::vector PlayerbotHolder::HandlePlayerbotCommand(char const* arg } } + + + + + if (!strncmp(cmd, "initself=", 9)) { + if (!strcmp(cmd, "initself=rare")) { + if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { + // OnBotLogin(master); + PlayerbotFactory factory(master, master->getLevel(), ITEM_QUALITY_RARE); + factory.Randomize(false); + messages.push_back("initself ok"); + return messages; + } else { + messages.push_back("ERROR: Only GM can use this command."); + return messages; + } + } + if (!strcmp(cmd, "initself=epic")) { + if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { + // OnBotLogin(master); + PlayerbotFactory factory(master, master->getLevel(), ITEM_QUALITY_EPIC); + factory.Randomize(false); + messages.push_back("initself ok"); + return messages; + } else { + messages.push_back("ERROR: Only GM can use this command."); + return messages; + } + } + int32 gs; + if (sscanf(cmd, "initself=%d", &gs) != -1) { + if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { + // OnBotLogin(master); + PlayerbotFactory factory(master, master->getLevel(), ITEM_QUALITY_LEGENDARY, gs); + factory.Randomize(false); + messages.push_back("initself ok, gs = " + std::to_string(gs)); + return messages; + } else { + messages.push_back("ERROR: Only GM can use this command."); + return messages; + } + } + } + if (!strcmp(cmd, "list")) { messages.push_back(ListBots(master));