void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y) { bool remove_result = GetBaseMap(mapid)->RemoveBones(guid, x, y); if (!remove_result) { sLog.outDebug("Bones %u not found in world. Delete from DB also.", GUID_LOPART(guid)); } }
Map* MapManager::GetMap(uint32 id, const WorldObject* obj) { Map *m = NULL; m = GetBaseMap(id); if (m && obj && m->Instanceable()) m = ((MapInstanced*)m)->GetInstance(obj); return m; }
// Spawns the object too, without which you can not interact with the object GameObject* MapMgr::CreateAndSpawnGameObject(uint32 entryID, float x, float y, float z, float o, float scale) { GameObjectInfo* goi = GameObjectNameStorage.LookupEntry(entryID); if(!goi) { LOG_DEBUG("Error looking up entry in CreateAndSpawnGameObject"); return NULL; } LOG_DEBUG("CreateAndSpawnGameObject: By Entry '%u'", entryID); GameObject* go = CreateGameObject(entryID); //Player *chr = m_session->GetPlayer(); uint32 mapid = GetMapId(); // Setup game object go->CreateFromProto(entryID, mapid, x, y, z, o); go->SetScale(scale); go->InitAI(); go->PushToWorld(this); // Create spawn instance GOSpawn* gs = new GOSpawn; gs->entry = go->GetEntry(); gs->facing = go->GetOrientation(); gs->faction = go->GetFaction(); gs->flags = go->GetUInt32Value(GAMEOBJECT_FLAGS); gs->id = objmgr.GenerateGameObjectSpawnID(); gs->o = 0.0f; gs->o1 = go->GetParentRotation(0); gs->o2 = go->GetParentRotation(2); gs->o3 = go->GetParentRotation(3); gs->scale = go->GetScale(); gs->x = go->GetPositionX(); gs->y = go->GetPositionY(); gs->z = go->GetPositionZ(); gs->state = go->GetByte(GAMEOBJECT_BYTES_1, 0); //gs->stateNpcLink = 0; gs->overrides = go->GetOverrides(); uint32 cx = GetPosX(x); uint32 cy = GetPosY(y); GetBaseMap()->GetSpawnsListAndCreate(cx, cy)->GOSpawns.push_back(gs); go->m_spawn = gs; MapCell* mCell = GetCell(cx, cy); if(mCell != NULL) mCell->SetLoaded(); return go; }
MapMgr::~MapMgr() { _shutdown=true; sEventMgr.RemoveEvents(this); delete ScriptInterface; // Remove objects if(_cells) { for (uint32 i = 0; i < _sizeX; i++) { if(_cells[i] != 0) { for (uint32 j = 0; j < _sizeY; j++) { if(_cells[i][j] != 0) { _cells[i][j]->_unloadpending=false; _cells[i][j]->RemoveObjects(); } } } } } for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr) { if((*itr)->IsInWorld()) (*itr)->RemoveFromWorld(false); delete (*itr); } free(m_GOStorage); free(m_CreatureStorage); Corpse * pCorpse; for(set<Corpse*>::iterator itr = m_corpses.begin(); itr != m_corpses.end();) { pCorpse = *itr; ++itr; if(pCorpse->IsInWorld()) pCorpse->RemoveFromWorld(false); delete pCorpse; } Log.Notice("MapMgr", "Instance %u shut down. (%s)" , m_instanceID, GetBaseMap()->GetName()); }
bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) { return GetBaseMap(mapid)->CanEnter(player); }
MapMgr::~MapMgr() { CollideInterface.DeactiveMap(_mapId); _shutdown = true; sEventMgr.RemoveEvents(this); if(ScriptInterface != NULL) { delete ScriptInterface; ScriptInterface = NULL; } delete _terrain; // Remove objects if(_cells) { for(uint32 i = 0; i < _sizeX; i++) { if(_cells[i] != 0) { for(uint32 j = 0; j < _sizeY; j++) { if(_cells[i][j] != 0) { _cells[i][j]->_unloadpending = false; _cells[i][j]->RemoveObjects(); } } } } } for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr) { if((*itr)->IsInWorld()) (*itr)->RemoveFromWorld(false); delete(*itr); } _mapWideStaticObjects.clear(); GOStorage.clear(); CreatureStorage.clear(); Corpse* pCorpse; for(set<Corpse*>::iterator itr = m_corpses.begin(); itr != m_corpses.end();) { pCorpse = *itr; ++itr; if(pCorpse->IsInWorld()) pCorpse->RemoveFromWorld(false); delete pCorpse; } m_corpses.clear(); if(mInstanceScript != NULL) mInstanceScript->Destroy(); // Empty remaining containers m_PlayerStorage.clear(); m_PetStorage.clear(); m_DynamicObjectStorage.clear(); _combatProgress.clear(); _updates.clear(); _processQueue.clear(); Sessions.clear(); activeCreatures.clear(); activeGameObjects.clear(); _sqlids_creatures.clear(); _sqlids_gameobjects.clear(); _reusable_guids_creature.clear(); _reusable_guids_gameobject.clear(); if(m_battleground) { m_battleground = NULL; } Log.Notice("MapMgr", "Instance %u shut down. (%s)" , m_instanceID, GetBaseMap()->GetName()); }
void MapMgr::RemoveObject(Object* obj, bool free_guid) { ///////////// // Assertions ///////////// ARCEMU_ASSERT(obj != NULL); ARCEMU_ASSERT(obj->GetMapId() == _mapId); //ARCEMU_ASSERT( obj->GetPositionX() > _minX && obj->GetPositionX() < _maxX); //ARCEMU_ASSERT( obj->GetPositionY() > _minY && obj->GetPositionY() < _maxY); ARCEMU_ASSERT(_cells != NULL); if(obj->IsActive()) obj->Deactivate(this); //there is a very small chance that on double player ports on same update player is added to multiple insertpools but not removed //one clear example was the double port proc when exploiting double resurrect m_objectinsertlock.Acquire(); m_objectinsertpool.erase(obj); m_objectinsertlock.Release(); _updates.erase(obj); obj->ClearUpdateMask(); /////////////////////////////////////// // Remove object from all needed places /////////////////////////////////////// switch(obj->GetTypeFromGUID()) { case HIGHGUID_TYPE_UNIT: case HIGHGUID_TYPE_VEHICLE: ARCEMU_ASSERT(obj->GetUIdFromGUID() <= m_CreatureHighGuid); CreatureStorage[ obj->GetUIdFromGUID() ] = NULL; if(TO_CREATURE(obj)->m_spawn != NULL) { _sqlids_creatures.erase(TO_CREATURE(obj)->m_spawn->id); } if(free_guid) _reusable_guids_creature.push_back(obj->GetUIdFromGUID()); break; case HIGHGUID_TYPE_PET: if(pet_iterator != m_PetStorage.end() && pet_iterator->second->GetGUID() == obj->GetGUID()) ++pet_iterator; m_PetStorage.erase(obj->GetUIdFromGUID()); break; case HIGHGUID_TYPE_DYNAMICOBJECT: m_DynamicObjectStorage.erase(obj->GetLowGUID()); break; case HIGHGUID_TYPE_GAMEOBJECT: ARCEMU_ASSERT(obj->GetUIdFromGUID() <= m_GOHighGuid); GOStorage[ obj->GetUIdFromGUID() ] = NULL; if(TO_GAMEOBJECT(obj)->m_spawn != NULL) { _sqlids_gameobjects.erase(TO_GAMEOBJECT(obj)->m_spawn->id); } if(free_guid) _reusable_guids_gameobject.push_back(obj->GetUIdFromGUID()); break; } // That object types are not map objects. TODO: add AI groups here? if(obj->IsItem() || obj->IsContainer()) { return; } if(obj->IsCorpse()) { m_corpses.erase(TO< Corpse* >(obj)); } MapCell* cell = GetCell(obj->GetMapCellX(), obj->GetMapCellY()); if(cell == NULL) { /* set the map cell correctly */ if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minY || obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY) { // do nothing } else { cell = this->GetCellByCoords(obj->GetPositionX(), obj->GetPositionY()); obj->SetMapCell(cell); } } if(cell != NULL) { // Remove object from cell cell->RemoveObject(obj); // Unset object's cell obj->SetMapCell(NULL); } Player* plObj = NULL; // Clear any updates pending if(obj->IsPlayer()) { plObj = TO_PLAYER(obj); _processQueue.erase(plObj); plObj->ClearAllPendingUpdates(); } obj->RemoveSelfFromInrangeSets(); // Clear object's in-range set obj->ClearInRangeSet(); // If it's a player - update his nearby cells if(!_shutdown && obj->IsPlayer()) { // get x/y if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minY || obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY) { // do nothing } else { uint32 x = GetPosX(obj->GetPositionX()); uint32 y = GetPosY(obj->GetPositionY()); UpdateCellActivity(x, y, 2); } m_PlayerStorage.erase(TO< Player* >(obj)->GetLowGUID()); } // Remove the session from our set if it is a player. if(obj->IsPlayer()) { for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr) { plObj->PushOutOfRange((*itr)->GetNewGUID()); } // Setting an instance ID here will trigger the session to be removed // by MapMgr::run(). :) plObj->GetSession()->SetInstance(0); // Add it to the global session set. // Don't "re-add" to session if it is being deleted. if(!plObj->GetSession()->bDeleted) sWorld.AddGlobalSession(plObj->GetSession()); } if(!HasPlayers()) { if(this->pInstance != NULL && this->pInstance->m_persistent) this->pInstance->m_creatorGroup = 0; if(!InactiveMoveTime && !forced_expire && GetMapInfo()->type != INSTANCE_NULL) { InactiveMoveTime = UNIXTIME + (MAPMGR_INACTIVE_MOVE_TIME * 60); Log.Debug("MapMgr", "Instance %u is now idle. (%s)", m_instanceID, GetBaseMap()->GetName()); } } }