mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
@@ -49,7 +49,7 @@ AiPlayerbot.RandomBotMinLevel = 1
|
|||||||
AiPlayerbot.RandomBotMaxLevel = 80
|
AiPlayerbot.RandomBotMaxLevel = 80
|
||||||
|
|
||||||
# Enable/Disable rotation of bots (randomly select a bot from the bots pool to go online and rotate them periodically)
|
# Enable/Disable rotation of bots (randomly select a bot from the bots pool to go online and rotate them periodically)
|
||||||
# Need reset rndbot after changing the setting
|
# Need to reset rndbot after changing the setting (.playerbot rndbot reset)
|
||||||
# default: 0 (disable, the online bots are fixed)
|
# default: 0 (disable, the online bots are fixed)
|
||||||
AiPlayerbot.EnableRotation = 0
|
AiPlayerbot.EnableRotation = 0
|
||||||
|
|
||||||
@@ -108,6 +108,10 @@ AiPlayerbot.RandombotStartingLevel = 5
|
|||||||
# Server XP Rate * AiPlayerbot.KillXPRate
|
# Server XP Rate * AiPlayerbot.KillXPRate
|
||||||
AiPlayerbot.KillXPRate = 1
|
AiPlayerbot.KillXPRate = 1
|
||||||
|
|
||||||
|
# Disable death knight for bots login
|
||||||
|
# Need to reset rndbot after changing the setting (.playerbot rndbot reset)
|
||||||
|
AiPlayerbot.DisableDeathKnightLogin = 0
|
||||||
|
|
||||||
# Specify percent of active bots
|
# Specify percent of active bots
|
||||||
# The default is 10. With 10% of all bots going active or inactive each minute.
|
# The default is 10. With 10% of all bots going active or inactive each minute.
|
||||||
AiPlayerbot.BotActiveAlone = 100
|
AiPlayerbot.BotActiveAlone = 100
|
||||||
@@ -213,8 +217,8 @@ AiPlayerbot.SyncQuestForPlayer = 0
|
|||||||
AiPlayerbot.SyncLevelWithPlayers = 0
|
AiPlayerbot.SyncLevelWithPlayers = 0
|
||||||
|
|
||||||
# Give free food to random bots
|
# Give free food to random bots
|
||||||
# Default: 1 (enabled)
|
# Default: 0 (disabled)
|
||||||
AiPlayerbot.FreeFood = 1
|
AiPlayerbot.FreeFood = 0
|
||||||
|
|
||||||
# Bot automatically trains spells when talking to trainer (yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells)
|
# Bot automatically trains spells when talking to trainer (yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells)
|
||||||
# Only for random bots
|
# Only for random bots
|
||||||
|
|||||||
@@ -281,11 +281,12 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
autoGearScoreLimit = sConfigMgr->GetOption<int32>("AiPlayerbot.AutoGearScoreLimit", 0);
|
autoGearScoreLimit = sConfigMgr->GetOption<int32>("AiPlayerbot.AutoGearScoreLimit", 0);
|
||||||
|
|
||||||
playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1);
|
playerbotsXPrate = sConfigMgr->GetOption<int32>("AiPlayerbot.KillXPRate", 1);
|
||||||
|
disableDeathKnightLogin = sConfigMgr->GetOption<bool>("AiPlayerbot.DisableDeathKnightLogin", 0);
|
||||||
botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 10);
|
botActiveAlone = sConfigMgr->GetOption<int32>("AiPlayerbot.BotActiveAlone", 10);
|
||||||
|
|
||||||
enablePrototypePerformanceDiff = sConfigMgr->GetOption<bool>("AiPlayerbot.EnablePrototypePerformanceDiff", false);
|
enablePrototypePerformanceDiff = sConfigMgr->GetOption<bool>("AiPlayerbot.EnablePrototypePerformanceDiff", false);
|
||||||
diffWithPlayer = sConfigMgr->GetOption("AiPlayerbot.DiffWithPlayer", 100);
|
diffWithPlayer = sConfigMgr->GetOption<int32>("AiPlayerbot.DiffWithPlayer", 100);
|
||||||
diffEmpty = sConfigMgr->GetIntDefault("AiPlayerbot.DiffEmpty", 200);
|
diffEmpty = sConfigMgr->GetOption<int32>("AiPlayerbot.DiffEmpty", 200);
|
||||||
|
|
||||||
randombotsWalkingRPG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandombotsWalkingRPG", false);
|
randombotsWalkingRPG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandombotsWalkingRPG", false);
|
||||||
randombotsWalkingRPGInDoors = sConfigMgr->GetOption<bool>("AiPlayerbot.RandombotsWalkingRPG.InDoors", false);
|
randombotsWalkingRPGInDoors = sConfigMgr->GetOption<bool>("AiPlayerbot.RandombotsWalkingRPG.InDoors", false);
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ class PlayerbotAIConfig
|
|||||||
bool randomBotShowCloak;
|
bool randomBotShowCloak;
|
||||||
bool disableRandomLevels;
|
bool disableRandomLevels;
|
||||||
uint32 playerbotsXPrate;
|
uint32 playerbotsXPrate;
|
||||||
|
bool disableDeathKnightLogin;
|
||||||
uint32 botActiveAlone;
|
uint32 botActiveAlone;
|
||||||
|
|
||||||
uint32 enablePrototypePerformanceDiff;
|
uint32 enablePrototypePerformanceDiff;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Battleground.h"
|
#include "Battleground.h"
|
||||||
#include "BattlegroundMgr.h"
|
#include "BattlegroundMgr.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
|
#include "DatabaseEnv.h"
|
||||||
#include "Define.h"
|
#include "Define.h"
|
||||||
#include "FleeManager.h"
|
#include "FleeManager.h"
|
||||||
#include "GameTime.h"
|
#include "GameTime.h"
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
#include "Random.h"
|
#include "Random.h"
|
||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
#include "ChannelMgr.h"
|
#include "ChannelMgr.h"
|
||||||
|
#include "SharedDefines.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "UpdateTime.h"
|
#include "UpdateTime.h"
|
||||||
@@ -480,7 +482,6 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
|
|||||||
{
|
{
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
ObjectGuid::LowType guid = fields[0].Get<uint32>();
|
ObjectGuid::LowType guid = fields[0].Get<uint32>();
|
||||||
|
|
||||||
if (GetEventValue(guid, "add"))
|
if (GetEventValue(guid, "add"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -492,6 +493,18 @@ uint32 RandomPlayerbotMgr::AddRandomBots()
|
|||||||
|
|
||||||
if (std::find(currentBots.begin(), currentBots.end(), guid) != currentBots.end())
|
if (std::find(currentBots.begin(), currentBots.end(), guid) != currentBots.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->disableDeathKnightLogin) {
|
||||||
|
QueryResult result = CharacterDatabase.Query("Select class from characters where guid = {}", guid);
|
||||||
|
if (!result) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
uint32 rClass = fields[0].Get<uint32>();
|
||||||
|
if (rClass == CLASS_DEATH_KNIGHT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
guids.push_back(guid);
|
guids.push_back(guid);
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
@@ -1161,12 +1174,10 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
|
|
||||||
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomTeleportByLocations");
|
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomTeleportByLocations");
|
||||||
|
|
||||||
uint32 index = 0;
|
std::shuffle(std::begin(tlocs), std::end(tlocs), RandomEngine::Instance());
|
||||||
for (uint32 i = 0; i < tlocs.size(); i++)
|
for (uint32 i = 0; i < tlocs.size(); i++)
|
||||||
{
|
{
|
||||||
for (uint8 attemtps = 0; attemtps < 3; ++attemtps)
|
WorldLocation loc = tlocs[i];
|
||||||
{
|
|
||||||
WorldLocation loc = tlocs[urand(0, tlocs.size() - 1)];
|
|
||||||
|
|
||||||
float x = loc.GetPositionX(); // + (attemtps > 0 ? urand(0, sPlayerbotAIConfig->grindDistance) - sPlayerbotAIConfig->grindDistance / 2 : 0);
|
float x = loc.GetPositionX(); // + (attemtps > 0 ? urand(0, sPlayerbotAIConfig->grindDistance) - sPlayerbotAIConfig->grindDistance / 2 : 0);
|
||||||
float y = loc.GetPositionY(); // + (attemtps > 0 ? urand(0, sPlayerbotAIConfig->grindDistance) - sPlayerbotAIConfig->grindDistance / 2 : 0);
|
float y = loc.GetPositionY(); // + (attemtps > 0 ? urand(0, sPlayerbotAIConfig->grindDistance) - sPlayerbotAIConfig->grindDistance / 2 : 0);
|
||||||
@@ -1190,14 +1201,26 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
if (map->IsInWater(bot->GetPhaseMask(), x, y, z, bot->GetCollisionHeight()))
|
if (map->IsInWater(bot->GetPhaseMask(), x, y, z, bot->GetCollisionHeight()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float ground = map->GetHeight(x, y, z + 0.5f);
|
float ground = map->GetHeight(bot->GetPhaseMask(), x, y, z + 0.5f);
|
||||||
if (ground <= INVALID_HEIGHT)
|
if (ground <= INVALID_HEIGHT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
z = 0.05f + ground;
|
z = 0.05f + ground;
|
||||||
|
PlayerInfo const* pInfo = sObjectMgr->GetPlayerInfo(bot->getRace(true), bot->getClass());
|
||||||
|
float dis = loc.GetExactDist(pInfo->positionX, pInfo->positionY, pInfo->positionZ);
|
||||||
|
// yunfan: distance check for low level
|
||||||
|
if (bot->GetLevel() <= 4 && (loc.GetMapId() != pInfo->mapId || dis > 500.0f)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bot->GetLevel() <= 10 && (loc.GetMapId() != pInfo->mapId || dis > 2500.0f)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bot->GetLevel() <= 18 && (loc.GetMapId() != pInfo->mapId || dis > 10000.0f)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to {} {},{},{} ({}/{} locations)",
|
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to {} {},{},{} ({}/{} locations)",
|
||||||
bot->GetName().c_str(), bot->GetLevel(), zone->area_name[0], x, y, z, attemtps, tlocs.size());
|
bot->GetName().c_str(), bot->GetLevel(), zone->area_name[0], x, y, z, i + 1, tlocs.size());
|
||||||
|
|
||||||
if (hearth)
|
if (hearth)
|
||||||
{
|
{
|
||||||
@@ -1216,12 +1239,11 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
|
|
||||||
LOG_ERROR("playerbots", "Cannot teleport bot {} - no locations available", bot->GetName().c_str());
|
LOG_ERROR("playerbots", "Cannot teleport bot {} - no locations available ({} locations)", bot->GetName().c_str(), tlocs.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RandomPlayerbotMgr::PrepareTeleportCache()
|
void RandomPlayerbotMgr::PrepareTeleportCache()
|
||||||
@@ -1388,7 +1410,7 @@ void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot)
|
|||||||
uint32 level = bot->getLevel();
|
uint32 level = bot->getLevel();
|
||||||
uint8 race = bot->getRace();
|
uint8 race = bot->getRace();
|
||||||
LOG_DEBUG("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
|
LOG_DEBUG("playerbots", "Random teleporting bot {} for level {} ({} locations available)", bot->GetName().c_str(), bot->GetLevel(), locsPerLevelCache[level].size());
|
||||||
if (urand(0, 100) < sPlayerbotAIConfig->probTeleToBankers * 100) {
|
if (level > 10 && urand(0, 100) < sPlayerbotAIConfig->probTeleToBankers * 100) {
|
||||||
RandomTeleport(bot, bankerLocsPerLevelCache[level], true);
|
RandomTeleport(bot, bankerLocsPerLevelCache[level], true);
|
||||||
} else {
|
} else {
|
||||||
RandomTeleport(bot, locsPerLevelCache[level]);
|
RandomTeleport(bot, locsPerLevelCache[level]);
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ void HealPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
NextAction::array(0,
|
NextAction::array(0,
|
||||||
new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8),
|
new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8),
|
||||||
new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7),
|
new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7),
|
||||||
new NextAction("prayer of healing on party", ACTION_MEDIUM_HEAL + 6),
|
|
||||||
NULL)));
|
NULL)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"medium group heal occasion",
|
"medium group heal occasion",
|
||||||
NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 5), NULL)));
|
NextAction::array(0,
|
||||||
|
new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 6),
|
||||||
|
new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 5),
|
||||||
|
nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"party member critical health",
|
"party member critical health",
|
||||||
|
|||||||
@@ -61,12 +61,14 @@ void HolyHealPriestStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
|||||||
"group heal occasion",
|
"group heal occasion",
|
||||||
NextAction::array(0,
|
NextAction::array(0,
|
||||||
new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8),
|
new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8),
|
||||||
new NextAction("prayer of healing on party", ACTION_MEDIUM_HEAL + 6),
|
|
||||||
NULL)));
|
NULL)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"medium group heal occasion",
|
"medium group heal occasion",
|
||||||
NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 5), NULL)));
|
NextAction::array(0,
|
||||||
|
new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 6),
|
||||||
|
new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 5),
|
||||||
|
nullptr)));
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode(
|
triggers.push_back(new TriggerNode(
|
||||||
"party member critical health",
|
"party member critical health",
|
||||||
|
|||||||
Reference in New Issue
Block a user