void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket) { uint32 team = GetPlayerTeam(guid); // Remove from lists/maps std::map::iterator itr = m_Players.find(guid); if(itr != m_Players.end()) { UpdatePlayersCountByTeam(team, true); // -1 player m_Players.erase(itr); } std::map::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(); }