void ZoneComponent::destroyObjectFromWorld(SceneObject* sceneObject, bool sendSelfDestroy) { ManagedReference<SceneObject*> par = sceneObject->getParent(); sceneObject->broadcastDestroy(sceneObject, sendSelfDestroy); ManagedReference<Zone*> rootZone = sceneObject->getZone(); ManagedReference<Zone*> zone = sceneObject->getLocalZone(); if (par != NULL) { uint64 parentID = sceneObject->getParentID(); par->removeObject(sceneObject, NULL, false); if (par->isCellObject()) { ManagedReference<BuildingObject*> build = cast<BuildingObject*>(par->getParent().get().get()); if (build != NULL) { CreatureObject* creature = cast<CreatureObject*>(sceneObject); if (creature != NULL) build->onExit(creature, parentID); } } sceneObject->notifyObservers(ObserverEventType::OBJECTREMOVEDFROMZONE, sceneObject, 0); } else if (zone != NULL) { zone->removeObject(sceneObject, NULL, false); } if (rootZone != NULL) { Locker locker(rootZone); if (!sceneObject->isActiveArea()) rootZone->remove(sceneObject); rootZone->dropSceneObject(sceneObject); SharedBuildingObjectTemplate* objtemplate = dynamic_cast<SharedBuildingObjectTemplate*>(sceneObject->getObjectTemplate()); if (objtemplate != NULL) { String modFile = objtemplate->getTerrainModificationFile(); if (!modFile.isEmpty()) { rootZone->getPlanetManager()->getTerrainManager()->removeTerrainModification(sceneObject->getObjectID()); } } locker.release(); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; CloseObjectsVector* closeobjects = (CloseObjectsVector*) sceneObject->getCloseObjects(); if (closeobjects != NULL) { try { closeobjects->safeCopyTo(closeSceneObjects); while (closeSceneObjects.size() > 0) { ManagedReference<QuadTreeEntry*> obj = closeSceneObjects.get(0); if (obj != NULL && obj != sceneObject && obj->getCloseObjects() != NULL) obj->removeInRangeObject(sceneObject); sceneObject->removeInRangeObject((int) 0); closeSceneObjects.remove((int) 0); } closeobjects->removeAll(); } catch (...) { } } else { SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; sceneObject->info("Null closeobjects vector in ZoneComponent::destroyObjectFromWorld", true); rootZone->getInRangeObjects(sceneObject->getPositionX(), sceneObject->getPositionY(), 512, &closeSceneObjects, false); for (int i = 0; i < closeSceneObjects.size(); ++i) { QuadTreeEntry* obj = closeSceneObjects.get(i); if (obj != sceneObject && obj->getCloseObjects() != NULL) obj->removeInRangeObject(sceneObject); } } // rootZone->dropSceneObject(sceneObject); // locker.release(); Vector<ManagedReference<ActiveArea*> >* activeAreas = sceneObject->getActiveAreas(); while (activeAreas->size() > 0) { Locker _alocker(sceneObject->getContainerLock()); ManagedReference<ActiveArea*> area = activeAreas->get(0); activeAreas->remove(0); _alocker.release(); area->enqueueExitEvent(sceneObject); } } }
bool ZoneContainerComponent::removeObject(SceneObject* sceneObject, SceneObject* object, SceneObject* destination, bool notifyClient) { Zone* zone = dynamic_cast<Zone*>(sceneObject); if (object->isActiveArea()) return removeActiveArea(zone, dynamic_cast<ActiveArea*>(object)); ManagedReference<SceneObject*> parent = object->getParent(); //SortedVector<ManagedReference<SceneObject*> >* notifiedSentObjects = sceneObject->getNotifiedSentObjects(); try { Locker locker(object); if (zone == NULL) return false; object->info("removing from zone"); Locker zoneLocker(zone); if (parent != NULL) { parent->removeObject(object, NULL, false); } else zone->remove(object); Zone* oldZone = zone; // oldZone->dropSceneObject(object); // zoneLocker.release(); SortedVector<ManagedReference<QuadTreeEntry*> >* closeObjects = object->getCloseObjects(); if (closeObjects != NULL) { try { while (closeObjects->size() > 0) { ManagedReference<QuadTreeEntry*> obj = closeObjects->get(0); if (obj != NULL && obj != object && obj->getCloseObjects() != NULL) obj->removeInRangeObject(object); object->removeInRangeObject((int) 0); } } catch (...) { } } else { object->info("Null closeobjects vector in ZoneContainerComponent::removeObject", true); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; zone->getInRangeObjects(object->getPositionX(), object->getPositionY(), 512, &closeSceneObjects, false); for (int i = 0; i < closeSceneObjects.size(); ++i) { QuadTreeEntry* obj = closeSceneObjects.get(i); if (obj != NULL && obj != object && obj->getCloseObjects() != NULL) obj->removeInRangeObject(object); } } // Zone* oldZone = zone; zone = NULL; oldZone->dropSceneObject(object); SharedBuildingObjectTemplate* objtemplate = dynamic_cast<SharedBuildingObjectTemplate*>(object->getObjectTemplate()); if (objtemplate != NULL) { String modFile = objtemplate->getTerrainModificationFile(); if (!modFile.isEmpty()) { oldZone->getPlanetManager()->getTerrainManager()->removeTerrainModification(object->getObjectID()); } } zoneLocker.release(); if (object->isTangibleObject()) { TangibleObject* tano = cast<TangibleObject*>(object); Vector<ManagedReference<ActiveArea*> >* activeAreas = tano->getActiveAreas(); while (activeAreas->size() > 0) { Locker _alocker(object->getContainerLock()); ManagedReference<ActiveArea*> area = activeAreas->get(0); activeAreas->remove(0); _alocker.release(); area->enqueueExitEvent(object); } } SortedVector<ManagedReference<SceneObject*> >* childObjects = object->getChildObjects(); //Remove all outdoor child objects from zone for (int i = 0; i < childObjects->size(); ++i) { ManagedReference<SceneObject*> outdoorChild = childObjects->get(i); if (outdoorChild == NULL) continue; if (outdoorChild->isInQuadTree()) { Locker locker(outdoorChild); outdoorChild->destroyObjectFromWorld(true); } } } catch (Exception& e) { } object->notifyObservers(ObserverEventType::OBJECTREMOVEDFROMZONE, NULL, 0); VectorMap<uint32, ManagedReference<Facade*> >* objectActiveSessions = object->getObjectActiveSessions(); while (objectActiveSessions->size()) { ManagedReference<Facade*> facade = objectActiveSessions->remove(0).getValue(); if (facade == NULL) continue; facade->cancelSession(); } //activeAreas.removeAll(); object->info("removed from zone"); object->notifyRemoveFromZone(); object->setZone(NULL); return true; }
void ZoneImplementation::updateActiveAreas(TangibleObject* tano) { //Locker locker(_this.getReferenceUnsafeStaticCast()); Locker _alocker(tano->getContainerLock()); SortedVector<ManagedReference<ActiveArea* > > areas = *dynamic_cast<SortedVector<ManagedReference<ActiveArea* > >* >(tano->getActiveAreas()); _alocker.release(); Vector3 worldPos = tano->getWorldPosition(); SortedVector<ManagedReference<QuadTreeEntry*> > entryObjects; Zone* managedRef = _this.getReferenceUnsafeStaticCast(); bool readlock = !managedRef->isLockedByCurrentThread(); managedRef->rlock(readlock); try { regionTree->inRange(worldPos.getX(), worldPos.getY(), entryObjects); } catch (...) { error("unexpeted error caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {"); } managedRef->runlock(readlock); //locker.release(); managedRef->unlock(!readlock); try { // update old ones for (int i = 0; i < areas.size(); ++i) { ManagedReference<ActiveArea*> area = areas.get(i); // Locker lockerO(object); // Locker locker(area, object); if (!area->containsPoint(worldPos.getX(), worldPos.getY(), tano->getParentID())) { tano->dropActiveArea(area); area->enqueueExitEvent(tano); // area->notifyExit(object); } else { area->notifyPositionUpdate(tano); } } // we update the ones in quadtree. for (int i = 0; i < entryObjects.size(); ++i) { //update in new ones ActiveArea* activeArea = dynamic_cast<ActiveArea*>(entryObjects.get(i).get()); if (!tano->hasActiveArea(activeArea) && activeArea->containsPoint(worldPos.getX(), worldPos.getY(), tano->getParentID())) { //Locker lockerO(object); //Locker locker(activeArea, object); tano->addActiveArea(activeArea); activeArea->enqueueEnterEvent(tano); //activeArea->notifyEnter(object); } } // update world areas if (creatureManager != NULL) { Vector<ManagedReference<SpawnArea*> >* worldAreas = creatureManager->getWorldSpawnAreas(); if (worldAreas != NULL) { for (int i = 0; i < worldAreas->size(); ++i) { ActiveArea* activeArea = worldAreas->get(i); Locker lockerO(tano); // Locker locker(activeArea, object); if (!tano->hasActiveArea(activeArea)) { tano->addActiveArea(activeArea); //activeArea->enqueueEnterEvent(object); activeArea->notifyEnter(tano); } else { activeArea->notifyPositionUpdate(tano); } } } } } catch (...) { error("unexpected exception caught in void ZoneImplementation::updateActiveAreas(SceneObject* object) {"); managedRef->wlock(!readlock); throw; } managedRef->wlock(!readlock); }