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;
}
예제 #2
0
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;
}