void MapMgr::SendChatMessageToCellPlayers(Object * obj, WorldPacket * packet, uint32 cell_radius, uint32 langpos, int32 lang, WorldSession * originator) { uint32 cellX = GetPosX(obj->GetPositionX()); uint32 cellY = GetPosY(obj->GetPositionY()); uint32 endX = ((cellX+cell_radius) <= _sizeX) ? cellX + cell_radius : (_sizeX-1); uint32 endY = ((cellY+cell_radius) <= _sizeY) ? cellY + cell_radius : (_sizeY-1); uint32 startX = (cellX-cell_radius) > 0 ? cellX - cell_radius : 0; uint32 startY = (cellY-cell_radius) > 0 ? cellY - cell_radius : 0; uint32 posX, posY; MapCell *cell; MapCell::ObjectSet::iterator iter, iend; for (posX = startX; posX <= endX; ++posX ) { for (posY = startY; posY <= endY; ++posY ) { cell = GetCell(posX, posY); if (cell && cell->HasPlayers() ) { iter = cell->Begin(); iend = cell->End(); for(; iter != iend; ++iter) { if((*iter)->IsPlayer()) { //static_cast< Player* >(*iter)->GetSession()->SendPacket(packet); static_cast< Player* >(*iter)->GetSession()->SendChatPacket(packet, langpos, lang, originator); } } } } } }
void MapMgr::ChangeFarsightLocation(Player *plr, DynamicObject *farsight) { if(farsight == 0) { // We're clearing. for(ObjectSet::iterator itr = plr->m_visibleFarsightObjects.begin(); itr != plr->m_visibleFarsightObjects.end(); ++itr) { if(plr->IsVisible((*itr)) && !plr->CanSee((*itr))) { // Send destroy plr->PushOutOfRange((*itr)->GetNewGUID()); } } plr->m_visibleFarsightObjects.clear(); } else { uint32 cellX = GetPosX(farsight->GetPositionX()); uint32 cellY = GetPosY(farsight->GetPositionY()); uint32 endX = (cellX <= _sizeX) ? cellX + 1 : (_sizeX-1); uint32 endY = (cellY <= _sizeY) ? cellY + 1 : (_sizeY-1); uint32 startX = cellX > 0 ? cellX - 1 : 0; uint32 startY = cellY > 0 ? cellY - 1 : 0; uint32 posX, posY; MapCell *cell; Object *obj; MapCell::ObjectSet::iterator iter, iend; uint32 count; for (posX = startX; posX <= endX; ++posX ) { for (posY = startY; posY <= endY; ++posY ) { cell = GetCell(posX, posY); if (cell) { iter = cell->Begin(); iend = cell->End(); for(; iter != iend; ++iter) { obj = (*iter); if(!plr->IsVisible(obj) && plr->CanSee(obj) && farsight->GetDistance2dSq(obj) <= m_UpdateDistance) { ByteBuffer buf; count = obj->BuildCreateUpdateBlockForPlayer(&buf, plr); plr->PushCreationData(&buf, count); plr->m_visibleFarsightObjects.insert(obj); } } } } } } }
uint32 MapScriptInterface::GetPlayerCountInRadius(float x, float y, float z /* = 0.0f */, float radius /* = 5.0f */) { // use a cell radius of 2 uint32 PlayerCount = 0; uint32 cellX = mapMgr.GetPosX(x); uint32 cellY = mapMgr.GetPosY(y); uint32 endX = cellX < _sizeX ? cellX + 1 : _sizeX; uint32 endY = cellY < _sizeY ? cellY + 1 : _sizeY; uint32 startX = cellX > 0 ? cellX - 1 : 0; uint32 startY = cellY > 0 ? cellY - 1 : 0; MapCell* pCell; ObjectSet::iterator iter, iter_end; for(uint32 cx = startX; cx < endX; ++cx) { for(uint32 cy = startY; cy < endY; ++cy) { pCell = mapMgr.GetCell(cx, cy); if(pCell == 0 || pCell->GetPlayerCount() == 0) continue; iter = pCell->Begin(); iter_end = pCell->End(); for(; iter != iter_end; ++iter) { if((*iter)->IsPlayer() && (*iter)->CalcDistance(x, y, (z == 0.0f ? (*iter)->GetPositionZ() : z)) < radius) { ++PlayerCount; } } } } return PlayerCount; }
void MapMgr::AddObject(Object *obj) { ASSERT(obj); // make sure object is a virgin ASSERT(obj->GetInRangeSetBegin() == obj->GetInRangeSetEnd()); ASSERT(obj->GetMapId() == _mapId); ASSERT(obj->GetPositionX() < _maxX && obj->GetPositionX() > _minX); ASSERT(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY); ASSERT(_cells); // That object types are not map objects. TODO: add AI groups here? if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER) { // mark object as updatable and exit obj->AddToWorld(); return; } uint32 x = (uint32)(obj->GetPositionX() > 0 ? abs(_minX) + obj->GetPositionX() : abs(_minX) - abs(obj->GetPositionX())); uint32 y = (uint32)(obj->GetPositionY() > 0 ? abs(_minY) + obj->GetPositionY() : abs(_minY) - abs(obj->GetPositionY())); x /= _sizeX; y /= _sizeY; /* sLog.outDetail("Obj position: %f %f Cell position: %u %u", obj->GetPositionX(), obj->GetPositionY(), x, y); */ MapCell *objCell = &(_cells[x][y]); uint32 endX = x < _sizeX ? x + 1 : _sizeX; uint32 endY = y < _sizeY ? y + 1 : _sizeY; uint32 startX = x > 0 ? x - 1 : 0; uint32 startY = y > 0 ? y - 1 : 0; uint32 posX, posY; MapCell *cell; MapCell::ObjectSet::iterator iter; WorldPacket packet; UpdateData data; UpdateData playerData; for (posX = startX; posX <= endX; posX++ ) { for (posY = startY; posY <= endY; posY++ ) { cell = &(_cells[posX][posY]); ASSERT(cell); for (iter = cell->Begin(); iter != cell->End(); iter++) { if ((*iter)->GetDistance2dSq(obj) <= UPDATE_DISTANCE*UPDATE_DISTANCE) { // Object in range, add to set if((*iter)->GetTypeId() == TYPEID_PLAYER) { sLog.outDetail("Creating object "I64FMT" for player "I64FMT".", obj->GetGUID(), (*iter)->GetGUID()); data.Clear(); obj->BuildCreateUpdateBlockForPlayer( &data, (Player*)*iter ); data.BuildPacket(&packet); ((Player*)*iter)->GetSession()->SendPacket( &packet ); } (*iter)->AddInRangeObject(obj); if(obj->GetTypeId() == TYPEID_PLAYER) { sLog.outDetail("Creating object "I64FMT" for player "I64FMT".", (*iter)->GetGUID(), obj->GetGUID()); (*iter)->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj ); } obj->AddInRangeObject(*iter); } } } } if(obj->GetTypeId() == TYPEID_PLAYER) { sLog.outDetail("Creating player "I64FMT" for himself.", obj->GetGUID()); obj->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj ); playerData.BuildPacket( &packet ); ((Player*)obj)->GetSession()->SendPacket( &packet ); } objCell->AddObject(obj); _objects[obj->GetGUID()] = obj; obj->SetMapCell(objCell); obj->AddToWorld(); }
void MapMgr::ChangeObjectLocation(Object *obj) { ASSERT(obj); ASSERT(obj->GetMapId() == _mapId); ASSERT(_cells); if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER) return; WorldPacket packet; UpdateData data; UpdateData playerData; Object* curObj; for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(); iter != obj->GetInRangeSetEnd();) { curObj = *iter; iter++; if (curObj->GetDistance2dSq(obj) > UPDATE_DISTANCE*UPDATE_DISTANCE) { sLog.outDetail("Object "I64FMT" no longer in field of view of object "I64FMT".", obj->GetGUID(), (curObj)->GetGUID()); if( obj->GetTypeId() == TYPEID_PLAYER ) curObj->BuildOutOfRangeUpdateBlock( &playerData ); obj->RemoveInRangeObject(curObj); if( curObj->GetTypeId() == TYPEID_PLAYER ) { data.Clear(); obj->BuildOutOfRangeUpdateBlock( &data ); data.BuildPacket(&packet); ((Player*)curObj)->GetSession()->SendPacket( &packet ); } curObj->RemoveInRangeObject(obj); } } uint32 cellX = (uint32)(obj->GetPositionX() > 0 ? abs(_minX) + obj->GetPositionX() : abs(_minX) - abs(obj->GetPositionX())); uint32 cellY = (uint32)(obj->GetPositionY() > 0 ? abs(_minY) + obj->GetPositionY() : abs(_minY) - abs(obj->GetPositionY())); cellX /= _sizeX; cellY /= _sizeY; /* sLog.outDetail("Obj position: %f %f Cell position: %u %u", obj->GetPositionX(), obj->GetPositionY(), cellX, cellY); */ MapCell *objCell = &(_cells[cellX][cellY]); if (objCell != obj->GetMapCell()) { obj->GetMapCell()->RemoveObject(obj); objCell->AddObject(obj); obj->SetMapCell(objCell); } uint32 endX = cellX < _sizeX ? cellX + 1 : _sizeX; uint32 endY = cellY < _sizeY ? cellY + 1 : _sizeY; uint32 startX = cellX > 0 ? cellX - 1 : 0; uint32 startY = cellY > 0 ? cellY - 1 : 0; uint32 posX, posY; MapCell *cell; MapCell::ObjectSet::iterator iter; for (posX = startX; posX <= endX; posX++ ) { for (posY = startY; posY <= endY; posY++ ) { cell = &(_cells[posX][posY]); ASSERT(cell); for (iter = cell->Begin(); iter != cell->End(); iter++) { curObj = *iter; if (curObj != obj && (curObj)->GetDistance2dSq(obj) <= UPDATE_DISTANCE*UPDATE_DISTANCE && !obj->IsInRangeSet(curObj)) { // Object in range, add to set if((curObj)->GetTypeId() == TYPEID_PLAYER) { sLog.outDetail("Creating object "I64FMT" for player "I64FMT".", obj->GetGUID(), (curObj)->GetGUID()); data.Clear(); obj->BuildCreateUpdateBlockForPlayer( &data, (Player*)curObj ); data.BuildPacket(&packet); ((Player*)curObj)->GetSession()->SendPacket( &packet ); } (curObj)->AddInRangeObject(obj); if(obj->GetTypeId() == TYPEID_PLAYER) { sLog.outDetail("Creating object "I64FMT" for player "I64FMT".", (curObj)->GetGUID(), obj->GetGUID()); (curObj)->BuildCreateUpdateBlockForPlayer( &playerData, (Player*)obj ); } obj->AddInRangeObject(curObj); } } } } if (obj->GetTypeId() == TYPEID_PLAYER) { playerData.BuildPacket(&packet); ((Player*)obj)->GetSession()->SendPacket( &packet ); } }