void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
{
uint32 team = GetPlayerTeam(guid);
// Remove from lists/maps
std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid);
if(itr != m_Players.end())
{
UpdatePlayersCountByTeam(team, true); // -1 player
m_Players.erase(itr);
}
std::map<uint64, BattleGroundScore*>::iterator itr2 = m_PlayerScores.find(guid);
if(itr2 != m_PlayerScores.end())
{
delete itr2->second; // delete player's score
m_PlayerScores.erase(itr2);
}
RemovePlayerFromResurrectQueue(guid);
Player *plr = objmgr.GetPlayer(guid);
// should remove spirit of redemption
if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
if(plr && !plr->isAlive()) // resurrect on exit
{
plr->ResurrectPlayer(1.0f);
plr->SpawnCorpseBones();
}
RemovePlayer(plr, guid); // BG subclass specific code
if(plr)
{
if(!team) team = plr->GetTeam();
uint32 bgTypeId = GetTypeID();
if(isArena())
{
if(!sWorld.IsFFAPvPRealm())
plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
plr->RemoveAurasDueToSpell(SPELL_ALLIANCE_GOLD_FLAG);
plr->RemoveAurasDueToSpell(SPELL_ALLIANCE_GREEN_FLAG);
plr->RemoveAurasDueToSpell(SPELL_HORDE_GOLD_FLAG);
plr->RemoveAurasDueToSpell(SPELL_HORDE_GREEN_FLAG);
bgTypeId=BATTLEGROUND_AA;
Pet* NewPet = new Pet(plr);
if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetOldPetNumber(), true))
delete NewPet;
(plr)->SetOldPetNumber(0);
}
WorldPacket data;
if(SendPacket)
{
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgTypeId), STATUS_NONE, 0, 0);
plr->GetSession()->SendPacket(&data);
}
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
plr->RemoveBattleGroundQueueId(bgTypeId);
DecreaseInvitedCount(team);
//we should update battleground queue, but only if bg isn't ending
if (GetQueueType() < MAX_BATTLEGROUND_QUEUES)
sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].Update(bgTypeId, GetQueueType());
if(!plr->GetBattleGroundId())
return;
Group * group = plr->GetGroup();
// remove from raid group if exist
if(group && group == GetBgRaid(team))
{
uint32 groupSize = group->GetMembersCount();
GroupReference * grpRef = group->GetFirstMember();
Player * grpGuy = grpRef->getSource();
if(grpGuy->GetGUID()==guid)
{
if(grpRef->hasNext())
{
grpRef = grpRef->next();
grpGuy = grpRef->getSource();
}
else if(grpRef->hasPrev())
{
grpRef = (GroupReference*)grpRef->prev();
grpGuy = grpRef->getSource();
}
else
grpGuy = NULL;
}
if(!group->RemoveMember(guid, 0)) // group was disbanded
{
SetBgRaid(team, NULL);
delete group;
if(groupSize >= 2 && grpGuy != 0) // someone's still left in the bg, recreate group for him
{
Group *group = new Group;
SetBgRaid(team, group);
group->ConvertToRaid();
group->AddMember(grpGuy->GetGUID(), grpGuy->GetName());
group->ChangeLeader(grpGuy->GetGUID());
}
}
}
// Do next only if found in battleground
plr->SetBattleGroundId(0); // We're not in BG.
// Let others know
sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr);
SendPacketToTeam(team, &data, plr, false);
if(Transport)
{
plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO(), true, false);
//plr->SetInstanceId(plr->GetBattleGroundEntryPointInstanceId());
//sLog.outDetail("BATTLEGROUND: Sending %s to %f,%f,%f,%f", pl->GetName(), x,y,z,O);
}
// Log
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
}
// remove player from bg instance!
CharacterDatabase.PExecute("DELETE FROM `character_instance` WHERE `guid` = '%u' AND `instance` = '%u'", guid, GetInstanceID());
if(plr)
{
// remove player from bg instance!!!
plr->m_BoundInstances.erase(GetMapId());
}
/// there will be code which will add battleground to BGFreeSlotQueue , when battleground instance will exist
// we always should check if BG is in that queue before adding..
if(!GetPlayersSize())
{
// // no one left, cleanup and reinit instance
// Reset();
// if(!SetupBattleGround())
// {
// // setup failed, remove battleground.
m_SetDeleteThis = true;
return;
// }
}
// a player exited the battleground, so there are free slots. add to queue
this->AddToBGFreeSlotQueue();
}