Compare commits

..

No commits in common. "5a0c27637e1d2b450637df3909d84e9f6e3b9199" and "1fb66e9d75c4eeb62aeb3405769d081bc3996577" have entirely different histories.

15 changed files with 66 additions and 114 deletions

View File

@ -378,7 +378,10 @@ void PlayerbotAI::UpdateAIGroupMembership()
PlayerbotAI* leaderAI = GET_PLAYERBOT_AI(leader); PlayerbotAI* leaderAI = GET_PLAYERBOT_AI(leader);
if (leaderAI && !leaderAI->IsRealPlayer()) if (leaderAI && !leaderAI->IsRealPlayer())
{ {
LeaveOrDisbandGroup(); WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
bot->GetSession()->QueuePacket(packet);
// bot->RemoveFromGroup();
ResetStrategies();
} }
} }
} }
@ -402,7 +405,10 @@ void PlayerbotAI::UpdateAIGroupMembership()
} }
if (!hasRealPlayer) if (!hasRealPlayer)
{ {
LeaveOrDisbandGroup(); WorldPacket* packet = new WorldPacket(CMSG_GROUP_DISBAND);
bot->GetSession()->QueuePacket(packet);
// bot->RemoveFromGroup();
ResetStrategies();
} }
} }
} }
@ -785,16 +791,6 @@ 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())

View File

@ -415,7 +415,6 @@ 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);
@ -602,7 +601,6 @@ 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);

View File

@ -514,7 +514,7 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
if (!groupValid) if (!groupValid)
{ {
botAI->LeaveOrDisbandGroup(); bot->RemoveFromGroup();
} }
} }

View File

@ -87,8 +87,7 @@ 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
@ -122,26 +121,6 @@ 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))

View File

@ -1517,38 +1517,33 @@ bool RandomPlayerbotMgr::ProcessBot(uint32 bot)
return false; return false;
} }
bool RandomPlayerbotMgr::ProcessBot(Player* bot) bool RandomPlayerbotMgr::ProcessBot(Player* player)
{ {
uint32 bot = player->GetGUID().GetCounter();
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); if (player->InBattleground())
if (!botAI)
return false; return false;
if (bot->InBattleground()) if (player->InBattlegroundQueue())
return false; return false;
if (bot->InBattlegroundQueue())
return false;
uint32 botId = bot->GetGUID().GetCounter();
// if death revive // if death revive
if (bot->isDead()) if (player->isDead())
{ {
if (!GetEventValue(botId, "dead")) if (!GetEventValue(bot, "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.", bot->GetName().c_str(), LOG_DEBUG("playerbots", "Mark bot {} as dead, will be revived in {}s.", player->GetName().c_str(),
randomTime); randomTime);
SetEventValue(botId, "dead", 1, sPlayerbotAIConfig->maxRandomBotInWorldTime); SetEventValue(bot, "dead", 1, sPlayerbotAIConfig->maxRandomBotInWorldTime);
SetEventValue(botId, "revive", 1, randomTime); SetEventValue(bot, "revive", 1, randomTime);
return false; return false;
} }
if (!GetEventValue(botId, "revive")) if (!GetEventValue(bot, "revive"))
{ {
Revive(bot); Revive(player);
return true; return true;
} }
@ -1556,15 +1551,18 @@ bool RandomPlayerbotMgr::ProcessBot(Player* bot)
} }
// leave group if leader is rndbot // leave group if leader is rndbot
Group* group = bot->GetGroup(); Group* group = player->GetGroup();
if (group && !group->isLFGGroup() && IsRandomBot(group->GetLeader())) if (group && !group->isLFGGroup() && IsRandomBot(group->GetLeader()))
{ {
botAI->LeaveOrDisbandGroup(); player->RemoveFromGroup();
LOG_INFO("playerbots", "Bot {} remove from group since leader is random bot.", bot->GetName().c_str()); LOG_INFO("playerbots", "Bot {} remove from group since leader is random bot.", player->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 (botAI)
{
if (TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get()) if (TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get())
{ {
if (target->getTravelState() == TravelState::TRAVEL_STATE_IDLE) if (target->getTravelState() == TravelState::TRAVEL_STATE_IDLE)
@ -1576,11 +1574,11 @@ bool RandomPlayerbotMgr::ProcessBot(Player* bot)
{ {
idleBot = true; idleBot = true;
} }
}
if (idleBot) if (idleBot)
{ {
// randomize // randomize
uint32 randomize = GetEventValue(botId, "randomize"); uint32 randomize = GetEventValue(bot, "randomize");
if (!randomize) if (!randomize)
{ {
// bool randomiser = true; // bool randomiser = true;
@ -1604,12 +1602,12 @@ bool RandomPlayerbotMgr::ProcessBot(Player* bot)
// } // }
// if (randomiser) // if (randomiser)
// { // {
Randomize(bot); Randomize(player);
LOG_DEBUG("playerbots", "Bot #{} {}:{} <{}>: randomized", botId, LOG_DEBUG("playerbots", "Bot #{} {}:{} <{}>: randomized", bot,
bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName()); player->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", player->GetLevel(), player->GetName());
uint32 randomTime = uint32 randomTime =
urand(sPlayerbotAIConfig->minRandomBotRandomizeTime, sPlayerbotAIConfig->maxRandomBotRandomizeTime); urand(sPlayerbotAIConfig->minRandomBotRandomizeTime, sPlayerbotAIConfig->maxRandomBotRandomizeTime);
ScheduleRandomize(botId, randomTime); ScheduleRandomize(bot, randomTime);
return true; return true;
} }
@ -1621,15 +1619,15 @@ bool RandomPlayerbotMgr::ProcessBot(Player* bot)
// return true; // return true;
// } // }
uint32 teleport = GetEventValue(botId, "teleport"); uint32 teleport = GetEventValue(bot, "teleport");
if (!teleport) if (!teleport)
{ {
LOG_DEBUG("playerbots", "Bot #{} <{}>: teleport for level and refresh", botId, bot->GetName()); LOG_DEBUG("playerbots", "Bot #{} <{}>: teleport for level and refresh", bot, player->GetName());
Refresh(bot); Refresh(player);
RandomTeleportForLevel(bot); RandomTeleportForLevel(player);
uint32 time = urand(sPlayerbotAIConfig->minRandomBotTeleportInterval, uint32 time = urand(sPlayerbotAIConfig->minRandomBotTeleportInterval,
sPlayerbotAIConfig->maxRandomBotTeleportInterval); sPlayerbotAIConfig->maxRandomBotTeleportInterval);
ScheduleTeleport(botId, time); ScheduleTeleport(bot, time);
return true; return true;
} }
} }
@ -1773,7 +1771,6 @@ 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();
@ -2379,10 +2376,6 @@ 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);
@ -2440,6 +2433,7 @@ 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);
@ -2461,10 +2455,11 @@ 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
botAI->Reset(true); if (GET_PLAYERBOT_AI(bot))
GET_PLAYERBOT_AI(bot)->Reset(true);
if (bot->GetGroup()) if (bot->GetGroup())
botAI->LeaveOrDisbandGroup(); bot->RemoveFromGroup();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@ -2474,13 +2469,12 @@ 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);
@ -2502,10 +2496,11 @@ 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
botAI->Reset(true); if (GET_PLAYERBOT_AI(bot))
GET_PLAYERBOT_AI(bot)->Reset(true);
if (bot->GetGroup()) if (bot->GetGroup())
botAI->LeaveOrDisbandGroup(); bot->RemoveFromGroup();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@ -2587,7 +2582,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())
botAI->LeaveOrDisbandGroup(); bot->RemoveFromGroup();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@ -3095,7 +3090,6 @@ 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());

View File

@ -176,7 +176,6 @@ 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(),

View File

@ -4289,16 +4289,10 @@ 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:
MoveTo(bg->GetMapId(), 764.65f + frand(-2, +2), -283.85f + frand(-2, +2), 28.28f, false, true); MoveTo(bg->GetMapId(), 764.65f + frand(-2, +2), -283.85f + frand(-2, +2), 28.28f, false, true);

View File

@ -106,7 +106,6 @@ 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;
} }

View File

@ -72,10 +72,8 @@ bool UninviteAction::Execute(Event event)
bool LeaveGroupAction::Leave(Player* player) bool LeaveGroupAction::Leave(Player* player)
{ {
if (player && if (player && !GET_PLAYERBOT_AI(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;
@ -86,7 +84,7 @@ bool LeaveGroupAction::Leave(Player* player)
bool shouldStay = randomBot && bot->GetGroup() && player == bot; bool shouldStay = randomBot && bot->GetGroup() && player == bot;
if (!shouldStay) if (!shouldStay)
{ {
botAI->LeaveOrDisbandGroup(); bot->RemoveFromGroup();
} }
if (randomBot) if (randomBot)

View File

@ -1148,7 +1148,6 @@ 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
@ -1176,7 +1175,6 @@ 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;
} }

View File

@ -147,7 +147,6 @@ 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");
@ -192,11 +191,12 @@ 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, reset release time and return true // If the bot already is a spirit, erase release time and return true
if (bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) if (bot->HasPlayerFlag(PLAYER_FLAGS_GHOST))
{ {
botAI->bgReleaseAttemptTime = 0; m_botReleaseTimes.erase(botId);
return true; return true;
} }
@ -204,13 +204,14 @@ 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;
if (botAI->bgReleaseAttemptTime == 0) auto& lastReleaseTime = m_botReleaseTimes[botId];
botAI->bgReleaseAttemptTime = now; if (lastReleaseTime == 0)
lastReleaseTime = now;
if (now - botAI->bgReleaseAttemptTime < RELEASE_DELAY) if (now - lastReleaseTime < RELEASE_DELAY)
return false; return false;
botAI->bgReleaseAttemptTime = 0; m_botReleaseTimes.erase(botId);
return true; return true;
} }
@ -243,7 +244,6 @@ 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");

View File

@ -38,6 +38,7 @@ 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;
}; };

View File

@ -169,7 +169,6 @@ 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);
} }
@ -351,7 +350,6 @@ 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);
// } // }

View File

@ -225,7 +225,6 @@ 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()))

View File

@ -67,7 +67,6 @@ 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);
} }