Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/modules/Bots/playerbot/PlayerbotAIConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ PlayerbotAIConfig::PlayerbotAIConfig()
maxRandomBotsPriceChangeInterval(0),
randomBotJoinLfg(false),
randomBotLoginAtStartup(false),
randomBotKeepGroups(false),
randomBotTeleLevel(0),
logInGroupOnly(false),
logValuesPerTick(false),
Expand Down Expand Up @@ -188,6 +189,7 @@ bool PlayerbotAIConfig::Initialize()
randomBotMinLevel = config.GetIntDefault("AiPlayerbot.RandomBotMinLevel", 1);
randomBotMaxLevel = config.GetIntDefault("AiPlayerbot.RandomBotMaxLevel", 255);
randomBotLoginAtStartup = config.GetBoolDefault("AiPlayerbot.RandomBotLoginAtStartup", true);
randomBotKeepGroups = config.GetBoolDefault("AiPlayerbot.RandomBotKeepGroups", false);
randomBotTeleLevel = config.GetIntDefault("AiPlayerbot.RandomBotTeleLevel", 3);

randomChangeMultiplier = config.GetFloatDefault("AiPlayerbot.RandomChangeMultiplier", 1.0);
Expand Down
1 change: 1 addition & 0 deletions src/modules/Bots/playerbot/PlayerbotAIConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class PlayerbotAIConfig
uint32 minRandomBotsPriceChangeInterval, maxRandomBotsPriceChangeInterval;
bool randomBotJoinLfg; ///< Indicates if random bots should join Looking For Group.
bool randomBotLoginAtStartup; ///< Indicates if random bots should login at startup.
bool randomBotKeepGroups; ///< Indicates if random bots should preserve groups across restarts.
uint32 randomBotTeleLevel; ///< The teleport level for random bots.
bool logInGroupOnly, logValuesPerTick;
bool fleeingEnabled; ///< Indicates if fleeing is enabled for bots.
Expand Down
78 changes: 76 additions & 2 deletions src/modules/Bots/playerbot/RandomPlayerbotMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed)
return;
}

if (sPlayerbotAIConfig.randomBotKeepGroups)
{
if (!processTicks)
EnsureGroupedBotsOnline();
LoadGroupedBots();
}

sLog.outBasic("Processing random bots...");

uint32 cachedMin = GetEventValue(0, "config_min");
Expand Down Expand Up @@ -157,8 +164,15 @@ bool RandomPlayerbotMgr::ProcessBot(uint32 bot)
Player* player = GetPlayerBot(bot);
if (!player || !player->GetGroup())
{
sLog.outDetail("Bot %d expired", bot);
SetEventValue(bot, "add", 0, 0);
if (sPlayerbotAIConfig.randomBotKeepGroups && m_groupedBots.count(bot))
{
SetEventValue(bot, "add", 1, sPlayerbotAIConfig.maxRandomBotInWorldTime);
}
else
{
sLog.outDetail("Bot %d expired", bot);
SetEventValue(bot, "add", 0, 0);
}
}
return true;
}
Expand Down Expand Up @@ -690,6 +704,66 @@ bool RandomPlayerbotMgr::IsZoneSafeForBot(Player* bot, uint32 mapId, float x, fl
return false;
}

QueryResult* RandomPlayerbotMgr::QueryGroupedBots()
{
if (sPlayerbotAIConfig.randomBotAccounts.empty())
return nullptr;

ostringstream os;
bool first = true;
for (list<uint32>::iterator i = sPlayerbotAIConfig.randomBotAccounts.begin(); i != sPlayerbotAIConfig.randomBotAccounts.end(); ++i)
{
if (!first) os << ",";
os << *i;
first = false;
}

return CharacterDatabase.PQuery(
"SELECT gm.`memberGuid` FROM `group_member` gm "
"INNER JOIN `characters` c ON gm.`memberGuid` = c.`guid` "
"INNER JOIN `groups` g ON gm.`groupId` = g.`groupId` "
"WHERE c.`account` IN (%s)",
os.str().c_str());
}

void RandomPlayerbotMgr::LoadGroupedBots()
{
m_groupedBots.clear();
QueryResult* result = QueryGroupedBots();
if (!result)
return;

do
{
Field* fields = result->Fetch();
m_groupedBots.insert(fields[0].GetUInt32());
} while (result->NextRow());
delete result;
}

void RandomPlayerbotMgr::EnsureGroupedBotsOnline()
{
QueryResult* result = QueryGroupedBots();
if (!result)
return;

uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 botGuid = fields[0].GetUInt32();
if (!GetEventValue(botGuid, "add"))
{
SetEventValue(botGuid, "add", 1, sPlayerbotAIConfig.maxRandomBotInWorldTime);
count++;
}
} while (result->NextRow());
delete result;

if (count > 0)
sLog.outString("Queued %u grouped bot(s) for login at startup", count);
}

uint32 RandomPlayerbotMgr::GetEventValue(uint32 bot, string event)
{
uint32 value = 0;
Expand Down
5 changes: 5 additions & 0 deletions src/modules/Bots/playerbot/RandomPlayerbotMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Common.h"
#include "PlayerbotAIBase.h"
#include "PlayerbotMgr.h"
#include <set>

class WorldPacket;
class Player;
Expand Down Expand Up @@ -205,6 +206,9 @@ class RandomPlayerbotMgr : public PlayerbotHolder
void ScheduleRandomize(uint32 bot, uint32 time);
void RandomTeleport(Player* bot, uint32 mapId, float teleX, float teleY, float teleZ);
void RandomTeleportForLevel(Player* bot);
void EnsureGroupedBotsOnline();
void LoadGroupedBots();
QueryResult* QueryGroupedBots();

/**
* @brief Teleports the given player bot to a random location.
Expand All @@ -228,6 +232,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder
private:
vector<Player*> players; ///< List of players.
int processTicks; ///< Number of process ticks.
set<uint32> m_groupedBots; ///< Cached set of bot GUIDs currently in a group, refreshed each update cycle.
std::map<uint32, AreaCreatureStats> m_areaCreatureStatsMap;
std::map<std::pair<uint32, uint32>, uint32> m_cellToAreaCache;
};
Expand Down
3 changes: 3 additions & 0 deletions src/modules/Bots/playerbot/aiplayerbot.conf.dist.in
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ AiPlayerbot.RandomBotTeleLevel = 3
# Log on all random bots on start
#AiPlayerbot.RandomBotLoginAtStartup = 1

# Preserve bot group assignments across server restarts
#AiPlayerbot.RandomBotKeepGroups = 0

# How far random bots are teleported after death
#AiPlayerbot.RandomBotTeleportDistance = 1000

Expand Down
Loading