int LuaSceneObject::getPlayersInRange(lua_State *L) { int range = lua_tonumber(L, -1); Zone* thisZone = realObject->getZone(); if (thisZone == NULL) { lua_pushnil(L); return 1; } lua_newtable(L); Reference<SortedVector<ManagedReference<QuadTreeEntry*> >*> closeObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >(); thisZone->getInRangeObjects(realObject->getWorldPositionX(), realObject->getWorldPositionY(), range, closeObjects, true); int numPlayers = 0; for (int i = 0; i < closeObjects->size(); ++i) { SceneObject* object = cast<SceneObject*>(closeObjects->get(i).get()); if (object == NULL || !object->isPlayerCreature()) continue; CreatureObject* player = object->asCreatureObject(); if (player == NULL || player->isInvisible()) continue; numPlayers++; lua_pushlightuserdata(L, object); lua_rawseti(L, -2, numPlayers); } return 1; }
void InstallationObjectImplementation::broadcastMessage(BasePacket* message, bool sendSelf) { Zone* zone = getZone(); if (zone == NULL) return; Locker zoneLocker(zone); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; zone->getInRangeObjects(getPositionX(), getPositionY(), 512, &closeSceneObjects, false); for (int i = 0; i < closeSceneObjects.size(); ++i) { ManagedReference<SceneObject*> scno = cast<SceneObject*>( closeSceneObjects.get(i).get()); if (!sendSelf && scno == _this.get()) continue; if(!scno->isPlayerCreature()) continue; CreatureObject* creo = cast<CreatureObject*>( scno.get()); if(isOnAdminList(creo)) scno->sendMessage(message->clone()); } delete message; }
void JukeboxImplementation::changeMusic(const String& song) { Zone* zone = getZone(); if (zone == NULL) return; curSong = song; SortedVector<ManagedReference<QuadTreeEntry*> > closeObjects; zone->getInRangeObjects(getWorldPositionX(), getWorldPositionY(), radius, &closeObjects, true); for (int i = 0; i < closeObjects.size(); i++) { SceneObject* targetObject = cast<SceneObject*>(closeObjects.get(i).get()); if (targetObject != NULL && targetObject->isPlayerCreature()) { ManagedReference<CreatureObject*> player = cast<CreatureObject*>(targetObject); if (player != NULL) playMusicToPlayer(player, song); } } }
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 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); } } } }
bool CollisionManager::checkShipCollision(ShipObject* ship, const Vector3& targetPosition, Vector3& collisionPoint) { Zone* zone = ship->getZone(); if (zone == NULL) return false; TerrainManager* terrainManager = zone->getPlanetManager()->getTerrainManager(); if (terrainManager->getProceduralTerrainAppearance() != NULL) { float height = terrainManager->getHeight(targetPosition.getX(), targetPosition.getY()); float waterHeight = -16368.f; if (terrainManager->getWaterHeight(targetPosition.getY(), targetPosition.getY(), waterHeight)) height = MAX(waterHeight, height); if (height > targetPosition.getZ()) { collisionPoint = targetPosition; collisionPoint.setZ(height); //ship->info("colliding with terrain", true); return true; } } Vector3 rayOrigin = ship->getWorldPosition(); rayOrigin.set(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ()); Vector3 rayEnd; rayEnd.set(targetPosition.getX(), targetPosition.getY(), targetPosition.getZ()); float dist = rayEnd.distanceTo(rayOrigin); float intersectionDistance; Triangle* triangle = NULL; SortedVector<ManagedReference<QuadTreeEntry*> > objects(512, 512); zone->getInRangeObjects(targetPosition.getX(), targetPosition.getY(), 512, &objects, true); for (int i = 0; i < objects.size(); ++i) { AABBTree* aabbTree = NULL; SceneObject* scno = cast<SceneObject*>(objects.get(i).get()); try { aabbTree = getAABBTree(scno, -1); if (aabbTree == NULL) continue; } catch (Exception& e) { aabbTree = NULL; } catch (...) { throw; } if (aabbTree != NULL) { //moving ray to model space 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)) { //rayOrigin.set(rayOrigin.getX(), rayOrigin.getY(), rayOrigin.getZ()); Vector3 direction = rayEnd - rayOrigin; direction.normalize(); //intersectionDistance -= 0.5f; collisionPoint.set(rayOrigin.getX() + (direction.getX() * intersectionDistance), rayOrigin.getY() + (direction.getY() * intersectionDistance), rayOrigin.getZ() + (direction.getZ() * intersectionDistance)); //ship->info("colliding with building", true); return true; } } catch (Exception& e) { ship->error(e.getMessage()); } catch (...) { throw; } } } return false; }
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; }