date: 2024-11-3 bronjahm strategy

This commit is contained in:
姜耀
2024-11-03 21:50:27 +08:00
10 changed files with 56 additions and 14 deletions

View File

@@ -1460,7 +1460,7 @@ AiPlayerbot.BotActiveAlone = 100
# Specify smart scaling is enabled or not. # Specify smart scaling is enabled or not.
# The default is 1. When enabled (smart) scales the 'BotActiveAlone' value. # The default is 1. When enabled (smart) scales the 'BotActiveAlone' value.
# Only when botLevel is between WhenMinLevel and WhenMaxLevel. # Only when botLevel is between WhenMinLevel and WhenMaxLevel.
AiPlayerbot.botActiveAloneSmartScale = 1 AiPlayerbot.botActiveAloneSmartScale = 0
AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1
AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80 AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80

View File

@@ -8,6 +8,7 @@
#include <cmath> #include <cmath>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <mutex>
#include "AiFactory.h" #include "AiFactory.h"
#include "BudgetValues.h" #include "BudgetValues.h"
@@ -2452,8 +2453,12 @@ bool PlayerbotAI::SayToWorld(const std::string& msg)
bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chanId) bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chanId)
{ {
// Checks whether the message or ChannelMgr is valid
if (msg.empty())
return false;
ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId()); ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId());
if (!cMgr || msg.empty()) if (!cMgr)
return false; return false;
AreaTableEntry const* current_zone = GetCurrentZone(); AreaTableEntry const* current_zone = GetCurrentZone();
@@ -2461,11 +2466,24 @@ bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chan
return false; return false;
const auto current_str_zone = GetLocalizedAreaName(current_zone); const auto current_str_zone = GetLocalizedAreaName(current_zone);
std::mutex socialMutex;
std::lock_guard<std::mutex> lock(socialMutex); // Blocking for thread safety when accessing SocialMgr
for (auto const& [key, channel] : cMgr->GetChannels()) for (auto const& [key, channel] : cMgr->GetChannels())
{ {
// check for current zone // Checks if the channel pointer is valid
if (channel && channel->GetChannelId() == chanId) if (!channel)
continue;
// Checks if the channel matches the specified ChatChannelId
if (channel->GetChannelId() == chanId)
{ {
// If the channel name is empty, skip it to avoid access problems
if (channel->GetName().empty())
continue;
// Checks if the channel name contains the current zone
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;
if (chanId != ChatChannelId::LOOKING_FOR_GROUP && chanId != ChatChannelId::WORLD_DEFENSE && !does_contains) if (chanId != ChatChannelId::LOOKING_FOR_GROUP && chanId != ChatChannelId::WORLD_DEFENSE && !does_contains)
{ {
@@ -2473,11 +2491,15 @@ bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chan
} }
else if (chanId == ChatChannelId::LOOKING_FOR_GROUP || chanId == ChatChannelId::WORLD_DEFENSE) else if (chanId == ChatChannelId::LOOKING_FOR_GROUP || chanId == ChatChannelId::WORLD_DEFENSE)
{ {
// check if capitals then return false if not // Here you can add the capital check if necessary
} }
channel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL); // Final check to ensure the channel is correct before trying to say something
return true; if (channel)
{
channel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
return true;
}
} }
} }

View File

@@ -465,7 +465,7 @@ bool PlayerbotAIConfig::Initialize()
playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1); playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1);
disableDeathKnightLogin = sConfigMgr->GetOption<bool>("AiPlayerbot.DisableDeathKnightLogin", 0); disableDeathKnightLogin = sConfigMgr->GetOption<bool>("AiPlayerbot.DisableDeathKnightLogin", 0);
botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 100); botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 100);
botActiveAloneSmartScale = sConfigMgr->GetOption<bool>("AiPlayerbot.botActiveAloneSmartScale", 1); botActiveAloneSmartScale = sConfigMgr->GetOption<bool>("AiPlayerbot.botActiveAloneSmartScale", 0);
botActiveAloneSmartScaleWhenMinLevel = botActiveAloneSmartScaleWhenMinLevel =
sConfigMgr->GetOption<uint32>("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); sConfigMgr->GetOption<uint32>("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1);
botActiveAloneSmartScaleWhenMaxLevel = botActiveAloneSmartScaleWhenMaxLevel =

View File

@@ -18,6 +18,7 @@
#include "TransportMgr.h" #include "TransportMgr.h"
#include "VMapFactory.h" #include "VMapFactory.h"
#include "VMapMgr2.h" #include "VMapMgr2.h"
#include "Corpse.h"
WorldPosition::WorldPosition(std::string const str) WorldPosition::WorldPosition(std::string const str)
{ {

View File

@@ -41,6 +41,7 @@
#include "Unit.h" #include "Unit.h"
#include "Vehicle.h" #include "Vehicle.h"
#include "WaypointMovementGenerator.h" #include "WaypointMovementGenerator.h"
#include "Corpse.h"
MovementAction::MovementAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name) MovementAction::MovementAction(PlayerbotAI* botAI, std::string const name) : Action(botAI, name)
{ {

View File

@@ -15,9 +15,13 @@
bool QuestAction::Execute(Event event) bool QuestAction::Execute(Event event)
{ {
ObjectGuid guid = event.getObject(); ObjectGuid guid = event.getObject();
Player* master = GetMaster(); Player* master = GetMaster();
// Checks if the bot and botAI are valid
if (!bot || !botAI)
return false;
// Sets guid based on bot or master target
if (!guid) if (!guid)
{ {
if (!master) if (!master)
@@ -36,19 +40,27 @@ bool QuestAction::Execute(Event event)
} }
bool result = false; bool result = false;
// Check the nearest NPCs
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs"); GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
for (const auto npc : npcs) for (const auto& npc : npcs)
{ {
Unit* unit = botAI->GetUnit(npc); Unit* unit = botAI->GetUnit(npc);
if (unit && bot->GetDistance(unit) <= INTERACTION_DISTANCE) if (unit && bot->GetDistance(unit) <= INTERACTION_DISTANCE)
{
result |= ProcessQuests(unit); result |= ProcessQuests(unit);
}
} }
// Checks the nearest game objects
std::list<ObjectGuid> gos = AI_VALUE(std::list<ObjectGuid>, "nearest game objects"); std::list<ObjectGuid> gos = AI_VALUE(std::list<ObjectGuid>, "nearest game objects");
for (const auto go : gos) for (const auto& go : gos)
{ {
GameObject* gameobj = botAI->GetGameObject(go); GameObject* gameobj = botAI->GetGameObject(go);
if (gameobj && bot->GetDistance(gameobj) <= INTERACTION_DISTANCE) if (gameobj && bot->GetDistance(gameobj) <= INTERACTION_DISTANCE)
{
result |= ProcessQuests(gameobj); result |= ProcessQuests(gameobj);
}
} }
return result; return result;

View File

@@ -11,6 +11,7 @@
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "Corpse.h"
bool ReleaseSpiritAction::Execute(Event event) bool ReleaseSpiritAction::Execute(Event event)
{ {

View File

@@ -13,6 +13,7 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "RandomPlayerbotMgr.h" #include "RandomPlayerbotMgr.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "Corpse.h"
bool ReviveFromCorpseAction::Execute(Event event) bool ReviveFromCorpseAction::Execute(Event event)
{ {

View File

@@ -8,15 +8,17 @@
float KrikthirMultiplier::GetValue(Action* action) float KrikthirMultiplier::GetValue(Action* action)
{ {
if (!botAI->IsDps(bot)) { return 1.0f; }
// Target is not findable from threat table using AI_VALUE2(), // Target is not findable from threat table using AI_VALUE2(),
// therefore need to search manually for the unit name // therefore need to search manually for the unit name
Unit* boss = nullptr; Unit* boss = nullptr;
Unit* watcher = nullptr; Unit* watcher = nullptr;
GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
for (auto i = targets.begin(); i != targets.end(); ++i) GuidVector targets = AI_VALUE(GuidVector, "possible targets no los");
for (auto& target : targets)
{ {
Unit* unit = botAI->GetUnit(*i); Unit* unit = botAI->GetUnit(target);
if (!unit) { continue; } if (!unit) { continue; }
switch (unit->GetEntry()) switch (unit->GetEntry())

View File

@@ -15,6 +15,8 @@ float MountingDrakeMultiplier::GetValue(Action* action)
// It seems like this is due to moving/other actions being processed during the 0.5 secs. // It seems like this is due to moving/other actions being processed during the 0.5 secs.
// If we suppress everything, they seem to mount properly. A bit of a ham-fisted solution but it works // If we suppress everything, they seem to mount properly. A bit of a ham-fisted solution but it works
Player* master = botAI->GetMaster(); Player* master = botAI->GetMaster();
if (!master) { return 1.0f; }
if (bot->GetMapId() != OCULUS_MAP_ID || !master->GetVehicleBase() || bot->GetVehicleBase()) { return 1.0f; } if (bot->GetMapId() != OCULUS_MAP_ID || !master->GetVehicleBase() || bot->GetVehicleBase()) { return 1.0f; }
if (!dynamic_cast<MountDrakeAction*>(action)) if (!dynamic_cast<MountDrakeAction*>(action))