mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge pull request #486 from liyunfan1223/misc_0819
Improvement gear intialization & Disable ExtractAllItemIds for heavy regex
This commit is contained in:
@@ -790,7 +790,7 @@ AiPlayerbot.PremadeSpecLink.2.0.80 = 50350152220013053100515221-503201312
|
|||||||
AiPlayerbot.PremadeSpecName.2.1 = prot pve
|
AiPlayerbot.PremadeSpecName.2.1 = prot pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.2.1 = 41100,43367,43869,43369,43365,45745
|
AiPlayerbot.PremadeSpecGlyph.2.1 = 41100,43367,43869,43369,43365,45745
|
||||||
AiPlayerbot.PremadeSpecLink.2.1.60 = -05005135203102311333112321
|
AiPlayerbot.PremadeSpecLink.2.1.60 = -05005135203102311333112321
|
||||||
AiPlayerbot.PremadeSpecLink.2.1.80 = -05005135203132311333312321-5023005
|
AiPlayerbot.PremadeSpecLink.2.1.80 = -05005135203102311333312321-502302012003
|
||||||
AiPlayerbot.PremadeSpecName.2.2 = ret pve
|
AiPlayerbot.PremadeSpecName.2.2 = ret pve
|
||||||
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43369,43365,43869
|
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43369,43365,43869
|
||||||
AiPlayerbot.PremadeSpecLink.2.2.60 = --05230051203331302133231131
|
AiPlayerbot.PremadeSpecLink.2.2.60 = --05230051203331302133231131
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "AiFactory.h"
|
#include "AiFactory.h"
|
||||||
#include "BudgetValues.h"
|
#include "BudgetValues.h"
|
||||||
|
#include "ChannelMgr.h"
|
||||||
#include "CharacterPackets.h"
|
#include "CharacterPackets.h"
|
||||||
#include "CreatureAIImpl.h"
|
#include "CreatureAIImpl.h"
|
||||||
#include "EmoteAction.h"
|
#include "EmoteAction.h"
|
||||||
@@ -45,10 +46,6 @@
|
|||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "UpdateTime.h"
|
#include "UpdateTime.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
#include "GuildMgr.h"
|
|
||||||
#include "SayAction.h"
|
|
||||||
#include "ChannelMgr.h"
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string> PlayerbotAI::dispel_whitelist = {
|
std::vector<std::string> PlayerbotAI::dispel_whitelist = {
|
||||||
"mutating injection",
|
"mutating injection",
|
||||||
@@ -351,11 +348,12 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
std::string const mapString = WorldPosition(bot).isOverworld() ? std::to_string(bot->GetMapId()) : "I";
|
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);
|
ExternalEventHelper helper(aiObjectContext);
|
||||||
|
|
||||||
// chat replies
|
// chat replies
|
||||||
for (auto it = chatReplies.begin(); it != chatReplies.end(); )
|
for (auto it = chatReplies.begin(); it != chatReplies.end();)
|
||||||
{
|
{
|
||||||
time_t checkTime = it->m_time;
|
time_t checkTime = it->m_time;
|
||||||
if (checkTime && time(0) < checkTime)
|
if (checkTime && time(0) < checkTime)
|
||||||
@@ -425,7 +423,7 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal
|
|||||||
void PlayerbotAI::HandleCommands()
|
void PlayerbotAI::HandleCommands()
|
||||||
{
|
{
|
||||||
ExternalEventHelper helper(aiObjectContext);
|
ExternalEventHelper helper(aiObjectContext);
|
||||||
for (auto it = chatCommands.begin(); it != chatCommands.end(); )
|
for (auto it = chatCommands.begin(); it != chatCommands.end();)
|
||||||
{
|
{
|
||||||
time_t& checkTime = it->GetTime();
|
time_t& checkTime = it->GetTime();
|
||||||
if (checkTime && time(0) < checkTime)
|
if (checkTime && time(0) < checkTime)
|
||||||
@@ -438,9 +436,9 @@ void PlayerbotAI::HandleCommands()
|
|||||||
Player* owner = it->GetOwner();
|
Player* owner = it->GetOwner();
|
||||||
if (!helper.ParseChatCommand(command, owner) && it->GetType() == CHAT_MSG_WHISPER)
|
if (!helper.ParseChatCommand(command, owner) && it->GetType() == CHAT_MSG_WHISPER)
|
||||||
{
|
{
|
||||||
//ostringstream out; out << "Unknown command " << command;
|
// ostringstream out; out << "Unknown command " << command;
|
||||||
//TellPlayer(out);
|
// TellPlayer(out);
|
||||||
//helper.ParseChatCommand("help");
|
// helper.ParseChatCommand("help");
|
||||||
}
|
}
|
||||||
it = chatCommands.erase(it);
|
it = chatCommands.erase(it);
|
||||||
}
|
}
|
||||||
@@ -451,15 +449,16 @@ void PlayerbotAI::HandleCommand(uint32 type, const std::string& text, Player& fr
|
|||||||
{
|
{
|
||||||
std::string filtered = text;
|
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;
|
return;
|
||||||
|
|
||||||
if (type == CHAT_MSG_ADDON)
|
if (type == CHAT_MSG_ADDON)
|
||||||
return;
|
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);
|
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;
|
return;
|
||||||
|
|
||||||
if (type == CHAT_MSG_SYSTEM)
|
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));
|
std::string response = HandleRemoteCommand(filtered.substr(6));
|
||||||
WorldPacket data;
|
WorldPacket data;
|
||||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_ADDON, response.c_str(), LANG_ADDON,
|
ChatHandler::BuildChatPacket(data, CHAT_MSG_ADDON, response.c_str(), LANG_ADDON, CHAT_TAG_NONE, bot->GetGUID(),
|
||||||
CHAT_TAG_NONE, bot->GetGUID(), bot->GetName());
|
bot->GetName());
|
||||||
sServerFacade->SendPacket(&fromPlayer, &data);
|
sServerFacade->SendPacket(&fromPlayer, &data);
|
||||||
return;
|
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;
|
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));
|
chatCommands.push_back(ChatCommandHolder("warning", &fromPlayer, type));
|
||||||
return;
|
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);
|
Event event("do", "", &fromPlayer);
|
||||||
std::string action = filtered.substr(filtered.find(" ") + 1);
|
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);
|
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);
|
std::string remaining = filtered.substr(filtered.find(" ") + 1);
|
||||||
uint32 delay = atof(remaining.c_str()) * IN_MILLISECONDS;
|
uint32 delay = atof(remaining.c_str()) * IN_MILLISECONDS;
|
||||||
@@ -928,10 +932,10 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
|||||||
{
|
{
|
||||||
if (!sPlayerbotAIConfig->randomBotTalk)
|
if (!sPlayerbotAIConfig->randomBotTalk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!AllowActivity())
|
if (!AllowActivity())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WorldPacket p(packet);
|
WorldPacket p(packet);
|
||||||
if (!p.empty() && (p.GetOpcode() == SMSG_MESSAGECHAT || p.GetOpcode() == SMSG_GM_MESSAGECHAT))
|
if (!p.empty() && (p.GetOpcode() == SMSG_MESSAGECHAT || p.GetOpcode() == SMSG_GM_MESSAGECHAT))
|
||||||
{
|
{
|
||||||
@@ -998,29 +1002,32 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
|
|||||||
if (lang == LANG_ADDON)
|
if (lang == LANG_ADDON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (message.starts_with(sPlayerbotAIConfig->toxicLinksPrefix)
|
// Disable since ExtractAllItemIds bad performance
|
||||||
&& (GetChatHelper()->ExtractAllItemIds(message).size() > 0 || GetChatHelper()->ExtractAllQuestIds(message).size() > 0)
|
// if (message.starts_with(sPlayerbotAIConfig->toxicLinksPrefix) &&
|
||||||
&& sPlayerbotAIConfig->toxicLinksRepliesChance)
|
// (GetChatHelper()->ExtractAllItemIds(message).size() > 0 ||
|
||||||
{
|
// GetChatHelper()->ExtractAllQuestIds(message).size() > 0) &&
|
||||||
if (urand(0, 50) > 0 || urand(1, 100) > sPlayerbotAIConfig->toxicLinksRepliesChance)
|
// sPlayerbotAIConfig->toxicLinksRepliesChance)
|
||||||
{
|
// {
|
||||||
return;
|
// if (urand(0, 50) > 0 || urand(1, 100) > sPlayerbotAIConfig->toxicLinksRepliesChance)
|
||||||
}
|
// {
|
||||||
}
|
// return;
|
||||||
else if ((GetChatHelper()->ExtractAllItemIds(message).count(19019) && sPlayerbotAIConfig->thunderfuryRepliesChance))
|
// }
|
||||||
{
|
// }
|
||||||
if (urand(0, 60) > 0 || urand(1, 100) > sPlayerbotAIConfig->thunderfuryRepliesChance)
|
// else if ((GetChatHelper()->ExtractAllItemIds(message).count(19019) &&
|
||||||
{
|
// sPlayerbotAIConfig->thunderfuryRepliesChance))
|
||||||
return;
|
// {
|
||||||
}
|
// if (urand(0, 60) > 0 || urand(1, 100) > sPlayerbotAIConfig->thunderfuryRepliesChance)
|
||||||
}
|
// {
|
||||||
else
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
{
|
{
|
||||||
if (isFromFreeBot && urand(0, 20))
|
if (isFromFreeBot && urand(0, 20))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if (msgtype == CHAT_MSG_GUILD && (!sPlayerbotAIConfig->guildRepliesRate || urand(1, 100) >= sPlayerbotAIConfig->guildRepliesRate))
|
// if (msgtype == CHAT_MSG_GUILD && (!sPlayerbotAIConfig->guildRepliesRate || urand(1, 100) >=
|
||||||
//return;
|
// sPlayerbotAIConfig->guildRepliesRate)) return;
|
||||||
|
|
||||||
if (!isFromFreeBot)
|
if (!isFromFreeBot)
|
||||||
{
|
{
|
||||||
@@ -1034,7 +1041,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<time_t>("last said", "chat")->Set(time(0) + urand(5, 25));
|
GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(0) + urand(5, 25));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2182,19 +2191,21 @@ WorldObject* PlayerbotAI::GetWorldObject(ObjectGuid guid)
|
|||||||
|
|
||||||
const AreaTableEntry* PlayerbotAI::GetCurrentArea()
|
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()
|
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)
|
std::string PlayerbotAI::GetLocalizedAreaName(const AreaTableEntry* entry)
|
||||||
{
|
{
|
||||||
if (entry)
|
if (entry)
|
||||||
return entry->area_name[sWorld->GetDefaultDbcLocale()];
|
return entry->area_name[sWorld->GetDefaultDbcLocale()];
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2254,7 +2265,7 @@ bool PlayerbotAI::SayToWorld(const std::string& msg)
|
|||||||
if (!cMgr)
|
if (!cMgr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//no zone
|
// no zone
|
||||||
if (Channel* worldChannel = cMgr->GetChannel("World", bot))
|
if (Channel* worldChannel = cMgr->GetChannel("World", bot))
|
||||||
{
|
{
|
||||||
worldChannel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
worldChannel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||||
@@ -2277,7 +2288,7 @@ bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chan
|
|||||||
const auto current_str_zone = GetLocalizedAreaName(current_zone);
|
const auto current_str_zone = GetLocalizedAreaName(current_zone);
|
||||||
for (auto const& [key, channel] : cMgr->GetChannels())
|
for (auto const& [key, channel] : cMgr->GetChannels())
|
||||||
{
|
{
|
||||||
//check for current zone
|
// check for current zone
|
||||||
if (channel && channel->GetChannelId() == chanId)
|
if (channel && channel->GetChannelId() == chanId)
|
||||||
{
|
{
|
||||||
const auto does_contains = channel->GetName().find(current_str_zone) != std::string::npos;
|
const auto does_contains = channel->GetName().find(current_str_zone) != std::string::npos;
|
||||||
@@ -2304,7 +2315,8 @@ bool PlayerbotAI::SayToParty(const std::string& msg)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldPacket data;
|
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())
|
for (auto reciever : GetPlayersInGroup())
|
||||||
{
|
{
|
||||||
@@ -2320,7 +2332,8 @@ bool PlayerbotAI::SayToRaid(const std::string& msg)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
WorldPacket data;
|
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())
|
for (auto reciever : GetPlayersInGroup())
|
||||||
{
|
{
|
||||||
@@ -4767,27 +4780,18 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// static const will only get created once whatever the call amout
|
// static const will only get created once whatever the call amout
|
||||||
static const std::vector<uint32_t> uPriorizedWizardOilIds =
|
static const std::vector<uint32_t> uPriorizedWizardOilIds = {
|
||||||
{
|
MINOR_WIZARD_OIL, MINOR_MANA_OIL, LESSER_WIZARD_OIL, LESSER_MANA_OIL, BRILLIANT_WIZARD_OIL,
|
||||||
MINOR_WIZARD_OIL, MINOR_MANA_OIL,
|
BRILLIANT_MANA_OIL, WIZARD_OIL, SUPERIOR_MANA_OIL, SUPERIOR_WIZARD_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 will only get created once whatever the call amout
|
||||||
static const std::vector<uint32_t> uPriorizedManaOilIds =
|
static const std::vector<uint32_t> uPriorizedManaOilIds = {
|
||||||
{
|
MINOR_MANA_OIL, MINOR_WIZARD_OIL, LESSER_MANA_OIL, LESSER_WIZARD_OIL, BRILLIANT_MANA_OIL,
|
||||||
MINOR_MANA_OIL, MINOR_WIZARD_OIL,
|
BRILLIANT_WIZARD_OIL, SUPERIOR_MANA_OIL, WIZARD_OIL, SUPERIOR_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;
|
Item* oil = nullptr;
|
||||||
if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_SWORD ||
|
if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_SWORD ||
|
||||||
item_template->SubClass == ITEM_SUBCLASS_WEAPON_STAFF ||
|
item_template->SubClass == ITEM_SUBCLASS_WEAPON_STAFF || item_template->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
|
||||||
item_template->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
|
|
||||||
{
|
{
|
||||||
for (const auto& id : uPriorizedWizardOilIds)
|
for (const auto& id : uPriorizedWizardOilIds)
|
||||||
{
|
{
|
||||||
@@ -4797,7 +4801,7 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item_template->SubClass == ITEM_SUBCLASS_WEAPON_MACE ||
|
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)
|
for (const auto& id : uPriorizedManaOilIds)
|
||||||
{
|
{
|
||||||
@@ -4940,7 +4944,6 @@ uint32 PlayerbotAI::GetInventoryItemsCountWithId(uint32 itemId)
|
|||||||
|
|
||||||
bool PlayerbotAI::HasItemInInventory(uint32 itemId)
|
bool PlayerbotAI::HasItemInInventory(uint32 itemId)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||||
{
|
{
|
||||||
if (Bag* pBag = (Bag*)bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
if (Bag* pBag = (Bag*)bot->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||||
@@ -5167,10 +5170,7 @@ bool PlayerbotAI::IsInRealGuild()
|
|||||||
return !(sPlayerbotAIConfig->IsInRandomAccountList(leaderAccount));
|
return !(sPlayerbotAIConfig->IsInRandomAccountList(leaderAccount));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerbotAI::QueueChatResponse(const ChatQueuedReply chatReply)
|
void PlayerbotAI::QueueChatResponse(const ChatQueuedReply chatReply) { chatReplies.push_back(std::move(chatReply)); }
|
||||||
{
|
|
||||||
chatReplies.push_back(std::move(chatReply));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlayerbotAI::EqualLowercaseName(std::string s1, std::string s2)
|
bool PlayerbotAI::EqualLowercaseName(std::string s1, std::string s2)
|
||||||
{
|
{
|
||||||
@@ -5507,11 +5507,13 @@ uint8 PlayerbotAI::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool sw
|
|||||||
|
|
||||||
bool PlayerbotAI::IsSafe(Player* player)
|
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)
|
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)
|
ChatChannelSource PlayerbotAI::GetChatChannelSource(Player* bot, uint32 type, std::string channelName)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2197,6 +2197,46 @@ void RandomItemMgr::BuildEquipCache()
|
|||||||
void RandomItemMgr::BuildEquipCacheNew()
|
void RandomItemMgr::BuildEquipCacheNew()
|
||||||
{
|
{
|
||||||
LOG_INFO("playerbots", "Loading equipments cache...");
|
LOG_INFO("playerbots", "Loading equipments cache...");
|
||||||
|
|
||||||
|
std::unordered_set<uint32> 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();
|
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
|
||||||
for (auto const& itr : *itemTemplates)
|
for (auto const& itr : *itemTemplates)
|
||||||
{
|
{
|
||||||
@@ -2204,6 +2244,10 @@ void RandomItemMgr::BuildEquipCacheNew()
|
|||||||
if (!proto)
|
if (!proto)
|
||||||
continue;
|
continue;
|
||||||
uint32 itemId = proto->ItemId;
|
uint32 itemId = proto->ItemId;
|
||||||
|
|
||||||
|
if (questItemIds.find(itemId) != questItemIds.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (IsTestItem(itemId))
|
if (IsTestItem(itemId))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1254,6 +1254,7 @@ bool PlayerbotFactory::CanEquipWeapon(ItemTemplate const* proto)
|
|||||||
case CLASS_ROGUE:
|
case CLASS_ROGUE:
|
||||||
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD &&
|
if (proto->SubClass != ITEM_SUBCLASS_WEAPON_DAGGER && proto->SubClass != ITEM_SUBCLASS_WEAPON_SWORD &&
|
||||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE &&
|
proto->SubClass != ITEM_SUBCLASS_WEAPON_FIST && proto->SubClass != ITEM_SUBCLASS_WEAPON_MACE &&
|
||||||
|
proto->SubClass != ITEM_SUBCLASS_WEAPON_AXE &&
|
||||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN && proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW &&
|
proto->SubClass != ITEM_SUBCLASS_WEAPON_GUN && proto->SubClass != ITEM_SUBCLASS_WEAPON_CROSSBOW &&
|
||||||
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN)
|
proto->SubClass != ITEM_SUBCLASS_WEAPON_BOW && proto->SubClass != ITEM_SUBCLASS_WEAPON_THROWN)
|
||||||
return false;
|
return false;
|
||||||
@@ -1263,14 +1264,11 @@ bool PlayerbotFactory::CanEquipWeapon(ItemTemplate const* proto)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality)
|
bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto)
|
||||||
{
|
{
|
||||||
if (proto->Duration != 0)
|
if (proto->Duration != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (proto->Quality != desiredQuality)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (proto->Bonding == BIND_QUEST_ITEM /*|| proto->Bonding == BIND_WHEN_USE*/)
|
if (proto->Bonding == BIND_QUEST_ITEM /*|| proto->Bonding == BIND_WHEN_USE*/)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1278,29 +1276,15 @@ bool PlayerbotFactory::CanEquipItem(ItemTemplate const* proto, uint32 desiredQua
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
uint32 requiredLevel = proto->RequiredLevel;
|
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;
|
return false;
|
||||||
|
|
||||||
uint32 level = bot->GetLevel();
|
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 false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1492,7 +1476,6 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
}
|
}
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
ItemTemplateContainer const* itemTemplate = sObjectMgr->GetItemTemplateStore();
|
|
||||||
for (uint32 requiredLevel = bot->GetLevel(); requiredLevel > std::max((int32)bot->GetLevel() - delta, 0);
|
for (uint32 requiredLevel = bot->GetLevel(); requiredLevel > std::max((int32)bot->GetLevel() - delta, 0);
|
||||||
requiredLevel--)
|
requiredLevel--)
|
||||||
{
|
{
|
||||||
@@ -1527,9 +1510,12 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR)
|
if (proto->Class != ITEM_CLASS_WEAPON && proto->Class != ITEM_CLASS_ARMOR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!CanEquipItem(proto, desiredQuality))
|
if (proto->Quality != desiredQuality)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!CanEquipItem(proto))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (proto->Class == ITEM_CLASS_ARMOR &&
|
if (proto->Class == ITEM_CLASS_ARMOR &&
|
||||||
(slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS ||
|
(slot == EQUIPMENT_SLOT_HEAD || slot == EQUIPMENT_SLOT_SHOULDERS ||
|
||||||
slot == EQUIPMENT_SLOT_CHEST || slot == EQUIPMENT_SLOT_WAIST ||
|
slot == EQUIPMENT_SLOT_CHEST || slot == EQUIPMENT_SLOT_WAIST ||
|
||||||
@@ -1594,6 +1580,11 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
uint32 newItemId = ids[index];
|
uint32 newItemId = ids[index];
|
||||||
|
|
||||||
uint16 dest;
|
uint16 dest;
|
||||||
|
|
||||||
|
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newItemId);
|
||||||
|
|
||||||
|
if (!CanEquipItem(proto))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (oldItem && oldItem->GetTemplate()->ItemId == newItemId)
|
if (oldItem && oldItem->GetTemplate()->ItemId == newItemId)
|
||||||
continue;
|
continue;
|
||||||
@@ -1608,36 +1599,12 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
|||||||
bestItemForSlot = newItemId;
|
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)
|
if (bestItemForSlot == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (oldItem)
|
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);
|
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||||
}
|
}
|
||||||
uint16 dest;
|
uint16 dest;
|
||||||
@@ -3333,8 +3300,11 @@ void PlayerbotFactory::InitInventoryEquip()
|
|||||||
|
|
||||||
if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(proto))
|
if (proto->Class == ITEM_CLASS_WEAPON && !CanEquipWeapon(proto))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!CanEquipItem(proto, desiredQuality))
|
if (proto->Quality != desiredQuality)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!CanEquipItem(proto))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ids.push_back(itr.first);
|
ids.push_back(itr.first);
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ private:
|
|||||||
void Prepare();
|
void Prepare();
|
||||||
// void InitSecondEquipmentSet();
|
// void InitSecondEquipmentSet();
|
||||||
// void InitEquipmentNew(bool incremental);
|
// void InitEquipmentNew(bool incremental);
|
||||||
bool CanEquipItem(ItemTemplate const* proto, uint32 desiredQuality);
|
bool CanEquipItem(ItemTemplate const* proto);
|
||||||
bool CanEquipUnseenItem(uint8 slot, uint16& dest, uint32 item);
|
bool CanEquipUnseenItem(uint8 slot, uint16& dest, uint32 item);
|
||||||
void InitTradeSkills();
|
void InitTradeSkills();
|
||||||
void UpdateTradeSkills();
|
void UpdateTradeSkills();
|
||||||
|
|||||||
@@ -89,13 +89,21 @@ void StatsCollector::CollectSpellStats(uint32 spellId, float multiplier, int32 s
|
|||||||
bool canNextTrigger = true;
|
bool canNextTrigger = true;
|
||||||
|
|
||||||
uint32 procFlags;
|
uint32 procFlags;
|
||||||
|
uint32 procChance;
|
||||||
if (eventEntry && eventEntry->procFlags)
|
if (eventEntry && eventEntry->procFlags)
|
||||||
procFlags = eventEntry->procFlags;
|
procFlags = eventEntry->procFlags;
|
||||||
else
|
else
|
||||||
procFlags = spellInfo->ProcFlags;
|
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;
|
canNextTrigger = false;
|
||||||
|
|
||||||
if (spellInfo->StackAmount)
|
if (spellInfo->StackAmount)
|
||||||
{
|
{
|
||||||
// Heuristic multiplier for spell with stackAmount since high stackAmount may not be available
|
// Heuristic multiplier for spell with stackAmount since high stackAmount may not be available
|
||||||
@@ -504,7 +512,8 @@ void StatsCollector::HandleApplyAura(const SpellEffectInfo& effectInfo, float mu
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELL_AURA_MOD_ATTACK_POWER:
|
case SPELL_AURA_MOD_ATTACK_POWER:
|
||||||
stats[STATS_TYPE_ATTACK_POWER] += val * multiplier;
|
if (type_ == CollectorType::MELEE)
|
||||||
|
stats[STATS_TYPE_ATTACK_POWER] += val * multiplier;
|
||||||
break;
|
break;
|
||||||
case SPELL_AURA_MOD_RANGED_ATTACK_POWER:
|
case SPELL_AURA_MOD_RANGED_ATTACK_POWER:
|
||||||
if (type_ == CollectorType::RANGED)
|
if (type_ == CollectorType::RANGED)
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ void StatsWeightCalculator::CalculateItemTypePenalty(ItemTemplate const* proto)
|
|||||||
weight_ *= 1.1;
|
weight_ *= 1.1;
|
||||||
}
|
}
|
||||||
if (cls == CLASS_WARRIOR && player_->HasAura(12785)
|
if (cls == CLASS_WARRIOR && player_->HasAura(12785)
|
||||||
&& (proto->SubClass == ITEM_SUBCLASS_WEAPON_THROWN || proto->SubClass == ITEM_SUBCLASS_WEAPON_AXE2))
|
&& (proto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || proto->SubClass == ITEM_SUBCLASS_WEAPON_AXE2))
|
||||||
{
|
{
|
||||||
weight_ *= 1.1;
|
weight_ *= 1.1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
((1 << ITEM_SUBCLASS_WEAPON_AXE) | (1 << ITEM_SUBCLASS_WEAPON_MACE) | (1 << ITEM_SUBCLASS_WEAPON_SWORD) | \
|
((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))
|
(1 << ITEM_SUBCLASS_WEAPON_DAGGER) | (1 << ITEM_SUBCLASS_WEAPON_FIST))
|
||||||
|
|
||||||
enum StatsOverflowThreshold {
|
enum StatsOverflowThreshold
|
||||||
|
{
|
||||||
SPELL_HIT_OVERFLOW = 17,
|
SPELL_HIT_OVERFLOW = 17,
|
||||||
MELEE_HIT_OVERFLOW = 8,
|
MELEE_HIT_OVERFLOW = 8,
|
||||||
RANGED_HIT_OVERFLOW = 8,
|
RANGED_HIT_OVERFLOW = 8,
|
||||||
@@ -30,6 +31,10 @@ public:
|
|||||||
float CalculateItem(uint32 itemId);
|
float CalculateItem(uint32 itemId);
|
||||||
float CalculateEnchant(uint32 enchantId);
|
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:
|
private:
|
||||||
void GenerateWeights(Player* player);
|
void GenerateWeights(Player* player);
|
||||||
void GenerateBasicWeights(Player* player);
|
void GenerateBasicWeights(Player* player);
|
||||||
@@ -53,7 +58,7 @@ private:
|
|||||||
bool enable_overflow_penalty_;
|
bool enable_overflow_penalty_;
|
||||||
bool enable_item_set_bonus_;
|
bool enable_item_set_bonus_;
|
||||||
bool enable_quality_blend_;
|
bool enable_quality_blend_;
|
||||||
|
|
||||||
float weight_;
|
float weight_;
|
||||||
float stats_weights_[STATS_TYPE_MAX];
|
float stats_weights_[STATS_TYPE_MAX];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ bool AcceptQuestAction::Execute(Event event)
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "AcceptQuestAction {" << qInfo->GetTitle() << "} - {" << std::to_string(qInfo->GetQuestId()) << "}";
|
ss << "AcceptQuestAction {" << qInfo->GetTitle() << "} - {" << std::to_string(qInfo->GetQuestId()) << "}";
|
||||||
LOG_INFO("playerbots", "{}", ss.str().c_str());
|
LOG_INFO("playerbots", "{}", ss.str().c_str());
|
||||||
botAI->TellMaster(ss.str());
|
// botAI->TellMaster(ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasAccept;
|
return hasAccept;
|
||||||
|
|||||||
@@ -195,9 +195,9 @@ bool ChooseRpgTargetAction::Execute(Event event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (possiblePlayers.size() > 200 || HasSameTarget(guidP, urand(5, 15), possiblePlayers))
|
// if (possiblePlayers.size() > 200 || HasSameTarget(guidP, urand(5, 15), possiblePlayers))
|
||||||
continue;
|
// continue;
|
||||||
|
|
||||||
float relevance = getMaxRelevance(guidP);
|
float relevance = getMaxRelevance(guidP);
|
||||||
|
|
||||||
|
|||||||
@@ -205,20 +205,21 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32& type, uint32& guid1, uint
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//toxic links
|
// Disable since ExtractAllItemIds bad performance
|
||||||
if (msg.starts_with(sPlayerbotAIConfig->toxicLinksPrefix)
|
// //toxic links
|
||||||
&& (GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg).size() > 0 || GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg).size() > 0))
|
// if (msg.starts_with(sPlayerbotAIConfig->toxicLinksPrefix)
|
||||||
{
|
// && (GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg).size() > 0 || GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg).size() > 0))
|
||||||
HandleToxicLinksReply(bot, chatChannelSource, msg, name);
|
// {
|
||||||
return;
|
// HandleToxicLinksReply(bot, chatChannelSource, msg, name);
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
//thunderfury
|
// //thunderfury
|
||||||
if (GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg).count(19019))
|
// if (GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg).count(19019))
|
||||||
{
|
// {
|
||||||
HandleThunderfuryReply(bot, chatChannelSource, msg, name);
|
// HandleThunderfuryReply(bot, chatChannelSource, msg, name);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
auto messageRepy = GenerateReplyMessage(bot, msg, guid1, name);
|
auto messageRepy = GenerateReplyMessage(bot, msg, guid1, name);
|
||||||
SendGeneralResponse(bot, chatChannelSource, messageRepy, name);
|
SendGeneralResponse(bot, chatChannelSource, messageRepy, name);
|
||||||
@@ -316,6 +317,8 @@ bool ChatReplyAction::HandleToxicLinksReply(Player* bot, ChatChannelSource chatC
|
|||||||
}
|
}
|
||||||
bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||||
{
|
{
|
||||||
|
// Disable since ExtractAllItemIds bad performance
|
||||||
|
return false;
|
||||||
auto messageItemIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg);
|
auto messageItemIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg);
|
||||||
|
|
||||||
if (messageItemIds.empty())
|
if (messageItemIds.empty())
|
||||||
@@ -409,6 +412,8 @@ bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatCha
|
|||||||
}
|
}
|
||||||
bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||||
{
|
{
|
||||||
|
// Disable since ExtractAllQuestIds bad performance
|
||||||
|
return false;
|
||||||
auto messageQuestIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg);
|
auto messageQuestIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg);
|
||||||
|
|
||||||
if (messageQuestIds.empty())
|
if (messageQuestIds.empty())
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("seal of vengeance",
|
return new ActionNode("seal of vengeance",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("seal of righteousness"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("seal of command"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ private:
|
|||||||
{
|
{
|
||||||
return new ActionNode("seal of command",
|
return new ActionNode("seal of command",
|
||||||
/*P*/ nullptr,
|
/*P*/ nullptr,
|
||||||
/*A*/ NextAction::array(0, new NextAction("seal of corruption"), nullptr),
|
/*A*/ NextAction::array(0, new NextAction("seal of righteousness"), nullptr),
|
||||||
/*C*/ nullptr);
|
/*C*/ nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ void DpsPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
GenericPaladinStrategy::InitTriggers(triggers);
|
GenericPaladinStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("seal", NextAction::array(0, new NextAction("seal of command", ACTION_HIGH), NULL)));
|
new TriggerNode("seal", NextAction::array(0, new NextAction("seal of corruption", ACTION_HIGH), NULL)));
|
||||||
// triggers.push_back(new TriggerNode("seal", NextAction::array(0, new NextAction("seal of command", 90.0f),
|
// triggers.push_back(new TriggerNode("seal", NextAction::array(0, new NextAction("seal of command", 90.0f),
|
||||||
// nullptr)));
|
// nullptr)));
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
|
|||||||
@@ -99,10 +99,11 @@ void DpsRogueStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
"slice and dice", NextAction::array(0, new NextAction("slice and dice", ACTION_HIGH + 2), nullptr)));
|
"slice and dice", NextAction::array(0, new NextAction("slice and dice", ACTION_HIGH + 2), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("combo points available",
|
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",
|
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(
|
triggers.push_back(
|
||||||
new TriggerNode("medium threat", NextAction::array(0, new NextAction("vanish", ACTION_HIGH), nullptr)));
|
new TriggerNode("medium threat", NextAction::array(0, new NextAction("vanish", ACTION_HIGH), nullptr)));
|
||||||
@@ -111,8 +112,8 @@ void DpsRogueStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
new TriggerNode("low health", NextAction::array(0, new NextAction("evasion", ACTION_HIGH + 9),
|
new TriggerNode("low health", NextAction::array(0, new NextAction("evasion", ACTION_HIGH + 9),
|
||||||
new NextAction("feint", ACTION_HIGH + 8), nullptr)));
|
new NextAction("feint", ACTION_HIGH + 8), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode(
|
||||||
new TriggerNode("critical health", NextAction::array(0, new NextAction("cloak of shadows", ACTION_HIGH + 7), nullptr)));
|
"critical health", NextAction::array(0, new NextAction("cloak of shadows", ACTION_HIGH + 7), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("kick", NextAction::array(0, new NextAction("kick", ACTION_INTERRUPT + 2), nullptr)));
|
new TriggerNode("kick", NextAction::array(0, new NextAction("kick", ACTION_INTERRUPT + 2), nullptr)));
|
||||||
@@ -128,8 +129,8 @@ void DpsRogueStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("light aoe", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), nullptr)));
|
new TriggerNode("light aoe", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 3), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(new TriggerNode("blade flurry",
|
||||||
new TriggerNode("blade flurry", NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 2), nullptr)));
|
NextAction::array(0, new NextAction("blade flurry", ACTION_HIGH + 2), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"enemy out of melee",
|
"enemy out of melee",
|
||||||
|
|||||||
@@ -47,10 +47,13 @@ NextAction** CasterShamanStrategy::getDefaultActions()
|
|||||||
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
GenericShamanStrategy::InitTriggers(triggers);
|
GenericShamanStrategy::InitTriggers(triggers);
|
||||||
|
|
||||||
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
|
// triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell",
|
||||||
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
|
// ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new
|
||||||
// NextAction("flametongue weapon", 23.0f), nullptr)));
|
// NextAction("flametongue weapon", 23.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode(
|
||||||
|
"enough mana", NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.1f), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("main hand weapon no imbue",
|
triggers.push_back(new TriggerNode("main hand weapon no imbue",
|
||||||
NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
|
NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr)));
|
||||||
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f),
|
// triggers.push_back(new TriggerNode("searing totem", NextAction::array(0, new NextAction("searing totem", 19.0f),
|
||||||
@@ -64,10 +67,12 @@ void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("no fire totem", NextAction::array(0, new NextAction("totem of wrath", 15.0f), NULL)));
|
new TriggerNode("no fire totem", NextAction::array(0, new NextAction("totem of wrath", 15.0f), NULL)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("enemy is close",
|
|
||||||
NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium mana", NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
new TriggerNode("medium mana", NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
||||||
|
|
||||||
|
|
||||||
|
triggers.push_back(new TriggerNode("enemy is close",
|
||||||
|
NextAction::array(0, new NextAction("thunderstorm", ACTION_HIGH + 1), nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("enemy too close for spell",
|
triggers.push_back(new TriggerNode("enemy too close for spell",
|
||||||
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr)));
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ void MeleeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
|
|
||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("medium mana", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
new TriggerNode("medium mana", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
||||||
|
|
||||||
|
triggers.push_back(
|
||||||
|
new TriggerNode("low health", NextAction::array(0, new NextAction("shamanistic rage", 23.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeleeAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void MeleeAoeShamanStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ ItemUsage ItemUsageValue::QueryItemUsageForEquip(ItemTemplate const* itemProto)
|
|||||||
bool shouldEquip = false;
|
bool shouldEquip = false;
|
||||||
// uint32 statWeight = sRandomItemMgr->GetLiveStatWeight(bot, itemProto->ItemId);
|
// uint32 statWeight = sRandomItemMgr->GetLiveStatWeight(bot, itemProto->ItemId);
|
||||||
StatsWeightCalculator calculator(bot);
|
StatsWeightCalculator calculator(bot);
|
||||||
|
calculator.SetItemSetBonus(false);
|
||||||
|
calculator.SetOverflowPenalty(false);
|
||||||
|
|
||||||
float itemScore = calculator.CalculateItem(itemProto->ItemId);
|
float itemScore = calculator.CalculateItem(itemProto->ItemId);
|
||||||
if (itemScore)
|
if (itemScore)
|
||||||
shouldEquip = true;
|
shouldEquip = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user