Changeset 279 for trunk/src/game/Map.cpp

Show
Ignore:
Timestamp:
11/22/08 00:36:22 (17 years ago)
Author:
yumileroy
Message:

Merged commit 269 (5f0e38da128a).

Original author: gvcoman
Date: 2008-11-21 14:34:05-05:00

Files:
1 modified

Legend:

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

    r272 r279  
    3636#include "ScriptCalls.h" 
    3737#include "Group.h" 
     38#include "MapRefManager.h" 
    3839 
    3940#include "MapInstanced.h" 
     
    450451bool Map::Add(Player *player) 
    451452{ 
     453    player->GetMapRef().link(this, player); 
     454 
    452455    player->SetInstanceId(GetInstanceId()); 
    453456 
     
    594597void Map::Update(const uint32 &t_diff) 
    595598{ 
     599    // TODO: need have an active object list for every map 
     600 
     601    /*resetMarkedCells(); 
     602 
     603    Trinity::ObjectUpdater updater(t_diff); 
     604    // for creature 
     605    TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer  > grid_object_update(updater); 
     606    // for pets 
     607    TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); 
     608 
     609    for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) 
     610    { 
     611        Player* plr = iter->getSource(); 
     612        if(!plr->IsInWorld()) 
     613            continue; 
     614 
     615        CellPair standing_cell(Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY())); 
     616 
     617        // Check for correctness of standing_cell, it also avoids problems with update_cell 
     618        if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) 
     619            continue; 
     620 
     621        // the overloaded operators handle range checking 
     622        // so ther's no need for range checking inside the loop 
     623        CellPair begin_cell(standing_cell), end_cell(standing_cell); 
     624        begin_cell << 1; begin_cell -= 1;               // upper left 
     625        end_cell >> 1; end_cell += 1;                   // lower right 
     626 
     627        for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x) 
     628        { 
     629            for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y) 
     630            { 
     631                // marked cells are those that have been visited 
     632                // don't visit the same cell twice 
     633                uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; 
     634                if(!isCellMarked(cell_id)) 
     635                { 
     636                    markCell(cell_id); 
     637                    CellPair pair(x,y); 
     638                    Cell cell(pair); 
     639                    cell.data.Part.reserved = CENTER_DISTRICT; 
     640                    cell.SetNoCreate(); 
     641                    CellLock<NullGuard> cell_lock(cell, pair); 
     642                    cell_lock->Visit(cell_lock, grid_object_update,  *this); 
     643                    cell_lock->Visit(cell_lock, world_object_update, *this); 
     644                } 
     645            } 
     646        } 
     647    }*/ 
     648 
    596649    // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! 
    597650    // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended 
     
    611664void Map::Remove(Player *player, bool remove) 
    612665{ 
     666    player->GetMapRef().unlink(); 
    613667    CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 
    614668    if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) 
     
    910964 
    911965    { 
    912         if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) ) 
     966        if(!pForce && PlayersNearGrid(x, y) ) 
    913967            return false; 
    914968 
     
    14191473} 
    14201474 
     1475uint32 Map::GetPlayersCountExceptGMs() const 
     1476{ 
     1477    uint32 count = 0; 
     1478    for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1479        if(!itr->getSource()->isGameMaster()) 
     1480            ++count; 
     1481    return count; 
     1482} 
     1483 
     1484void Map::SendToPlayers(WorldPacket const* data) const 
     1485{ 
     1486    for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1487        itr->getSource()->GetSession()->SendPacket(data); 
     1488} 
     1489 
     1490bool Map::PlayersNearGrid(uint32 x, uint32 y) const 
     1491{ 
     1492    CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); 
     1493    CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); 
     1494    cell_min << 2; 
     1495    cell_min -= 2; 
     1496    cell_max >> 2; 
     1497    cell_max += 2; 
     1498 
     1499    for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) 
     1500    { 
     1501        Player* plr = iter->getSource(); 
     1502 
     1503        CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()); 
     1504        if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && 
     1505            (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) 
     1506            return true; 
     1507    } 
     1508 
     1509    return false; 
     1510} 
     1511 
    14211512template void Map::Add(Corpse *); 
    14221513template void Map::Add(Creature *); 
     
    14541545bool InstanceMap::CanEnter(Player *player) 
    14551546{ 
    1456     if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 
     1547    if(player->GetMapRef().getTarget() == this) 
    14571548    { 
    14581549        sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); 
     
    15711662        SetResetSchedule(false); 
    15721663 
    1573         i_Players.push_back(player); 
    15741664        player->SendInitWorldStates(); 
    15751665        sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); 
     
    15961686{ 
    15971687    sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); 
    1598     i_Players.remove(player); 
    15991688    SetResetSchedule(true); 
    1600     if(!m_unloadTimer && i_Players.empty()) 
     1689    //if last player set unload timer 
     1690    if(!m_unloadTimer && m_mapRefManager.getSize() == 1) 
    16011691        m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); 
    16021692    Map::Remove(player, remove); 
     
    16251715    if (mInstance) 
    16261716    { 
    1627         i_script = mInstance->script; 
     1717        i_script_id = mInstance->script_id; 
    16281718        i_data = Script->CreateInstanceData(this); 
    16291719    } 
     
    16421732            if(data) 
    16431733            { 
    1644                 sLog.outDebug("Loading instance data for `%s` with id %u", i_script.c_str(), i_InstanceId); 
     1734                sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId); 
    16451735                i_data->Load(data); 
    16461736            } 
     
    16501740    else 
    16511741    { 
    1652         sLog.outDebug("New instance data, \"%s\" ,initialized!",i_script.c_str()); 
     1742        sLog.outDebug("New instance data, \"%s\" ,initialized!", objmgr.GetScriptName(i_script_id)); 
    16531743        i_data->Initialize(); 
    16541744    } 
     
    16631753    // the instance must be deleted from the DB by InstanceSaveManager 
    16641754 
    1665     if(!i_Players.empty()) 
     1755    if(HavePlayers()) 
    16661756    { 
    16671757        if(method == INSTANCE_RESET_ALL) 
    16681758        { 
    16691759            // notify the players to leave the instance so it can be reset 
    1670             for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1671                 (*itr)->SendResetFailedNotify(GetId()); 
     1760            for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1761                itr->getSource()->SendResetFailedNotify(GetId()); 
    16721762        } 
    16731763        else 
     
    16761766            { 
    16771767                // set the homebind timer for players inside (1 minute) 
    1678                 for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1679                     (*itr)->m_InstanceValid = false; 
     1768                for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1769                    itr->getSource()->m_InstanceValid = false; 
    16801770            } 
    16811771 
     
    16931783    } 
    16941784 
    1695     return i_Players.empty(); 
    1696 } 
    1697  
    1698 uint32 InstanceMap::GetPlayersCountExceptGMs() const 
    1699 { 
    1700     uint32 count = 0; 
    1701     for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1702         if(!(*itr)->isGameMaster()) 
    1703             ++count; 
    1704     return count; 
     1785    return m_mapRefManager.isEmpty(); 
    17051786} 
    17061787 
     
    17161797    Group *group = player->GetGroup(); 
    17171798    // group members outside the instance group don't get bound 
    1718     for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1719     { 
    1720         if(*itr) 
    1721         { 
    1722             // players inside an instance cannot be bound to other instances 
    1723             // some players may already be permanently bound, in this case nothing happens 
    1724             InstancePlayerBind *bind = (*itr)->GetBoundInstance(save->GetMapId(), save->GetDifficulty()); 
    1725             if(!bind || !bind->perm) 
    1726             { 
    1727                 (*itr)->BindToInstance(save, true); 
    1728                 WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); 
    1729                 data << uint32(0); 
    1730                 (*itr)->GetSession()->SendPacket(&data); 
    1731             } 
    1732  
    1733             // if the leader is not in the instance the group will not get a perm bind 
    1734             if(group && group->GetLeaderGUID() == (*itr)->GetGUID()) 
    1735                 group->BindToInstance(save, true); 
    1736         } 
     1799    for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1800    { 
     1801        Player* plr = itr->getSource(); 
     1802        // players inside an instance cannot be bound to other instances 
     1803        // some players may already be permanently bound, in this case nothing happens 
     1804        InstancePlayerBind *bind = plr->GetBoundInstance(save->GetMapId(), save->GetDifficulty()); 
     1805        if(!bind || !bind->perm) 
     1806        { 
     1807            plr->BindToInstance(save, true); 
     1808            WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); 
     1809            data << uint32(0); 
     1810            plr->GetSession()->SendPacket(&data); 
     1811        } 
     1812 
     1813        // if the leader is not in the instance the group will not get a perm bind 
     1814        if(group && group->GetLeaderGUID() == plr->GetGUID()) 
     1815            group->BindToInstance(save, true); 
    17371816    } 
    17381817} 
     
    17461825void InstanceMap::UnloadAll(bool pForce) 
    17471826{ 
    1748     if(!i_Players.empty()) 
     1827    if(HavePlayers()) 
    17491828    { 
    17501829        sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!"); 
    1751         for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1752             if(*itr) (*itr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation()); 
     1830        for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1831        { 
     1832            Player* plr = itr->getSource(); 
     1833            plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation()); 
     1834        } 
    17531835    } 
    17541836 
     
    17591841} 
    17601842 
    1761 void InstanceMap::SendResetWarnings(uint32 timeLeft) 
    1762 { 
    1763     for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1764         (*itr)->SendInstanceResetWarning(GetId(), timeLeft); 
     1843void InstanceMap::SendResetWarnings(uint32 timeLeft) const 
     1844{ 
     1845    for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
     1846        itr->getSource()->SendInstanceResetWarning(GetId(), timeLeft); 
    17651847} 
    17661848 
     
    17701852    // the reset time is only scheduled when there are no payers inside 
    17711853    // it is assumed that the reset time will rarely (if ever) change while the reset is scheduled 
    1772     if(i_Players.empty() && !IsRaid() && !IsHeroic()) 
     1854    if(!HavePlayers() && !IsRaid() && !IsHeroic()) 
    17731855    { 
    17741856        InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); 
     
    17781860} 
    17791861 
    1780 void InstanceMap::SendToPlayers(WorldPacket const* data) const 
    1781 { 
    1782     for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
    1783         (*itr)->GetSession()->SendPacket(data); 
    1784 } 
    1785  
    17861862/* ******* Battleground Instance Maps ******* */ 
    17871863 
     
    17971873bool BattleGroundMap::CanEnter(Player * player) 
    17981874{ 
    1799     if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 
     1875    if(player->GetMapRef().getTarget() == this) 
    18001876    { 
    18011877        sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow()); 
     
    18181894        if(!CanEnter(player)) 
    18191895            return false; 
    1820         i_Players.push_back(player); 
    18211896        // reset instance validity, battleground maps do not homebind 
    18221897        player->m_InstanceValid = true; 
     
    18281903{ 
    18291904    sLog.outDetail("MAP: Removing player '%s' from bg '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); 
    1830     i_Players.remove(player); 
    18311905    Map::Remove(player, remove); 
    18321906} 
     
    18391913void BattleGroundMap::UnloadAll(bool pForce) 
    18401914{ 
    1841     while(!i_Players.empty()) 
    1842     { 
    1843         PlayerList::iterator itr = i_Players.begin(); 
    1844         Player * plr = *itr; 
    1845         if(plr) (plr)->TeleportTo((*itr)->m_homebindMapId, (*itr)->m_homebindX, (*itr)->m_homebindY, (*itr)->m_homebindZ, (*itr)->GetOrientation()); 
     1915    while(HavePlayers()) 
     1916    { 
     1917        Player * plr = m_mapRefManager.getFirst()->getSource(); 
     1918        if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation()); 
    18461919        // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator. 
    18471920        // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop 
    18481921        // note that this remove is not needed if the code works well in other places 
    1849         i_Players.remove(plr); 
     1922        plr->GetMapRef().unlink(); 
    18501923    } 
    18511924