All pastes #991101 Raw Edit

Stuff

public diff v1 · immutable
#991101 ·published 2008-04-20 18:47 UTC
rendered paste body
Index: src/game/BattleGround.cpp===================================================================--- src/game/BattleGround.cpp	(revision 5051)+++ src/game/BattleGround.cpp	(working copy)@@ -29,6 +29,7 @@ BattleGround::BattleGround() {     m_TypeID            = 0;+    m_TeamType          = 0;     m_InstanceID        = 0;     m_Status            = 0;     m_EndTime           = 0;@@ -45,6 +46,8 @@     m_Name              = "";     m_LevelMin          = 0;     m_LevelMax          = 0;+    m_InBGFreeSlotQueue = false;+    m_SetDeleteThis     = false;      m_MaxPlayersPerTeam = 0;     m_MaxPlayers        = 0;@@ -74,7 +77,17 @@  BattleGround::~BattleGround() {-+    // delete bound char instances (this should have been already deleted?)+    CharacterDatabase.PExecute("DELETE FROM `character_instance` WHERE `instance` = '%u'", GetInstanceID());+    // delete creature and go respawn times+    WorldDatabase.PExecute("DELETE FROM `creature_respawn` WHERE `instance` = '%u'",GetInstanceID());+    WorldDatabase.PExecute("DELETE FROM `gameobject_respawn` WHERE `instance` = '%u'",GetInstanceID());+    // delete instance from db+    CharacterDatabase.PExecute("DELETE FROM `instance` WHERE id = '%u'",GetInstanceID());+    // remove from battlegrounds+    sBattleGroundMgr.RemoveBattleGround(GetInstanceID());+    // remove from bg free slot queue+    this->RemoveFromBGFreeSlotQueue(); }  void BattleGround::Update(time_t diff)@@ -236,7 +249,10 @@         if(!self && sender == plr)             continue; -        if(plr->GetTeam() == TeamID)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        if(team == TeamID)             plr->GetSession()->SendPacket(packet);     } }@@ -262,7 +278,10 @@             continue;         } -        if(plr->GetTeam() == TeamID)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        if(team == TeamID)         {             sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID);             plr->GetSession()->SendPacket(&data);@@ -282,7 +301,10 @@             continue;         } -        if(plr->GetTeam() == TeamID)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();+       +        if(team == TeamID)             plr->CastSpell(plr, SpellID, true);     } }@@ -299,7 +321,10 @@             continue;         } -        if(plr->GetTeam() == TeamID)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        if(team == TeamID)             UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor);     } }@@ -321,7 +346,10 @@             continue;         } -        if(plr->GetTeam() == TeamID)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        if(team == TeamID)             plr->ModifyFactionReputation(factionEntry, Reputation);     } }@@ -335,6 +363,8 @@  void BattleGround::EndBattleGround(uint32 winner) {+    this->RemoveFromBGFreeSlotQueue();+     WorldPacket data;     Player *Source = NULL;     const char *winmsg = "";@@ -376,7 +406,10 @@             plr->SpawnCorpseBones();         } -        if(plr->GetTeam() == winner)+        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        if(team == winner)         {             if(!Source)                 Source = plr;@@ -428,7 +461,12 @@         sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);         plr->GetSession()->SendPacket(&data); -        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());+        uint32 bgTypeId = m_TypeID;+        if( m_TypeID == BATTLEGROUND_NA ||+            m_TypeID == BATTLEGROUND_RL ||+            m_TypeID == BATTLEGROUND_BE )+            bgTypeId = BATTLEGROUND_AA;+        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());         plr->GetSession()->SendPacket(&data);     } @@ -477,39 +515,68 @@      if(plr)     {+        uint32 team = GetPlayerTeam(plr->GetGUID());+        if(!team) team = plr->GetTeam();++        uint32 bgTypeId = GetTypeID();         if(isArena())         {-            plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);             plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);+            bgTypeId=BATTLEGROUND_AA;         }          WorldPacket data;         if(SendPacket)         {-            sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0);+            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(m_TypeID);+        plr->RemoveBattleGroundQueueId(bgTypeId); -        DecreaseInvitedCount(plr->GetTeam());+        DecreaseInvitedCount(team);         //we should update battleground queue, but only if bg isn't ending         if (GetQueueType() < MAX_BATTLEGROUND_QUEUES)-            sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].Update(GetTypeID(), GetQueueType());+            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(plr->GetTeam()))+        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(plr->GetTeam(), NULL);+                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());+                }             }         } @@ -518,11 +585,12 @@          // Let others know         sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr);-        SendPacketToTeam(plr->GetTeam(), &data, plr, false);+        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);         } @@ -530,13 +598,32 @@         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())     {-        Reset();+   //     // 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(); }  // this method is called when no players remains in battleground@@ -548,6 +635,9 @@     SetStartTime(0);     SetEndTime(0);     SetLastResurrectTime(0);+    SetTeamType(BG_TEAM_TYPE_NORMAL);+    SetArenaType(0);+    SetRated(false);      m_Events = 0; @@ -556,6 +646,7 @@      m_InvitedAlliance = 0;     m_InvitedHorde = 0;+    m_InBGFreeSlotQueue = false;      m_Players.clear();     m_PlayerScores.clear();@@ -573,43 +664,28 @@      WorldPacket data;     BattleGround *bg = NULL;--    /// this code seems not correct:-    if(GetTypeID() == BATTLEGROUND_AA)-    {-        // we must select one of running arena-        uint8 arenas[3] = { BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL };-        uint8 arena_type = arenas[urand(0, 2)];--        bg = sBattleGroundMgr.GetBattleGround(arena_type);-        if(!bg)-            return;--        bg->SetStatus(STATUS_WAIT_JOIN);--        bg->SetStartTime(0);-        bg->SetLastResurrectTime(0);-    } } -void BattleGround::AddPlayer(Player *plr)+void BattleGround::AddPlayer(Player *plr, uint32 team) {     // score struct must be created in inherited class+    if(team==0)+        team = plr->GetTeam();      uint64 guid = plr->GetGUID();      BattleGroundPlayer bp;     bp.LastOnlineTime = 0;-    bp.Team = plr->GetTeam();+    bp.Team = team;      // Add to list/maps     m_Players[guid] = bp; -    UpdatePlayersCountByTeam(plr->GetTeam(), false);        // +1 player+    UpdatePlayersCountByTeam(team, false);        // +1 player      WorldPacket data;     sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr);-    SendPacketToTeam(plr->GetTeam(), &data, plr, false);+    SendPacketToTeam(team, &data, plr, false);      if(isArena())     {@@ -618,7 +694,6 @@             // temporary disabled             //plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true);         }-        plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);     }      // Log@@ -628,13 +703,18 @@ /* This method should be called only once ... it adds pointer to queue */ void BattleGround::AddToBGFreeSlotQueue() {-    sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);+    if(!m_InBGFreeSlotQueue)+    {+        sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);+        m_InBGFreeSlotQueue = true;+    } }  /* This method removes this battleground from free queue - it must be called when deleting battleground - not used now*/ void BattleGround::RemoveFromBGFreeSlotQueue() {-    /* uncomment this code when battlegrounds will work like instances+    m_InBGFreeSlotQueue = false;+    // uncomment this code when battlegrounds will work like instances     for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)     {         if ((*itr)->GetInstanceID() == m_InstanceID)@@ -642,7 +722,7 @@             sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].erase(itr);             return;         }-    }*/+    } }  /*@@ -745,7 +825,7 @@  bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 spawntime) {-    GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);+/*    GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);     if(!goinfo)     {         sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry);@@ -769,16 +849,33 @@     data.spawntimesecs  = spawntime;     data.animprogress   = 100;     data.go_state       = 1;-    objmgr.AddGameobjectToGrid(guid, &data); +//    objmgr.AddGameobjectToGrid(guid, &data);+     m_BgObjects[type] = MAKE_GUID(guid, HIGHGUID_GAMEOBJECT); +/*    GameObject * go = ObjectAccessor::Instance().GetObjectInWorld(m_BgObjects[type], (GameObject*)NULL);+    go->SetInstanceId(GetInstanceID());//*/++    GameObject * go = new GameObject(NULL);+    go->SetInstanceId(GetInstanceID());+    if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, GetMapId(),x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))+    {+        sLog.outErrorDb("Cannot create gameobject template %u! BattleGround not created!", entry);+        delete go;+        return false;+    }++//    objmgr.SaveGORespawnTime(go->GetGUIDLow(),go->GetInstanceId(),spawntime);+//    MapManager::Instance().GetMap(go->GetMapId(), go)->Add(go);++    m_BgObjects[type] = go;//*/     return true; }  void BattleGround::DoorOpen(uint32 type) {-    GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);+    GameObject *obj = m_BgObjects[type];     if(obj)     {         obj->SetUInt32Value(GAMEOBJECT_FLAGS,33);@@ -795,32 +892,35 @@ {     if(respawntime == 0)     {-        GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);+        GameObject *obj = m_BgObjects[type];         if(obj)         {             //obj->Respawn();                               // bugged             obj->SetRespawnTime(0);-            objmgr.SaveGORespawnTime(obj->GetGUIDLow(), 0, 0);+            objmgr.SaveGORespawnTime(obj->GetGUIDLow(), GetInstanceID(), 0);+            MapManager::Instance().GetMap(obj->GetMapId(), obj)->Add(obj);         }-        else-            objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, 0);+//        else+//            objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), GetInstanceID(), 0);     }     else     {-        GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);+        GameObject *obj = m_BgObjects[type];         if(obj)         {             obj->SetRespawnTime(respawntime);             obj->SetLootState(GO_LOOTED);+            MapManager::Instance().GetMap(obj->GetMapId(), obj)->Add(obj);         }-        else-            objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, time(NULL) + respawntime);+//        else+//            objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), GetInstanceID(), time(NULL) + respawntime);     } } -Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o)+Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime) {     Creature* pCreature = new Creature(NULL);+    pCreature->SetInstanceId(GetInstanceID());     if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMapId(), x, y, z, o, entry, teamval))     {         sLog.outError("Can't create creature entry: %u",entry);@@ -831,17 +931,47 @@     pCreature->AIM_Initialize();      //pCreature->SetDungeonDifficulty(0);-    MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);-    m_BgCreatures[type] = pCreature->GetGUID();+//    objmgr.SaveCreatureRespawnTime(pCreature->GetGUIDLow(), pCreature->GetInstanceId(), respawntime);+//    MapManager::Instance().GetMap(pCreature->GetMapId(), pCreature)->Add(pCreature);+    m_BgCreatures[type] = pCreature;     return  pCreature; } +void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)+{+    if(respawntime == 0)+    {+        Creature *obj = m_BgCreatures[type];+        if(obj)+        {+            //obj->Respawn();                               // bugged+            obj->SetRespawnTime(0);+            objmgr.SaveCreatureRespawnTime(obj->GetGUIDLow(), GetInstanceID(), 0);+            MapManager::Instance().GetMap(obj->GetMapId(), obj)->Add(obj);+        }+       // else+       //     objmgr.SaveCreatureRespawnTime(GUID_LOPART(m_BgCreatures[type]), GetInstanceID(), 0);+    }+    else+    {+        Creature *obj = m_BgCreatures[type];+        if(obj)+        {+            obj->setDeathState(DEAD);+            obj->SetRespawnTime(respawntime);+            MapManager::Instance().GetMap(obj->GetMapId(), obj)->Add(obj);+        }+       // else+       //     objmgr.SaveCreatureRespawnTime(GUID_LOPART(m_BgCreatures[type]), GetInstanceID(), time(NULL) + respawntime);+    }+}+ bool BattleGround::DelCreature(uint32 type) {-    Creature *cr = HashMapHolder<Creature>::Find(m_BgCreatures[type]);+    Creature *cr = m_BgCreatures[type];     if(!cr)     {-        sLog.outError("Can't find creature guid: %u",m_BgCreatures[type]);+        sLog.outError("Can't find creature.");         return false;     }     cr->CleanupsBeforeDelete();@@ -852,10 +982,10 @@  bool BattleGround::DelObject(uint32 type) {-    GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);+    GameObject *obj = m_BgObjects[type];     if(!obj)     {-        sLog.outError("Can't find gobject guid: %u",m_BgObjects[type]);+        sLog.outError("Can't find gobject.");         return false;     }     obj->SetRespawnTime(0);                                 // not save respawn time@@ -911,3 +1041,11 @@     SetStatus(STATUS_WAIT_LEAVE);     SetEndTime(TIME_TO_AUTOREMOVE); }++uint32 BattleGround::GetPlayerTeam(uint64 guid)+{+    std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);+    if(itr!=m_Players.end())+        return itr->second.Team;+    return 0;+}Index: src/game/BattleGround.h===================================================================--- src/game/BattleGround.h	(revision 5051)+++ src/game/BattleGround.h	(working copy)@@ -166,6 +166,13 @@     BG_TEAM_HORDE           = 1 }; +enum BattleGroundTeamType+{+    BG_TEAM_TYPE_NORMAL     = 0,    // one side is ally, other is horde+    BG_TEAM_TYPE_ALLIANCE_ONLY = 1, // both sides are alliance+    BG_TEAM_TYPE_HORDE_ONLY = 2     // both sides are horde+};+ class BattleGroundScore {     public:@@ -193,6 +200,7 @@     public:         /* Construction */         BattleGround();+        /*BattleGround(const BattleGround& bg);*/         virtual ~BattleGround();         virtual void Update(time_t diff);                   // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version         virtual bool SetupBattleGround()                    // must be implemented in BG subclass@@ -342,24 +350,30 @@         // must be implemented in BG subclass if need         virtual void HandleDropFlag(Player* /*player*/) {} -        virtual void AddPlayer(Player *plr);                // must be implemented in BG subclass+        virtual void AddPlayer(Player *plr, uint32 team = 0);                // must be implemented in BG subclass         virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket);                                                             // can be extended in in BG subclass          // TODO: make this protected:-        typedef std::vector<uint64> BGObjects;-        typedef std::vector<uint64> BGCreatures;+        typedef std::vector<GameObject*> BGObjects;+        typedef std::vector<Creature*> BGCreatures;         BGObjects m_BgObjects;         BGCreatures m_BgCreatures;         void SpawnBGObject(uint32 type, uint32 respawntime);+        void SpawnBGCreature(uint32 type, uint32 respawntime);         bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawntime = 0);-        Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o);+        Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime = 0);         bool DelCreature(uint32 type);         bool DelObject(uint32 type);         bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team);          void DoorOpen(uint32 type); +        uint32 GetPlayerTeam(uint64 guid);++        uint8 GetTeamType() const {return m_TeamType;}+        void SetTeamType(uint8 type){m_TeamType=type;}+     protected:         //this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround         void EndNow();@@ -387,6 +401,9 @@         uint32 m_LastResurrectTime;         uint32 m_Queue_type;         uint8  m_ArenaType;                                 // 2=2v2, 3=3v3, 5=5v5+        uint8  m_TeamType;+        bool   m_InBGFreeSlotQueue;+        bool   m_SetDeleteThis;         // this variable is not used .... it can be found in many other ways... but to store it in BG object instance is useless         //uint8  m_BattleGroundType;                        // 3=BG, 4=arena         //instead of uint8 (in previous line) is bool usedIndex: src/game/BattleGroundAA.cpp===================================================================--- src/game/BattleGroundAA.cpp	(revision 5051)+++ src/game/BattleGroundAA.cpp	(working copy)@@ -35,9 +35,9 @@     BattleGround::Update(diff); } -void BattleGroundAA::AddPlayer(Player *plr)+void BattleGroundAA::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr,team);     //create score and add it to map, default values are set in constructor     BattleGroundAAScore* sc = new BattleGroundAAScore; Index: src/game/BattleGroundAA.h===================================================================--- src/game/BattleGroundAA.h	(revision 5051)+++ src/game/BattleGroundAA.h	(working copy)@@ -38,7 +38,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);         void RemovePlayer(Player *plr, uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);         bool SetupBattleGround();Index: src/game/BattleGroundAB.cpp===================================================================--- src/game/BattleGroundAB.cpp	(revision 5051)+++ src/game/BattleGroundAB.cpp	(working copy)@@ -237,9 +237,9 @@     } } -void BattleGroundAB::AddPlayer(Player *plr)+void BattleGroundAB::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in the constructor     BattleGroundABScore* sc = new BattleGroundABScore; @@ -342,6 +342,7 @@         else goId = BG_AB_OBJECTID_BANNER_H;      m_bgobjects[obj] = new GameObject(NULL);+    m_bgobjects[obj]->SetInstanceId(GetInstanceID());     m_bgobjects[obj]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), goId, GetMapId(), BG_AB_NodePositions[node][0], BG_AB_NodePositions[node][1], BG_AB_NodePositions[node][2], BG_AB_NodePositions[node][3], 0, 0, sin(BG_AB_NodePositions[node][3]/2), cos(BG_AB_NodePositions[node][3]/2), 100, 1);     MapManager::Instance().GetMap(GetMapId(), m_bgobjects[obj])->Add(m_bgobjects[obj]); @@ -463,6 +464,7 @@     if (m_spiritGuides[node])         return;     m_spiritGuides[node] = new Creature(NULL);+    m_spiritGuides[node]->SetInstanceId(GetInstanceID());     if (!m_spiritGuides[node]->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), 529, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], (node>4)?BG_AB_SpiritGuideId[node-5]:BG_AB_SpiritGuideId[m_Nodes[node]-3], (node>4)?BG_AB_SpiritGuideTeamId[node-5]:BG_AB_SpiritGuideTeamId[m_Nodes[node]-3]))         ASSERT(0);     m_spiritGuides[node]->setDeathState(DEAD);@@ -626,6 +628,7 @@     for (int banner = BG_AB_OBJECT_BANNER_NEUTRAL, i = 0; i < 5; banner += 8, ++i)     {         m_bgobjects[banner] = new GameObject(NULL);+        m_bgobjects[banner]->SetInstanceId(GetInstanceID());         if(!m_bgobjects[banner]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_NODE_BANNER_0+i, GetMapId(), BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), 100, 1))            return false;     }@@ -634,27 +637,32 @@     for (int banner = BG_AB_OBJECT_AURA_ALLY, i = 0; i < 5; banner += 8, ++i)     {         m_bgobjects[banner] = new GameObject(NULL);+        m_bgobjects[banner]->SetInstanceId(GetInstanceID());         if(!m_bgobjects[banner]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_AURA_A, GetMapId(), BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), 0, 0))            return false;     }     for (int banner = BG_AB_OBJECT_AURA_HORDE, i = 0; i < 5; banner += 8, ++i)     {         m_bgobjects[banner] = new GameObject(NULL);+        m_bgobjects[banner]->SetInstanceId(GetInstanceID());         if(!m_bgobjects[banner]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_AURA_H, GetMapId(), BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), 0, 0))            return false;     }     for (int banner = BG_AB_OBJECT_AURA_CONTESTED, i = 0; i < 5; banner += 8, ++i)     {         m_bgobjects[banner] = new GameObject(NULL);+        m_bgobjects[banner]->SetInstanceId(GetInstanceID());         if(!m_bgobjects[banner]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_AURA_C, GetMapId(), BG_AB_NodePositions[i][0], BG_AB_NodePositions[i][1], BG_AB_NodePositions[i][2], BG_AB_NodePositions[i][3], 0, 0, sin(BG_AB_NodePositions[i][3]/2), cos(BG_AB_NodePositions[i][3]/2), 0, 0))            return false;     }      // Starting gates     m_bgobjects[BG_AB_OBJECT_GATE_A] = new GameObject(NULL);+    m_bgobjects[BG_AB_OBJECT_GATE_A]->SetInstanceId(GetInstanceID());     if(!m_bgobjects[BG_AB_OBJECT_GATE_A]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_GATE_A, GetMapId(), BG_AB_DoorPositions[0][0], BG_AB_DoorPositions[0][1], BG_AB_DoorPositions[0][2], BG_AB_DoorPositions[0][3], BG_AB_DoorPositions[0][4], BG_AB_DoorPositions[0][5], BG_AB_DoorPositions[0][6], BG_AB_DoorPositions[0][7], 100, 1))         return false;     m_bgobjects[BG_AB_OBJECT_GATE_H] = new GameObject(NULL);+    m_bgobjects[BG_AB_OBJECT_GATE_H]->SetInstanceId(GetInstanceID());     if(!m_bgobjects[BG_AB_OBJECT_GATE_H]->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), BG_AB_OBJECTID_GATE_H, GetMapId(), BG_AB_DoorPositions[1][0], BG_AB_DoorPositions[1][1], BG_AB_DoorPositions[1][2], BG_AB_DoorPositions[1][3], BG_AB_DoorPositions[1][4], BG_AB_DoorPositions[1][5], BG_AB_DoorPositions[1][6], BG_AB_DoorPositions[1][7], 100, 1))         return false; @@ -755,3 +763,4 @@ }  +Index: src/game/BattleGroundAB.h===================================================================--- src/game/BattleGroundAB.h	(revision 5051)+++ src/game/BattleGroundAB.h	(working copy)@@ -222,7 +222,7 @@         ~BattleGroundAB();          void Update(time_t diff);-        void AddPlayer(Player *plr);+        void AddPlayer(Player *plr, uint32 team = 0);         void RemovePlayer(Player *plr,uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);         virtual bool SetupBattleGround();Index: src/game/BattleGroundAV.cpp===================================================================--- src/game/BattleGroundAV.cpp	(revision 5051)+++ src/game/BattleGroundAV.cpp	(working copy)@@ -40,9 +40,9 @@     BattleGround::Update(diff); } -void BattleGroundAV::AddPlayer(Player *plr)+void BattleGroundAV::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in constructor     BattleGroundAVScore* sc = new BattleGroundAVScore; Index: src/game/BattleGroundAV.h===================================================================--- src/game/BattleGroundAV.h	(revision 5051)+++ src/game/BattleGroundAV.h	(working copy)@@ -45,7 +45,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          void RemovePlayer(Player *plr,uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);Index: src/game/BattleGroundBE.cpp===================================================================--- src/game/BattleGroundBE.cpp	(revision 5051)+++ src/game/BattleGroundBE.cpp	(working copy)@@ -98,9 +98,9 @@     }*/ } -void BattleGroundBE::AddPlayer(Player *plr)+void BattleGroundBE::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in constructor     BattleGroundBEScore* sc = new BattleGroundBEScore; @@ -123,14 +123,20 @@         return;     } -    uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());+    uint32 killer_team = GetPlayerTeam(killer->GetGUID());+    if(!killer_team) killer_team = killer->GetTeam(); +    uint32 killer_team_index = GetTeamIndexByTeamId(killer_team);+     m_TeamKills[killer_team_index]++;                       // add kills to killer's team -    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))+    uint32 team = GetPlayerTeam(player->GetGUID());+    if(!team) team = player->GetTeam();++    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(team))     {         // all opponents killed-        EndBattleGround(killer->GetTeam());+        EndBattleGround(killer_team);     } } @@ -141,14 +147,14 @@         return;      uint32 SpellId = 0;-    uint64 buff_guid = 0;+    GameObject* obj = 0;     switch(Trigger)     {         case 4538:                                          // buff trigger?-            buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_1];+            obj = m_BgObjects[BG_BE_OBJECT_BUFF_1];             break;         case 4539:                                          // buff trigger?-            buff_guid = m_BgObjects[BG_BE_OBJECT_BUFF_2];+            obj = m_BgObjects[BG_BE_OBJECT_BUFF_2];             break;         default:             sLog.outError("WARNING: Unhandled AreaTrigger in Battleground: %u", Trigger);@@ -156,11 +162,8 @@             break;     } -    if(buff_guid)+    if(obj)     {-        GameObject *obj = HashMapHolder<GameObject>::Find(buff_guid);-        if(obj)-        {             if(!obj->isSpawned())                 return;                                     // buff not spawned yet             obj->SetRespawnTime(BUFF_RESPAWN_TIME);@@ -168,7 +171,6 @@             SpellId = obj->GetGOInfo()->data3;             if(SpellId)                 Source->CastSpell(Source, SpellId, true);-        }     } } Index: src/game/BattleGroundBE.h===================================================================--- src/game/BattleGroundBE.h	(revision 5051)+++ src/game/BattleGroundBE.h	(working copy)@@ -58,7 +58,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          void RemovePlayer(Player *plr, uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);Index: src/game/BattleGroundEY.cpp===================================================================--- src/game/BattleGroundEY.cpp	(revision 5051)+++ src/game/BattleGroundEY.cpp	(working copy)@@ -40,9 +40,9 @@     BattleGround::Update(diff); } -void BattleGroundEY::AddPlayer(Player *plr)+void BattleGroundEY::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map     BattleGroundEYScore* sc = new BattleGroundEYScore; Index: src/game/BattleGroundEY.h===================================================================--- src/game/BattleGroundEY.h	(revision 5051)+++ src/game/BattleGroundEY.h	(working copy)@@ -39,7 +39,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          void RemovePlayer(Player *plr,uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);Index: src/game/BattleGroundHandler.cpp===================================================================--- src/game/BattleGroundHandler.cpp	(revision 5051)+++ src/game/BattleGroundHandler.cpp	(working copy)@@ -78,6 +78,12 @@     recv_data >> instanceId;                                // instance id, 0 if First Available selected     recv_data >> joinAsGroup;                               // join as group +    if(bgTypeId >= MAX_BATTLEGROUND_TYPES)+    {+        sLog.outError("bgport: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());+        return;+    }+     sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid);      // ignore if we already in BG or BG queue@@ -100,10 +106,15 @@         return;     } -    // check existence-    BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);-    if(!bg)+    BattleGround * bg = 0;+    if(instanceId)+        BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);++    if(!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))+    {+        sLog.outDebug("bgjoin: no available bg / template found");         return;+    }      if(joinAsGroup && _player->GetGroup())     {@@ -134,7 +145,7 @@             }              // store entry point coords (same as leader entry point)-            member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());+            member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetInstanceId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());                                                              // send status packet (in queue)             sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);@@ -159,7 +170,7 @@         }          // store entry point coords-        _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());+        _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetInstanceId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());          WorldPacket data;                                                             // send status packet (in queue)@@ -247,6 +258,12 @@     uint32 bgTypeId;     recv_data >> bgTypeId;                                  // id from DBC +    if(bgTypeId >= MAX_BATTLEGROUND_TYPES)+    {+        sLog.outError("bgport: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());+        return;+    }+     BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);      if(!bl)@@ -265,37 +282,78 @@      uint8 unk1;     uint8 unk2;                                             // unk, can be 0x0 (may be if was invited?) and 0x1+    uint32 instanceId;                                           uint32 bgTypeId;                                        // type id from dbc     uint16 unk;                                             // 0x1F90 constant?     uint8 action;                                           // enter battle 0x1, leave queue 0x0      recv_data >> unk1 >> unk2 >> bgTypeId >> unk >> action; -    BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);+    if(bgTypeId >= MAX_BATTLEGROUND_TYPES)+    {+        sLog.outError("bgport: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());+        return;+    }++    // get the bg what we were invited to +    uint32 bgQueueTypeId = bgTypeId;+    if( bgTypeId == BATTLEGROUND_NA ||+        bgTypeId == BATTLEGROUND_BE ||+        bgTypeId == BATTLEGROUND_RL )+        bgQueueTypeId = BATTLEGROUND_AA;+    BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());+    if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())+    {+        sLog.outDebug("bgport: itrplayerstatus not found.");+        return;+    }+    instanceId = itrPlayerStatus->second.IsInvitedToBGInstanceGUID;//*/++    if(!instanceId && action == 1)+    {+        sLog.outDebug("bgport: instance not found.");+        return;+    }++    BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);++    if(!bg && action == 0)+        bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);++    if(!bg)+    {+        sLog.outDebug("bgport: bg not found.");+        return;+    }++    bgTypeId = bg->GetTypeID();     if(bg)     {         if(_player->InBattleGroundQueue())         {             uint32 queueSlot = 0;+            uint32 team = 0;             WorldPacket data;             switch(action)             {                 case 1:                                     // port to battleground                     _player->RemoveFromGroup();-                    queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId);+                    queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);                     sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());                     _player->GetSession()->SendPacket(&data);+                    // get the team info from the queue+                    team = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID())->second.Team;                     // remove battleground queue status from BGmgr-                    sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), false);-                    // check if player is not deserter-                    if( !_player->CanJoinToBattleground() )+                    sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false);+                    // check if player is not deserter -- check in signup, not here!+                    /*if( !_player->CanJoinToBattleground() )                     {                         WorldPacket data2;                         data2.Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4);                         data2 << (uint32) 0xFFFFFFFE;                         SendPacket(&data2);                         return;-                    }+                    }*/                     // if player is in battleground already, remove him and port him to new battleground                     if ( _player->InBattleGround() )                     {@@ -303,15 +361,16 @@                         if (currentBg)                             currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);                     }-                    _player->SetBattleGroundId(bg->GetTypeID());-                    sBattleGroundMgr.SendToBattleGround(_player, bgTypeId);-                    bg->AddPlayer(_player);+                    _player->SetBattleGroundId(bg->GetInstanceID());    // really bg type, or rather instance id?+                    // for now, it works with typeid, but should be instance id. +                    sBattleGroundMgr.SendToBattleGround(_player, instanceId, team);+                    bg->AddPlayer(_player,team);                     break;                 case 0:                                     // leave queue-                    queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId);-                    _player->RemoveBattleGroundQueueId(bgTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs+                    queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);+                    _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs                     sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_NONE, 0, 0);-                    sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), true);+                    sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true);                     SendPacket(&data);                     break;                 default:@@ -350,7 +409,10 @@         BattleGround *bg = _player->GetBattleGround();         if(bg)         {-            uint32 queueSlot = _player->GetBattleGroundQueueIndex(bg->GetTypeID());+            uint32 bgQueueTypeId = bg->GetTypeID();+            if(bg->isArena())+                bgQueueTypeId = BATTLEGROUND_AA;+            uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);             if((bg->GetStatus() <= STATUS_IN_PROGRESS))             {                 sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());@@ -358,8 +420,8 @@             }             for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)             {-                uint32 queue_id = _player->GetBattleGroundQueueId(i);-                if (i == queueSlot || !queue_id)+                uint32 queue_id = _player->GetBattleGroundQueueId(i);       // battlegroundqueueid stores the type id, not the instance id, so this is definitely wrong+                if (i == queueSlot || !queue_id)                            // we need to get the instance ids                     continue;                 BattleGround *bg2 = sBattleGroundMgr.GetBattleGround(queue_id);                 if(bg2)@@ -496,11 +558,30 @@     if(asGroup && !_player->GetGroup())                     // player not in group         return; -    // check existence+/*    // check existence     BattleGround *bg = sBattleGroundMgr.GetBattleGround(BATTLEGROUND_AA);     if(!bg)         return;+*/+//    BattleGround * bg = 0;+//    /* try to get a wait_queue arena */+//    if(!(bg=sBattleGroundMgr.GetArena(STATUS_WAIT_QUEUE,arenatype,isRated)) +//    /* try to get a wait_join arena, not sure if we should try this or not */+//    //    && !(bg=sBattleGroundMgr.GetArena(STATUS_WAIT_JOIN,arenatype,isRated))+//    /* get and init a not yet initiated one */      +//    // we create the new battleground here, not in the update code. by doing this, it's possible to handle rated and different size arenas.+//        && !(bg=sBattleGroundMgr.GetNewArena(arenatype,isRated)))+//        return;+    //check existance+    BattleGround* bg = NULL;+    if( !(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)) )+    {+        sLog.outDebug("arena_join template bg (all arenas) not found");     +        return;+    } +    uint8 bgTypeId = bg->GetTypeID();+     if(asGroup && _player->GetGroup())     {         Group *grp = _player->GetGroup();@@ -513,13 +594,17 @@                 //player has deserter aura .. do nothing             */ -            if (member->GetBattleGroundQueueIndex(BATTLEGROUND_AA) < PLAYER_MAX_BATTLEGROUND_QUEUES)+            if (member->GetBattleGroundQueueIndex(bgTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)+            {+                sLog.outDebug("all arenas: player is already in this queue");                 //player is already in this queue                 continue;+            } -            uint32 queueSlot = member->AddBattleGroundQueueId(BATTLEGROUND_AA);// add to queue+            uint32 queueSlot = member->AddBattleGroundQueueId(bgTypeId);// add to queue             if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)             {+                sLog.outDebug("arena_join player max bg queues are filled. error");                 WorldPacket data;                 //fill data                 //member->GetSession()->SendPacket(data);@@ -527,15 +612,15 @@             }              // store entry point coords (same as leader entry point)-            member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());+            member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetInstanceId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());              WorldPacket data;             // send status packet (in queue)             sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);             member->GetSession()->SendPacket(&data);-            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, BATTLEGROUND_AA);+            sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);             member->GetSession()->SendPacket(&data);-            sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(member, BATTLEGROUND_AA);+            sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(member, bgTypeId, arenatype, isRated);         }     }     else@@ -544,13 +629,17 @@             //player has deserter aura .. do nothing         */ -        if (_player->GetBattleGroundQueueIndex(BATTLEGROUND_AA) < PLAYER_MAX_BATTLEGROUND_QUEUES)+        if (_player->GetBattleGroundQueueIndex(bgTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)+        {+            sLog.outDebug("player is already in all_arenas queue");             //player is already in this queue             return;+        } -        uint32 queueSlot = _player->AddBattleGroundQueueId(BATTLEGROUND_AA);+        uint32 queueSlot = _player->AddBattleGroundQueueId(bgTypeId);         if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)         {+            sLog.outDebug("arenajoin player queues are already full");             WorldPacket data;             //fill data (player is in 3 queues already)             //SendPacket(data);@@ -558,12 +647,12 @@         }          // store entry point coords-        _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());+        _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetInstanceId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());          WorldPacket data;         // send status packet (in queue)         sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);         SendPacket(&data);-        sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(_player, BATTLEGROUND_AA);+        sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(_player, bgTypeId, arenatype, isRated);     } }Index: src/game/BattleGroundMgr.cpp===================================================================--- src/game/BattleGroundMgr.cpp	(revision 5051)+++ src/game/BattleGroundMgr.cpp	(working copy)@@ -59,7 +59,7 @@     } } -void BattleGroundQueue::AddPlayer(Player *plr, uint32 bgTypeId)+void BattleGroundQueue::AddPlayer(Player *plr, uint32 bgTypeId, uint8 arenatype, bool isRated) {     uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(); @@ -70,6 +70,8 @@     info.LastInviteTime             = 0;     info.LastOnlineTime             = getMSTime();     info.Team                       = plr->GetTeam();+    info.IsRated                    = isRated;+    info.ArenaType                  = arenatype;      //add player to waiting order queue     m_PlayersSortedByWaitTime[queue_id].push_back(plr->GetGUID());@@ -84,7 +86,7 @@     str << "Battleground queue invited status: horde: " << m_QueuedPlayers[queue_id].Horde << ", aliance: " << m_QueuedPlayers[queue_id].Alliance;     plr->Say(str.str(), LANG_UNIVERSAL);*/ -    this->Update(bgTypeId, queue_id);+    this->Update(bgTypeId, queue_id, arenatype, isRated); }  void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)@@ -142,12 +144,90 @@     } } +bool BattleGroundQueue::InvitePlayerToBG(PlayerGuidsSortedByTimeQueue::iterator &itr2, Player *plr, BattleGround *bg2, uint32 side)+{+    uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel();+    // iterator to player's queue status+    QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2);++    // remove him from time queue+    itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);++    // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it)+    if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())+        return false;   //player not added++    //check if player is not already invited+    if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID)+    {+        itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg2->GetInstanceID();+        itrPlayerStatus->second.InviteTime = getMSTime();+        itrPlayerStatus->second.LastInviteTime = getMSTime();+        itrPlayerStatus->second.Team = side?side:plr->GetTeam();++        // ally only bg, so decrease from the alliance+        if(bg2->GetTeamType() == BG_TEAM_TYPE_ALLIANCE_ONLY)+        {+            m_QueuedPlayers[queue_id].Alliance--;+        }+        // horde only bg, decrease from horde+        else if(bg2->GetTeamType() == BG_TEAM_TYPE_HORDE_ONLY)+        {+            m_QueuedPlayers[queue_id].Horde--;+        }+        // normal bg (ally vs. horde), so decrease from player's team+        else+        {+            if(plr->GetTeam() == ALLIANCE)+                m_QueuedPlayers[queue_id].Alliance--;+            else+                m_QueuedPlayers[queue_id].Horde--;+        }++        sBattleGroundMgr.InvitePlayer(plr, bg2->GetInstanceID(),itrPlayerStatus->second.Team);++        WorldPacket data;++        uint32 queueSlot = 0;+        if(bg2->isArena())+            queueSlot = plr->GetBattleGroundQueueIndex(BATTLEGROUND_AA);+        else+            queueSlot = plr->GetBattleGroundQueueIndex(bg2->GetTypeID());++        sLog.outDebug("invite plr %u queueindex %u bgtype %u",plr->GetGUIDLow(),queueSlot,bg2->GetTypeID());++        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, side?side:plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0);+        plr->GetSession()->SendPacket(&data);++        return true;    //player was invited+    }+    sLog.outDebug("player %u was already invited to bg %u", plr->GetGUIDLow(), bg2->GetTypeID());+    return false; //player wasn't invited+}++uint32 BattleGroundQueue::GetPlayerCount(uint32 queueId, uint32 team, uint8 arenatype, bool isRated, uint32 instanceGUID)+{+    if(queueId >= MAX_BATTLEGROUND_QUEUES)+        return 0;+    uint32 count = 0;+    for(QueuedPlayersMap::iterator itr = m_QueuedPlayers[queueId].begin(); itr != m_QueuedPlayers[queueId].end(); ++itr)+    {+        if( itr->second.ArenaType == arenatype &&+            itr->second.IsRated == isRated &&+            itr->second.Team == team &&+            itr->second.IsInvitedToBGInstanceGUID == instanceGUID)+            ++count;+    }+    return count;+}+ /* this method is called when player is inserted, or removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue add method calls this by itself, the remove method could works in other way, so you have to call this method from other code after calling remove method */-void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id)+void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype, bool isRated) {+    sLog.outError("bgqueue - update with bgtype %u, queueid %u", bgTypeId, queue_id);     if (queue_id >= MAX_BATTLEGROUND_QUEUES)     {         //this is error, that caused crashes (not in , but now it shouldn't)@@ -161,7 +241,7 @@      //battleground with free slot for player should be always the last in this queue     BGFreeSlotQueueType::iterator itr;-    for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); ++itr)+    for (itr = sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[bgTypeId].end(); ++itr) // iterate only till .back(), not .end()!     {         // battleground is running, so if:         // DO NOT allow queue manager to invite new player to running arena@@ -176,6 +256,7 @@             {                 for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();)                 {+                    sLog.outError("update - bg add - player by time iteration");                     Player* plr = objmgr.GetPlayer(*itr2);                     if (!plr)                     {@@ -198,7 +279,13 @@                          // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and pls report it)                         if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())-                            continue;+                        {+                            sLog.outError("player not in queued players, error! removing the player");+                            uint64 oldval = *itr2;+                            itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                            this->RemovePlayer(oldval, true);+                            continue;   //player not added+                        }                          // check if player is not already invited                         if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID)@@ -210,7 +297,7 @@                                 m_QueuedPlayers[queue_id].Alliance--;                             else                                 m_QueuedPlayers[queue_id].Horde--;-                            sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID());+                            sBattleGroundMgr.InvitePlayer(plr, bg->GetInstanceID(),plr->GetTeam());                              WorldPacket data;                             uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId);@@ -227,13 +314,122 @@                         //if bg is full, there is no need to invite other players, so break                         break;                         //remove BG from BGFreeSlotQueue - not used now, in this system we don't remove BGs from free queue-                        //bg->RemoveFromBGFreeSlotQueue() --- do not uncomment this - not yet implemented+                        bg->RemoveFromBGFreeSlotQueue(); // --- do not uncomment this - not yet implemented                     }                 }             }         }     }+    if(bgTypeId==BATTLEGROUND_AA)+    {+        uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};+        for(int i=0; i<3; ++i)+        {+            for (itr = sBattleGroundMgr.BGFreeSlotQueue[arenas[i]].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[arenas[i]].end(); ++itr) // iterate only till .back(), not .end()!+            {+                // insert here the arena code for late joining+                // an arena is in wait join state. Get the real arena in wait_join state, and add the waiting players to that.+                if ((*itr)->isArena() && (*itr)->GetQueueType() == queue_id && (*itr)->GetStatus() == STATUS_WAIT_JOIN && (*itr)->GetArenaType() == arenatype && (*itr)->isRated() == isRated)+                {+                    // store pointer to bg+                    BattleGround * bg2 = (*itr); +                    // find out if it's a one-sided match +                    uint32 side = 0;+                    uint32 other_side = 0;+                    switch(bg2->GetTeamType())+                    {+                    case BG_TEAM_TYPE_ALLIANCE_ONLY:+                        side = ALLIANCE;+                        other_side = HORDE;+                        break;+                    case BG_TEAM_TYPE_HORDE_ONLY:+                        side = HORDE;+                        other_side = ALLIANCE;+                        break;+                    default:+                        break;+                    }++                    //check if there are some players in queue matching the one- or two-sided setting+                    if ((side == ALLIANCE && m_QueuedPlayers[queue_id].Alliance == 0)  // alliance only match, with no alliance player in the queue+                        || (side == HORDE && m_QueuedPlayers[queue_id].Horde == 0))     // horde only match with no horde player in the queue+        //                || (m_QueuedPlayers[queue_id].Alliance == 0 && m_QueuedPlayers[queue_id].Horde == 0))   // normal match with empty queue; actually this has been already checked, so this ain't needed+                        continue;++                    for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();)+                    {+                        sLog.outError("update - arena add - player by time iteration");+                        Player* plr = objmgr.GetPlayer(*itr2);+                        if (!plr)+                        {+                            //something is wrong!, kick player from queue+                            sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug");+                            uint64 oldval = *itr2;+                            itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                            this->RemovePlayer(oldval, true);+                            continue;+                        }++                        if (side && plr->GetTeam()!=side)   //prevent mixed faction teams, should use a config option here+                        {+                            ++itr2;+                            continue;+                        }++                        QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2);++                        // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it)+                        if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())+                        {+                            sLog.outError("player not in queued players, error! removing the player");+                            uint64 oldval = *itr2;+                            itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                            this->RemovePlayer(oldval, true);+                            continue;   //player not added+                        }++                        // if arena or rating type doesn't match, skip the player+                        if (itrPlayerStatus->second.ArenaType != arenatype || +                            itrPlayerStatus->second.IsRated != isRated)+                        {+                            ++itr2;+                            continue;+                        }++                        if(bg2->GetTeamType()==BG_TEAM_TYPE_NORMAL)+                        {+                            // player will be invited, if in bg there is a free slot for him+                            if (bg2->HasFreeSlotsForTeam(plr->GetTeam()))+                                InvitePlayerToBG(itr2,plr,bg2,0);+                            else+                                ++itr2;+                        }+                        else+                        {+                            // player will be invited, if in bg there is a free slot for him+                            if (bg2->HasFreeSlotsForTeam(side))+                                InvitePlayerToBG(itr2,plr,bg2,side);+                            else if (bg2->HasFreeSlotsForTeam(other_side))+                                InvitePlayerToBG(itr2,plr,bg2,other_side);+                            else+                                ++itr2;+                        }++                        //if battleground is FULL, then it is removed from free slot queue - not yet implemented!+                        if (!bg2->HasFreeSlots())+                        {+                            //if bg is full, there is no need to invite other players, so break+                            break;+                            //remove BG from BGFreeSlotQueue - not used now, in this system we don't remove BGs from free queue+                            bg2->RemoveFromBGFreeSlotQueue(); // --- do not uncomment this - not yet implemented+                        }+                    }+                }+            }+        }+    }+     /* THIS IS A CASE THAT IN QUEUE THERE IS ENOUGHT PLAYERS TO START NEW BG */     //itr->end is the last BG - template, which is not already started! @@ -244,16 +440,80 @@             (battleground template will be used only to create new BGs, it will be an instance of BG class, but it won't ever start) */      /* folowing code is working with current Battleground system and it should be removed, when BGs will work like instances */-    BattleGround* bg2 = sBattleGroundMgr.GetBattleGround(bgTypeId);+    // use bg2 = CreateNewBattleGround(bgTypeId); instead the following+    //BattleGround* bg2 = sBattleGroundMgr.GetBattleGround(bgTypeId);++/*    // check if we created a new bg     if (bg2->GetQueueType() != MAX_BATTLEGROUND_QUEUES || bg2->GetStatus() != STATUS_WAIT_QUEUE)+        return;*/+    // there are enough players on both sides+//    if(true)    // test for instanced bgs+    BattleGround * bg_template = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);+    if(!bg_template)+    {+        sLog.outDebug("update: bg template not found for %u", bgTypeId);         return;-    if (m_QueuedPlayers[queue_id].Alliance >= bg2->GetMinPlayersPerTeam() && m_QueuedPlayers[queue_id].Horde >= bg2->GetMinPlayersPerTeam())+    }+//    if (m_QueuedPlayers[queue_id].Alliance >= 1 || m_QueuedPlayers[queue_id].Horde >= 1)    // still a test!!!+    if (GetPlayerCount(queue_id,ALLIANCE,arenatype,isRated) >= bg_template->GetMinPlayersPerTeam() && GetPlayerCount(queue_id,HORDE,arenatype,isRated) >= bg_template->GetMinPlayersPerTeam())     {+        // TODO::::add a number check for arenas based on arena rating and type+        BattleGround * bg2 = 0;+        if(bg_template->isArena())+        {+            uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};+            uint32 arena_num = urand(0,2);+            if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&+                !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&+                !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+2)%3])) )+            {+                sLog.outDebug("update - normal - couldn't create arena");+                return; // todo: use random arena order+            }++            switch(arenatype)+            {+            case ARENA_TYPE_2v2:+                bg2->SetMaxPlayersPerTeam(2);+                bg2->SetMaxPlayers(4);+                break;+            case ARENA_TYPE_3v3:+                bg2->SetMaxPlayersPerTeam(3);+                bg2->SetMaxPlayers(6);+                break;+            case ARENA_TYPE_5v5:+                bg2->SetMaxPlayersPerTeam(5);+                bg2->SetMaxPlayers(10);+                break;+            default:+                break;+            }++            bg2->SetRated(isRated);++        }+        else+        {+            // create new battleground+            bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId);+        }++        if(!bg2)+        {+            sLog.outDebug("update- normal - couldn't create bg %u",bgTypeId);+            return;+        }++        // start the joining of the bg         bg2->SetStatus(STATUS_WAIT_JOIN);         bg2->SetQueueType(queue_id);+        // initialize arena / rating info+        bg2->SetArenaType(arenatype);+        bg2->SetRated(isRated);          for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();)         {+            sLog.outError("update - normal creation - player by time iteration");             Player* plr = objmgr.GetPlayer(*itr2);             if (!plr)             {@@ -265,45 +525,148 @@                 continue;             } -            /* TODO: (i'm not sure this code will be useful:-            here should be some condition like if (bg2->isArena() && bg2->isRated())+            QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2);++            // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it)+            if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())             {-                invite players from 1 certain group on each faction to play arena match-            } else if ....and existing code-            */+                sLog.outError("player not in queued players, error! removing the player");+                uint64 oldval = *itr2;+                itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                this->RemovePlayer(oldval, true);+                continue;   //player not added+            }++            // if arena or rating type doesn't match, skip the player+            if (itrPlayerStatus->second.ArenaType != arenatype || +                itrPlayerStatus->second.IsRated != isRated)+            {+                ++itr2;+                continue;+            }+             // player will be invited, if in bg there is a free slot for him             if (bg2->HasFreeSlotsForTeam(plr->GetTeam()))+                InvitePlayerToBG(itr2, plr,bg2,0);+            else+                ++itr2;+        }+        bg2->StartBattleGround(0);+    }+    // there weren't enough players for a "normal"+    // if arena, enable horde versus horde or alliance versus alliance teams here+    else if ( (bg_template->isArena())+        && ( (GetPlayerCount(queue_id,ALLIANCE,arenatype,isRated) >= bg_template->GetMaxPlayersPerTeam() + bg_template->GetMinPlayersPerTeam()) +            || (GetPlayerCount(queue_id,HORDE,arenatype,isRated) >= bg_template->GetMaxPlayersPerTeam() + bg_template->GetMinPlayersPerTeam())))+    {+        uint8 arenas[] = {BATTLEGROUND_NA, BATTLEGROUND_BE, BATTLEGROUND_RL};+        uint32 arena_num = urand(0,2);+        BattleGround* bg2 = NULL;+        if( !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[arena_num%3])) &&+            !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&+            !(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+2)%3])) )+            return; // todo: use random arena order++        if(!bg2)+            return;++        switch(arenatype)+        {+        case ARENA_TYPE_2v2:+            bg2->SetMaxPlayersPerTeam(2);+            bg2->SetMaxPlayers(4);+            break;+        case ARENA_TYPE_3v3:+            bg2->SetMaxPlayersPerTeam(3);+            bg2->SetMaxPlayers(6);+            break;+        case ARENA_TYPE_5v5:+            bg2->SetMaxPlayersPerTeam(5);+            bg2->SetMaxPlayers(10);+            break;+        default:+            break;+        }++        bg2->SetRated(isRated);+        // which side has enough players?+        uint32 side = (GetPlayerCount(queue_id,ALLIANCE,arenatype,isRated) >= bg2->GetMaxPlayersPerTeam() + bg2->GetMinPlayersPerTeam())?ALLIANCE:HORDE;+        // how many players will be there per group+        uint32 side_max;+        // assigned team of the other group+        uint32 other_side;+        if(side == ALLIANCE)+        {+            other_side = HORDE;+            side_max = m_QueuedPlayers[queue_id].Alliance / 2;+        }+        else+        {+            other_side = ALLIANCE;+            side_max = m_QueuedPlayers[queue_id].Horde / 2;+        }++        // set the team type of the arena+        if(side == ALLIANCE)+            bg2->SetTeamType(BG_TEAM_TYPE_ALLIANCE_ONLY);+        else+            bg2->SetTeamType(BG_TEAM_TYPE_HORDE_ONLY);++        // start the joining of the bg+        bg2->SetStatus(STATUS_WAIT_JOIN);+        bg2->SetQueueType(queue_id);+        // initialize arena / rating info+        bg2->SetArenaType(arenatype);+        bg2->SetRated(isRated);++        // how many players are added to the first group+        uint32 side_added = 0;++        for (PlayerGuidsSortedByTimeQueue::iterator itr2 = m_PlayersSortedByWaitTime[queue_id].begin(); itr2 != m_PlayersSortedByWaitTime[queue_id].end();)+        {+            sLog.outError("update - 1sided creation - player by time iteration");+            Player* plr = objmgr.GetPlayer(*itr2);+            if (!plr)             {-                // iterator to player's queue status-                QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2);--                // remove him from time queue+                //something is wrong!, kick player from queue+                sLog.outError("BATTLEGROUND: problem with inviting offline player to Battleground queue .... pls report bug");+                uint64 oldval = *itr2;                 itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                this->RemovePlayer(oldval, true);+                continue;+            } -                // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it)-                if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())-                    continue;+            if (plr->GetTeam()!=side)   //prevent mixed faction teams, should use a config option here+            {+                ++itr2;+                continue;+            } -                //check if player is not already invited-                if (!itrPlayerStatus->second.IsInvitedToBGInstanceGUID)-                {-                    itrPlayerStatus->second.IsInvitedToBGInstanceGUID = bg2->GetInstanceID();-                    itrPlayerStatus->second.InviteTime = getMSTime();-                    itrPlayerStatus->second.LastInviteTime = getMSTime();+            QueuedPlayersMap::iterator itrPlayerStatus = m_QueuedPlayers[queue_id].find(*itr2); -                    if(itrPlayerStatus->second.Team == ALLIANCE)-                        m_QueuedPlayers[queue_id].Alliance--;-                    else-                        m_QueuedPlayers[queue_id].Horde--;+            // only check to be sure ... but this condition shouldn't be true (if it is true, then there is a bug somewhere and report it)+            if (itrPlayerStatus == m_QueuedPlayers[queue_id].end())+            {+                sLog.outError("player not in queued players, error! removing the player");+                uint64 oldval = *itr2;+                itr2 = m_PlayersSortedByWaitTime[queue_id].erase(itr2);+                this->RemovePlayer(oldval, true);+                continue;   //player not added+            } -                    sBattleGroundMgr.InvitePlayer(plr, bg2->GetInstanceID());+            // if arena or rating type doesn't match, skip the player+            if (itrPlayerStatus->second.ArenaType != arenatype || +                itrPlayerStatus->second.IsRated != isRated)+            {+                ++itr2;+                continue;+            } -                    WorldPacket data;-                    uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgTypeId);-                    sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, plr->GetTeam(), queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0);-                    plr->GetSession()->SendPacket(&data);-                }-            }+            // player will be invited, if in bg there is a free slot for him+            if (bg2->HasFreeSlotsForTeam(side) && (side_added < side_max) && InvitePlayerToBG(itr2,plr,bg2,side))+                ++side_added;+            else if (bg2->HasFreeSlotsForTeam(other_side))+                InvitePlayerToBG(itr2,plr,bg2,other_side);             else                 ++itr2;         }@@ -330,11 +693,14 @@     BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID);     if (bg)     {-        uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID());+        uint32 bgQueueTypeId = bg->GetTypeID();+        if(bg->isArena())+            bgQueueTypeId = BATTLEGROUND_AA;+        uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);         if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue         {             // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems-            BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()];+            BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()];             BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid);             if (qItr != qpMap.end() && qItr->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID)             {@@ -366,17 +732,20 @@     BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID);     if (bg)     {-        uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID());+        uint32 bgQueueTypeId = bg->GetTypeID();+        if(bg->isArena())+            bgQueueTypeId = BATTLEGROUND_AA;+        uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId);         if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue         {             // check if player is invited to this bg ... this check must be here, because when player leaves queue and joins another, it would cause a problems-            if (sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].find(m_PlayerGuid)->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID)+            if (sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].find(m_PlayerGuid)->second.IsInvitedToBGInstanceGUID == m_BgInstanceGUID)             {-                plr->RemoveBattleGroundQueueId(bg->GetTypeID());-                sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].RemovePlayer(m_PlayerGuid, true);-                sBattleGroundMgr.m_BattleGroundQueues[bg->GetTypeID()].Update(bg->GetTypeID(), bg->GetQueueType());+                plr->RemoveBattleGroundQueueId(bgQueueTypeId);+                sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);+                sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgQueueTypeId, bg->GetQueueType());                 WorldPacket data;-                sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, plr->GetTeam(), queueSlot, STATUS_NONE, 0, 0);+                sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, m_PlayersTeam, queueSlot, STATUS_NONE, 0, 0);                 plr->GetSession()->SendPacket(&data);             }         }@@ -402,15 +771,33 @@  BattleGroundMgr::~BattleGroundMgr() {-    for(std::map<uint32, BattleGround*>::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr)-        delete itr->second;+    BattleGroundSet::iterator itr, next;+    for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)+    {+        next = itr;+        ++next;+        BattleGround * bg = itr->second;+        m_BattleGrounds.erase(itr);+        delete bg;+    }     m_BattleGrounds.clear(); }  void BattleGroundMgr::Update(time_t diff) {-    for(BattleGroundSet::iterator itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); ++itr)+    BattleGroundSet::iterator itr, next;+    for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next)+    {+        next = itr;+        ++next;         itr->second->Update(diff);+        if(itr->second->m_SetDeleteThis)+        {+            BattleGround * bg = itr->second;+            m_BattleGrounds.erase(itr);+            delete bg;+        }+    } }  void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2)@@ -460,12 +847,13 @@     }      if(bg->isArena() && (StatusID == STATUS_WAIT_QUEUE))-        *data << uint32(BATTLEGROUND_AA);                   // all arenas+        *data << uint32(BATTLEGROUND_AA);                   // all arenas   I don't think so.     else-        *data << uint32(bg->GetTypeID());                   // BG id from DBC+    *data << uint32(bg->GetTypeID());                   // BG id from DBC      *data << uint16(0x1F90);                                // unk value 8080     *data << uint32(bg->GetInstanceID());                   // instance id+//    *data << uint32(bg->GetTypeID());                   // BG id from DBC      if(bg->isBattleGround())         *data << uint8(bg->GetTeamIndexByTeamId(team));     // team@@ -536,11 +924,13 @@         {             // that part probably wrong             Player *plr = objmgr.GetPlayer(itr->first);+            uint32 team = bg->GetPlayerTeam(plr->GetGUID());+            if(!team) team = plr->GetTeam();             if(plr)             {-                if(plr->GetTeam() == HORDE)+                if(team == HORDE)                     *data << uint8(0);-                else if(plr->GetTeam() == ALLIANCE)+                else if(team == ALLIANCE)                     *data << uint8(1);                 else                     *data << uint8(0);@@ -624,20 +1014,88 @@     *data << uint64(plr->GetGUID()); } -void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID)+void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team) {     // set invited player counters:     BattleGround* bg = this->GetBattleGround(bgInstanceGUID);-    bg->IncreaseInvitedCount(plr->GetTeam());+    bg->IncreaseInvitedCount(team);      // create invite events:     //add events to player's counters ---- this is not good way - there should be something like global event processor, where we should add those events     BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), bgInstanceGUID);     plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(BG_REMIND_INVITE_TIME));-    BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, plr->GetTeam());+    BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), bgInstanceGUID, team);     plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(2*BG_REMIND_INVITE_TIME)); } +BattleGround * BattleGroundMgr::GetBattleGroundTemplate(uint32 bgTypeId)+{+    return BGFreeSlotQueue[bgTypeId].empty() ? NULL : BGFreeSlotQueue[bgTypeId].back();+}++BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)+{+    // Create the BG+    BattleGround *bg = NULL;++    BattleGround *bg_template = GetBattleGroundTemplate(bgTypeId);++    if(!bg_template)+    {+        sLog.outDebug("CreateNewBG - bg template not found for %u", bgTypeId);+        return 0;+    }+    +    switch(bgTypeId)+    {+        case BATTLEGROUND_AV: +            bg = new BattleGroundAV(*(BattleGroundAV*)bg_template); +            break;+        case BATTLEGROUND_WS: +            bg = new BattleGroundWS(*(BattleGroundWS*)bg_template); +            break;+        case BATTLEGROUND_AB: +            bg = new BattleGroundAB(*(BattleGroundAB*)bg_template); +            break;+        case BATTLEGROUND_NA: +            bg = new BattleGroundNA(*(BattleGroundNA*)bg_template); +            break;+        case BATTLEGROUND_BE: +            bg = new BattleGroundBE(*(BattleGroundBE*)bg_template); +            break;+        case BATTLEGROUND_AA: +            bg = new BattleGroundAA(*(BattleGroundAA*)bg_template); +            break;+        case BATTLEGROUND_EY: +            bg = new BattleGroundEY(*(BattleGroundEY*)bg_template); +            break;+        case BATTLEGROUND_RL: +            bg = new BattleGroundRL(*(BattleGroundRL*)bg_template); +            break;+        default:+            //bg = new BattleGround;   +            return 0;+            break;             // placeholder for non implemented BG+    }+    +    bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id++    bg->Reset();+    +    if(!(bg->SetupBattleGround()))    // setup the battleground in its update function to ensure that a player is present in the instance. Otherwise the objects won't be spawned :(+    {+        sLog.outDebug("CreateNewBattleGround - SetupBattleGround failed for bg %u", bgTypeId);+        delete bg;+        return 0;+    }++    bg->AddToBGFreeSlotQueue();++    AddBattleGround(bg->GetInstanceID(), bg);++    return bg;+}+ uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO) {     // Create the BG@@ -657,13 +1115,19 @@     }      bg->SetMapId(MapID);++    // set unloadflag to false+    Map* map = const_cast<Map*>(MapManager::Instance().GetBaseMap(MapID));+//    Map * map = MapManager::Instance().GetMap(GetMapId(), m_bgobjects[BG_AB_OBJECT_GATE_H]);+    if(map) map->SetUnloadMap(false);+     bg->Reset();-    if(!bg->SetupBattleGround())+/*    if(!bg->SetupBattleGround())      do not setup for template bgs!     {         delete bg;         return 0;     }-+*/     BattlemasterListEntry const *bl = sBattlemasterListStore.LookupEntry(bgTypeId);     //in previous method is checked if exists entry in sBattlemasterListStore, so no check needed     if (bl)@@ -672,7 +1136,8 @@     }      bg->SetTypeID(bgTypeId);-    bg->SetInstanceID(bgTypeId);                               // temporary+//    bg->SetInstanceID(bgTypeId);                               // temporary+    bg->SetInstanceID(0);                               // template bg, instance id is 0     bg->SetMinPlayersPerTeam(MinPlayersPerTeam);     bg->SetMaxPlayersPerTeam(MaxPlayersPerTeam);     bg->SetMinPlayers(MinPlayersPerTeam*2);@@ -684,9 +1149,9 @@     //add BaggleGround instance to FreeSlotQueue     bg->AddToBGFreeSlotQueue(); -    AddBattleGround(bg->GetInstanceID(), bg);+//    AddBattleGround(bg->GetInstanceID(), bg); // do not! we're instantiating! only working ones need to be added, but not the templates!     //sLog.outDetail("BattleGroundMgr: Created new battleground: %u %s (Map %u, %u players per team, Levels %u-%u)", bg_TypeID, bg->m_Name, bg->m_MapId, bg->m_MaxPlayersPerTeam, bg->m_LevelMin, bg->m_LevelMax);-    return bg->GetInstanceID();+    return bgTypeId; //bg->GetInstanceID(); }  void BattleGroundMgr::CreateInitialBattleGrounds()@@ -841,16 +1306,20 @@     } } -void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 bgTypeId)+void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, uint32 team) {-    BattleGround *bg = GetBattleGround(bgTypeId);+    BattleGround *bg = GetBattleGround(instanceId);     if(bg)     {         uint32 mapid = bg->GetMapId();         float x, y, z, O;-        bg->GetTeamStartLoc(pl->GetTeam(), x, y, z, O);+        if(team==0)+            team = pl->GetTeam();+        bg->GetTeamStartLoc(team, x, y, z, O);          sLog.outDetail("BATTLEGROUND: Sending %s to %f, %f, %f, %f", pl->GetName(), x, y, z, O);+        pl->SetInstanceId(instanceId);+        pl->m_BoundInstances[mapid]=std::pair<uint32,uint32>(instanceId, pl->GetGUIDLow());         pl->TeleportTo(mapid, x, y, z, O);     } }@@ -864,3 +1333,10 @@     data << guid << time_;     pl->GetSession()->SendPacket(&data); }++void BattleGroundMgr::RemoveBattleGround(uint32 instanceID)+{+    BattleGroundSet::iterator itr = m_BattleGrounds.find(instanceID);+    if(itr!=m_BattleGrounds.end())+        m_BattleGrounds.erase(itr);+}Index: src/game/BattleGroundMgr.h===================================================================--- src/game/BattleGroundMgr.h	(revision 5051)+++ src/game/BattleGroundMgr.h	(working copy)@@ -63,6 +63,7 @@         //uint32 AverageTime; //not already implemented (it should be average time in queue for last 10 players) }; +class BattleGround; class BattleGroundQueue {     public:@@ -72,15 +73,18 @@         uint32 GetType();         void SetType(uint32 type);*/ -        void Update(uint32 bgTypeId, uint32 queue_id);+        void Update(uint32 bgTypeId, uint32 queue_id, uint8 arenateam = 0, bool isRated = false); -        void AddPlayer(Player *plr, uint32 bgTypeId);+        void AddPlayer(Player *plr, uint32 bgTypeId, uint8 arenatype = 0, bool isRated = false);         void RemovePlayer(uint64 guid, bool decreaseInvitedCount); +        uint32 GetPlayerCount(uint32 queueId, uint32 team, uint8 arenatype, bool isRated, uint32 instanceGUID = 0);         typedef bgqueue<uint64, PlayerQueueInfo> QueuedPlayersMap;         QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES];         typedef std::list<uint64> PlayerGuidsSortedByTimeQueue;         PlayerGuidsSortedByTimeQueue m_PlayersSortedByWaitTime[MAX_BATTLEGROUND_QUEUES];+    private:+        bool InvitePlayerToBG(PlayerGuidsSortedByTimeQueue::iterator &itr, Player * plr, BattleGround * bg, uint32 side); };  /*@@ -139,13 +143,13 @@          /* Player invitation */         // called from Queue update, or from Addplayer to queue-        void InvitePlayer(Player* plr, uint32 bgInstanceGUID);+        void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team);          /* Battlegrounds */         BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); };         BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); }; -        BattleGround* GetBattleGround(uint8 ID)+        BattleGround* GetBattleGround(uint32 ID)         {             BattleGroundSet::iterator i = m_BattleGrounds.find(ID);             if(i != m_BattleGrounds.end())@@ -154,13 +158,17 @@                 return NULL;         }; +        BattleGround * GetBattleGroundTemplate(uint32 bgTypeId);+        BattleGround * CreateNewBattleGround(uint32 bgTypeId);+         uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO);          inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; };+        void RemoveBattleGround(uint32 instanceID);          void CreateInitialBattleGrounds(); -        void SendToBattleGround(Player *pl, uint32 bgTypeId);+        void SendToBattleGround(Player *pl, uint32 bgTypeId, uint32 team = 0);          /* Battleground queues */         //these queues are instantiated when creating BattlegroundMrgIndex: src/game/BattleGroundNA.cpp===================================================================--- src/game/BattleGroundNA.cpp	(revision 5051)+++ src/game/BattleGroundNA.cpp	(working copy)@@ -92,9 +92,9 @@     }*/ } -void BattleGroundNA::AddPlayer(Player *plr)+void BattleGroundNA::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in constructor     BattleGroundNAScore* sc = new BattleGroundNAScore; @@ -117,14 +117,20 @@         return;     } -    uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());+    uint32 killer_team = GetPlayerTeam(killer->GetGUID());+    if(!killer_team) killer_team = killer->GetTeam(); +    uint32 killer_team_index = GetTeamIndexByTeamId(killer_team);+     m_TeamKills[killer_team_index]++;                       // add kills to killer's team -    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))+    uint32 team = GetPlayerTeam(player->GetGUID());+    if(!team) team = player->GetTeam();++    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(team))     {         // all opponents killed-        EndBattleGround(killer->GetTeam());+        EndBattleGround(killer_team);     } } Index: src/game/BattleGroundNA.h===================================================================--- src/game/BattleGroundNA.h	(revision 5051)+++ src/game/BattleGroundNA.h	(working copy)@@ -55,7 +55,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          void RemovePlayer(Player *plr, uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);Index: src/game/BattleGroundRL.cpp===================================================================--- src/game/BattleGroundRL.cpp	(revision 5051)+++ src/game/BattleGroundRL.cpp	(working copy)@@ -93,9 +93,9 @@     }*/ } -void BattleGroundRL::AddPlayer(Player *plr)+void BattleGroundRL::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in constructor     BattleGroundRLScore* sc = new BattleGroundRLScore; @@ -118,14 +118,20 @@         return;     } -    uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());+    uint32 killer_team = GetPlayerTeam(killer->GetGUID());+    if(!killer_team) killer_team = killer->GetTeam(); +    uint32 killer_team_index = GetTeamIndexByTeamId(killer_team);+     m_TeamKills[killer_team_index]++;                       // add kills to killer's team -    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))+    uint32 team = GetPlayerTeam(player->GetGUID());+    if(!team) team = player->GetTeam();++    if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(team))     {         // all opponents killed-        EndBattleGround(killer->GetTeam());+        EndBattleGround(killer_team);     } } Index: src/game/BattleGroundRL.h===================================================================--- src/game/BattleGroundRL.h	(revision 5051)+++ src/game/BattleGroundRL.h	(working copy)@@ -51,7 +51,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          void RemovePlayer(Player *plr, uint64 guid);         void HandleAreaTrigger(Player *Source, uint32 Trigger);Index: src/game/BattleGroundWS.cpp===================================================================--- src/game/BattleGroundWS.cpp	(revision 5051)+++ src/game/BattleGroundWS.cpp	(working copy)@@ -49,6 +49,9 @@         {             m_Events |= 0x01; +            for(uint32 i = WS_SPIRIT_MAIN_ALLIANCE; i <= WS_SPIRIT_MAIN_HORDE; i++)+                SpawnBGCreature(i, RESPAWN_IMMEDIATELY);+             for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)                 SpawnBGObject(i, RESPAWN_IMMEDIATELY); @@ -110,9 +113,9 @@     } } -void BattleGroundWS::AddPlayer(Player *plr)+void BattleGroundWS::AddPlayer(Player *plr, uint32 team) {-    BattleGround::AddPlayer(plr);+    BattleGround::AddPlayer(plr, team);     //create score and add it to map, default values are set in constructor     BattleGroundWGScore* sc = new BattleGroundWGScore; @@ -387,7 +390,7 @@         return;      uint32 SpellId = 0;-    uint64 buff_guid = 0;+    GameObject* buff_guid = 0;     switch(Trigger)     {         case 3686:                                          // Alliance elixir of speed spawn. Trigger not working, because located inside other areatrigger, can be replaced by IsWithinDist(object, dist) in BattleGround::Update().@@ -431,7 +434,7 @@      if(buff_guid)     {-        GameObject *obj = HashMapHolder<GameObject>::Find(buff_guid);+        GameObject *obj = buff_guid;         if(obj)         {             if(!obj->isSpawned())@@ -502,12 +505,13 @@     m_FlagState[BG_TEAM_HORDE]          = BG_WS_FLAG_STATE_ON_BASE;     m_TeamScores[BG_TEAM_ALLIANCE]      = 0;     m_TeamScores[BG_TEAM_HORDE]         = 0;-+/*  currently crashes the server, must find out the problem, till then, let the instance unloading solve this     if(m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE])         DelCreature(WS_SPIRIT_MAIN_ALLIANCE);      if(m_BgCreatures[WS_SPIRIT_MAIN_HORDE])         DelCreature(WS_SPIRIT_MAIN_HORDE);+*/ }  void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer)Index: src/game/BattleGroundWS.h===================================================================--- src/game/BattleGroundWS.h	(revision 5051)+++ src/game/BattleGroundWS.h	(working copy)@@ -97,7 +97,7 @@     BG_WS_FLAG_STATE_ON_GROUND    = 3 }; -enum BattleGroundGaveyardsWS+enum BattleGroundGraveyardsWS {     WS_GRAVEYARD_MAIN_ALLIANCE   = 771,     WS_GRAVEYARD_MAIN_HORDE      = 772@@ -122,7 +122,7 @@         void Update(time_t diff);          /* inherited from BattlegroundClass */-        virtual void AddPlayer(Player *plr);+        virtual void AddPlayer(Player *plr, uint32 team = 0);          /* BG Flags */         uint64 GetAllianceFlagPickerGUID() const    { return m_FlagKeepers[BG_TEAM_ALLIANCE]; }Index: src/game/Map.cpp===================================================================--- src/game/Map.cpp	(revision 5051)+++ src/game/Map.cpp	(working copy)@@ -273,6 +273,8 @@     else         i_data = NULL; +    i_unloadmap = sWorld.getConfig(CONFIG_GRID_UNLOAD);+     i_Players.clear(); } @@ -411,7 +413,7 @@         if( !(i_gridMask[p.x_coord] & mask) )         {             i_grids[p.x_coord][p.y_coord] = new NGridType(p.x_coord*MAX_NUMBER_OF_GRIDS + p.y_coord);-            i_info[p.x_coord][p.y_coord] = new GridInfo(i_gridExpiry,sWorld.getConfig(CONFIG_GRID_UNLOAD));+            i_info[p.x_coord][p.y_coord] = new GridInfo(i_gridExpiry,i_unloadmap);             i_gridMask[p.x_coord] |= mask;              i_grids[p.x_coord][p.y_coord]->SetGridState(GRID_STATE_IDLE);Index: src/game/Map.h===================================================================--- src/game/Map.h	(revision 5051)+++ src/game/Map.h	(working copy)@@ -167,6 +167,8 @@          bool GetUnloadFlag(const GridPair &p) const { return i_info[p.x_coord][p.y_coord]->i_unloadflag; }         void SetUnloadFlag(const GridPair &p, bool unload) { i_info[p.x_coord][p.y_coord]->i_unloadflag = unload; }+        void SetUnloadMap(bool unload){ i_unloadmap = unload; }+        bool GetUnloadMap() const { return i_unloadmap; }         void LoadGrid(const Cell& cell, bool no_unload = false);         bool UnloadGrid(const uint32 &x, const uint32 &y);         virtual void UnloadAll();@@ -225,7 +227,7 @@         bool CanEnter(Player* player) const;         const char* GetMapName() const; -        bool Instanceable() const { return(i_mapEntry && ((i_mapEntry->map_type == MAP_INSTANCE) || (i_mapEntry->map_type == MAP_RAID))); }+        bool Instanceable() const { return(i_mapEntry && ((i_mapEntry->map_type == MAP_INSTANCE) || (i_mapEntry->map_type == MAP_RAID) || (i_mapEntry->map_type == MAP_BATTLEGROUND) || (i_mapEntry->map_type == MAP_ARENA))); }         // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable         bool IsDungeon() const { return(i_mapEntry && ((i_mapEntry->map_type == MAP_INSTANCE) || (i_mapEntry->map_type == MAP_RAID))); }         bool IsRaid() const { return(i_mapEntry && (i_mapEntry->map_type == MAP_RAID)); }@@ -295,6 +297,7 @@         uint32 i_resetDelayTime;         uint32 i_InstanceId;         uint32 i_maxPlayers;+        bool i_unloadmap;         InstanceData* i_data;         std::string i_script; Index: src/game/MapInstanced.cpp===================================================================--- src/game/MapInstanced.cpp	(revision 5051)+++ src/game/MapInstanced.cpp	(working copy)@@ -44,6 +44,7 @@         {             if (i->second->GetPlayersCount() == 0)             {+                DEBUG_LOG("reseting instance in update for instance id = %u and map id = %u named %s",this->GetInstanceId(),this->GetId(),this->GetMapName());                 i->second->Reset();                 // avoid doing ++ on invalid data                 InstancedMaps::iterator i_old = i;@@ -305,6 +306,7 @@             // map for the instance is present, but the instance itself is no more valid, destroy map             Guard guard(*this); +            DEBUG_LOG("reseting instance in createinstance for instance id = %u and map id = %u named %s",this->GetInstanceId(),this->GetId(),this->GetMapName());             map->Reset();             m_InstancedMaps.erase(InstanceId);             VMAP::VMapFactory::createOrGetVMapManager()->unloadMap(GetId());@@ -320,6 +322,7 @@         Guard guard(*this);          map = new Map(GetId(), GetGridExpiry(), InstanceId);+        map->SetUnloadMap(GetUnloadMap());         m_InstancedMaps[InstanceId] = map;     } }Index: src/game/MapManager.cpp===================================================================--- src/game/MapManager.cpp	(revision 5051)+++ src/game/MapManager.cpp	(working copy)@@ -66,7 +66,7 @@         Guard guard(*this);          const MapEntry* entry = sMapStore.LookupEntry(id);-        if (entry && ((entry->map_type == MAP_INSTANCE) || (entry->map_type == MAP_RAID)))+        if (entry && ((entry->map_type == MAP_INSTANCE) || (entry->map_type == MAP_RAID) || (entry->map_type == MAP_BATTLEGROUND) || (entry->map_type == MAP_ARENA)))         {             m = new MapInstanced(id, i_gridCleanUpDelay, 0);         }Index: src/game/MovementHandler.cpp===================================================================--- src/game/MovementHandler.cpp	(revision 5051)+++ src/game/MovementHandler.cpp	(working copy)@@ -79,17 +79,20 @@         {             if(bg->GetMapId() == _player->GetMapId())       // we teleported to bg             {-                if(!bg->GetBgRaid(_player->GetTeam()))      // first player joined+                uint32 team = bg->GetPlayerTeam(_player->GetGUID());+                if(!team)+                    team = _player->GetTeam();+                if(!bg->GetBgRaid(team))      // first player joined                 {                     Group *group = new Group;-                    bg->SetBgRaid(_player->GetTeam(), group);+                    bg->SetBgRaid(team, group);                     group->ConvertToRaid();                     group->AddMember(_player->GetGUID(), _player->GetName());                     group->ChangeLeader(_player->GetGUID());                 }                 else                                        // raid already exist                 {-                    bg->GetBgRaid(_player->GetTeam())->AddMember(_player->GetGUID(), _player->GetName());+                    bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName());                 }             }         }Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp	(revision 5051)+++ src/game/Player.cpp	(working copy)@@ -103,6 +103,9 @@     m_zoneUpdateId = 0;     m_zoneUpdateTimer = 0; +    m_areaUpdateId = 0;+    m_areaUpdateTimer = 0;+     m_dismountCost = 0;      m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE);@@ -925,6 +928,20 @@             m_zoneUpdateTimer -= p_time;     } +    if (m_areaUpdateTimer > 0)+    {+        if(p_time >= m_areaUpdateTimer)+        {+            uint32 newarea = GetAreaId();+            if( m_areaUpdateId != newarea )+                UpdateArea(newarea);+            else+                m_areaUpdateTimer = ZONE_UPDATE_INTERVAL;+        }+        else+            m_areaUpdateTimer -= p_time;+    }+     if (isAlive())     {         RegenerateAll();@@ -5617,8 +5634,27 @@     return zone; } +void Player::UpdateArea(uint32 newArea)+{+    m_areaUpdateId    = newArea;+    m_areaUpdateTimer = ZONE_UPDATE_INTERVAL;++    AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);++    if(area && (area->flags & 0x80))+    {+        SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);+    }+    else+    {+        if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP))+            RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);+    }+}+ void Player::UpdateZone(uint32 newZone) {+    UpdateArea(GetAreaId());     m_zoneUpdateId    = newZone;     m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -15849,7 +15885,7 @@  bool Player::GetBGAccessByLevel(uint32 bgTypeId) const {-    BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);+    BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);     if(!bg)         return false; Index: src/game/Player.h===================================================================--- src/game/Player.h	(revision 5051)+++ src/game/Player.h	(working copy)@@ -1339,6 +1339,7 @@         PvPInfo pvpInfo;         void UpdatePvP(bool state, bool ovrride=false);         void UpdateZone(uint32 newZone);+        void UpdateArea(uint32 newArea);         void UpdatePvPFlag(time_t currTime);          /** todo: -maybe move UpdateDuelFlag+DuelComplete to independent DuelHandler.. **/@@ -1660,9 +1661,11 @@         float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; }         float GetBattleGroundEntryPointZ() const { return m_bgEntryPointZ; }         float GetBattleGroundEntryPointO() const { return m_bgEntryPointO; }-        void SetBattleGroundEntryPoint(uint32 Map, float PosX, float PosY, float PosZ, float PosO )+        uint32 GetBattleGroundEntryPointInstanceId() const { return m_bgEntryPointInstanceId; }+        void SetBattleGroundEntryPoint(uint32 Map, uint32 InstanceId, float PosX, float PosY, float PosZ, float PosO )         {             m_bgEntryPointMap = Map;+            m_bgEntryPointInstanceId = InstanceId;             m_bgEntryPointX = PosX;             m_bgEntryPointY = PosY;             m_bgEntryPointZ = PosZ;@@ -1807,6 +1810,7 @@         */         uint32 m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];         uint32 m_bgEntryPointMap;+        uint32 m_bgEntryPointInstanceId;         float m_bgEntryPointX;         float m_bgEntryPointY;         float m_bgEntryPointZ;@@ -1971,6 +1975,9 @@         uint32 m_zoneUpdateId;         uint32 m_zoneUpdateTimer; +        uint32 m_areaUpdateId;+        uint32 m_areaUpdateTimer;+         uint32 m_deathTimer;         time_t m_resurrectingSicknessExpire; Index: src/game/SpellHandler.cpp===================================================================--- src/game/SpellHandler.cpp	(revision 5051)+++ src/game/SpellHandler.cpp	(working copy)@@ -465,7 +465,8 @@                             if(((BattleGroundWS*)bg)->GetFlagState(ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE)                                 return;                             // check if it's correct flag-                            if(((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_A_FLAG] != obj->GetGUID())+                            if(!(((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_A_FLAG]) ||+                                (((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_A_FLAG]->GetGUID() != obj->GetGUID()))                                 return;                             // check player team                             if(_player->GetTeam() == ALLIANCE)@@ -480,7 +481,8 @@                             if(((BattleGroundWS*)bg)->GetFlagState(HORDE) != BG_WS_FLAG_STATE_ON_BASE)                                 return;                             // check if it's correct flag-                            if(((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_H_FLAG] != obj->GetGUID())+                            if(!(((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_H_FLAG]) ||+                                (((BattleGroundWS*)bg)->m_BgObjects[BG_WS_OBJECT_H_FLAG]->GetGUID() != obj->GetGUID()))                                 return;                             // check player team                             if(_player->GetTeam() == HORDE)Index: src/game/WorldSession.cpp===================================================================--- src/game/WorldSession.cpp	(revision 5051)+++ src/game/WorldSession.cpp	(working copy)@@ -647,6 +647,10 @@             for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)             {                 int32 bgTypeId = _player->GetBattleGroundQueueId(i);+                if( bgTypeId == BATTLEGROUND_NA ||+                    bgTypeId == BATTLEGROUND_RL ||+                    bgTypeId == BATTLEGROUND_BE )+                    bgTypeId = BATTLEGROUND_AA;                 if (bgTypeId != 0)                 {                     _player->RemoveBattleGroundQueueId(bgTypeId);