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

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

Delete possessed AI only on creature delete.

Original author: gvcoman
Date: 2008-11-16 14:38:02-05:00

Files:
1 modified

Legend:

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

    r268 r272  
    3636#include "ScriptCalls.h" 
    3737#include "Group.h" 
    38 #include "MapRefManager.h" 
    3938 
    4039#include "MapInstanced.h" 
     
    451450bool Map::Add(Player *player) 
    452451{ 
    453     player->GetMapRef().link(this, player); 
    454  
    455452    player->SetInstanceId(GetInstanceId()); 
    456453 
     
    595592} 
    596593 
    597 void Map::UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff) 
    598 { 
    599     CellPair standing_cell(Trinity::ComputeCellPair(x, y)); 
    600  
    601     // Check for correctness of standing_cell, it also avoids problems with update_cell 
    602     if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) 
    603         return; 
    604  
    605     // will this reduce the speed? 
    606     Trinity::ObjectUpdater updater(t_diff); 
    607     // for creature 
    608     TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer  > grid_object_update(updater); 
    609     // for pets 
    610     TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); 
    611  
    612     // the overloaded operators handle range checking 
    613     // so ther's no need for range checking inside the loop 
    614     CellPair begin_cell(standing_cell), end_cell(standing_cell); 
    615     begin_cell << 1; begin_cell -= 1;               // upper left 
    616     end_cell >> 1; end_cell += 1;                   // lower right 
    617  
    618     for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; ++x) 
    619     { 
    620         for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; ++y) 
    621         { 
    622             // marked cells are those that have been visited 
    623             // don't visit the same cell twice 
    624             uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x; 
    625             if(!isCellMarked(cell_id)) 
    626             { 
    627                 markCell(cell_id); 
    628                 CellPair pair(x,y); 
    629                 Cell cell(pair); 
    630                 cell.data.Part.reserved = CENTER_DISTRICT; 
    631                 cell.SetNoCreate(); 
    632                 CellLock<NullGuard> cell_lock(cell, pair); 
    633                 cell_lock->Visit(cell_lock, grid_object_update,  *this); 
    634                 cell_lock->Visit(cell_lock, world_object_update, *this); 
    635             } 
    636         } 
    637     } 
    638 } 
    639  
    640594void Map::Update(const uint32 &t_diff) 
    641595{ 
    642     resetMarkedCells(); 
    643  
    644     // update cells around players 
    645     for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) 
    646     { 
    647         Player* plr = iter->getSource(); 
    648         if(plr->IsInWorld()) 
    649             UpdateActiveCells(plr->GetPositionX(), plr->GetPositionY(), t_diff); 
    650     } 
    651  
    652     // update cells around active objects 
    653     // clone the active object list, because update might remove from it 
    654     std::set<WorldObject *> activeObjects(i_activeObjects); 
    655     for(std::set<WorldObject *>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter) 
    656     { 
    657         if((*iter)->IsInWorld()) 
    658             UpdateActiveCells((*iter)->GetPositionX(), (*iter)->GetPositionY(), t_diff); 
    659     } 
    660  
    661596    // 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 ! 
    662597    // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended 
     
    676611void Map::Remove(Player *player, bool remove) 
    677612{ 
    678     player->GetMapRef().unlink(); 
    679613    CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 
    680614    if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) 
     
    826760        AddCreatureToMoveList(creature,x,y,z,ang); 
    827761        // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList 
    828         if(creature->isActive()) 
    829         { 
    830             if(creature->isPossessedByPlayer()) 
    831                 EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); 
    832             else 
    833                 EnsureGridLoadedForPlayer(new_cell, NULL, false); 
    834         } 
     762        if(creature->isPossessedByPlayer()) 
     763            EnsureGridLoadedForPlayer(new_cell, (Player*)creature->GetCharmer(), false); 
    835764    } 
    836765    else 
     
    981910 
    982911    { 
    983         if(!pForce && PlayersNearGrid(x, y) ) 
     912        if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) ) 
    984913            return false; 
    985914 
     
    14901419} 
    14911420 
    1492 uint32 Map::GetPlayersCountExceptGMs() const 
    1493 { 
    1494     uint32 count = 0; 
    1495     for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1496         if(!itr->getSource()->isGameMaster()) 
    1497             ++count; 
    1498     return count; 
    1499 } 
    1500  
    1501 void Map::SendToPlayers(WorldPacket const* data) const 
    1502 { 
    1503     for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1504         itr->getSource()->GetSession()->SendPacket(data); 
    1505 } 
    1506  
    1507 bool Map::PlayersNearGrid(uint32 x, uint32 y) const 
    1508 { 
    1509     CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); 
    1510     CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); 
    1511     cell_min << 2; 
    1512     cell_min -= 2; 
    1513     cell_max >> 2; 
    1514     cell_max += 2; 
    1515  
    1516     for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) 
    1517     { 
    1518         Player* plr = iter->getSource(); 
    1519  
    1520         CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()); 
    1521         if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && 
    1522             (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) 
    1523             return true; 
    1524     } 
    1525  
    1526     return false; 
    1527 } 
    1528  
    1529 bool Map::ActiveObjectsNearGrid(uint32 x, uint32 y) const 
    1530 { 
    1531     CellPair cell_min(x*MAX_NUMBER_OF_CELLS, y*MAX_NUMBER_OF_CELLS); 
    1532     CellPair cell_max(cell_min.x_coord + MAX_NUMBER_OF_CELLS, cell_min.y_coord+MAX_NUMBER_OF_CELLS); 
    1533     cell_min << 2; 
    1534     cell_min -= 2; 
    1535     cell_max >> 2; 
    1536     cell_max += 2; 
    1537  
    1538     for(MapRefManager::const_iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) 
    1539     { 
    1540         Player* plr = iter->getSource(); 
    1541  
    1542         CellPair p = Trinity::ComputeCellPair(plr->GetPositionX(), plr->GetPositionY()); 
    1543         if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && 
    1544             (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) 
    1545             return true; 
    1546     } 
    1547  
    1548     for(std::set<WorldObject*>::const_iterator itr = i_activeObjects.begin(); itr != i_activeObjects.end(); ++itr) 
    1549     { 
    1550         CellPair p = Trinity::ComputeCellPair((*itr)->GetPositionX(), (*itr)->GetPositionY()); 
    1551         if( (cell_min.x_coord <= p.x_coord && p.x_coord <= cell_max.x_coord) && 
    1552             (cell_min.y_coord <= p.y_coord && p.y_coord <= cell_max.y_coord) ) 
    1553             return true; 
    1554     } 
    1555  
    1556     return false; 
    1557 } 
    1558  
    15591421template void Map::Add(Corpse *); 
    15601422template void Map::Add(Creature *); 
     
    15921454bool InstanceMap::CanEnter(Player *player) 
    15931455{ 
    1594     if(player->GetMapRef().getTarget() == this) 
     1456    if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 
    15951457    { 
    15961458        sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); 
     
    17091571        SetResetSchedule(false); 
    17101572 
     1573        i_Players.push_back(player); 
    17111574        player->SendInitWorldStates(); 
    17121575        sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); 
     
    17331596{ 
    17341597    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); 
    17351599    SetResetSchedule(true); 
    1736     //if last player set unload timer 
    1737     if(!m_unloadTimer && m_mapRefManager.getSize() == 1) 
     1600    if(!m_unloadTimer && i_Players.empty()) 
    17381601        m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); 
    17391602    Map::Remove(player, remove); 
     
    17621625    if (mInstance) 
    17631626    { 
    1764         i_script_id = mInstance->script_id; 
     1627        i_script = mInstance->script; 
    17651628        i_data = Script->CreateInstanceData(this); 
    17661629    } 
     
    17791642            if(data) 
    17801643            { 
    1781                 sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId); 
     1644                sLog.outDebug("Loading instance data for `%s` with id %u", i_script.c_str(), i_InstanceId); 
    17821645                i_data->Load(data); 
    17831646            } 
     
    17871650    else 
    17881651    { 
    1789         sLog.outDebug("New instance data, \"%s\" ,initialized!", objmgr.GetScriptName(i_script_id)); 
     1652        sLog.outDebug("New instance data, \"%s\" ,initialized!",i_script.c_str()); 
    17901653        i_data->Initialize(); 
    17911654    } 
     
    18001663    // the instance must be deleted from the DB by InstanceSaveManager 
    18011664 
    1802     if(HavePlayers()) 
     1665    if(!i_Players.empty()) 
    18031666    { 
    18041667        if(method == INSTANCE_RESET_ALL) 
    18051668        { 
    18061669            // notify the players to leave the instance so it can be reset 
    1807             for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1808                 itr->getSource()->SendResetFailedNotify(GetId()); 
     1670            for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
     1671                (*itr)->SendResetFailedNotify(GetId()); 
    18091672        } 
    18101673        else 
     
    18131676            { 
    18141677                // set the homebind timer for players inside (1 minute) 
    1815                 for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1816                     itr->getSource()->m_InstanceValid = false; 
     1678                for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
     1679                    (*itr)->m_InstanceValid = false; 
    18171680            } 
    18181681 
     
    18301693    } 
    18311694 
    1832     return m_mapRefManager.isEmpty(); 
     1695    return i_Players.empty(); 
     1696} 
     1697 
     1698uint32 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; 
    18331705} 
    18341706 
     
    18441716    Group *group = player->GetGroup(); 
    18451717    // group members outside the instance group don't get bound 
    1846     for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1847     { 
    1848         Player* plr = itr->getSource(); 
    1849         // players inside an instance cannot be bound to other instances 
    1850         // some players may already be permanently bound, in this case nothing happens 
    1851         InstancePlayerBind *bind = plr->GetBoundInstance(save->GetMapId(), save->GetDifficulty()); 
    1852         if(!bind || !bind->perm) 
    1853         { 
    1854             plr->BindToInstance(save, true); 
    1855             WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); 
    1856             data << uint32(0); 
    1857             plr->GetSession()->SendPacket(&data); 
    1858         } 
    1859  
    1860         // if the leader is not in the instance the group will not get a perm bind 
    1861         if(group && group->GetLeaderGUID() == plr->GetGUID()) 
    1862             group->BindToInstance(save, true); 
     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        } 
    18631737    } 
    18641738} 
     
    18721746void InstanceMap::UnloadAll(bool pForce) 
    18731747{ 
    1874     if(HavePlayers()) 
     1748    if(!i_Players.empty()) 
    18751749    { 
    18761750        sLog.outError("InstanceMap::UnloadAll: there are still players in the instance at unload, should not happen!"); 
    1877         for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1878         { 
    1879             Player* plr = itr->getSource(); 
    1880             plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation()); 
    1881         } 
     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()); 
    18821753    } 
    18831754 
     
    18881759} 
    18891760 
    1890 void InstanceMap::SendResetWarnings(uint32 timeLeft) const 
    1891 { 
    1892     for(MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) 
    1893         itr->getSource()->SendInstanceResetWarning(GetId(), timeLeft); 
     1761void InstanceMap::SendResetWarnings(uint32 timeLeft) 
     1762{ 
     1763    for(PlayerList::iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr) 
     1764        (*itr)->SendInstanceResetWarning(GetId(), timeLeft); 
    18941765} 
    18951766 
     
    18991770    // the reset time is only scheduled when there are no payers inside 
    19001771    // it is assumed that the reset time will rarely (if ever) change while the reset is scheduled 
    1901     if(!HavePlayers() && !IsRaid() && !IsHeroic()) 
     1772    if(i_Players.empty() && !IsRaid() && !IsHeroic()) 
    19021773    { 
    19031774        InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); 
     
    19071778} 
    19081779 
     1780void 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 
    19091786/* ******* Battleground Instance Maps ******* */ 
    19101787 
     
    19201797bool BattleGroundMap::CanEnter(Player * player) 
    19211798{ 
    1922     if(player->GetMapRef().getTarget() == this) 
     1799    if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 
    19231800    { 
    19241801        sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow()); 
     
    19411818        if(!CanEnter(player)) 
    19421819            return false; 
     1820        i_Players.push_back(player); 
    19431821        // reset instance validity, battleground maps do not homebind 
    19441822        player->m_InstanceValid = true; 
     
    19501828{ 
    19511829    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); 
    19521831    Map::Remove(player, remove); 
    19531832} 
     
    19601839void BattleGroundMap::UnloadAll(bool pForce) 
    19611840{ 
    1962     while(HavePlayers()) 
    1963     { 
    1964         Player * plr = m_mapRefManager.getFirst()->getSource(); 
    1965         if(plr) (plr)->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation()); 
     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()); 
    19661846        // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator. 
    19671847        // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop 
    19681848        // note that this remove is not needed if the code works well in other places 
    1969         plr->GetMapRef().unlink(); 
     1849        i_Players.remove(plr); 
    19701850    } 
    19711851