Exemplo n.º 1
0
Vector<CreatureObject*> TurretDataComponent::getAvailableTargets(bool aggroOnly) {
	Vector<CreatureObject*> targets;

	ManagedReference<TangibleObject*> turret = cast<TangibleObject*>(getParent());

	if (turret == NULL)
		return targets;

	CloseObjectsVector* vec = (CloseObjectsVector*)turret->getCloseObjects();

	SortedVector<QuadTreeEntry*> closeObjects;

	vec->safeCopyTo(closeObjects);

	int targetTotal = 0;

	for (int i = 0; i < closeObjects.size(); ++i) {
		CreatureObject* creo = cast<CreatureObject*>(closeObjects.get(i));

		if (creo != NULL && checkTarget(creo, turret, aggroOnly)) {
			targets.add(creo);
		}
	}

	return targets;
}
Exemplo n.º 2
0
SceneObject* StructureManager::getInRangeParkingGarage(SceneObject* obj, int range) {
	ManagedReference<Zone*> zone = obj->getZone();

	if (zone == NULL)
		return NULL;

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	CloseObjectsVector* closeObjectsVector = (CloseObjectsVector*) obj->getCloseObjects();

	if (closeObjectsVector == NULL) {
		zone->getInRangeObjects(obj->getPositionX(), obj->getPositionY(), 128, &closeSceneObjects, true);
	} else {
		closeObjectsVector->safeCopyTo(closeSceneObjects);
	}

	for (int i = 0; i < closeSceneObjects.size(); ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (scno == obj)
			continue;

		if (scno->isGarage() && scno->isInRange(obj, range))
			return scno;
	}

	return NULL;
}
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = getRootParent().get();

		if (grandParent != NULL) {
			grandParent->broadcastDestroyPrivate(object, selfObject);

			return;
		} else {
			return;
		}
	}

	if (zone == NULL)
		return;

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	if (closeobjects == NULL) {
		info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true);
		zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true);

		maxInRangeObjectCount = closeSceneObjects.size();
	} else {

		CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects;
		closeSceneObjects.removeAll(vec->size(), 10);

		vec->safeCopyTo(closeSceneObjects);

		maxInRangeObjectCount = closeSceneObjects.size();

	}

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = static_cast<SceneObject*>(closeSceneObjects.get(i).get());

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			object->sendDestroyTo(scno);
		}
	}
}
void GroupObjectImplementation::updatePvPStatusNearCreature(CreatureObject* creature) {
	CloseObjectsVector* creatureCloseObjects = (CloseObjectsVector*) creature->getCloseObjects();
	SortedVector<QuadTreeEntry*> closeObjectsVector;

	creatureCloseObjects->safeCopyReceiversTo(closeObjectsVector, CloseObjectsVector::CREOTYPE);

	for (int i = 0; i < groupMembers.size(); i++) {
		CreatureObject* member = groupMembers.get(i).get().get();

		if (closeObjectsVector.contains(member)) {

			if (creature->isPlayerCreature())
				member->sendPvpStatusTo(creature);

			if (member->isPlayerCreature())
				creature->sendPvpStatusTo(member);
		}
	}
}
Exemplo n.º 5
0
void ZoneComponent::updateInRangeObjectsOnMount(SceneObject* sceneObject) {
	CloseObjectsVector* closeObjectsVector = (CloseObjectsVector*) sceneObject->getCloseObjects();
	CloseObjectsVector* parentCloseObjectsVector = (CloseObjectsVector*) sceneObject->getRootParent().get()->getCloseObjects();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeObjects(closeObjectsVector->size(), 10);
	closeObjectsVector->safeCopyTo(closeObjects);

	SortedVector<ManagedReference<QuadTreeEntry*> > parentCloseObjects(parentCloseObjectsVector->size(), 10);
	parentCloseObjectsVector->safeCopyTo(parentCloseObjects);

	//remove old ones
	float rangesq = 192.f * 192.f;

	float x = sceneObject->getPositionX();
	float y = sceneObject->getPositionY();

	float oldx = sceneObject->getPreviousPositionX();
	float oldy = sceneObject->getPreviousPositionY();

	for (int i = 0; i < closeObjects.size(); ++i) {
		ManagedReference<QuadTreeEntry*> o = closeObjects.get(i);
		ManagedReference<QuadTreeEntry*> objectToRemove = o;
		ManagedReference<QuadTreeEntry*> rootParent = o->getRootParent();

		if (rootParent != NULL)
			o = rootParent;

		if (o != sceneObject) {
			float deltaX = x - o->getPositionX();
			float deltaY = y - o->getPositionY();

			if (deltaX * deltaX + deltaY * deltaY > rangesq) {
				float oldDeltaX = oldx - o->getPositionX();
				float oldDeltaY = oldy - o->getPositionY();

				if (oldDeltaX * oldDeltaX + oldDeltaY * oldDeltaY <= rangesq) {

					if (sceneObject->getCloseObjects() != NULL)
						sceneObject->removeInRangeObject(objectToRemove);

					if (objectToRemove->getCloseObjects() != NULL)
						objectToRemove->removeInRangeObject(sceneObject);
				}
			}
		}
	}

	//insert new ones
	for (int i = 0; i < parentCloseObjects.size(); ++i) {
		QuadTreeEntry* o = parentCloseObjects.get(i);

		if (sceneObject->getCloseObjects() != NULL)
			sceneObject->addInRangeObject(o, false);

		if (o->getCloseObjects() != NULL)
			o->addInRangeObject(sceneObject, true);
	}
}
Exemplo n.º 6
0
float VisibilityManager::calculateVisibilityIncrease(CreatureObject* creature) {
	ManagedReference<Zone*> zone = creature->getZone();

	float visibilityIncrease = 0;

	if (zone != NULL) {
		SortedVector<ManagedReference<QuadTreeEntry* > > closeObjects;
		CloseObjectsVector* closeObjectsVector = (CloseObjectsVector*) creature->getCloseObjects();
		if (closeObjectsVector == NULL) {
			zone->getInRangeObjects(creature->getWorldPositionX(), creature->getWorldPositionY(), 32, &closeObjects, true);
		} else {
			closeObjectsVector->safeCopyTo(closeObjects);
		}

		for (int i = 0; i < closeObjects.size(); ++i) {
			SceneObject* obj = cast<SceneObject*>(closeObjects.get(i).get());
			if (obj->isCreatureObject() && creature->isInRange(obj, 32)) {
				ManagedReference<CreatureObject*> c = cast<CreatureObject*>(obj);
				if (c->isNonPlayerCreatureObject()) {
					if (creature->getFaction() == 0 || (c->getFaction() != factionImperial && c->getFaction() != factionRebel)) {
						visibilityIncrease += 0.5;
					} else {
						if (creature->getFaction() == c->getFaction()) {
							visibilityIncrease += 0.25;
						} else {
							visibilityIncrease += 1;
						}
					}
				}
			}
		}
	}

	//info("Increasing visibility for player " + String::valueOf(creature->getObjectID()) + " with " + String::valueOf(visibilityIncrease), true);
	return visibilityIncrease;
}
void ChatManagerImplementation::broadcastMessage(CreatureObject* player, const UnicodeString& message,  uint64 target, uint32 moodid, uint32 mood2) {
	Zone* zone = player->getZone();
	PlayerObject* myGhost = NULL;
	bool godMode = false;

	if (zone == NULL)
		return;

	int language = 0;
	String firstName;

	if (player->isPlayerCreature() /*|| !((Player *)player)->isChatMuted() */) {
		CreatureObject* playerCreature = cast<CreatureObject*>(player);
		if (playerCreature)
		{
			firstName = playerCreature->getFirstName().toLowerCase();
			myGhost = playerCreature->getPlayerObject();
		}

		if (myGhost)
			language = myGhost->getLanguageID();
	}

	if (myGhost)
	{
		if (myGhost->hasGodMode())
			godMode = true;
	}

	StringIdChatParameter* param = NULL;

	if (message[0] == '@' && message.indexOf(":") != -1) {
		param = new StringIdChatParameter(message.toString());
	}

	CloseObjectsVector* closeObjects = (CloseObjectsVector*) player->getCloseObjects();

	SortedVector<QuadTreeEntry*> closeEntryObjects(200, 50);

	if (closeObjects != NULL) {
		closeObjects->safeCopyTo(closeEntryObjects);
	} else {
		player->info("Null closeobjects vector in ChatManager::broadcastMessage", true);
		zone->getInRangeObjects(player->getWorldPositionX(), player->getWorldPositionY(), 128, &closeEntryObjects, true);
	}

	float range = defaultSpatialChatDistance;

	float specialRange = spatialChatDistances.get(mood2);
	if (specialRange != -1) {
		range = specialRange;
	}

	try {
		for (int i = 0; i < closeEntryObjects.size(); ++i) {
			SceneObject* object = cast<SceneObject*>(closeEntryObjects.get(i));

			if (player->isInRange(object, range)) {

				//Notify observers that are expecting spatial chat.
				if (object->getObserverCount(ObserverEventType::SPATIALCHATRECEIVED)) {
					ManagedReference<ChatMessage*> chatMessage = new ChatMessage();
					chatMessage->setString(message.toString());

					EXECUTE_TASK_3(object, chatMessage, player, {
						if (player_p == NULL || object_p == NULL)
							return;

						Locker locker(object_p);

						SortedVector<ManagedReference<Observer*> > observers = object_p->getObservers(ObserverEventType::SPATIALCHATRECEIVED);
						for (int oc = 0; oc < observers.size(); oc++) {
							Observer* observer = observers.get(oc);
							Locker clocker(observer, object_p);
							if (observer->notifyObserverEvent(ObserverEventType::SPATIALCHATRECEIVED, object_p, chatMessage_p, player_p->getObjectID()) == 1)
								object_p->dropObserver(ObserverEventType::SPATIALCHATRECEIVED, observer);
						}
					});
				}

				if (object->isPlayerCreature()) {
					CreatureObject* creature = cast<CreatureObject*>(object);
					PlayerObject* ghost = creature->getPlayerObject();

					if (ghost == NULL)
						continue;

					if (!ghost->isIgnoring(firstName) || godMode) {
						SpatialChat* cmsg = NULL;

						if (param == NULL) {
							cmsg = new SpatialChat(player->getObjectID(), creature->getObjectID(), message, target, moodid, mood2, language);
						} else {
							cmsg = new SpatialChat(player->getObjectID(), creature->getObjectID(), *param, target, moodid, mood2);
						}

						creature->sendMessage(cmsg);
					}
				}
				else if( object->isPet() ){
					AiAgent* pet = cast<AiAgent*>(object);

					if (pet == NULL )
						continue;

					if( pet->isDead() || pet->isIncapacitated() )
						continue;

					PetManager* petManager = server->getPetManager();
					Locker clocker(pet, player);
					petManager->handleChat( player, pet, message.toString() );

				}
			}
		}
void ChatManagerImplementation::handleSocialInternalMessage(CreatureObject* sender, const UnicodeString& arguments) {
	if (sender->isPlayerCreature()) {
		ManagedReference<PlayerObject*> senderGhost = sender->getPlayerObject();

		if (senderGhost == NULL)
			return;

		if (senderGhost->isMuted()) {
			String reason = senderGhost->getMutedReason();

			if (reason != "")
				sender->sendSystemMessage("Your chat abilities are currently disabled by Customer Support for '" + reason + "'.");
			else
				sender->sendSystemMessage("Your chat abilities are currently disabled by Customer Support.");

			return;
		}
	}

	Zone* zone = sender->getZone();

	if (zone == NULL)
		return;

	StringTokenizer tokenizer(arguments.toString());
	uint64 targetid;
	uint32 emoteid, unkint, unkint2;

	try {
		targetid = tokenizer.getLongToken();
		emoteid = tokenizer.getIntToken();
		unkint = tokenizer.getIntToken();
		unkint2 = tokenizer.getIntToken();
	} catch (const Exception& e) {
		return;
	}

	//bool readlock = !zone->isLockedByCurrentThread();

	bool showtext = true;

	if (unkint2 == 0)
		showtext = false;

	String firstName;

	if (sender->isPlayerCreature())
		firstName = (cast<CreatureObject*>(sender))->getFirstName().toLowerCase();

	CloseObjectsVector* vec = (CloseObjectsVector*) sender->getCloseObjects();

	SortedVector<QuadTreeEntry* > closeEntryObjects(200, 50);

	if (vec != NULL) {
		vec->safeCopyTo(closeEntryObjects);
	} else {
		sender->info("Null closeobjects vector in ChatManager::handleSocialInternalMessage", true);
		zone->getInRangeObjects(sender->getWorldPositionX(), sender->getWorldPositionX(), 128, &closeEntryObjects, true);
	}

	float range = defaultSpatialChatDistance;

	for (int i = 0; i < closeEntryObjects.size(); ++i) {
		SceneObject* object = cast<SceneObject*>(closeEntryObjects.get(i));

		if (object->isPlayerCreature()) {
			CreatureObject* creature = cast<CreatureObject*>(object);

			Reference<PlayerObject*> ghost = creature->getSlottedObject("ghost").castTo<PlayerObject*>();

			if (ghost == NULL)
				continue;

			if (!ghost->isIgnoring(firstName) && creature->isInRange(sender, range)) {
				Emote* emsg = new Emote(creature, sender, targetid, emoteid, showtext);
				creature->sendMessage(emsg);

			}
		}
	}

}
Exemplo n.º 9
0
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);
		}
	}
}
Exemplo n.º 10
0
void ZoneComponent::updateZoneWithParent(SceneObject* sceneObject, SceneObject* newParent, bool lightUpdate, bool sendPackets) {
	ManagedReference<Zone*> zone = sceneObject->getZone();
	ManagedReference<SceneObject*> oldParent = sceneObject->getParent();

	if (oldParent != NULL && !oldParent->isCellObject())
		return;

	if (zone == NULL)
		zone = newParent->getRootParent().get()->getZone();

	Locker _locker(zone);

	if (oldParent == NULL) { // we are in zone, enter cell
		//zone->remove(sceneObject);

		newParent->transferObject(sceneObject, -1, true);

		zone->unlock();
		//insertToBuilding(sceneObject, dynamic_cast<BuildingObject*>(newParent->getParent()));
	} else { // we are in cell already
		if (oldParent != newParent) {
			//oldParent->removeObject(sceneObject, false);
			newParent->transferObject(sceneObject, -1, true);

			zone->unlock();
		} else {
			zone->unlock();

			zone->updateActiveAreas(sceneObject);
		}

		//notify in range objects that i moved
	}

	CloseObjectsVector* closeObjects = (CloseObjectsVector*) sceneObject->getCloseObjects();

	if (closeObjects != NULL) {
		SortedVector<ManagedReference<QuadTreeEntry*> > objects(closeObjects->size(), 10);
		closeObjects->safeCopyTo(objects);

		for (int i = 0; i < objects.size(); ++i) {
			QuadTreeEntry* object = objects.get(i);
			try {
				object->notifyPositionUpdate(sceneObject);
			} catch (Exception& e) {

			}
		}
	}

	//zoneLocker.release();

	//zone->unlock();

	bool isInvis = false;

	if (sceneObject->isCreatureObject()) {
		CreatureObject* creo = cast<CreatureObject*>(sceneObject);
		if(creo->isInvisible())
			isInvis = true;
	}

	if (sendPackets && !isInvis) {
		if (lightUpdate) {
			LightUpdateTransformWithParentMessage* message = new LightUpdateTransformWithParentMessage(sceneObject);
			sceneObject->broadcastMessage(message, false, true);
		} else {
			UpdateTransformWithParentMessage* message = new UpdateTransformWithParentMessage(sceneObject);
			sceneObject->broadcastMessage(message, false, true);
		}
	}

	try {
		notifySelfPositionUpdate(sceneObject);
	} catch (Exception& e) {
		sceneObject->error("Exception caught while calling notifySelfPositionUpdate(sceneObject) in ZoneComponent::updateZoneWithParent");
		sceneObject->error(e.getMessage());
	}

	zone->wlock();
}
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastDestroyPrivate(object, selfObject);

			return;
		} else {
			return;
		}
	}

	if (zone == NULL)
		return;

	//Locker zoneLocker(zone);

	//	bool readlock = !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	//	zone->rlock(readlock);

	try {
		if (closeobjects == NULL) {
			info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true);
			zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects.size();
		} else {

			CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects;
			closeSceneObjects.removeAll(vec->size(), 10);
			//			closeSceneObjects.addAll(*closeobjects);
			vec->safeCopyTo(closeSceneObjects);

			maxInRangeObjectCount = closeSceneObjects.size();//closeobjects->size();

		}


	} catch (...) {
		//zone->runlock(readlock);

		throw;
	}

	//	zone->runlock(readlock);

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			object->sendDestroyTo(scno);
		}
	}
}
bool CollisionManager::checkLineOfSight(SceneObject* object1, SceneObject* object2) {
	Zone* zone = object1->getZone();

	if (zone == NULL)
		return false;

	if (object2->getZone() != zone)
		return false;

	if (object1->isAiAgent() || object2->isAiAgent()) {
		Vector<WorldCoordinates>* path = PathFinderManager::instance()->findPath(object1, object2);

		if (path == NULL)
			return false;
		else
			delete path;
	}

	ManagedReference<SceneObject*> rootParent1 = object1->getRootParent();
	ManagedReference<SceneObject*> rootParent2 = object2->getRootParent();

	if (rootParent1 != NULL || rootParent2 != NULL) {
		if (rootParent1 == rootParent2) {
			return CollisionManager::checkLineOfSightInBuilding(object1, object2, rootParent1);
		} else if (rootParent1 != NULL && rootParent2 != NULL)
			return false; //different buildings
	}

	//switching z<->y, adding player height (head)
	Vector3 rayOrigin = object1->getWorldPosition();

	float heightOrigin = 1.f;
	float heightEnd = 1.f;

	Reference<SortedVector<ManagedReference<QuadTreeEntry*> >*> closeObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >();
	// = object1->getCloseObjects();

	int maxInRangeObjectCount = 0;

	if (object1->getCloseObjects() == NULL) {
		object1->info("Null closeobjects vector in CollisionManager::checkLineOfSight", true);
//		closeObjectsCopy = new SortedVector<ManagedReference<QuadTreeEntry*> >();
		zone->getInRangeObjects(object1->getPositionX(), object1->getPositionY(), 512, closeObjects, true);
	} else {
		CloseObjectsVector* vec = (CloseObjectsVector*) object1->getCloseObjects();
		vec->safeCopyTo(*closeObjects);		
	}

	if (object1->isCreatureObject())
		heightOrigin = getRayOriginPoint(cast<CreatureObject*>(object1));

	if (object2->isCreatureObject())
		heightEnd = getRayOriginPoint(cast<CreatureObject*>(object2));

	rayOrigin.set(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ() + heightOrigin);

	Vector3 rayEnd = object2->getWorldPosition();
	rayEnd.set(rayEnd.getX(), rayEnd.getY(), rayEnd.getZ() + heightEnd);

	float dist = rayEnd.distanceTo(rayOrigin);
	float intersectionDistance;
	Triangle* triangle = NULL;

//	zone->rlock();

	try {
		for (int i = 0; i < closeObjects->size(); ++i) {
			AABBTree* aabbTree = NULL;

			SceneObject* scno = cast<SceneObject*>(closeObjects->get(i).get());

			try {
				aabbTree = getAABBTree(scno, 255);

				if (aabbTree == NULL)
					continue;

			} catch (Exception& e) {
				aabbTree = NULL;
			} catch (...) {
//				zone->runlock();

				throw;
			}

			if (aabbTree != NULL) {
				//moving ray to model space
//				zone->runlock();

				try {
					Ray ray = convertToModelSpace(rayOrigin, rayEnd, scno);

					//structure->info("checking ray with building dir" + String::valueOf(structure->getDirectionAngle()), true);

					if (aabbTree->intersects(ray, dist, intersectionDistance, triangle, true)) {
						return false;
					}
				} catch (...) {
					throw;
				}

//				zone->rlock();

			}
		}
	} catch (Exception& e) {
		Logger::console.error("unreported exception caught in bool CollisionManager::checkLineOfSight(SceneObject* object1, SceneObject* object2) ");
		Logger::console.error(e.getMessage());
	}

//	zone->runlock();

	ManagedReference<SceneObject*> parent1 = object1->getParent();
	ManagedReference<SceneObject*> parent2 = object2->getParent();

	if (parent1 != NULL || parent2 != NULL) {
		CellObject* cell = NULL;

		if (parent1 != NULL && parent1->isCellObject()) {
			cell = cast<CellObject*>(parent1.get());
		} else if (parent2 != NULL && parent2->isCellObject()) {
			cell = cast<CellObject*>(parent2.get());
		}

		if (cell != NULL) {
			return checkLineOfSightWorldToCell(rayOrigin, rayEnd, dist, cell);
		}
	}

	return true;
}