mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-02-20 18:10:02 +01:00
Compare commits
11 Commits
1fb66e9d75
...
5a0c27637e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a0c27637e | ||
|
|
cea1e90f57 | ||
|
|
31ed5cbb65 | ||
|
|
5681f29060 | ||
|
|
cf4f0f6dc7 | ||
|
|
c90b155a70 | ||
|
|
780f6d60e0 | ||
|
|
1faf20f567 | ||
|
|
d26c2a3549 | ||
|
|
21ea3a7226 | ||
|
|
387c491265 |
@ -378,10 +378,7 @@ void PlayerbotAI::UpdateAIGroupMembership()
|
|||||||
PlayerbotAI* leaderAI = GET_PLAYERBOT_AI(leader);
|
PlayerbotAI* leaderAI = GET_PLAYERBOT_AI(leader);
|
||||||
if (leaderAI && !leaderAI->IsRealPlayer())
|
if (leaderAI && !leaderAI->IsRealPlayer())
|
||||||
{
|
{
|
||||||
WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
|
LeaveOrDisbandGroup();
|
||||||
bot->GetSession()->QueuePacket(packet);
|
|
||||||
// bot->RemoveFromGroup();
|
|
||||||
ResetStrategies();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,10 +402,7 @@ void PlayerbotAI::UpdateAIGroupMembership()
|
|||||||
}
|
}
|
||||||
if (!hasRealPlayer)
|
if (!hasRealPlayer)
|
||||||
{
|
{
|
||||||
WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
|
LeaveOrDisbandGroup();
|
||||||
bot->GetSession()->QueuePacket(packet);
|
|
||||||
// bot->RemoveFromGroup();
|
|
||||||
ResetStrategies();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -791,6 +785,16 @@ void PlayerbotAI::Reset(bool full)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerbotAI::LeaveOrDisbandGroup()
|
||||||
|
{
|
||||||
|
if (!bot || !bot->GetGroup() || IsRealPlayer())
|
||||||
|
return;
|
||||||
|
|
||||||
|
WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
|
||||||
|
bot->GetSession()->QueuePacket(packet);
|
||||||
|
ResetStrategies();
|
||||||
|
}
|
||||||
|
|
||||||
bool PlayerbotAI::IsAllowedCommand(std::string const text)
|
bool PlayerbotAI::IsAllowedCommand(std::string const text)
|
||||||
{
|
{
|
||||||
if (unsecuredCommands.empty())
|
if (unsecuredCommands.empty())
|
||||||
|
|||||||
@ -415,6 +415,7 @@ public:
|
|||||||
void ResetStrategies(bool load = false);
|
void ResetStrategies(bool load = false);
|
||||||
void ReInitCurrentEngine();
|
void ReInitCurrentEngine();
|
||||||
void Reset(bool full = false);
|
void Reset(bool full = false);
|
||||||
|
void LeaveOrDisbandGroup();
|
||||||
static bool IsTank(Player* player, bool bySpec = false);
|
static bool IsTank(Player* player, bool bySpec = false);
|
||||||
static bool IsHeal(Player* player, bool bySpec = false);
|
static bool IsHeal(Player* player, bool bySpec = false);
|
||||||
static bool IsDps(Player* player, bool bySpec = false);
|
static bool IsDps(Player* player, bool bySpec = false);
|
||||||
@ -601,6 +602,7 @@ public:
|
|||||||
NewRpgInfo rpgInfo;
|
NewRpgInfo rpgInfo;
|
||||||
NewRpgStatistic rpgStatistic;
|
NewRpgStatistic rpgStatistic;
|
||||||
std::unordered_set<uint32> lowPriorityQuest;
|
std::unordered_set<uint32> lowPriorityQuest;
|
||||||
|
time_t bgReleaseAttemptTime = 0;
|
||||||
|
|
||||||
// Schedules a callback to run once after <delayMs> milliseconds.
|
// Schedules a callback to run once after <delayMs> milliseconds.
|
||||||
void AddTimedEvent(std::function<void()> callback, uint32 delayMs);
|
void AddTimedEvent(std::function<void()> callback, uint32 delayMs);
|
||||||
|
|||||||
@ -514,7 +514,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
|
|
||||||
if (!groupValid)
|
if (!groupValid)
|
||||||
{
|
{
|
||||||
bot->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,8 @@ public:
|
|||||||
PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS,
|
PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS,
|
||||||
PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE,
|
PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE,
|
||||||
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
|
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
|
||||||
PLAYERHOOK_ON_GIVE_EXP
|
PLAYERHOOK_ON_GIVE_EXP,
|
||||||
|
PLAYERHOOK_ON_BEFORE_TELEPORT
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
void OnPlayerLogin(Player* player) override
|
void OnPlayerLogin(Player* player) override
|
||||||
@ -121,6 +122,26 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OnPlayerBeforeTeleport(Player* player, uint32 mapid, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) override
|
||||||
|
{
|
||||||
|
// Only apply to bots to prevent affecting real players
|
||||||
|
if (!player || !player->GetSession()->IsBot())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If changing maps, proactively clean visibility references to prevent
|
||||||
|
// stale pointers in other players' visibility maps during the teleport.
|
||||||
|
// This fixes a race condition where:
|
||||||
|
// 1. Bot A teleports and its visible objects start getting cleaned up
|
||||||
|
// 2. Bot B is simultaneously updating visibility and tries to access objects in Bot A's old visibility map
|
||||||
|
// 3. Those objects may already be freed, causing a segmentation fault
|
||||||
|
if (player->GetMapId() != mapid && player->IsInWorld())
|
||||||
|
{
|
||||||
|
player->GetObjectVisibilityContainer().CleanVisibilityReferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // Allow teleport to continue
|
||||||
|
}
|
||||||
|
|
||||||
void OnPlayerAfterUpdate(Player* player, uint32 diff) override
|
void OnPlayerAfterUpdate(Player* player, uint32 diff) override
|
||||||
{
|
{
|
||||||
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
|
if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))
|
||||||
|
|||||||
@ -1517,33 +1517,38 @@ bool RandomPlayerbotMgr::ProcessBot(uint32 bot)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RandomPlayerbotMgr::ProcessBot(Player* player)
|
bool RandomPlayerbotMgr::ProcessBot(Player* bot)
|
||||||
{
|
{
|
||||||
uint32 bot = player->GetGUID().GetCounter();
|
|
||||||
|
|
||||||
if (player->InBattleground())
|
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||||
|
if (!botAI)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (player->InBattlegroundQueue())
|
if (bot->InBattleground())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (bot->InBattlegroundQueue())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 botId = bot->GetGUID().GetCounter();
|
||||||
|
|
||||||
// if death revive
|
// if death revive
|
||||||
if (player->isDead())
|
if (bot->isDead())
|
||||||
{
|
{
|
||||||
if (!GetEventValue(bot, "dead"))
|
if (!GetEventValue(botId, "dead"))
|
||||||
{
|
{
|
||||||
uint32 randomTime =
|
uint32 randomTime =
|
||||||
urand(sPlayerbotAIConfig->minRandomBotReviveTime, sPlayerbotAIConfig->maxRandomBotReviveTime);
|
urand(sPlayerbotAIConfig->minRandomBotReviveTime, sPlayerbotAIConfig->maxRandomBotReviveTime);
|
||||||
LOG_DEBUG("playerbots", "Mark bot {} as dead, will be revived in {}s.", player->GetName().c_str(),
|
LOG_DEBUG("playerbots", "Mark bot {} as dead, will be revived in {}s.", bot->GetName().c_str(),
|
||||||
randomTime);
|
randomTime);
|
||||||
SetEventValue(bot, "dead", 1, sPlayerbotAIConfig->maxRandomBotInWorldTime);
|
SetEventValue(botId, "dead", 1, sPlayerbotAIConfig->maxRandomBotInWorldTime);
|
||||||
SetEventValue(bot, "revive", 1, randomTime);
|
SetEventValue(botId, "revive", 1, randomTime);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetEventValue(bot, "revive"))
|
if (!GetEventValue(botId, "revive"))
|
||||||
{
|
{
|
||||||
Revive(player);
|
Revive(bot);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1551,34 +1556,31 @@ bool RandomPlayerbotMgr::ProcessBot(Player* player)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// leave group if leader is rndbot
|
// leave group if leader is rndbot
|
||||||
Group* group = player->GetGroup();
|
Group* group = bot->GetGroup();
|
||||||
if (group && !group->isLFGGroup() && IsRandomBot(group->GetLeader()))
|
if (group && !group->isLFGGroup() && IsRandomBot(group->GetLeader()))
|
||||||
{
|
{
|
||||||
player->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
LOG_INFO("playerbots", "Bot {} remove from group since leader is random bot.", player->GetName().c_str());
|
LOG_INFO("playerbots", "Bot {} remove from group since leader is random bot.", bot->GetName().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// only randomize and teleport idle bots
|
// only randomize and teleport idle bots
|
||||||
bool idleBot = false;
|
bool idleBot = false;
|
||||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(player);
|
if (TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get())
|
||||||
if (botAI)
|
|
||||||
{
|
{
|
||||||
if (TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get())
|
if (target->getTravelState() == TravelState::TRAVEL_STATE_IDLE)
|
||||||
{
|
|
||||||
if (target->getTravelState() == TravelState::TRAVEL_STATE_IDLE)
|
|
||||||
{
|
|
||||||
idleBot = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
idleBot = true;
|
idleBot = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idleBot = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (idleBot)
|
if (idleBot)
|
||||||
{
|
{
|
||||||
// randomize
|
// randomize
|
||||||
uint32 randomize = GetEventValue(bot, "randomize");
|
uint32 randomize = GetEventValue(botId, "randomize");
|
||||||
if (!randomize)
|
if (!randomize)
|
||||||
{
|
{
|
||||||
// bool randomiser = true;
|
// bool randomiser = true;
|
||||||
@ -1602,12 +1604,12 @@ bool RandomPlayerbotMgr::ProcessBot(Player* player)
|
|||||||
// }
|
// }
|
||||||
// if (randomiser)
|
// if (randomiser)
|
||||||
// {
|
// {
|
||||||
Randomize(player);
|
Randomize(bot);
|
||||||
LOG_DEBUG("playerbots", "Bot #{} {}:{} <{}>: randomized", bot,
|
LOG_DEBUG("playerbots", "Bot #{} {}:{} <{}>: randomized", botId,
|
||||||
player->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", player->GetLevel(), player->GetName());
|
bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName());
|
||||||
uint32 randomTime =
|
uint32 randomTime =
|
||||||
urand(sPlayerbotAIConfig->minRandomBotRandomizeTime, sPlayerbotAIConfig->maxRandomBotRandomizeTime);
|
urand(sPlayerbotAIConfig->minRandomBotRandomizeTime, sPlayerbotAIConfig->maxRandomBotRandomizeTime);
|
||||||
ScheduleRandomize(bot, randomTime);
|
ScheduleRandomize(botId, randomTime);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1619,15 +1621,15 @@ bool RandomPlayerbotMgr::ProcessBot(Player* player)
|
|||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
uint32 teleport = GetEventValue(bot, "teleport");
|
uint32 teleport = GetEventValue(botId, "teleport");
|
||||||
if (!teleport)
|
if (!teleport)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("playerbots", "Bot #{} <{}>: teleport for level and refresh", bot, player->GetName());
|
LOG_DEBUG("playerbots", "Bot #{} <{}>: teleport for level and refresh", botId, bot->GetName());
|
||||||
Refresh(player);
|
Refresh(bot);
|
||||||
RandomTeleportForLevel(player);
|
RandomTeleportForLevel(bot);
|
||||||
uint32 time = urand(sPlayerbotAIConfig->minRandomBotTeleportInterval,
|
uint32 time = urand(sPlayerbotAIConfig->minRandomBotTeleportInterval,
|
||||||
sPlayerbotAIConfig->maxRandomBotTeleportInterval);
|
sPlayerbotAIConfig->maxRandomBotTeleportInterval);
|
||||||
ScheduleTeleport(bot, time);
|
ScheduleTeleport(botId, time);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1771,6 +1773,7 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||||
if (botAI)
|
if (botAI)
|
||||||
botAI->Reset(true);
|
botAI->Reset(true);
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
|
bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
|
||||||
bot->SendMovementFlagUpdate();
|
bot->SendMovementFlagUpdate();
|
||||||
|
|
||||||
@ -2376,6 +2379,10 @@ void RandomPlayerbotMgr::IncreaseLevel(Player* bot)
|
|||||||
|
|
||||||
void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
||||||
{
|
{
|
||||||
|
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||||
|
if (!botAI)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
uint32 maxLevel = sPlayerbotAIConfig->randomBotMaxLevel;
|
||||||
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
if (maxLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||||
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
maxLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
|
||||||
@ -2433,7 +2440,6 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetValue(bot, "level", level);
|
SetValue(bot, "level", level);
|
||||||
|
|
||||||
PlayerbotFactory factory(bot, level);
|
PlayerbotFactory factory(bot, level);
|
||||||
factory.Randomize(false);
|
factory.Randomize(false);
|
||||||
|
|
||||||
@ -2455,11 +2461,10 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
|||||||
PlayerbotsDatabase.Execute(stmt);
|
PlayerbotsDatabase.Execute(stmt);
|
||||||
|
|
||||||
// teleport to a random inn for bot level
|
// teleport to a random inn for bot level
|
||||||
if (GET_PLAYERBOT_AI(bot))
|
botAI->Reset(true);
|
||||||
GET_PLAYERBOT_AI(bot)->Reset(true);
|
|
||||||
|
|
||||||
if (bot->GetGroup())
|
if (bot->GetGroup())
|
||||||
bot->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
|
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
@ -2469,12 +2474,13 @@ void RandomPlayerbotMgr::RandomizeFirst(Player* bot)
|
|||||||
|
|
||||||
void RandomPlayerbotMgr::RandomizeMin(Player* bot)
|
void RandomPlayerbotMgr::RandomizeMin(Player* bot)
|
||||||
{
|
{
|
||||||
|
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||||
|
if (!botAI)
|
||||||
|
return;
|
||||||
|
|
||||||
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomizeMin");
|
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "RandomizeMin");
|
||||||
|
|
||||||
uint32 level = sPlayerbotAIConfig->randomBotMinLevel;
|
uint32 level = sPlayerbotAIConfig->randomBotMinLevel;
|
||||||
|
|
||||||
SetValue(bot, "level", level);
|
SetValue(bot, "level", level);
|
||||||
|
|
||||||
PlayerbotFactory factory(bot, level);
|
PlayerbotFactory factory(bot, level);
|
||||||
factory.Randomize(false);
|
factory.Randomize(false);
|
||||||
|
|
||||||
@ -2496,11 +2502,10 @@ void RandomPlayerbotMgr::RandomizeMin(Player* bot)
|
|||||||
PlayerbotsDatabase.Execute(stmt);
|
PlayerbotsDatabase.Execute(stmt);
|
||||||
|
|
||||||
// teleport to a random inn for bot level
|
// teleport to a random inn for bot level
|
||||||
if (GET_PLAYERBOT_AI(bot))
|
botAI->Reset(true);
|
||||||
GET_PLAYERBOT_AI(bot)->Reset(true);
|
|
||||||
|
|
||||||
if (bot->GetGroup())
|
if (bot->GetGroup())
|
||||||
bot->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
|
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
@ -2582,7 +2587,7 @@ void RandomPlayerbotMgr::Refresh(Player* bot)
|
|||||||
bot->SetMoney(money + 500 * sqrt(urand(1, bot->GetLevel() * 5)));
|
bot->SetMoney(money + 500 * sqrt(urand(1, bot->GetLevel() * 5)));
|
||||||
|
|
||||||
if (bot->GetGroup())
|
if (bot->GetGroup())
|
||||||
bot->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
|
|
||||||
if (pmo)
|
if (pmo)
|
||||||
pmo->finish();
|
pmo->finish();
|
||||||
@ -3090,6 +3095,7 @@ void RandomPlayerbotMgr::OnPlayerLogin(Player* player)
|
|||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
player->TeleportTo(botPos);
|
player->TeleportTo(botPos);
|
||||||
|
|
||||||
// player->Relocate(botPos.getX(), botPos.getY(), botPos.getZ(), botPos.getO());
|
// player->Relocate(botPos.getX(), botPos.getY(), botPos.getZ(), botPos.getO());
|
||||||
|
|||||||
@ -176,6 +176,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
memberBotAI->Reset();
|
memberBotAI->Reset();
|
||||||
|
member->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(),
|
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(),
|
||||||
|
|||||||
@ -4289,9 +4289,15 @@ bool ArenaTactics::moveToCenter(Battleground* bg)
|
|||||||
{
|
{
|
||||||
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
||||||
if (bot->GetDistance(1333.07f, 817.18f, 13.35f) < 4)
|
if (bot->GetDistance(1333.07f, 817.18f, 13.35f) < 4)
|
||||||
|
{
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
||||||
|
}
|
||||||
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 4)
|
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 4)
|
||||||
|
{
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BATTLEGROUND_RV:
|
case BATTLEGROUND_RV:
|
||||||
|
|||||||
@ -106,6 +106,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
|||||||
else
|
else
|
||||||
botAI->TellMaster("You are too far away from me! I will there soon.");
|
botAI->TellMaster("You are too far away from me! I will there soon.");
|
||||||
|
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(),
|
bot->TeleportTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(),
|
||||||
master->GetOrientation()); return true;
|
master->GetOrientation()); return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,8 +72,10 @@ bool UninviteAction::Execute(Event event)
|
|||||||
|
|
||||||
bool LeaveGroupAction::Leave(Player* player)
|
bool LeaveGroupAction::Leave(Player* player)
|
||||||
{
|
{
|
||||||
if (player && !GET_PLAYERBOT_AI(player) &&
|
if (player &&
|
||||||
|
!botAI &&
|
||||||
!botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, false, player))
|
!botAI->GetSecurity()->CheckLevelFor(PLAYERBOT_SECURITY_INVITE, false, player))
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool aiMaster = GET_PLAYERBOT_AI(botAI->GetMaster()) != nullptr;
|
bool aiMaster = GET_PLAYERBOT_AI(botAI->GetMaster()) != nullptr;
|
||||||
@ -84,7 +86,7 @@ bool LeaveGroupAction::Leave(Player* player)
|
|||||||
bool shouldStay = randomBot && bot->GetGroup() && player == bot;
|
bool shouldStay = randomBot && bot->GetGroup() && player == bot;
|
||||||
if (!shouldStay)
|
if (!shouldStay)
|
||||||
{
|
{
|
||||||
bot->RemoveFromGroup();
|
botAI->LeaveOrDisbandGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (randomBot)
|
if (randomBot)
|
||||||
|
|||||||
@ -1148,6 +1148,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
|||||||
if ((target->GetMap() && target->GetMap()->IsBattlegroundOrArena()) || (bot->GetMap() &&
|
if ((target->GetMap() && target->GetMap()->IsBattlegroundOrArena()) || (bot->GetMap() &&
|
||||||
bot->GetMap()->IsBattlegroundOrArena())) return false;
|
bot->GetMap()->IsBattlegroundOrArena())) return false;
|
||||||
|
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(target->GetMapId(), x, y, z, bot->GetOrientation());
|
bot->TeleportTo(target->GetMapId(), x, y, z, bot->GetOrientation());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1175,6 +1176,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
|||||||
|
|
||||||
bot->CombatStop(true);
|
bot->CombatStop(true);
|
||||||
botAI->TellMasterNoFacing("I will there soon.");
|
botAI->TellMasterNoFacing("I will there soon.");
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
|
bot->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
|
||||||
target->GetOrientation()); return false;
|
target->GetOrientation()); return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -147,6 +147,7 @@ bool AutoReleaseSpiritAction::HandleBattlegroundSpiritHealer()
|
|||||||
// and in IOC it's not within clicking range when they res in own base
|
// and in IOC it's not within clicking range when they res in own base
|
||||||
|
|
||||||
// Teleport to nearest friendly Spirit Healer when not currently in range of one.
|
// Teleport to nearest friendly Spirit Healer when not currently in range of one.
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(bot->GetMapId(), spiritHealer->GetPositionX(), spiritHealer->GetPositionY(), spiritHealer->GetPositionZ(), 0.f);
|
bot->TeleportTo(bot->GetMapId(), spiritHealer->GetPositionX(), spiritHealer->GetPositionY(), spiritHealer->GetPositionZ(), 0.f);
|
||||||
RESET_AI_VALUE(bool, "combat::self target");
|
RESET_AI_VALUE(bool, "combat::self target");
|
||||||
RESET_AI_VALUE(WorldPosition, "current position");
|
RESET_AI_VALUE(WorldPosition, "current position");
|
||||||
@ -191,12 +192,11 @@ bool AutoReleaseSpiritAction::ShouldDelayBattlegroundRelease() const
|
|||||||
{
|
{
|
||||||
// The below delays release to spirit with 6 seconds.
|
// The below delays release to spirit with 6 seconds.
|
||||||
// This prevents currently casted (ranged) spells to be re-directed to the died bot's ghost.
|
// This prevents currently casted (ranged) spells to be re-directed to the died bot's ghost.
|
||||||
const int32_t botId = bot->GetGUID().GetRawValue();
|
|
||||||
|
|
||||||
// If the bot already is a spirit, erase release time and return true
|
// If the bot already is a spirit, reset release time and return true
|
||||||
if (bot->HasPlayerFlag(PLAYER_FLAGS_GHOST))
|
if (bot->HasPlayerFlag(PLAYER_FLAGS_GHOST))
|
||||||
{
|
{
|
||||||
m_botReleaseTimes.erase(botId);
|
botAI->bgReleaseAttemptTime = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,14 +204,13 @@ bool AutoReleaseSpiritAction::ShouldDelayBattlegroundRelease() const
|
|||||||
const time_t now = time(nullptr);
|
const time_t now = time(nullptr);
|
||||||
constexpr time_t RELEASE_DELAY = 6;
|
constexpr time_t RELEASE_DELAY = 6;
|
||||||
|
|
||||||
auto& lastReleaseTime = m_botReleaseTimes[botId];
|
if (botAI->bgReleaseAttemptTime == 0)
|
||||||
if (lastReleaseTime == 0)
|
botAI->bgReleaseAttemptTime = now;
|
||||||
lastReleaseTime = now;
|
|
||||||
|
|
||||||
if (now - lastReleaseTime < RELEASE_DELAY)
|
if (now - botAI->bgReleaseAttemptTime < RELEASE_DELAY)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_botReleaseTimes.erase(botId);
|
botAI->bgReleaseAttemptTime = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +243,7 @@ int64 RepopAction::CalculateDeadTime() const
|
|||||||
|
|
||||||
void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) const
|
void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) const
|
||||||
{
|
{
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(graveyard->Map, graveyard->x, graveyard->y, graveyard->z, 0.f);
|
bot->TeleportTo(graveyard->Map, graveyard->x, graveyard->y, graveyard->z, 0.f);
|
||||||
RESET_AI_VALUE(bool, "combat::self target");
|
RESET_AI_VALUE(bool, "combat::self target");
|
||||||
RESET_AI_VALUE(WorldPosition, "current position");
|
RESET_AI_VALUE(WorldPosition, "current position");
|
||||||
|
|||||||
@ -38,7 +38,6 @@ private:
|
|||||||
bool ShouldAutoRelease() const;
|
bool ShouldAutoRelease() const;
|
||||||
bool ShouldDelayBattlegroundRelease() const;
|
bool ShouldDelayBattlegroundRelease() const;
|
||||||
|
|
||||||
inline static std::unordered_map<uint32_t, time_t> m_botReleaseTimes;
|
|
||||||
time_t m_bgGossipTime = 0;
|
time_t m_bgGossipTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -169,6 +169,7 @@ bool FindCorpseAction::Execute(Event event)
|
|||||||
if (deadTime > delay)
|
if (deadTime > delay)
|
||||||
{
|
{
|
||||||
bot->GetMotionMaster()->Clear();
|
bot->GetMotionMaster()->Clear();
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0);
|
bot->TeleportTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +351,7 @@ bool SpiritHealerAction::Execute(Event event)
|
|||||||
// if (!botAI->HasActivePlayerMaster())
|
// if (!botAI->HasActivePlayerMaster())
|
||||||
// {
|
// {
|
||||||
context->GetValue<uint32>("death count")->Set(dCount + 1);
|
context->GetValue<uint32>("death count")->Set(dCount + 1);
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
return bot->TeleportTo(ClosestGrave->Map, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, 0.f);
|
return bot->TeleportTo(ClosestGrave->Map, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, 0.f);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
@ -225,6 +225,7 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
|
|||||||
|
|
||||||
player->GetMotionMaster()->Clear();
|
player->GetMotionMaster()->Clear();
|
||||||
AI_VALUE(LastMovement&, "last movement").clear();
|
AI_VALUE(LastMovement&, "last movement").clear();
|
||||||
|
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
player->TeleportTo(mapId, x, y, z, 0);
|
player->TeleportTo(mapId, x, y, z, 0);
|
||||||
|
|
||||||
if (botAI->HasStrategy("stay", botAI->GetState()))
|
if (botAI->HasStrategy("stay", botAI->GetState()))
|
||||||
|
|||||||
@ -67,6 +67,7 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
|
|||||||
bot->GetName(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId(),
|
bot->GetName(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId(),
|
||||||
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(),
|
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(),
|
||||||
zone_name);
|
zone_name);
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
return bot->TeleportTo(dest);
|
return bot->TeleportTo(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user