mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
1144 lines
40 KiB
C++
1144 lines
40 KiB
C++
/*
|
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
|
*/
|
|
|
|
#include "BattleGroundJoinAction.h"
|
|
#include "ArenaTeam.h"
|
|
#include "ArenaTeamMgr.h"
|
|
#include "BattlegroundMgr.h"
|
|
#include "Event.h"
|
|
#include "GroupMgr.h"
|
|
#include "PlayerbotAI.h"
|
|
#include "Playerbots.h"
|
|
#include "PositionValue.h"
|
|
#include "UpdateTime.h"
|
|
|
|
bool BGJoinAction::Execute(Event event)
|
|
{
|
|
uint32 queueType = AI_VALUE(uint32, "bg type");
|
|
if (!queueType) // force join to fill bg
|
|
{
|
|
if (bgList.empty())
|
|
return false;
|
|
|
|
BattlegroundQueueTypeId queueTypeId = (BattlegroundQueueTypeId)bgList[urand(0, bgList.size() - 1)];
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
BattlegroundBracketId bracketId;
|
|
bool isArena = false;
|
|
bool isRated = false;
|
|
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
|
if (!bg)
|
|
return false;
|
|
|
|
uint32 mapId = bg->GetMapId();
|
|
PvPDifficultyEntry const* pvpDiff = GetBattlegroundBracketByLevel(mapId, bot->getLevel());
|
|
if (!pvpDiff)
|
|
return false;
|
|
|
|
bracketId = pvpDiff->GetBracketId();
|
|
|
|
if (ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId)))
|
|
{
|
|
isArena = true;
|
|
|
|
std::vector<uint32>::iterator i = find(ratedList.begin(), ratedList.end(), queueTypeId);
|
|
if (i != ratedList.end())
|
|
isRated = true;
|
|
|
|
if (isRated && !gatherArenaTeam(type))
|
|
return false;
|
|
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Set(isRated);
|
|
}
|
|
|
|
// set bg type and bm guid
|
|
//botAI->GetAiObjectContext()->GetValue<ObjectGuid>("bg master")->Set(bmGUID);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(queueTypeId);
|
|
queueType = queueTypeId;
|
|
}
|
|
|
|
return JoinQueue(queueType);
|
|
}
|
|
|
|
bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
|
{
|
|
ArenaTeam* arenateam = nullptr;
|
|
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
|
|
{
|
|
ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot));
|
|
if (!temp)
|
|
continue;
|
|
|
|
if (temp->GetCaptain() != bot->GetGUID())
|
|
continue;
|
|
|
|
if (temp->GetType() != type)
|
|
continue;
|
|
|
|
if (temp->GetMembersSize() < ((uint32) temp->GetType()))
|
|
continue;
|
|
|
|
arenateam = temp;
|
|
}
|
|
|
|
if (!arenateam)
|
|
return false;
|
|
|
|
GuidVector members;
|
|
|
|
// search for arena team members and make them online
|
|
for (ArenaTeam::MemberList::iterator itr = arenateam->GetMembers().begin(); itr != arenateam->GetMembers().end(); ++itr)
|
|
{
|
|
bool offline = false;
|
|
Player* member = ObjectAccessor::FindConnectedPlayer(itr->Guid);
|
|
if (!member)
|
|
{
|
|
offline = true;
|
|
}
|
|
//if (!member && !sObjectMgr->GetPlayerAccountIdByGUID(itr->guid))
|
|
// continue;
|
|
|
|
if (offline)
|
|
sRandomPlayerbotMgr->AddPlayerBot(itr->Guid, 0);
|
|
|
|
if (member)
|
|
{
|
|
PlayerbotAI* memberBotAI = GET_PLAYERBOT_AI(member);
|
|
if (!memberBotAI)
|
|
continue;
|
|
|
|
if (member->GetGroup() && memberBotAI->HasRealPlayerMaster())
|
|
continue;
|
|
|
|
if (!sPlayerbotAIConfig->IsInRandomAccountList(member->GetSession()->GetAccountId()))
|
|
continue;
|
|
|
|
if (member->IsInCombat())
|
|
continue;
|
|
|
|
if (member->GetGUID() == bot->GetGUID())
|
|
continue;
|
|
|
|
if (member->GetGroup())
|
|
member->GetGroup()->RemoveMember(member->GetGUID());
|
|
|
|
memberBotAI->Reset();
|
|
}
|
|
|
|
if (member)
|
|
members.push_back(member->GetGUID());
|
|
}
|
|
|
|
if (!members.size() || (int)members.size() < (int)(arenateam->GetType() - 1))
|
|
{
|
|
LOG_INFO("playerbots", "Team #{} <{}> has not enough members for match", arenateam->GetId(), arenateam->GetName().c_str());
|
|
return false;
|
|
}
|
|
|
|
Group* group = new Group();
|
|
uint32 count = 1;
|
|
|
|
// disband leaders group
|
|
if (bot->GetGroup())
|
|
bot->GetGroup()->Disband(true);
|
|
|
|
if (!group->Create(bot))
|
|
{
|
|
LOG_INFO("playerbots", "Team #{} <{}>: Can't create group for arena queue", arenateam->GetId(), arenateam->GetName());
|
|
return false;
|
|
}
|
|
else
|
|
sGroupMgr->AddGroup(group);
|
|
|
|
LOG_INFO("playerbots", "Bot {} <{}>: Leader of <{}>", bot->GetGUID().ToString().c_str(), bot->GetName(), arenateam->GetName());
|
|
|
|
|
|
for (auto i = begin(members); i != end(members); ++i)
|
|
{
|
|
if (*i == bot->GetGUID())
|
|
continue;
|
|
|
|
//if (count >= (int)arenateam->GetType())
|
|
//break;
|
|
|
|
if (group->GetMembersCount() >= (uint32) arenateam->GetType())
|
|
break;
|
|
|
|
Player* member = ObjectAccessor::FindConnectedPlayer(*i);
|
|
if (!member)
|
|
continue;
|
|
|
|
if (member->getLevel() < 70)
|
|
continue;
|
|
|
|
if (!group->AddMember(member))
|
|
continue;
|
|
|
|
PlayerbotAI* memberBotAI = GET_PLAYERBOT_AI(member);
|
|
if (!memberBotAI)
|
|
continue;
|
|
|
|
memberBotAI->Reset();
|
|
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
|
|
|
|
|
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(), member->GetName().c_str(), arenateam->GetName().c_str());
|
|
|
|
count++;
|
|
}
|
|
|
|
if (group && group->GetMembersCount() >= (uint32)arenateam->GetType())
|
|
{
|
|
LOG_INFO("playerbots", "Team #{} <{}> Group is ready for match", arenateam->GetId(), arenateam->GetName().c_str());
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
LOG_INFO("playerbots", "Team #{} <{}> Group is not ready for match (not enough members)", arenateam->GetId(), arenateam->GetName().c_str());
|
|
group->Disband();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool BGJoinAction::canJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId)
|
|
{
|
|
// check if bot can join this bg/bracket
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
|
|
// check if already in queue
|
|
if (bot->InBattlegroundQueueForBattlegroundQueueType(queueTypeId))
|
|
return false;
|
|
|
|
// check too low/high level
|
|
if (!bot->GetBGAccessByLevel(bgTypeId))
|
|
return false;
|
|
|
|
// check bracket
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
|
uint32 mapId = bg->GetMapId();
|
|
PvPDifficultyEntry const* pvpDiff = GetBattlegroundBracketByLevel(mapId, bot->getLevel());
|
|
if (!pvpDiff)
|
|
return false;
|
|
|
|
BattlegroundBracketId bracket_temp = pvpDiff->GetBracketId();
|
|
|
|
if (bracket_temp != bracketId)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId)
|
|
{
|
|
// check if bot should join (queue has real players)
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
|
if (!bg)
|
|
return false;
|
|
|
|
bool isArena = false;
|
|
bool isRated = false;
|
|
bool noLag = sWorldUpdateTime.GetAverageUpdateTime() < (sRandomPlayerbotMgr->GetPlayers().empty() ? sPlayerbotAIConfig->diffEmpty : sPlayerbotAIConfig->diffWithPlayer) * 1.1;
|
|
|
|
ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
|
if (type != ARENA_TYPE_NONE)
|
|
isArena = true;
|
|
|
|
bool hasPlayers = (sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]) > 0;
|
|
bool hasBots = (sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE]) >= bg->GetMinPlayersPerTeam();
|
|
|
|
if (!sPlayerbotAIConfig->randomBotAutoJoinBG && !hasPlayers)
|
|
return false;
|
|
|
|
if (!hasPlayers && isArena) // avoid many arena's being created when 1 player queues a skirmish
|
|
return false;
|
|
|
|
if (!(hasPlayers || hasBots))
|
|
return false;
|
|
|
|
if (sPlayerbotAIConfig->enablePrototypePerformanceDiff && !hasPlayers && !noLag)
|
|
return false;
|
|
|
|
uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2;
|
|
uint32 TeamSize = bg->GetMaxPlayersPerTeam();
|
|
|
|
uint32 ACount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE];
|
|
uint32 HCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
|
|
uint32 BgCount = ACount + HCount;
|
|
uint32 SCount = 0;
|
|
uint32 RCount = 0;
|
|
|
|
TeamId teamId = bot->GetTeamId();
|
|
|
|
if (isArena)
|
|
{
|
|
uint32 rated_players = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
if (rated_players)
|
|
{
|
|
isRated = true;
|
|
}
|
|
|
|
isArena = true;
|
|
BracketSize = (uint32)(type * 2);
|
|
TeamSize = type;
|
|
ACount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_ALLIANCE];
|
|
HCount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_HORDE];
|
|
BgCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE];
|
|
SCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE];
|
|
RCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
}
|
|
|
|
// do not try if not a captain of arena team
|
|
if (isRated)
|
|
{
|
|
if (!sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID()))
|
|
return false;
|
|
|
|
// check if bot has correct team
|
|
ArenaTeam* arenateam = nullptr;
|
|
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
|
|
{
|
|
ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot));
|
|
if (!temp)
|
|
continue;
|
|
|
|
if (temp->GetType() != type)
|
|
continue;
|
|
|
|
arenateam = temp;
|
|
}
|
|
|
|
if (!arenateam)
|
|
return false;
|
|
|
|
ratedList.push_back(queueTypeId);
|
|
}
|
|
|
|
// hack fix crash in queue remove event
|
|
if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID()))
|
|
return false;
|
|
|
|
bool needBots = sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId];
|
|
|
|
// add more bots if players are not invited or 1st BG instance is full
|
|
if (needBots/* || (hasPlayers && BgCount > BracketSize && (BgCount % BracketSize) != 0)*/)
|
|
return true;
|
|
|
|
// do not join if BG queue is full
|
|
if (BgCount >= BracketSize && (ACount >= TeamSize) && (HCount >= TeamSize))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!isArena && ((ACount >= TeamSize && teamId == TEAM_ALLIANCE) || (HCount >= TeamSize && teamId == TEAM_HORDE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && (((ACount >= TeamSize && HCount > 0) && teamId == TEAM_ALLIANCE) || ((HCount >= TeamSize && ACount > 0) && teamId == TEAM_HORDE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && (((ACount > TeamSize && HCount == 0) && teamId == TEAM_HORDE) || ((HCount > TeamSize && ACount == 0) && teamId == TEAM_ALLIANCE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && ((!isRated && SCount >= BracketSize) || (isRated && RCount >= BracketSize)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGJoinAction::isUseful()
|
|
{
|
|
// do not try if BG bots disabled
|
|
if (!sPlayerbotAIConfig->randomBotJoinBG)
|
|
return false;
|
|
|
|
// can't queue in BG
|
|
if (bot->InBattleground())
|
|
return false;
|
|
|
|
// do not try right after login
|
|
if ((time(nullptr) - bot->GetInGameTime()) < 30)
|
|
return false;
|
|
|
|
// check level
|
|
if (bot->getLevel() < 10)
|
|
return false;
|
|
|
|
// do not try if with player master or in combat/group
|
|
if (GET_PLAYERBOT_AI(bot)->HasActivePlayerMaster())
|
|
return false;
|
|
|
|
if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID()))
|
|
return false;
|
|
|
|
if (bot->IsInCombat())
|
|
return false;
|
|
|
|
// check Deserter debuff
|
|
if (!bot->CanJoinToBattleground())
|
|
return false;
|
|
|
|
// check if has free queue slots
|
|
if (!bot->HasFreeBattlegroundQueueId())
|
|
return false;
|
|
|
|
// do not try if in dungeon
|
|
//Map* map = bot->GetMap();
|
|
//if (map && map->Instanceable())
|
|
// return false;
|
|
|
|
bgList.clear();
|
|
ratedList.clear();
|
|
|
|
for (int i = BG_BRACKET_ID_FIRST; i < MAX_BATTLEGROUND_BRACKETS; ++i)
|
|
{
|
|
for (int j = BATTLEGROUND_QUEUE_AV; j < MAX_BATTLEGROUND_QUEUE_TYPES; ++j)
|
|
{
|
|
BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(j);
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
BattlegroundBracketId bracketId = BattlegroundBracketId(i);
|
|
|
|
if (!canJoinBg(queueTypeId, bracketId))
|
|
continue;
|
|
|
|
if (shouldJoinBg(queueTypeId, bracketId))
|
|
bgList.push_back(queueTypeId);
|
|
}
|
|
}
|
|
|
|
if (!bgList.empty())
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool BGJoinAction::JoinQueue(uint32 type)
|
|
{
|
|
// ignore if player is already in BG, is logging out, or already being teleport
|
|
if (!bot || (!bot->IsInWorld() && !bot->IsBeingTeleported()) || bot->InBattleground())
|
|
return false;
|
|
|
|
// get BG TypeId
|
|
BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(type);
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
BattlegroundBracketId bracketId;
|
|
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
|
if (!bg)
|
|
return false;
|
|
|
|
uint32 mapId = bg->GetMapId();
|
|
PvPDifficultyEntry const* pvpDiff = GetBattlegroundBracketByLevel(mapId, bot->getLevel());
|
|
if (!pvpDiff)
|
|
return false;
|
|
|
|
bracketId = pvpDiff->GetBracketId();
|
|
|
|
uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2;
|
|
uint32 TeamSize = bg->GetMaxPlayersPerTeam();
|
|
TeamId teamId = bot->GetTeamId();
|
|
|
|
// check if already in queue
|
|
if (bot->InBattlegroundQueueForBattlegroundQueueType(queueTypeId))
|
|
return false;
|
|
|
|
// check bg req level
|
|
if (!bot->GetBGAccessByLevel(bgTypeId))
|
|
return false;
|
|
|
|
// get BG MapId
|
|
uint32 bgTypeId_ = bgTypeId;
|
|
uint32 instanceId = 0; // 0 = First Available
|
|
|
|
bool isPremade = false;
|
|
bool isArena = false;
|
|
bool isRated = false;
|
|
uint8 arenaslot = 0;
|
|
uint8 asGroup = false;
|
|
|
|
std::string _bgType;
|
|
|
|
// check if arena
|
|
ArenaType arenaType = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
|
if (arenaType != ARENA_TYPE_NONE)
|
|
isArena = true;
|
|
|
|
// get battlemaster
|
|
//Unit* unit = botAI->GetUnit(AI_VALUE2(CreatureData const*, "bg master", bgTypeId));
|
|
Unit* unit = botAI->GetUnit(sRandomPlayerbotMgr->GetBattleMasterGUID(bot, bgTypeId));
|
|
if (!unit && isArena)
|
|
{
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
LOG_DEBUG("playerbots", "Bot {} could not find Battlemaster to join", bot->GetGUID().ToString().c_str());
|
|
return false;
|
|
}
|
|
|
|
// refresh food/regs
|
|
sRandomPlayerbotMgr->Refresh(bot);
|
|
|
|
bool joinAsGroup = bot->GetGroup() && bot->GetGroup()->GetLeaderGUID() == bot->GetGUID();
|
|
|
|
// in wotlk only arena requires battlemaster guid
|
|
ObjectGuid guid = isArena ? unit->GetGUID() : bot->GetGUID();
|
|
|
|
switch (bgTypeId)
|
|
{
|
|
case BATTLEGROUND_AV:
|
|
_bgType = "AV";
|
|
break;
|
|
case BATTLEGROUND_WS:
|
|
_bgType = "WSG";
|
|
break;
|
|
case BATTLEGROUND_AB:
|
|
_bgType = "AB";
|
|
break;
|
|
case BATTLEGROUND_EY:
|
|
_bgType = "EotS";
|
|
break;
|
|
case BATTLEGROUND_RB:
|
|
_bgType = "Random";
|
|
break;
|
|
case BATTLEGROUND_SA:
|
|
_bgType = "SotA";
|
|
break;
|
|
case BATTLEGROUND_IC:
|
|
_bgType = "IoC";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (isArena)
|
|
{
|
|
isArena = true;
|
|
BracketSize = type * 2;
|
|
TeamSize = type;
|
|
isRated = botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Get();
|
|
|
|
if (joinAsGroup)
|
|
asGroup = true;
|
|
|
|
switch (arenaType)
|
|
{
|
|
case ARENA_TYPE_2v2:
|
|
arenaslot = 0;
|
|
_bgType = "2v2";
|
|
break;
|
|
case ARENA_TYPE_3v3:
|
|
arenaslot = 1;
|
|
_bgType = "3v3";
|
|
break;
|
|
case ARENA_TYPE_5v5:
|
|
arenaslot = 2;
|
|
_bgType = "5v5";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> queued {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str(), _bgType.c_str(),
|
|
isRated ? "Rated Arena" : isArena ? "Arena" : "");
|
|
|
|
|
|
if (isArena)
|
|
{
|
|
if (isRated)
|
|
{
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] += TeamSize;
|
|
sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId] += TeamSize;
|
|
}
|
|
else
|
|
{
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE]++;
|
|
sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId]++;
|
|
}
|
|
}
|
|
else if (!joinAsGroup)
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]++;
|
|
else
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId] += bot->GetGroup()->GetMembersCount();
|
|
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
|
|
if (!isArena)
|
|
{
|
|
WorldPacket packet(CMSG_BATTLEMASTER_JOIN, 20);
|
|
packet << bot->GetGUID() << bgTypeId_ << instanceId << joinAsGroup;
|
|
bot->GetSession()->HandleBattlemasterJoinOpcode(packet);
|
|
}
|
|
else
|
|
{
|
|
WorldPacket arena_packet(CMSG_BATTLEMASTER_JOIN_ARENA, 20);
|
|
arena_packet << unit->GetGUID() << arenaslot << asGroup << uint8(isRated);
|
|
bot->GetSession()->HandleBattlemasterJoinArena(arena_packet);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId)
|
|
{
|
|
BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
|
|
if (!bg)
|
|
return false;
|
|
|
|
bool isArena = false;
|
|
bool isRated = false;
|
|
|
|
ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
|
if (type != ARENA_TYPE_NONE)
|
|
isArena = true;
|
|
|
|
uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2;
|
|
uint32 TeamSize = bg->GetMaxPlayersPerTeam();
|
|
|
|
uint32 ACount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE];
|
|
uint32 HCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
|
|
uint32 BgCount = ACount + HCount;
|
|
uint32 SCount, RCount = 0;
|
|
|
|
TeamId teamId = bot->GetTeamId();
|
|
|
|
if (isArena)
|
|
{
|
|
uint32 rated_players = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
if (rated_players)
|
|
{
|
|
isRated = true;
|
|
}
|
|
|
|
isArena = true;
|
|
BracketSize = (uint32)(type * 2);
|
|
TeamSize = type;
|
|
ACount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_ALLIANCE];
|
|
HCount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_HORDE];
|
|
BgCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE];
|
|
SCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE];
|
|
RCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE];
|
|
}
|
|
|
|
// do not try if not a captain of arena team
|
|
|
|
if (isRated)
|
|
{
|
|
if (!sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID()))
|
|
return false;
|
|
|
|
// check if bot has correct team
|
|
ArenaTeam* arenateam = nullptr;
|
|
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
|
|
{
|
|
ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot));
|
|
if (!temp)
|
|
continue;
|
|
|
|
if (temp->GetType() != type)
|
|
continue;
|
|
|
|
arenateam = temp;
|
|
}
|
|
|
|
if (!arenateam)
|
|
return false;
|
|
|
|
ratedList.push_back(queueTypeId);
|
|
}
|
|
|
|
// hack fix crash in queue remove event
|
|
if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID()))
|
|
return false;
|
|
|
|
bool needBots = sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId];
|
|
|
|
// add more bots if players are not invited or 1st BG instance is full
|
|
if (needBots/* || (hasPlayers && BgCount > BracketSize && (BgCount % BracketSize) != 0)*/)
|
|
return true;
|
|
|
|
// do not join if BG queue is full
|
|
if (BgCount >= BracketSize && (ACount >= TeamSize) && (HCount >= TeamSize))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!isArena && ((ACount >= TeamSize && teamId == TEAM_ALLIANCE) || (HCount >= TeamSize && teamId == TEAM_HORDE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && (((ACount >= TeamSize && HCount > 0) && teamId == TEAM_ALLIANCE) || ((HCount >= TeamSize && ACount > 0) && teamId == TEAM_HORDE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && (((ACount > TeamSize && HCount == 0) && teamId == TEAM_HORDE) || ((HCount > TeamSize && ACount == 0) && teamId == TEAM_ALLIANCE)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (isArena && ((!isRated && SCount >= BracketSize) || (isRated && RCount >= BracketSize)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGLeaveAction::Execute(Event event)
|
|
{
|
|
if (!(bot->InBattlegroundQueue() || bot->InBattleground()))
|
|
return false;
|
|
|
|
//botAI->ChangeStrategy("-bg", BOT_STATE_NON_COMBAT);
|
|
|
|
BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(0);
|
|
BattlegroundTypeId _bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
uint8 type = false;
|
|
uint16 unk = 0x1F90;
|
|
uint8 unk2 = 0x0;
|
|
bool isArena = false;
|
|
bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
|
|
|
|
ArenaType arenaType = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
|
if (arenaType)
|
|
{
|
|
isArena = true;
|
|
type = arenaType;
|
|
}
|
|
|
|
if (bot->InBattleground())
|
|
{
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> leaves {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG");
|
|
|
|
WorldPacket leave(CMSG_LEAVE_BATTLEFIELD);
|
|
leave << uint8(0) << uint8(0) << uint32(0) << uint16(0);
|
|
bot->GetSession()->HandleBattlefieldLeaveOpcode(leave);
|
|
|
|
if (IsRandomBot)
|
|
botAI->SetMaster(nullptr);
|
|
|
|
botAI->ResetStrategies(!IsRandomBot);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg role")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Set(0);
|
|
|
|
return true;
|
|
}
|
|
|
|
uint32 queueType = AI_VALUE(uint32, "bg type");
|
|
if (!queueType)
|
|
return false;
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> leaves {} queue",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str(), isArena ? "Arena" : "BG");
|
|
|
|
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
|
|
packet << type << unk2 << (uint32)_bgTypeId << unk << uint8(0);
|
|
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
|
|
|
|
if (IsRandomBot)
|
|
botAI->SetMaster(nullptr);
|
|
|
|
botAI->ResetStrategies(!IsRandomBot);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg role")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Set(0);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGStatusAction::isUseful()
|
|
{
|
|
return bot->InBattlegroundQueue();
|
|
}
|
|
|
|
bool BGStatusAction::Execute(Event event)
|
|
{
|
|
uint32 QueueSlot;
|
|
uint32 instanceId;
|
|
uint32 mapId;
|
|
uint32 statusid;
|
|
uint32 Time1;
|
|
uint32 Time2;
|
|
std::string _bgType;
|
|
|
|
uint64 arenaByte;
|
|
uint8 arenaTeam;
|
|
uint8 isRated;
|
|
uint64 unk0;
|
|
uint8 minlevel;
|
|
uint8 maxlevel;
|
|
|
|
WorldPacket p(event.getPacket());
|
|
statusid = 0;
|
|
p >> QueueSlot; // queue id (0...2) - player can be in 3 queues in time
|
|
p >> arenaByte;
|
|
if (arenaByte == 0)
|
|
return false;
|
|
p >> minlevel;
|
|
p >> maxlevel;
|
|
p >> instanceId;
|
|
p >> isRated;
|
|
p >> statusid;
|
|
|
|
// check status
|
|
switch (statusid)
|
|
{
|
|
case STATUS_WAIT_QUEUE: // status_in_queue
|
|
p >> Time1; // average wait time, milliseconds
|
|
p >> Time2; // time in queue, updated every minute!, milliseconds
|
|
break;
|
|
case STATUS_WAIT_JOIN: // status_invite
|
|
p >> mapId; // map id
|
|
p >> unk0;
|
|
p >> Time1; // time to remove from queue, milliseconds
|
|
break;
|
|
case STATUS_IN_PROGRESS: // status_in_progress
|
|
p >> mapId; // map id
|
|
p >> unk0;
|
|
p >> Time1; // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds
|
|
p >> Time2; // time from bg start, milliseconds
|
|
p >> arenaTeam;
|
|
break;
|
|
default:
|
|
LOG_ERROR("playerbots", "Unknown BG status!");
|
|
break;
|
|
}
|
|
|
|
bool IsRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
|
|
BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(QueueSlot);
|
|
BattlegroundTypeId _bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId);
|
|
if (!queueTypeId)
|
|
return false;
|
|
|
|
BattlegroundBracketId bracketId;
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(_bgTypeId);
|
|
mapId = bg->GetMapId();
|
|
PvPDifficultyEntry const* pvpDiff = GetBattlegroundBracketByLevel(mapId, bot->getLevel());
|
|
if (pvpDiff)
|
|
bracketId = pvpDiff->GetBracketId();
|
|
|
|
bool isArena = false;
|
|
uint8 type = false; // arenatype if arena
|
|
uint16 unk = 0x1F90;
|
|
uint8 unk2 = 0x0;
|
|
uint8 action = 0x1;
|
|
|
|
ArenaType arenaType = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId));
|
|
if (arenaType)
|
|
{
|
|
isArena = true;
|
|
type = arenaType;
|
|
}
|
|
|
|
switch (_bgTypeId)
|
|
{
|
|
case BATTLEGROUND_AV:
|
|
_bgType = "AV";
|
|
break;
|
|
case BATTLEGROUND_WS:
|
|
_bgType = "WSG";
|
|
break;
|
|
case BATTLEGROUND_AB:
|
|
_bgType = "AB";
|
|
break;
|
|
case BATTLEGROUND_EY:
|
|
_bgType = "EotS";
|
|
break;
|
|
case BATTLEGROUND_RB:
|
|
_bgType = "Random";
|
|
break;
|
|
case BATTLEGROUND_SA:
|
|
_bgType = "SotA";
|
|
break;
|
|
case BATTLEGROUND_IC:
|
|
_bgType = "IoC";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (arenaType)
|
|
{
|
|
case ARENA_TYPE_2v2:
|
|
_bgType = "2v2";
|
|
break;
|
|
case ARENA_TYPE_3v3:
|
|
_bgType = "3v3";
|
|
break;
|
|
case ARENA_TYPE_5v5:
|
|
_bgType = "5v5";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
TeamId teamId = bot->GetTeamId();
|
|
|
|
if (Time1 == TIME_TO_AUTOREMOVE) //Battleground is over, bot needs to leave
|
|
{
|
|
LOG_INFO("playerbots", "Bot {} <{}> ({} {}): Received BG status TIME_REMOVE for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetName(), bot->getLevel(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", isArena ? "Arena" : "BG", _bgType);
|
|
|
|
if (Battleground* bg = bot->GetBattleground())
|
|
{
|
|
if (isArena)
|
|
{
|
|
sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId]--;
|
|
teamId = isRated ? TEAM_HORDE : TEAM_ALLIANCE;
|
|
}
|
|
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]--;
|
|
sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][teamId] = 0;
|
|
}
|
|
|
|
// remove warsong strategy
|
|
if (IsRandomBot)
|
|
botAI->SetMaster(nullptr);
|
|
|
|
botAI->ChangeStrategy("-warsong", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-warsong", BOT_STATE_NON_COMBAT);
|
|
botAI->ChangeStrategy("-arathi", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-arathi", BOT_STATE_NON_COMBAT);
|
|
botAI->ChangeStrategy("-eye", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-eye", BOT_STATE_NON_COMBAT);
|
|
botAI->ChangeStrategy("-isle", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-isle", BOT_STATE_NON_COMBAT);
|
|
botAI->ChangeStrategy("-Battleground", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-Battleground", BOT_STATE_NON_COMBAT);
|
|
botAI->ChangeStrategy("-arena", BOT_STATE_COMBAT);
|
|
botAI->ChangeStrategy("-arena", BOT_STATE_NON_COMBAT);
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> leaves {} - {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
|
|
WorldPacket packet(CMSG_LEAVE_BATTLEFIELD);
|
|
packet << uint8(0);
|
|
packet << uint8(0); // BattlegroundTypeId-1 ?
|
|
packet << uint32(0);
|
|
packet << uint16(0);
|
|
|
|
bot->GetSession()->HandleBattlefieldLeaveOpcode(packet);
|
|
|
|
botAI->ResetStrategies(!IsRandomBot);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg role")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Set(0);
|
|
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
|
|
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()["bg objective"];
|
|
pos.Reset();
|
|
posMap["bg objective"] = pos;
|
|
}
|
|
|
|
if (statusid == STATUS_WAIT_QUEUE) // bot is in queue
|
|
{
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Received BG status WAIT_QUEUE (wait time: {}) for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), Time2, isArena ? "Arena" : "BG", _bgType);
|
|
// temp fix for crash
|
|
//return true;
|
|
|
|
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(queueTypeId);
|
|
GroupQueueInfo ginfo;
|
|
if (bgQueue.GetPlayerGroupInfoData(bot->GetGUID(), &ginfo))
|
|
{
|
|
if (ginfo.IsInvitedToBGInstanceGUID && !bot->InBattleground())
|
|
{
|
|
// BattlegroundMgr::GetBattleground() does not return battleground if bgTypeId==BATTLEGROUND_AA
|
|
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, _bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : _bgTypeId);
|
|
if (bg)
|
|
{
|
|
if (isArena)
|
|
{
|
|
_bgTypeId = bg->GetBgTypeID();
|
|
}
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Force join {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
WorldPacket emptyPacket;
|
|
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
|
action = 0x1;
|
|
|
|
// bg started so players should get invites by now
|
|
sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? TeamId(isRated) : bot->GetTeamId()] = false;
|
|
|
|
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
|
|
packet << type << unk2 << (uint32)_bgTypeId << unk << action;
|
|
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
|
|
|
|
botAI->ResetStrategies(false);
|
|
if (!bot->GetBattleground()) {
|
|
// first bot to join wont have battleground and PlayerbotAI::ResetStrategies() wont set them up properly, set bg for "bg strategy check" to fix that
|
|
botAI->ChangeStrategy("+bg", BOT_STATE_NON_COMBAT);
|
|
}
|
|
context->GetValue<uint32>("bg role")->Set(urand(0, 9));
|
|
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
|
|
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()["bg objective"];
|
|
pos.Reset();
|
|
posMap["bg objective"] = pos;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(_bgTypeId);
|
|
if (!bg)
|
|
return false;
|
|
|
|
bool leaveQ = false;
|
|
uint32 timer;
|
|
if (isArena)
|
|
timer = TIME_TO_AUTOREMOVE;
|
|
else
|
|
timer = TIME_TO_AUTOREMOVE + 1000 * (bg->GetMaxPlayersPerTeam() * 8);
|
|
|
|
if (Time2 > timer && isArena) // disabled for BG
|
|
leaveQ = true;
|
|
|
|
if (leaveQ && ((bot->GetGroup() && bot->GetGroup()->IsLeader(bot->GetGUID())) || !(bot->GetGroup() || botAI->GetMaster())))
|
|
{
|
|
TeamId teamId = bot->GetTeamId();
|
|
bool realPlayers = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][teamId];
|
|
if (realPlayers)
|
|
return false;
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> waited too long and leaves queue ({} {}).",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
|
|
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
|
|
action = 0;
|
|
packet << type << unk2 << (uint32)_bgTypeId << unk << action;
|
|
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
|
|
|
|
botAI->ResetStrategies(!IsRandomBot);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("bg role")->Set(0);
|
|
botAI->GetAiObjectContext()->GetValue<uint32>("arena type")->Set(0);
|
|
sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]--;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (statusid == STATUS_IN_PROGRESS) // placeholder for Leave BG if it takes too long
|
|
{
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Received BG status IN_PROGRESS for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
return false;
|
|
}
|
|
|
|
if (statusid == STATUS_WAIT_JOIN) //bot may join
|
|
{
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: Received BG status WAIT_JOIN for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
|
|
if (isArena)
|
|
{
|
|
isArena = true;
|
|
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(queueTypeId);
|
|
|
|
GroupQueueInfo ginfo;
|
|
if (!bgQueue.GetPlayerGroupInfoData(bot->GetGUID(), &ginfo))
|
|
{
|
|
LOG_ERROR("playerbots", "Bot {} {}:{} <{}>: Missing QueueInfo for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
return false;
|
|
}
|
|
|
|
if (ginfo.IsInvitedToBGInstanceGUID)
|
|
{
|
|
// BattlegroundMgr::GetBattleground() does not return battleground if bgTypeId==BATTLEGROUND_AA
|
|
Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, _bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : _bgTypeId);
|
|
if (!bg)
|
|
{
|
|
LOG_ERROR("playerbots", "Bot {} {}:{} <{}>: Missing QueueInfo for {} {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
return false;
|
|
}
|
|
|
|
_bgTypeId = bg->GetBgTypeID();
|
|
}
|
|
}
|
|
|
|
LOG_INFO("playerbots", "Bot {} {}:{} <{}> joined {} - {}",
|
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName(), isArena ? "Arena" : "BG", _bgType);
|
|
|
|
WorldPacket emptyPacket;
|
|
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
|
|
|
|
action = 0x1;
|
|
|
|
// bg started so players should get invites by now
|
|
sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId] = false;
|
|
|
|
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
|
|
packet << type << unk2 << (uint32)_bgTypeId << unk << action;
|
|
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
|
|
|
|
botAI->ResetStrategies(false);
|
|
if (!bot->GetBattleground()) {
|
|
// first bot to join wont have battleground and PlayerbotAI::ResetStrategies() wont set them up properly, set bg for "bg strategy check" to fix that
|
|
botAI->ChangeStrategy("+bg", BOT_STATE_NON_COMBAT);
|
|
}
|
|
context->GetValue<uint32>("bg role")->Set(urand(0, 9));
|
|
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
|
|
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()["bg objective"];
|
|
PositionInfo pos2 = context->GetValue<PositionMap&>("position")->Get()["bg siege"];
|
|
pos.Reset();
|
|
pos2.Reset();
|
|
posMap["bg objective"] = pos;
|
|
posMap["bg siege"] = pos2;
|
|
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGStatusCheckAction::Execute(Event event)
|
|
{
|
|
if (bot->IsBeingTeleported())
|
|
return false;
|
|
|
|
WorldPacket packet(CMSG_BATTLEFIELD_STATUS);
|
|
bot->GetSession()->HandleBattlefieldStatusOpcode(packet);
|
|
|
|
LOG_INFO("playerbots", "Bot {} <{}> ({} {}) : Checking BG invite status",
|
|
bot->GetGUID().ToString().c_str(), bot->GetName(), bot->getLevel(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BGStatusCheckAction::isUseful()
|
|
{
|
|
return bot->InBattlegroundQueue();
|
|
}
|
|
|
|
bool BGStrategyCheckAction::Execute(Event event)
|
|
{
|
|
bool inside_bg = bot->InBattleground() && bot->GetBattleground();;
|
|
if (!inside_bg && botAI->HasStrategy("battleground", BOT_STATE_NON_COMBAT)) {
|
|
botAI->ResetStrategies();
|
|
return true;
|
|
}
|
|
if (inside_bg && !botAI->HasStrategy("battleground", BOT_STATE_NON_COMBAT)) {
|
|
botAI->ResetStrategies();
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|