Changeset 279 for trunk/src/game/Map.cpp
- Timestamp:
- 11/22/08 00:36:22 (17 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/game/Map.cpp
r272 r279 36 36 #include "ScriptCalls.h" 37 37 #include "Group.h" 38 #include "MapRefManager.h" 38 39 39 40 #include "MapInstanced.h" … … 450 451 bool Map::Add(Player *player) 451 452 { 453 player->GetMapRef().link(this, player); 454 452 455 player->SetInstanceId(GetInstanceId()); 453 456 … … 594 597 void Map::Update(const uint32 &t_diff) 595 598 { 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 596 649 // 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 ! 597 650 // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended … … 611 664 void Map::Remove(Player *player, bool remove) 612 665 { 666 player->GetMapRef().unlink(); 613 667 CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); 614 668 if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) … … 910 964 911 965 { 912 if(!pForce && ObjectAccessor::Instance().ActiveObjectsNearGrid(x, y, i_id, i_InstanceId) )966 if(!pForce && PlayersNearGrid(x, y) ) 913 967 return false; 914 968 … … 1419 1473 } 1420 1474 1475 uint32 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 1484 void 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 1490 bool 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 1421 1512 template void Map::Add(Corpse *); 1422 1513 template void Map::Add(Creature *); … … 1454 1545 bool InstanceMap::CanEnter(Player *player) 1455 1546 { 1456 if( std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end())1547 if(player->GetMapRef().getTarget() == this) 1457 1548 { 1458 1549 sLog.outError("InstanceMap::CanEnter - player %s(%u) already in map %d,%d,%d!", player->GetName(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); … … 1571 1662 SetResetSchedule(false); 1572 1663 1573 i_Players.push_back(player);1574 1664 player->SendInitWorldStates(); 1575 1665 sLog.outDetail("MAP: Player '%s' entered the instance '%u' of map '%s'", player->GetName(), GetInstanceId(), GetMapName()); … … 1596 1686 { 1597 1687 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);1599 1688 SetResetSchedule(true); 1600 if(!m_unloadTimer && i_Players.empty()) 1689 //if last player set unload timer 1690 if(!m_unloadTimer && m_mapRefManager.getSize() == 1) 1601 1691 m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); 1602 1692 Map::Remove(player, remove); … … 1625 1715 if (mInstance) 1626 1716 { 1627 i_script = mInstance->script;1717 i_script_id = mInstance->script_id; 1628 1718 i_data = Script->CreateInstanceData(this); 1629 1719 } … … 1642 1732 if(data) 1643 1733 { 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); 1645 1735 i_data->Load(data); 1646 1736 } … … 1650 1740 else 1651 1741 { 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)); 1653 1743 i_data->Initialize(); 1654 1744 } … … 1663 1753 // the instance must be deleted from the DB by InstanceSaveManager 1664 1754 1665 if( !i_Players.empty())1755 if(HavePlayers()) 1666 1756 { 1667 1757 if(method == INSTANCE_RESET_ALL) 1668 1758 { 1669 1759 // 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()); 1672 1762 } 1673 1763 else … … 1676 1766 { 1677 1767 // 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; 1680 1770 } 1681 1771 … … 1693 1783 } 1694 1784 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(); 1705 1786 } 1706 1787 … … 1716 1797 Group *group = player->GetGroup(); 1717 1798 // 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); 1737 1816 } 1738 1817 } … … 1746 1825 void InstanceMap::UnloadAll(bool pForce) 1747 1826 { 1748 if( !i_Players.empty())1827 if(HavePlayers()) 1749 1828 { 1750 1829 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 } 1753 1835 } 1754 1836 … … 1759 1841 } 1760 1842 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);1843 void 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); 1765 1847 } 1766 1848 … … 1770 1852 // the reset time is only scheduled when there are no payers inside 1771 1853 // 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()) 1773 1855 { 1774 1856 InstanceSave *save = sInstanceSaveManager.GetInstanceSave(GetInstanceId()); … … 1778 1860 } 1779 1861 1780 void InstanceMap::SendToPlayers(WorldPacket const* data) const1781 {1782 for(PlayerList::const_iterator itr = i_Players.begin(); itr != i_Players.end(); ++itr)1783 (*itr)->GetSession()->SendPacket(data);1784 }1785 1786 1862 /* ******* Battleground Instance Maps ******* */ 1787 1863 … … 1797 1873 bool BattleGroundMap::CanEnter(Player * player) 1798 1874 { 1799 if( std::find(i_Players.begin(),i_Players.end(),player)!=i_Players.end())1875 if(player->GetMapRef().getTarget() == this) 1800 1876 { 1801 1877 sLog.outError("BGMap::CanEnter - player %u already in map!", player->GetGUIDLow()); … … 1818 1894 if(!CanEnter(player)) 1819 1895 return false; 1820 i_Players.push_back(player);1821 1896 // reset instance validity, battleground maps do not homebind 1822 1897 player->m_InstanceValid = true; … … 1828 1903 { 1829 1904 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);1831 1905 Map::Remove(player, remove); 1832 1906 } … … 1839 1913 void BattleGroundMap::UnloadAll(bool pForce) 1840 1914 { 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()); 1846 1919 // TeleportTo removes the player from this map (if the map exists) -> calls BattleGroundMap::Remove -> invalidates the iterator. 1847 1920 // just in case, remove the player from the list explicitly here as well to prevent a possible infinite loop 1848 1921 // note that this remove is not needed if the code works well in other places 1849 i_Players.remove(plr);1922 plr->GetMapRef().unlink(); 1850 1923 } 1851 1924