Changeset 272 for trunk/src/game/Map.cpp
- Timestamp:
- 11/22/08 00:35:41 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Map.cpp
r268 r272 36 36 #include "ScriptCalls.h" 37 37 #include "Group.h" 38 #include "MapRefManager.h"39 38 40 39 #include "MapInstanced.h" … … 451 450 bool Map::Add(Player *player) 452 451 { 453 player->GetMapRef().link(this, player);454 455 452 player->SetInstanceId(GetInstanceId()); 456 453 … … 595 592 } 596 593 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_cell602 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 creature608 TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer > grid_object_update(updater);609 // for pets610 TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);611 612 // the overloaded operators handle range checking613 // so ther's no need for range checking inside the loop614 CellPair begin_cell(standing_cell), end_cell(standing_cell);615 begin_cell << 1; begin_cell -= 1; // upper left616 end_cell >> 1; end_cell += 1; // lower right617 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 visited623 // don't visit the same cell twice624 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 640 594 void Map::Update(const uint32 &t_diff) 641 595 { 642 resetMarkedCells();643 644 // update cells around players645 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 objects653 // clone the active object list, because update might remove from it654 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 661 596 // 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 ! 662 597 // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended … … 676 611 void Map::Remove(Player *player, bool remove) 677 612 { 678 player->GetMapRef().unlink();679 613 CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 680 614 if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) … … 826 760 AddCreatureToMoveList(creature,x,y,z,ang); 827 761 // 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); 835 764 } 836 765 else … … 981 910 982 911 { 983 if(!pForce && PlayersNearGrid(x, y) )912 if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) ) 984 913 return false; 985 914 … … 1490 1419 } 1491 1420 1492 uint32 Map::GetPlayersCountExceptGMs() const1493 {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) const1502 {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) const1508 {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) const1530 {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 1559 1421 template void Map::Add(Corpse *); 1560 1422 template void Map::Add(Creature *); … … 1592 1454 bool InstanceMap::CanEnter(Player *player) 1593 1455 { 1594 if( player->GetMapRef().getTarget() == this)1456 if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 1595 1457 { 1596 1458 sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); … … 1709 1571 SetResetSchedule(false); 1710 1572 1573 i_Players.push_back(player); 1711 1574 player->SendInitWorldStates(); 1712 1575 sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); … … 1733 1596 { 1734 1597 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); 1735 1599 SetResetSchedule(true); 1736 //if last player set unload timer 1737 if(!m_unloadTimer && m_mapRefManager.getSize() == 1) 1600 if(!m_unloadTimer && i_Players.empty()) 1738 1601 m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); 1739 1602 Map::Remove(player, remove); … … 1762 1625 if (mInstance) 1763 1626 { 1764 i_script _id = mInstance->script_id;1627 i_script = mInstance->script; 1765 1628 i_data = Script->CreateInstanceData(this); 1766 1629 } … … 1779 1642 if(data) 1780 1643 { 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); 1782 1645 i_data->Load(data); 1783 1646 } … … 1787 1650 else 1788 1651 { 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()); 1790 1653 i_data->Initialize(); 1791 1654 } … … 1800 1663 // the instance must be deleted from the DB by InstanceSaveManager 1801 1664 1802 if( HavePlayers())1665 if(!i_Players.empty()) 1803 1666 { 1804 1667 if(method == INSTANCE_RESET_ALL) 1805 1668 { 1806 1669 // 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()); 1809 1672 } 1810 1673 else … … 1813 1676 { 1814 1677 // 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; 1817 1680 } 1818 1681 … … 1830 1693 } 1831 1694 1832 return m_mapRefManager.isEmpty(); 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; 1833 1705 } 1834 1706 … … 1844 1716 Group *group = player->GetGroup(); 1845 1717 // 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 } 1863 1737 } 1864 1738 } … … 1872 1746 void InstanceMap::UnloadAll(bool pForce) 1873 1747 { 1874 if( HavePlayers())1748 if(!i_Players.empty()) 1875 1749 { 1876 1750 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()); 1882 1753 } 1883 1754 … … 1888 1759 } 1889 1760 1890 void InstanceMap::SendResetWarnings(uint32 timeLeft) const1891 { 1892 for( MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)1893 itr->getSource()->SendInstanceResetWarning(GetId(), timeLeft);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); 1894 1765 } 1895 1766 … … 1899 1770 // the reset time is only scheduled when there are no payers inside 1900 1771 // 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()) 1902 1773 { 1903 1774 InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); … … 1907 1778 } 1908 1779 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 1909 1786 /* ******* Battleground Instance Maps ******* */ 1910 1787 … … 1920 1797 bool BattleGroundMap::CanEnter(Player * player) 1921 1798 { 1922 if( player->GetMapRef().getTarget() == this)1799 if(std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end()) 1923 1800 { 1924 1801 sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow()); … … 1941 1818 if(!CanEnter(player)) 1942 1819 return false; 1820 i_Players.push_back(player); 1943 1821 // reset instance validity, battleground maps do not homebind 1944 1822 player->m_InstanceValid = true; … … 1950 1828 { 1951 1829 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); 1952 1831 Map::Remove(player, remove); 1953 1832 } … … 1960 1839 void BattleGroundMap::UnloadAll(bool pForce) 1961 1840 { 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()); 1966 1846 // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator. 1967 1847 // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop 1968 1848 // note that this remove is not needed if the code works well in other places 1969 plr->GetMapRef().unlink();1849 i_Players.remove(plr); 1970 1850 } 1971 1851