Show
Ignore:
Timestamp:
11/19/08 13:22:41 (17 years ago)
Author:
yumileroy
Message:

[svn] -enabled instantiated battlegrounds
-enabled arena matches
-rewritten battleground queuing to support joining as group
-removed queue announcements

Original author: w12x
Date: 2008-10-05 08:48:32-05:00

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/BattleGround.cpp

    r2 r9  
    2525#include "Chat.h" 
    2626#include "SpellAuras.h" 
     27#include "ArenaTeam.h" 
    2728#include "World.h" 
    2829#include "Util.h" 
     
    4849    m_LevelMin          = 0; 
    4950    m_LevelMax          = 0; 
     51    m_InBGFreeSlotQueue = false; 
     52    m_SetDeleteThis     = false; 
    5053 
    5154    m_MaxPlayersPerTeam = 0; 
     
    6871    m_TeamStartLocO[BG_TEAM_HORDE]      = 0; 
    6972 
     73    m_ArenaTeamIds[BG_TEAM_ALLIANCE]   = 0; 
     74    m_ArenaTeamIds[BG_TEAM_HORDE]      = 0; 
     75 
     76    m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE]   = 0; 
     77    m_ArenaTeamRatingChanges[BG_TEAM_HORDE]      = 0; 
     78 
    7079    m_BgRaids[BG_TEAM_ALLIANCE]         = NULL; 
    7180    m_BgRaids[BG_TEAM_HORDE]            = NULL; 
     
    7382    m_PlayersCount[BG_TEAM_ALLIANCE]    = 0; 
    7483    m_PlayersCount[BG_TEAM_HORDE]       = 0; 
     84 
     85    m_PrematureCountDown = false; 
     86    m_PrematureCountDown = 0; 
    7587} 
    7688 
    7789BattleGround::~BattleGround() 
    7890{ 
    79  
     91    // remove objects and creatures 
     92    // (this is done automatically in mapmanager update, when the instance is reset after the reset time)     
     93    int size = m_BgCreatures.size(); 
     94    for(int i = 0; i < size; ++i) 
     95    { 
     96        DelCreature(i); 
     97    } 
     98    size = m_BgObjects.size(); 
     99    for(int i = 0; i < size; ++i) 
     100    { 
     101        DelObject(i); 
     102    } 
     103 
     104    // delete creature and go respawn times 
     105    WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'",GetInstanceID()); 
     106    WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'",GetInstanceID()); 
     107    // delete instance from db 
     108    CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID()); 
     109    // remove from battlegrounds 
     110    sBattleGroundMgr.RemoveBattleGround(GetInstanceID()); 
     111    // unload map 
     112    if(Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID())) 
     113        if(map->IsBattleGroundOrArena()) 
     114            ((BattleGroundMap*)map)->SetUnload(); 
     115    // remove from bg free slot queue 
     116    this->RemoveFromBGFreeSlotQueue(); 
    80117} 
    81118 
    82119void BattleGround::Update(time_t diff) 
    83120{ 
    84  
    85121    if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) 
    86122        //BG is empty 
     
    189225    } 
    190226 
     227    // if less then minimum players are in on one side, then start premature finish timer 
     228    if(GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam())) 
     229    { 
     230        if(!m_PrematureCountDown) 
     231        { 
     232            m_PrematureCountDown = true; 
     233            m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime(); 
     234            SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); 
     235        } 
     236        else if(m_PrematureCountDownTimer < diff) 
     237        { 
     238            // time's up! 
     239            EndBattleGround(0); // noone wins 
     240            m_PrematureCountDown = false; 
     241        }  
     242        else  
     243        { 
     244            uint32 newtime = m_PrematureCountDownTimer - diff; 
     245            // announce every minute 
     246            if(m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / 60000 != m_PrematureCountDownTimer / 60000) 
     247                SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING); 
     248            m_PrematureCountDownTimer = newtime; 
     249        } 
     250    } 
     251    else if (m_PrematureCountDown) 
     252        m_PrematureCountDown = false; 
     253 
    191254    if(GetStatus() == STATUS_WAIT_LEAVE) 
    192255    { 
     
    240303            continue; 
    241304 
    242         if(plr->GetTeam() == TeamID) 
     305        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     306 
     307        if(team == TeamID) 
    243308            plr->GetSession()->SendPacket(packet); 
    244309    } 
     
    266331        } 
    267332 
    268         if(plr->GetTeam() == TeamID) 
     333        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     334 
     335        if(team == TeamID) 
    269336        { 
    270337            sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); 
     
    286353        } 
    287354 
    288         if(plr->GetTeam() == TeamID) 
     355        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     356        
     357        if(team == TeamID) 
    289358            plr->CastSpell(plr, SpellID, true); 
    290359    } 
     
    303372        } 
    304373 
    305         if(plr->GetTeam() == TeamID) 
     374        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     375 
     376        if(team == TeamID) 
    306377            UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor); 
    307378    } 
     
    325396        } 
    326397 
    327         if(plr->GetTeam() == TeamID) 
     398        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     399 
     400        if(team == TeamID) 
    328401            plr->ModifyFactionReputation(factionEntry, Reputation); 
    329402    } 
     
    346419void BattleGround::EndBattleGround(uint32 winner) 
    347420{ 
     421    // battleground finished, remove from the running bg's list 
     422    this->RemoveFromBGFreeSlotQueue(); 
     423 
     424    ArenaTeam * winner_arena_team = NULL; 
     425    ArenaTeam * loser_arena_team = NULL; 
     426    uint32 loser_rating = 0; 
     427    uint32 winner_rating = 0; 
    348428    WorldPacket data; 
    349429    Player *Source = NULL; 
     
    352432    if(winner == ALLIANCE) 
    353433    { 
    354         winmsg = GetMangosString(LANG_BG_A_WINS); 
     434        if(isBattleGround()) 
     435            winmsg = GetMangosString(LANG_BG_A_WINS); 
     436        else 
     437            winmsg = GetMangosString(LANG_ARENA_GOLD_WINS); 
    355438 
    356439        PlaySoundToAll(SOUND_ALLIANCE_WINS);                // alliance wins sound 
     
    358441        SetWinner(WINNER_ALLIANCE); 
    359442    } 
     443    else if(winner == HORDE) 
     444    { 
     445        if(isBattleGround()) 
     446            winmsg = GetMangosString(LANG_BG_H_WINS); 
     447        else 
     448            winmsg = GetMangosString(LANG_ARENA_GREEN_WINS); 
     449 
     450        PlaySoundToAll(SOUND_HORDE_WINS);                   // horde wins sound 
     451 
     452        SetWinner(WINNER_HORDE); 
     453    } 
    360454    else 
    361455    { 
    362         winmsg = GetMangosString(LANG_BG_H_WINS); 
    363  
    364         PlaySoundToAll(SOUND_HORDE_WINS);                   // horde wins sound 
    365  
    366         SetWinner(WINNER_HORDE); 
     456        SetWinner(3); 
    367457    } 
    368458 
     
    370460    m_EndTime = 0; 
    371461 
     462    // arena rating calculation 
     463    if(isArena() && isRated()) 
     464    { 
     465        if(winner == ALLIANCE) 
     466        { 
     467            winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 
     468            loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 
     469        } 
     470        else if(winner == HORDE) 
     471        { 
     472            winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 
     473            loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 
     474        } 
     475        if(winner_arena_team && loser_arena_team) 
     476        { 
     477            loser_rating = loser_arena_team->GetStats().rating; 
     478            winner_rating = winner_arena_team->GetStats().rating; 
     479            float winner_chance = winner_arena_team->GetChanceAgainst(loser_rating); 
     480            float loser_chance = loser_arena_team->GetChanceAgainst(winner_rating); 
     481            int32 winner_change = winner_arena_team->WonAgainstChance(winner_chance); 
     482            int32 loser_change = loser_arena_team->LostAgainstChance(loser_chance); 
     483            sLog.outDebug("--- %u ; %u ; %d ; %d ; %u ; %u ---",winner_rating,loser_rating,winner_chance,loser_chance,winner_change,loser_change); 
     484            if(winner == ALLIANCE) 
     485            { 
     486                SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change); 
     487                SetArenaTeamRatingChangeForTeam(HORDE, loser_change); 
     488            } 
     489            else 
     490            { 
     491                SetArenaTeamRatingChangeForTeam(HORDE, winner_change); 
     492                SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change); 
     493            } 
     494        } 
     495        else 
     496        { 
     497            SetArenaTeamRatingChangeForTeam(ALLIANCE, 0); 
     498            SetArenaTeamRatingChangeForTeam(HORDE, 0); 
     499        } 
     500    } 
     501 
    372502    for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) 
    373503    { 
     
    379509        } 
    380510 
     511        // should remove spirit of redemption 
     512        if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) 
     513            plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); 
     514 
    381515        if(!plr->isAlive()) 
    382516        { 
     
    385519        } 
    386520 
    387         if(plr->GetTeam() == winner) 
     521        uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID()); 
     522        if(!team) team = plr->GetTeam(); 
     523 
     524        // per player calculation 
     525        if(isArena() && isRated() && winner_arena_team && loser_arena_team) 
     526        { 
     527            if(team == winner) 
     528                winner_arena_team->MemberWon(plr,loser_rating); 
     529            else 
     530                loser_arena_team->MemberLost(plr,winner_rating); 
     531        } 
     532 
     533        if(team == winner) 
    388534        { 
    389535            if(!Source) 
     
    405551        plr->GetSession()->SendPacket(&data); 
    406552 
    407         sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); 
     553        uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); 
     554        sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); 
    408555        plr->GetSession()->SendPacket(&data); 
    409556    } 
     557 
     558    if(isArena() && isRated() && winner_arena_team && loser_arena_team) 
     559    { 
     560        // update arena points only after increasing the player's match count! 
     561        winner_arena_team->UpdateArenaPointsHelper(); 
     562        loser_arena_team->UpdateArenaPointsHelper(); 
     563        // save the stat changes 
     564        winner_arena_team->SaveToDB(); 
     565        loser_arena_team->SaveToDB(); 
     566        // send updated arena team stats to players 
     567        // this way all arena team members will get notified, not only the ones who participated in this match 
     568        winner_arena_team->NotifyStatsChanged(); 
     569        loser_arena_team->NotifyStatsChanged(); 
     570    } 
     571 
     572    // inform invited players about the removal 
     573    sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); 
    410574 
    411575    if(Source) 
     
    559723void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket) 
    560724{ 
     725    uint32 team = GetPlayerTeam(guid); 
     726    bool participant = false; 
    561727    // Remove from lists/maps 
    562728    std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid); 
    563729    if(itr != m_Players.end()) 
    564730    { 
    565         UpdatePlayersCountByTeam(itr->second.Team, true);   // -1 player 
     731        UpdatePlayersCountByTeam(team, true);   // -1 player 
    566732        m_Players.erase(itr); 
     733        // check if the player was a participant of the match, or only entered through gm command (goname) 
     734        participant = true; 
    567735    } 
    568736 
     
    578746    Player *plr = objmgr.GetPlayer(guid); 
    579747 
     748    // should remove spirit of redemption 
     749    if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) 
     750        plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT); 
     751 
    580752    if(plr && !plr->isAlive())                              // resurrect on exit 
    581753    { 
     
    590762        plr->ClearAfkReports(); 
    591763 
    592         if(isArena()) 
    593         { 
    594             if(!sWorld.IsFFAPvPRealm()) 
    595                 plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); 
    596         } 
    597  
    598         WorldPacket data; 
    599         if(SendPacket) 
    600         { 
    601             sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0); 
    602             plr->GetSession()->SendPacket(&data); 
    603         } 
    604  
    605         // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg 
    606         plr->RemoveBattleGroundQueueId(m_TypeID); 
    607  
    608         DecreaseInvitedCount(plr->GetTeam()); 
    609         //we should update battleground queue, but only if bg isn't ending 
    610         if (GetQueueType() < MAX_BATTLEGROUND_QUEUES) 
    611             sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].Update(GetTypeID(), GetQueueType()); 
    612  
    613         if(!plr->GetBattleGroundId()) 
    614             return; 
    615  
    616         Group * group = plr->GetGroup(); 
    617  
    618         // remove from raid group if exist 
    619         if(group && group == GetBgRaid(plr->GetTeam())) 
    620         { 
    621             if(!group->RemoveMember(guid, 0))               // group was disbanded 
     764        if(participant) // if the player was a match participant, remove auras, calc rating, update queue 
     765        { 
     766            if(!team) team = plr->GetTeam(); 
     767 
     768            uint32 bgTypeId = GetTypeID(); 
     769            uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); 
     770            // if arena, remove the specific arena auras 
     771            if(isArena()) 
    622772            { 
    623                 SetBgRaid(plr->GetTeam(), NULL); 
    624                 delete group; 
     773                plr->RemoveArenaAuras(true);    // removes debuffs / dots etc., we don't want the player to die after porting out 
     774                bgTypeId=BATTLEGROUND_AA;       // set the bg type to all arenas (it will be used for queue refreshing) 
     775 
     776                // summon old pet if there was one and there isn't a current pet 
     777                if(!plr->GetPet() && plr->GetTemporaryUnsummonedPetNumber()) 
     778                { 
     779                    Pet* NewPet = new Pet; 
     780                    if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetTemporaryUnsummonedPetNumber(), true)) 
     781                        delete NewPet; 
     782 
     783                    (plr)->SetTemporaryUnsummonedPetNumber(0); 
     784                } 
     785 
     786                if(isRated() && GetStatus() == STATUS_IN_PROGRESS) 
     787                { 
     788                    //left a rated match while the encounter was in progress, consider as loser 
     789                    ArenaTeam * winner_arena_team = 0; 
     790                    ArenaTeam * loser_arena_team = 0; 
     791                    if(team == HORDE) 
     792                    { 
     793                        winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 
     794                        loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 
     795                    } 
     796                    else 
     797                    { 
     798                        winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE)); 
     799                        loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE)); 
     800                    } 
     801                    if(winner_arena_team && loser_arena_team) 
     802                    { 
     803                        loser_arena_team->MemberLost(plr,winner_arena_team->GetRating()); 
     804                    } 
     805                } 
    625806            } 
     807 
     808            WorldPacket data; 
     809            if(SendPacket) 
     810            { 
     811                sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0); 
     812                plr->GetSession()->SendPacket(&data); 
     813            } 
     814 
     815            // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg 
     816            plr->RemoveBattleGroundQueueId(bgQueueTypeId); 
     817 
     818            DecreaseInvitedCount(team); 
     819            //we should update battleground queue, but only if bg isn't ending 
     820            if (GetQueueType() < MAX_BATTLEGROUND_QUEUES) 
     821                sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueType()); 
     822 
     823            Group * group = plr->GetGroup(); 
     824            // remove from raid group if exist 
     825            if(group && group == GetBgRaid(team)) 
     826            { 
     827                if(!group->RemoveMember(guid, 0))               // group was disbanded 
     828                { 
     829                    SetBgRaid(team, NULL); 
     830                    delete group; 
     831                } 
     832            } 
     833 
     834            // Let others know 
     835            sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr); 
     836            SendPacketToTeam(team, &data, plr, false); 
    626837        } 
    627838 
    628839        // Do next only if found in battleground 
    629840        plr->SetBattleGroundId(0);                          // We're not in BG. 
    630  
    631         // Let others know 
    632         sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr); 
    633         SendPacketToTeam(plr->GetTeam(), &data, plr, false); 
     841        // reset destination bg team 
     842        plr->SetBGTeam(0); 
    634843 
    635844        if(Transport) 
    636845        { 
    637846            plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO()); 
    638             //sLog.outDetail("BATTLEGROUND: Sending %s to %f,%f,%f,%f", pl->GetName(), x,y,z,O); 
    639847        } 
    640848 
     
    643851    } 
    644852 
    645     /// there will be code which will add battleground to BGFreeSlotQueue , when battleground instance will exist 
    646     // we always should check if BG is in that queue before adding.. 
    647  
    648     if(!GetPlayersSize()) 
    649     { 
    650         Reset(); 
    651     } 
     853    if(!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE)) 
     854    { 
     855        // if no players left AND no invitees left, set this bg to delete in next update 
     856        // direct deletion could cause crashes 
     857        m_SetDeleteThis = true; 
     858        // return to prevent addition to freeslotqueue 
     859        return; 
     860    } 
     861 
     862    // a player exited the battleground, so there are free slots. add to queue 
     863    this->AddToBGFreeSlotQueue(); 
    652864} 
    653865 
     
    661873    SetEndTime(0); 
    662874    SetLastResurrectTime(0); 
     875    SetArenaType(0); 
     876    SetRated(false); 
    663877 
    664878    m_Events = 0; 
     
    669883    m_InvitedAlliance = 0; 
    670884    m_InvitedHorde = 0; 
     885    m_InBGFreeSlotQueue = false; 
    671886 
    672887    m_Players.clear(); 
    673888    m_PlayerScores.clear(); 
    674889 
    675     // reset BGSubclass 
     890    // reset BGSubclass (this cleans up creatures and gos as well) 
    676891    this->ResetBGSubclass(); 
    677892} 
     
    699914    m_Players[guid] = bp; 
    700915 
    701     UpdatePlayersCountByTeam(team, false);                  // +1 player 
     916    UpdatePlayersCountByTeam(team, false);        // +1 player 
    702917 
    703918    WorldPacket data; 
     
    705920    SendPacketToTeam(team, &data, plr, false); 
    706921 
     922    // add arena specific auras 
    707923    if(isArena()) 
    708924    { 
     925        // remove auras first, only then reset spell cooldowns 
     926        // this is to prevent bugging amp. curse, combustion, etc. like spells 
     927        plr->RemoveArenaAuras(); 
    709928        plr->RemoveArenaSpellCooldowns(); 
    710         //plr->RemoveArenaAuras(); 
    711929        plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT); 
    712930        if(team == ALLIANCE && plr->GetTeam() == ALLIANCE) 
     
    720938        plr->DestroyConjuredItems(true); 
    721939 
     940        Pet* pet = plr->GetPet(); 
     941        if(pet) 
     942        { 
     943            if(pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET) 
     944            { 
     945                (plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber()); 
     946                (plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); 
     947            } 
     948            (plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT); 
     949        } 
     950 
    722951        if(GetStatus() == STATUS_WAIT_JOIN)                 // not started yet 
    723952        { 
     
    734963    } 
    735964 
    736     if(isArena()) 
    737         plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP); 
    738  
    739965    // Log 
    740966    sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName()); 
     
    744970void BattleGround::AddToBGFreeSlotQueue() 
    745971{ 
    746     sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this); 
     972    // make sure to add only once 
     973    if(!m_InBGFreeSlotQueue) 
     974    { 
     975        sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this); 
     976        m_InBGFreeSlotQueue = true; 
     977    } 
    747978} 
    748979 
     
    750981void BattleGround::RemoveFromBGFreeSlotQueue() 
    751982{ 
    752     /* uncomment this code when battlegrounds will work like instances 
     983    // set to be able to re-add if needed 
     984    m_InBGFreeSlotQueue = false; 
     985    // uncomment this code when battlegrounds will work like instances 
    753986    for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr) 
    754987    { 
     
    758991            return; 
    759992        } 
    760     }*/ 
    761 } 
    762  
    763 /* 
    764 this method should decide, if we can invite new player of certain team to BG, it is based on BATTLEGROUND_STATUS 
    765 */ 
    766 bool BattleGround::HasFreeSlotsForTeam(uint32 Team) const 
     993    } 
     994} 
     995 
     996// get the number of free slots for team 
     997// works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group 
     998uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const 
    767999{ 
    7681000    //if BG is starting ... invite anyone: 
    7691001    if (GetStatus() == STATUS_WAIT_JOIN) 
    770         return GetInvitedCount(Team) < GetMaxPlayersPerTeam(); 
     1002        return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0; 
    7711003    //if BG is already started .. do not allow to join too much players of one faction 
    7721004    uint32 otherTeam; 
     1005    uint32 otherIn; 
    7731006    if (Team == ALLIANCE) 
     1007    { 
    7741008        otherTeam = GetInvitedCount(HORDE); 
     1009        otherIn = GetPlayersCountByTeam(HORDE); 
     1010    } 
    7751011    else 
     1012    { 
    7761013        otherTeam = GetInvitedCount(ALLIANCE); 
     1014        otherIn = GetPlayersCountByTeam(ALLIANCE); 
     1015    } 
    7771016    if (GetStatus() == STATUS_IN_PROGRESS) 
    778         return (GetInvitedCount(Team) <= otherTeam && GetInvitedCount(Team) < GetMaxPlayersPerTeam()); 
    779  
    780     return false; 
    781 } 
    782  
    783 /* this method isn't called already, it will be useful when more battlegrounds of one type will be available */ 
     1017    { 
     1018        // difference based on ppl invited (not necessarily entered battle) 
     1019        // default: allow 0 
     1020        uint32 diff = 0; 
     1021        // allow join one person if the sides are equal (to fill up bg to minplayersperteam) 
     1022        if (otherTeam == GetInvitedCount(Team))  
     1023            diff = 1; 
     1024        // allow join more ppl if the other side has more players 
     1025        else if(otherTeam > GetInvitedCount(Team)) 
     1026            diff = otherTeam - GetInvitedCount(Team); 
     1027 
     1028        // difference based on max players per team (don't allow inviting more) 
     1029        uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0; 
     1030 
     1031        // difference based on players who already entered 
     1032        // default: allow 0 
     1033        uint32 diff3 = 0; 
     1034        // allow join one person if the sides are equal (to fill up bg minplayersperteam) 
     1035        if (otherIn == GetPlayersCountByTeam(Team)) 
     1036            diff3 = 1; 
     1037        // allow join more ppl if the other side has more players 
     1038        else if (otherIn > GetPlayersCountByTeam(Team)) 
     1039            diff3 = otherIn - GetPlayersCountByTeam(Team); 
     1040 
     1041        // return the minimum of the 3 differences 
     1042 
     1043        // min of diff and diff 2 
     1044        diff = diff < diff2 ? diff : diff2; 
     1045 
     1046        // min of diff, diff2 and diff3 
     1047        return diff < diff3 ? diff : diff3 ; 
     1048    } 
     1049 
     1050    return 0; 
     1051} 
     1052 
    7841053bool BattleGround::HasFreeSlots() const 
    7851054{ 
     
    8071076            break; 
    8081077        case SCORE_BONUS_HONOR:                             // Honor bonus 
    809             // reward honor instantly 
    810             if(Source->RewardHonor(NULL, 1, value)) 
    811                 itr->second->BonusHonor += value; 
     1078            // do not add honor in arenas 
     1079            if(isBattleGround()) 
     1080            { 
     1081                // reward honor instantly 
     1082                if(Source->RewardHonor(NULL, 1, value)) 
     1083                    itr->second->BonusHonor += value; 
     1084            } 
    8121085            break; 
    8131086            //used only in EY, but in MSG_PVP_LOG_DATA opcode 
     
    8651138bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime) 
    8661139{ 
    867     GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry); 
    868     if(!goinfo) 
     1140    Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 
     1141    if(!map) 
     1142        return false; 
     1143 
     1144    // must be created this way, adding to godatamap would add it to the base map of the instance 
     1145    // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created 
     1146    // so we must create it specific for this instance 
     1147    GameObject * go = new GameObject; 
     1148    if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1)) 
    8691149    { 
    8701150        sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry); 
     1151        sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry); 
     1152        delete go; 
    8711153        return false; 
    8721154    } 
    873  
    874     uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); 
    875  
     1155/* 
     1156    uint32 guid = go->GetGUIDLow(); 
     1157 
     1158    // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata 
     1159    // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed 
    8761160    GameObjectData& data = objmgr.NewGOData(guid); 
    8771161 
     
    8871171    data.rotation3      = rotation3; 
    8881172    data.spawntimesecs  = respawnTime; 
     1173    data.spawnMask      = 1; 
    8891174    data.animprogress   = 100; 
    8901175    data.go_state       = 1; 
    891     data.spawnMask      = 1; 
    892     objmgr.AddGameobjectToGrid(guid, &data); 
    893  
    894     m_BgObjects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT); 
    895  
     1176*/ 
     1177    // add to world, so it can be later looked up from HashMapHolder 
     1178    go->AddToWorld(); 
     1179    m_BgObjects[type] = go->GetGUID(); 
    8961180    return true; 
    8971181} 
     
    9351219void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) 
    9361220{ 
     1221    Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 
     1222    if(!map) 
     1223        return; 
    9371224    if( respawntime == 0 ) 
    9381225    { 
     
    9431230            if( obj->getLootState() == GO_JUST_DEACTIVATED ) 
    9441231                obj->SetLootState(GO_READY); 
    945             obj->Respawn(); 
    946         } 
    947         else 
    948             objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, 0); 
     1232            obj->SetRespawnTime(0); 
     1233            map->Add(obj); 
     1234        } 
    9491235    } 
    9501236    else 
     
    9531239        if(obj) 
    9541240        { 
     1241            map->Add(obj); 
    9551242            obj->SetRespawnTime(respawntime); 
    9561243            obj->SetLootState(GO_JUST_DEACTIVATED); 
    9571244        } 
    958         else 
    959             objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, time(NULL) + respawntime); 
    960     } 
    961 } 
    962  
    963 Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o) 
    964 { 
    965     // note: this should normally be FindMap 
    966     // but it's a hack to allow the battlegrounds to initialize at server startup 
    967     Map * map = MapManager::Instance().GetMap(GetMapId(), 0); 
    968     if(!map) return NULL; 
     1245    } 
     1246} 
     1247 
     1248Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime) 
     1249{ 
     1250    Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); 
     1251    if(!map) 
     1252        return NULL; 
    9691253 
    9701254    Creature* pCreature = new Creature; 
     
    9901274    map->Add(pCreature); 
    9911275    m_BgCreatures[type] = pCreature->GetGUID(); 
     1276 
    9921277    return  pCreature; 
    9931278} 
     
    10731358void BattleGround::EndNow() 
    10741359{ 
     1360    RemoveFromBGFreeSlotQueue(); 
    10751361    SetStatus(STATUS_WAIT_LEAVE); 
    10761362    SetEndTime(TIME_TO_AUTOREMOVE); 
     1363    // inform invited players about the removal 
     1364    sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); 
    10771365} 
    10781366 
     
    11521440    player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); 
    11531441} 
     1442 
     1443// return the player's team based on battlegroundplayer info 
     1444// used in same faction arena matches mainly 
     1445uint32 BattleGround::GetPlayerTeam(uint64 guid) 
     1446{ 
     1447    std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid); 
     1448    if(itr!=m_Players.end()) 
     1449        return itr->second.Team; 
     1450    return 0; 
     1451} 
     1452 
     1453uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const 
     1454{ 
     1455    int count = 0; 
     1456    for(std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) 
     1457    { 
     1458        if(itr->second.Team == Team) 
     1459        { 
     1460            Player * pl = objmgr.GetPlayer(itr->first); 
     1461            if(pl && pl->isAlive()) 
     1462                ++count; 
     1463        } 
     1464    } 
     1465    return count; 
     1466}