From 1700a20c89e4cd30b1313b3951044f0bfa6ca7c5 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Mon, 19 Aug 2024 18:46:23 +0800 Subject: [PATCH] Add quest rewards to gear initialization --- src/PlayerbotAI.cpp | 113 +++++++++--------- src/RandomItemMgr.cpp | 44 +++++++ src/factory/PlayerbotFactory.cpp | 71 ++++------- src/factory/PlayerbotFactory.h | 2 +- src/factory/StatsCollector.cpp | 12 +- src/factory/StatsWeightCalculator.h | 9 +- .../actions/ChooseRpgTargetAction.cpp | 6 +- src/strategy/rogue/DpsRogueStrategy.cpp | 13 +- src/strategy/values/ItemUsageValue.cpp | 3 + 9 files changed, 151 insertions(+), 122 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 7a4a803f..b611f620 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -11,6 +11,7 @@ #include "AiFactory.h" #include "BudgetValues.h" +#include "ChannelMgr.h" #include "CharacterPackets.h" #include "CreatureAIImpl.h" #include "EmoteAction.h" @@ -45,10 +46,6 @@ #include "Unit.h" #include "UpdateTime.h" #include "Vehicle.h" -#include "GuildMgr.h" -#include "SayAction.h" -#include "ChannelMgr.h" - std::vector PlayerbotAI::dispel_whitelist = { "mutating injection", @@ -351,11 +348,12 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal return; std::string const mapString = WorldPosition(bot).isOverworld() ? std::to_string(bot->GetMapId()) : "I"; - PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_TOTAL, "PlayerbotAI::UpdateAIInternal " + mapString); + PerformanceMonitorOperation* pmo = + sPerformanceMonitor->start(PERF_MON_TOTAL, "PlayerbotAI::UpdateAIInternal " + mapString); ExternalEventHelper helper(aiObjectContext); // chat replies - for (auto it = chatReplies.begin(); it != chatReplies.end(); ) + for (auto it = chatReplies.begin(); it != chatReplies.end();) { time_t checkTime = it->m_time; if (checkTime && time(0) < checkTime) @@ -425,7 +423,7 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal void PlayerbotAI::HandleCommands() { ExternalEventHelper helper(aiObjectContext); - for (auto it = chatCommands.begin(); it != chatCommands.end(); ) + for (auto it = chatCommands.begin(); it != chatCommands.end();) { time_t& checkTime = it->GetTime(); if (checkTime && time(0) < checkTime) @@ -438,9 +436,9 @@ void PlayerbotAI::HandleCommands() Player* owner = it->GetOwner(); if (!helper.ParseChatCommand(command, owner) && it->GetType() == CHAT_MSG_WHISPER) { - //ostringstream out; out << "Unknown command " << command; - //TellPlayer(out); - //helper.ParseChatCommand("help"); + // ostringstream out; out << "Unknown command " << command; + // TellPlayer(out); + // helper.ParseChatCommand("help"); } it = chatCommands.erase(it); } @@ -451,15 +449,16 @@ void PlayerbotAI::HandleCommand(uint32 type, const std::string& text, Player& fr { std::string filtered = text; - if (!IsAllowedCommand(filtered) && !GetSecurity()->CheckLevelFor(PlayerbotSecurityLevel::PLAYERBOT_SECURITY_INVITE, type != CHAT_MSG_WHISPER, &fromPlayer)) + if (!IsAllowedCommand(filtered) && !GetSecurity()->CheckLevelFor(PlayerbotSecurityLevel::PLAYERBOT_SECURITY_INVITE, + type != CHAT_MSG_WHISPER, &fromPlayer)) return; if (type == CHAT_MSG_ADDON) return; - if (filtered.find("BOT\t") == 0) //Mangosbot has BOT prefix so we remove that. + if (filtered.find("BOT\t") == 0) // Mangosbot has BOT prefix so we remove that. filtered = filtered.substr(4); - else if (lang == LANG_ADDON) //Other addon messages should not command bots. + else if (lang == LANG_ADDON) // Other addon messages should not command bots. return; if (type == CHAT_MSG_SYSTEM) @@ -511,22 +510,26 @@ void PlayerbotAI::HandleCommand(uint32 type, const std::string& text, Player& fr { std::string response = HandleRemoteCommand(filtered.substr(6)); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_ADDON, response.c_str(), LANG_ADDON, - CHAT_TAG_NONE, bot->GetGUID(), bot->GetName()); + ChatHandler::BuildChatPacket(data, CHAT_MSG_ADDON, response.c_str(), LANG_ADDON, CHAT_TAG_NONE, bot->GetGUID(), + bot->GetName()); sServerFacade->SendPacket(&fromPlayer, &data); return; } - if (!IsAllowedCommand(filtered) && !GetSecurity()->CheckLevelFor(PlayerbotSecurityLevel::PLAYERBOT_SECURITY_ALLOW_ALL, type != CHAT_MSG_WHISPER, &fromPlayer)) + if (!IsAllowedCommand(filtered) && + !GetSecurity()->CheckLevelFor(PlayerbotSecurityLevel::PLAYERBOT_SECURITY_ALLOW_ALL, type != CHAT_MSG_WHISPER, + &fromPlayer)) return; - if (type == CHAT_MSG_RAID_WARNING && filtered.find(bot->GetName()) != std::string::npos && filtered.find("award") == std::string::npos) + if (type == CHAT_MSG_RAID_WARNING && filtered.find(bot->GetName()) != std::string::npos && + filtered.find("award") == std::string::npos) { chatCommands.push_back(ChatCommandHolder("warning", &fromPlayer, type)); return; } - if ((filtered.size() > 2 && filtered.substr(0, 2) == "d ") || (filtered.size() > 3 && filtered.substr(0, 3) == "do ")) + if ((filtered.size() > 2 && filtered.substr(0, 2) == "d ") || + (filtered.size() > 3 && filtered.substr(0, 3) == "do ")) { Event event("do", "", &fromPlayer); std::string action = filtered.substr(filtered.find(" ") + 1); @@ -590,7 +593,8 @@ void PlayerbotAI::HandleCommand(uint32 type, const std::string& text, Player& fr SetShouldLogOut(false); } } - else if ((filtered.size() > 5) && (filtered.substr(0, 5) == "wait ") && (filtered.find("wait for attack") == std::string::npos)) + else if ((filtered.size() > 5) && (filtered.substr(0, 5) == "wait ") && (filtered.find("wait for attack") == + std::string::npos)) { std::string remaining = filtered.substr(filtered.find(" ") + 1); uint32 delay = atof(remaining.c_str()) * IN_MILLISECONDS; @@ -928,10 +932,10 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) { if (!sPlayerbotAIConfig->randomBotTalk) return; - + if (!AllowActivity()) return; - + WorldPacket p(packet); if (!p.empty() && (p.GetOpcode() == SMSG_MESSAGECHAT || p.GetOpcode() == SMSG_GM_MESSAGECHAT)) { @@ -1019,8 +1023,8 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) if (isFromFreeBot && urand(0, 20)) return; - //if (msgtype == CHAT_MSG_GUILD && (!sPlayerbotAIConfig->guildRepliesRate || urand(1, 100) >= sPlayerbotAIConfig->guildRepliesRate)) - //return; + // if (msgtype == CHAT_MSG_GUILD && (!sPlayerbotAIConfig->guildRepliesRate || urand(1, 100) >= + // sPlayerbotAIConfig->guildRepliesRate)) return; if (!isFromFreeBot) { @@ -1034,7 +1038,9 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) } } - QueueChatResponse(std::move(ChatQueuedReply{msgtype, guid1.GetCounter(), guid2.GetCounter(), message, chanName, name, time(nullptr) + urand(inCombat ? 10 : 5, inCombat ? 25 : 15)})); + QueueChatResponse( + std::move(ChatQueuedReply{msgtype, guid1.GetCounter(), guid2.GetCounter(), message, chanName, + name, time(nullptr) + urand(inCombat ? 10 : 5, inCombat ? 25 : 15)})); GetAiObjectContext()->GetValue("last said", "chat")->Set(time(0) + urand(5, 25)); return; } @@ -2182,19 +2188,21 @@ WorldObject* PlayerbotAI::GetWorldObject(ObjectGuid guid) const AreaTableEntry* PlayerbotAI::GetCurrentArea() { - return sAreaTableStore.LookupEntry(bot->GetMap()->GetAreaId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())); + return sAreaTableStore.LookupEntry( + bot->GetMap()->GetAreaId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())); } const AreaTableEntry* PlayerbotAI::GetCurrentZone() { - return sAreaTableStore.LookupEntry(bot->GetMap()->GetZoneId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())); + return sAreaTableStore.LookupEntry( + bot->GetMap()->GetZoneId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ())); } std::string PlayerbotAI::GetLocalizedAreaName(const AreaTableEntry* entry) { if (entry) return entry->area_name[sWorld->GetDefaultDbcLocale()]; - + return ""; } @@ -2254,7 +2262,7 @@ bool PlayerbotAI::SayToWorld(const std::string& msg) if (!cMgr) return false; - //no zone + // no zone if (Channel* worldChannel = cMgr->GetChannel("World", bot)) { worldChannel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL); @@ -2277,7 +2285,7 @@ bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chan const auto current_str_zone = GetLocalizedAreaName(current_zone); for (auto const& [key, channel] : cMgr->GetChannels()) { - //check for current zone + // check for current zone if (channel && channel->GetChannelId() == chanId) { const auto does_contains = channel->GetName().find(current_str_zone) != std::string::npos; @@ -2304,7 +2312,8 @@ bool PlayerbotAI::SayToParty(const std::string& msg) return false; WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_PARTY, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(), bot->GetName()); + ChatHandler::BuildChatPacket(data, CHAT_MSG_PARTY, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(), + bot->GetName()); for (auto reciever : GetPlayersInGroup()) { @@ -2320,7 +2329,8 @@ bool PlayerbotAI::SayToRaid(const std::string& msg) return false; WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(), bot->GetName()); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, msg.c_str(), LANG_UNIVERSAL, CHAT_TAG_NONE, bot->GetGUID(), + bot->GetName()); for (auto reciever : GetPlayersInGroup()) { @@ -2772,7 +2782,7 @@ bool PlayerbotAI::CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell, // break; // } // } - + if (target->IsImmunedToSpell(spellInfo)) { if (!sPlayerbotAIConfig->logInGroupOnly || (bot->GetGroup() && HasRealPlayerMaster())) @@ -4767,27 +4777,18 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const return nullptr; // static const will only get created once whatever the call amout - static const std::vector uPriorizedWizardOilIds = - { - MINOR_WIZARD_OIL, MINOR_MANA_OIL, - LESSER_WIZARD_OIL, LESSER_MANA_OIL, - BRILLIANT_WIZARD_OIL, BRILLIANT_MANA_OIL, - WIZARD_OIL, SUPERIOR_MANA_OIL, SUPERIOR_WIZARD_OIL - }; + static const std::vector uPriorizedWizardOilIds = { + MINOR_WIZARD_OIL, MINOR_MANA_OIL, LESSER_WIZARD_OIL, LESSER_MANA_OIL, BRILLIANT_WIZARD_OIL, + BRILLIANT_MANA_OIL, WIZARD_OIL, SUPERIOR_MANA_OIL, SUPERIOR_WIZARD_OIL}; // static const will only get created once whatever the call amout - static const std::vector uPriorizedManaOilIds = - { - MINOR_MANA_OIL, MINOR_WIZARD_OIL, - LESSER_MANA_OIL, LESSER_WIZARD_OIL, - BRILLIANT_MANA_OIL, BRILLIANT_WIZARD_OIL, - SUPERIOR_MANA_OIL, WIZARD_OIL, SUPERIOR_WIZARD_OIL - }; + static const std::vector uPriorizedManaOilIds = { + MINOR_MANA_OIL, MINOR_WIZARD_OIL, LESSER_MANA_OIL, LESSER_WIZARD_OIL, BRILLIANT_MANA_OIL, + BRILLIANT_WIZARD_OIL, SUPERIOR_MANA_OIL, WIZARD_OIL, SUPERIOR_WIZARD_OIL}; Item* oil = nullptr; - if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_SWORD || - item_template->SubClass == ITEM_SUBCLASS_WEAPON_STAFF || - item_template->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) + if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_SWORD || + item_template->SubClass == ITEM_SUBCLASS_WEAPON_STAFF || item_template->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) { for (const auto& id : uPriorizedWizardOilIds) { @@ -4797,7 +4798,7 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const } } else if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_MACE || - item_template->SubClass == ITEM_SUBCLASS_WEAPON_MACE2) + item_template->SubClass == ITEM_SUBCLASS_WEAPON_MACE2) { for (const auto& id : uPriorizedManaOilIds) { @@ -4940,7 +4941,6 @@ uint32 PlayerbotAI::GetInventoryItemsCountWithId(uint32 itemId) bool PlayerbotAI::HasItemInInventory(uint32 itemId) { - for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { if (Bag* pBag = (Bag*)bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) @@ -5167,10 +5167,7 @@ bool PlayerbotAI::IsInRealGuild() return !(sPlayerbotAIConfig->IsInRandomAccountList(leaderAccount)); } -void PlayerbotAI::QueueChatResponse(const ChatQueuedReply chatReply) -{ - chatReplies.push_back(std::move(chatReply)); -} +void PlayerbotAI::QueueChatResponse(const ChatQueuedReply chatReply) { chatReplies.push_back(std::move(chatReply)); } bool PlayerbotAI::EqualLowercaseName(std::string s1, std::string s2) { @@ -5507,11 +5504,13 @@ uint8 PlayerbotAI::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool sw bool PlayerbotAI::IsSafe(Player* player) { - return player && player->GetMapId() == bot->GetMapId() && player->GetInstanceId() == bot->GetInstanceId() && !player->IsBeingTeleported(); + return player && player->GetMapId() == bot->GetMapId() && player->GetInstanceId() == bot->GetInstanceId() && + !player->IsBeingTeleported(); } bool PlayerbotAI::IsSafe(WorldObject* obj) { - return obj && obj->GetMapId() == bot->GetMapId() && obj->GetInstanceId() == bot->GetInstanceId() && (!obj->IsPlayer() || !((Player*)obj)->IsBeingTeleported()); + return obj && obj->GetMapId() == bot->GetMapId() && obj->GetInstanceId() == bot->GetInstanceId() && + (!obj->IsPlayer() || !((Player*)obj)->IsBeingTeleported()); } ChatChannelSource PlayerbotAI::GetChatChannelSource(Player* bot, uint32 type, std::string channelName) { diff --git a/src/RandomItemMgr.cpp b/src/RandomItemMgr.cpp index 415ccb15..7a62891a 100644 --- a/src/RandomItemMgr.cpp +++ b/src/RandomItemMgr.cpp @@ -2197,6 +2197,46 @@ void RandomItemMgr::BuildEquipCache() void RandomItemMgr::BuildEquipCacheNew() { LOG_INFO("playerbots", "Loading equipments cache..."); + + std::unordered_set questItemIds; + ObjectMgr::QuestMap const& questTemplates = sObjectMgr->GetQuestTemplates(); + for (ObjectMgr::QuestMap::const_iterator i = questTemplates.begin(); i != questTemplates.end(); ++i) + { + uint32 questId = i->first; + Quest const* quest = i->second; + + if (quest->IsRepeatable()) + continue; + + if (quest->GetQuestLevel() <= 0) + continue; + + if (quest->GetRequiredClasses()) + continue; + + for (int j = 0; j < quest->GetRewChoiceItemsCount(); j++) + if (uint32 itemId = quest->RewardChoiceItemId[j]) + { + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId); + if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR) + continue; + int requiredLevel = std::max((int)proto->RequiredLevel, quest->GetQuestLevel()); + equipCacheNew[requiredLevel][proto->InventoryType].push_back(itemId); + questItemIds.insert(itemId); + } + + for (int j = 0; j < quest->GetRewItemsCount(); j++) + if (uint32 itemId = quest->RewardItemId[j]) + { + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId); + if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR) + continue; + int requiredLevel = std::max((int)proto->RequiredLevel, quest->GetQuestLevel()); + equipCacheNew[requiredLevel][proto->InventoryType].push_back(itemId); + questItemIds.insert(itemId); + } + } + ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore(); for (auto const& itr : *itemTemplates) { @@ -2204,6 +2244,10 @@ void RandomItemMgr::BuildEquipCacheNew() if (!proto) continue; uint32 itemId = proto->ItemId; + + if (questItemIds.find(itemId) != questItemIds.end()) + continue; + if (IsTestItem(itemId)) { continue; diff --git a/src/factory/PlayerbotFactory.cpp b/src/factory/PlayerbotFactory.cpp index 93069c77..7c969b95 100644 --- a/src/factory/PlayerbotFactory.cpp +++ b/src/factory/PlayerbotFactory.cpp @@ -1264,14 +1264,11 @@ bool PlayerbotFactory::CanEquipWeapon(ItemTemplate const* proto) return true; } -bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality) +bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto) { if (proto->Duration != 0) return false; - if (proto->Quality != desiredQuality) - return false; - if (proto->Bonding == BIND_QUEST_ITEM /*|| proto->Bonding == BIND_WHEN_USE*/) return false; @@ -1279,29 +1276,15 @@ bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto, uint32 desiredQua return true; uint32 requiredLevel = proto->RequiredLevel; - if (!requiredLevel) + bool hasItem = bot->HasItemCount(proto->ItemId, 1, true); + // bot->GetItemCount() + // !requiredLevel -> it's a quest reward item + if (!requiredLevel && hasItem) return false; uint32 level = bot->GetLevel(); - uint32 delta = 2; - if (level < 15) - delta = std::min(level, 15u); // urand(7, 15); - // else if (proto->Class == ITEM_CLASS_WEAPON || proto->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD) - // delta = urand(2, 3); - // else if (!(level % 10) || (level % 10) == 9) - // delta = 2; - else if (level < 40) - delta = 10; // urand(5, 10); - else if (level < 60) - delta = 6; // urand(3, 7); - else if (level < 70) - delta = 9; // urand(2, 5); - else if (level < 80) - delta = 9; // urand(2, 4); - else if (level == 80) - delta = 9; // urand(2, 4); - if (desiredQuality > ITEM_QUALITY_NORMAL && (requiredLevel > level || requiredLevel < level - delta)) + if (requiredLevel > level) return false; return true; @@ -1493,7 +1476,6 @@ void PlayerbotFactory::InitEquipment(bool incremental) } do { - ItemTemplateContainer const* itemTemplate = sObjectMgr->GetItemTemplateStore(); for (uint32 requiredLevel = bot->GetLevel(); requiredLevel > std::max((int32)bot->GetLevel() - delta, 0); requiredLevel--) { @@ -1528,9 +1510,12 @@ void PlayerbotFactory::InitEquipment(bool incremental) if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR) continue; - if (!CanEquipItem(proto, desiredQuality)) + if (proto->Quality != desiredQuality) continue; + if (!CanEquipItem(proto)) + continue; + if (proto->Class == ITEM_CLASS_ARMOR && (slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS || slot == EQUIPMENT_SLOT_CHEST || slot == EQUIPMENT_SLOT_WAIST || @@ -1595,6 +1580,11 @@ void PlayerbotFactory::InitEquipment(bool incremental) uint32 newItemId = ids[index]; uint16 dest; + + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newItemId); + + if (!CanEquipItem(proto)) + continue; if (oldItem && oldItem->GetTemplate()->ItemId == newItemId) continue; @@ -1609,36 +1599,12 @@ void PlayerbotFactory::InitEquipment(bool incremental) bestItemForSlot = newItemId; } } - // for (int attempts = 0; attempts < std::max((int)(ids.size() * 0.75), 1); attempts++) - // { - // uint32 index = urand(0, ids.size() - 1); - // uint32 newItemId = ids[index]; - - // uint16 dest; - - // if (oldItem && oldItem->GetTemplate()->ItemId == newItemId) - // continue; - - // if (!CanEquipUnseenItem(slot, dest, newItemId)) - // continue; - - // float cur_score = calculator.CalculateItem(newItemId); - // if (cur_score > bestScoreForSlot) - // { - // bestScoreForSlot = cur_score; - // bestItemForSlot = newItemId; - // } - // } if (bestItemForSlot == 0) { continue; } if (oldItem) { - // uint8 dstBag = NULL_BAG; - // WorldPacket packet(CMSG_AUTOSTORE_BAG_ITEM, 3); - // packet << INVENTORY_SLOT_BAG_0 << slot << dstBag; - // bot->GetSession()->HandleAutoStoreBagItemOpcode(packet); bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true); } uint16 dest; @@ -3334,8 +3300,11 @@ void PlayerbotFactory::InitInventoryEquip() if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(proto)) continue; - - if (!CanEquipItem(proto, desiredQuality)) + + if (proto->Quality != desiredQuality) + continue; + + if (!CanEquipItem(proto)) continue; ids.push_back(itr.first); diff --git a/src/factory/PlayerbotFactory.h b/src/factory/PlayerbotFactory.h index 65de201b..f88ce96e 100644 --- a/src/factory/PlayerbotFactory.h +++ b/src/factory/PlayerbotFactory.h @@ -141,7 +141,7 @@ private: void Prepare(); // void InitSecondEquipmentSet(); // void InitEquipmentNew(bool incremental); - bool CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality); + bool CanEquipItem(ItemTemplate const* proto); bool CanEquipUnseenItem(uint8 slot, uint16& dest, uint32 item); void InitTradeSkills(); void UpdateTradeSkills(); diff --git a/src/factory/StatsCollector.cpp b/src/factory/StatsCollector.cpp index 81226049..1216b35c 100644 --- a/src/factory/StatsCollector.cpp +++ b/src/factory/StatsCollector.cpp @@ -89,13 +89,21 @@ void StatsCollector::CollectSpellStats(uint32 spellId, float multiplier, int32 s bool canNextTrigger = true; uint32 procFlags; + uint32 procChance; if (eventEntry && eventEntry->procFlags) procFlags = eventEntry->procFlags; else procFlags = spellInfo->ProcFlags; - - if (procFlags && !CanBeTriggeredByType(spellInfo, procFlags)) + + if (eventEntry && eventEntry->customChance) + procChance = eventEntry->customChance; + else + procChance = spellInfo->ProcChance; + bool lowChance = procChance <= 5; + + if (lowChance || (procFlags && !CanBeTriggeredByType(spellInfo, procFlags))) canNextTrigger = false; + if (spellInfo->StackAmount) { // Heuristic multiplier for spell with stackAmount since high stackAmount may not be available diff --git a/src/factory/StatsWeightCalculator.h b/src/factory/StatsWeightCalculator.h index 030f1540..721eff9e 100644 --- a/src/factory/StatsWeightCalculator.h +++ b/src/factory/StatsWeightCalculator.h @@ -13,7 +13,8 @@ ((1 << ITEM_SUBCLASS_WEAPON_AXE) | (1 << ITEM_SUBCLASS_WEAPON_MACE) | (1 << ITEM_SUBCLASS_WEAPON_SWORD) | \ (1 << ITEM_SUBCLASS_WEAPON_DAGGER) | (1 << ITEM_SUBCLASS_WEAPON_FIST)) -enum StatsOverflowThreshold { +enum StatsOverflowThreshold +{ SPELL_HIT_OVERFLOW = 17, MELEE_HIT_OVERFLOW = 8, RANGED_HIT_OVERFLOW = 8, @@ -30,6 +31,10 @@ public: float CalculateItem(uint32 itemId); float CalculateEnchant(uint32 enchantId); + void SetOverflowPenalty(bool apply) { enable_overflow_penalty_ = apply; } + void SetItemSetBonus(bool apply) { enable_item_set_bonus_ = apply; } + void SetQualityBlend(bool apply) { enable_quality_blend_ = apply; } + private: void GenerateWeights(Player* player); void GenerateBasicWeights(Player* player); @@ -53,7 +58,7 @@ private: bool enable_overflow_penalty_; bool enable_item_set_bonus_; bool enable_quality_blend_; - + float weight_; float stats_weights_[STATS_TYPE_MAX]; }; diff --git a/src/strategy/actions/ChooseRpgTargetAction.cpp b/src/strategy/actions/ChooseRpgTargetAction.cpp index d376d236..dfd1cef5 100644 --- a/src/strategy/actions/ChooseRpgTargetAction.cpp +++ b/src/strategy/actions/ChooseRpgTargetAction.cpp @@ -195,9 +195,9 @@ bool ChooseRpgTargetAction::Execute(Event event) } } } - - if (possiblePlayers.size() > 200 || HasSameTarget(guidP, urand(5, 15), possiblePlayers)) - continue; + + // if (possiblePlayers.size() > 200 || HasSameTarget(guidP, urand(5, 15), possiblePlayers)) + // continue; float relevance = getMaxRelevance(guidP); diff --git a/src/strategy/rogue/DpsRogueStrategy.cpp b/src/strategy/rogue/DpsRogueStrategy.cpp index 6fc450b9..91cc8044 100644 --- a/src/strategy/rogue/DpsRogueStrategy.cpp +++ b/src/strategy/rogue/DpsRogueStrategy.cpp @@ -99,10 +99,11 @@ void DpsRogueStrategy::InitTriggers(std::vector& triggers) "slice and dice", NextAction::array(0, new NextAction("slice and dice", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode("combo points available", - NextAction::array(0, new NextAction("rupture", ACTION_HIGH + 1), nullptr))); + NextAction::array(0, new NextAction("rupture", ACTION_HIGH + 1), + new NextAction("eviscerate", ACTION_HIGH), nullptr))); triggers.push_back(new TriggerNode("target with combo points almost dead", - NextAction::array(0, new NextAction("eviscerate", ACTION_HIGH + 1), nullptr))); + NextAction::array(0, new NextAction("eviscerate", ACTION_HIGH + 2), nullptr))); triggers.push_back( new TriggerNode("medium threat", NextAction::array(0, new NextAction("vanish", ACTION_HIGH), nullptr))); @@ -111,8 +112,8 @@ void DpsRogueStrategy::InitTriggers(std::vector& triggers) new TriggerNode("low health", NextAction::array(0, new NextAction("evasion", ACTION_HIGH + 9), new NextAction("feint", ACTION_HIGH + 8), nullptr))); - triggers.push_back( - new TriggerNode("critical health", NextAction::array(0, new NextAction("cloak of shadows", ACTION_HIGH + 7), nullptr))); + triggers.push_back(new TriggerNode( + "critical health", NextAction::array(0, new NextAction("cloak of shadows", ACTION_HIGH + 7), nullptr))); triggers.push_back( new TriggerNode("kick", NextAction::array(0, new NextAction("kick", ACTION_INTERRUPT + 2), nullptr))); @@ -128,8 +129,8 @@ void DpsRogueStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("light aoe", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), nullptr))); - triggers.push_back( - new TriggerNode("blade flurry", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 2), nullptr))); + triggers.push_back(new TriggerNode("blade flurry", + NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 2), nullptr))); triggers.push_back(new TriggerNode( "enemy out of melee", diff --git a/src/strategy/values/ItemUsageValue.cpp b/src/strategy/values/ItemUsageValue.cpp index ca294165..9bdf206d 100644 --- a/src/strategy/values/ItemUsageValue.cpp +++ b/src/strategy/values/ItemUsageValue.cpp @@ -192,6 +192,9 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto) bool shouldEquip = false; // uint32 statWeight = sRandomItemMgr->GetLiveStatWeight(bot, itemProto->ItemId); StatsWeightCalculator calculator(bot); + calculator.SetItemSetBonus(false); + calculator.SetOverflowPenalty(false); + float itemScore = calculator.CalculateItem(itemProto->ItemId); if (itemScore) shouldEquip = true;