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; }
SceneObject* ObjectManager::cloneObject(SceneObject* object, bool makeTransient) { ObjectOutputStream objectData(500); (cast<ManagedObject*>(object))->writeObject(&objectData); objectData.reset(); ObjectInputStream objectInput; objectData.copy(&objectInput, 0); objectInput.reset(); uint32 serverCRC = object->getServerObjectCRC(); SceneObject* clonedObject = NULL; ObjectDatabase* database = getTable(object->getObjectID()); String databaseName; uint64 oid; if (database != NULL) { database->getDatabaseName(databaseName); oid = getNextObjectID(databaseName); } else oid = getNextFreeObjectID(); clonedObject = instantiateSceneObject(serverCRC, oid, false); if (makeTransient || !object->isPersistent()) { //clonedObject = createObject(serverCRC, 0, databaseName); clonedObject->setPersistent(0); } else if (object->isPersistent()) { //clonedObject = createObject(serverCRC, object->getPersistenceLevel(), databaseName); clonedObject->setPersistent(object->getPersistenceLevel()); } Locker locker(clonedObject); clonedObject->readObject(&objectInput); clonedObject->createComponents(); clonedObject->setParent(NULL); VectorMap<String, ManagedReference<SceneObject*> > slottedObjects; clonedObject->getSlottedObjects(slottedObjects); for (int i=slottedObjects.size()-1; i>=0; i--) { String key = slottedObjects.elementAt(i).getKey(); Reference<SceneObject*> obj = slottedObjects.elementAt(i).getValue(); clonedObject->removeSlottedObject(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); slottedObjects.put(key, clonedChild); } VectorMap<uint64, ManagedReference<SceneObject*> > objects; clonedObject->getContainerObjects(objects); for (int i=objects.size()-1; i>=0; i--) { uint64 key = objects.elementAt(i).getKey(); Reference<SceneObject*> obj = objects.elementAt(i).getValue(); objects.remove(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); objects.put(key, clonedChild); } clonedObject->onCloneObject(object); if (clonedObject->isPersistent()) updatePersistentObject(clonedObject); return clonedObject; }