//********************************************************************* //a Player or creature is ALWAYS in the grid and possibly in a cell void SpatialIndexManager::RemoveObjectFromWorld(PlayerObject *removePlayer) { DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld:: Player : " << removePlayer->getId(); //remove us from the grid _RemoveObjectFromGrid(removePlayer); //remove us out of the cell if(removePlayer->getParentId() == 0) { return; } CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(removePlayer->getParentId())); if(cell) { //unregister from the building and all its cells if(BuildingObject* building = dynamic_cast<BuildingObject*>(gWorldManager->getObjectById(cell->getParentId()))) { gContainerManager->unRegisterPlayerFromBuilding(building,removePlayer); } cell->removeObject(removePlayer); } else { DLOG(info) << "SpatialIndexManager::RemoveObjectFromWorld (player): couldn't find cell " << removePlayer->getParentId(); } }
void MovingObject::updatePositionInCell(uint64 parentId, const glm::vec3& newPosition) { uint64 oldParentId = this->getParentId(); if (oldParentId != parentId) { // We changed cell CellObject* cell = NULL; // Remove us. if (!this->getKnownPlayers()->empty()) { gMessageLib->broadcastContainmentMessage(this,oldParentId,0); } // only remove us from si, if we just entered the building if (oldParentId != 0) { // We are still inside. if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId)))) { cell->removeObject(this); } else { LOG(WARNING) << "Error removing " << this->getId() << " from cell " << this->getParentId(); } } else { // remove us from qt // We just entered a building. if (this->getSubZoneId()) { if (std::shared_ptr<QTRegion> region = gWorldManager->getQTRegion(this->getSubZoneId())) { this->setSubZoneId(0); region->mTree->removeObject(this); } } } // put us into new one if (!this->getKnownPlayers()->empty()) { gMessageLib->broadcastContainmentMessage(this,parentId,4); } if ((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId)))) { cell->addObjectSecure(this); } else { LOG(WARNING) << "Error adding " << this->getId() << " from cell " << this->getParentId(); } // update the player this->setParentId(parentId); } }
void ElevatorTerminal::handleObjectMenuSelect(uint8 messageType,Object* srcObject) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(srcObject); if(!playerObject || !playerObject->isConnected() || playerObject->getSamplingState() || playerObject->isIncapacitated() || playerObject->isDead()) { return; } if(messageType == radId_elevatorUp) { gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectUp),"",playerObject); // remove player from current position, elevators can only be inside CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())); if(cell) { cell->removeObject(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId()); } // put him into new one playerObject->mDirection = mDstDirUp; playerObject->mPosition = mDstPosUp; playerObject->setParentId(mDstCellUp); cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellUp)); if(cell) { cell->addObjectSecure(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellUp); } gMessageLib->sendDataTransformWithParent(playerObject); } else if(messageType == radId_elevatorDown) { gMessageLib->sendPlayClientEffectObjectMessage(gWorldManager->getClientEffect(mEffectDown),"",playerObject); // remove player from current position, elevators can only be inside CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(playerObject->getParentId())); if(cell) { cell->removeObject(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,playerObject->getParentId()); } // put him into new one playerObject->mDirection = mDstDirDown; playerObject->mPosition = mDstPosDown; playerObject->setParentId(mDstCellDown); cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(mDstCellDown)); if(cell) { cell->addObjectSecure(playerObject); } else { gLogger->logMsgF("could not find cell %"PRIu64"",MSG_HIGH,mDstCellDown); } gMessageLib->sendDataTransformWithParent(playerObject); } else { gLogger->logMsgF("ElevatorTerminal: Unhandled MenuSelect: %u",MSG_HIGH,messageType); } }
bool ObjectController::removeFromContainer(uint64 targetContainerId, uint64 targetId) { PlayerObject* playerObject = dynamic_cast<PlayerObject*>(mObject); Object* itemObject = gWorldManager->getObjectById(targetId); Inventory* inventory = dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory)); TangibleObject* targetContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(targetContainerId)); TangibleObject* tangible = dynamic_cast<TangibleObject*>(itemObject); Item* item = dynamic_cast<Item*>(itemObject); // its us if (tangible->getParentId() == playerObject->getId()) { // unequip it return playerObject->getEquipManager()->unEquipItem(itemObject); } //the containerObject is the container used in the tutorial or some random dungeon container Container* container = dynamic_cast<Container*>(gWorldManager->getObjectById(tangible->getParentId())); if (container) { container->removeObject(itemObject); //gContainerManager->destroyObjectToRegisteredPlayers(container, tangible->getId()); if (gWorldConfig->isTutorial()) { playerObject->getTutorial()->transferedItemFromContainer(targetId, tangible->getParentId()); // If object is owned by player (private owned for instancing), we remove the owner from the object. // what is this used for ??? if (itemObject->getPrivateOwner() == playerObject->getId()) { itemObject->setPrivateOwner(0); } } return true; } //creature inventories are a special case - their items are temporary!!! we cannot loot them directly CreatureObject* unknownCreature; Inventory* creatureInventory; if (itemObject->getParentId() && (unknownCreature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(itemObject->getParentId() - INVENTORY_OFFSET))) && (creatureInventory = dynamic_cast<Inventory*>(unknownCreature->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))) && (creatureInventory->getId() == itemObject->getParentId()) && (creatureInventory->getId() != inventory->getId())) { if(!creatureInventory->removeObject(itemObject)) { LOG(warning) << "ObjectController::removeFromContainer: Internal Error could not remove " << itemObject->getId() << " from creature inventory " << creatureInventory->getId(); return false; } // we destroy the item in this case as its a temporary!! // we do not want to clog the db with unlooted items gContainerManager->destroyObjectToRegisteredPlayers(creatureInventory, tangible->getId()); ObjectIDList* invObjList = creatureInventory->getObjects(); if (invObjList->size() == 0) { // Put this creature in the pool of delayed destruction and remove the corpse from scene. gWorldManager->addCreatureObjectForTimedDeletion(creatureInventory->getParentId(), LootedCorpseTimeout); } if (gWorldConfig->isTutorial()) { // TODO: Update tutorial about the loot. playerObject->getTutorial()->transferedItemFromContainer(targetId, creatureInventory->getId()); } //bail out here and request the item over the db - as the item in the NPC has a temporary id and we dont want that in the db // This ensure that we do not use/store any of the temp id's in the database. gObjectFactory->requestNewDefaultItem(inventory, item->getItemFamily(), item->getItemType(), inventory->getId(), 99, glm::vec3(), ""); return false; } //cells are NOT tangibles - thei are static Objects CellObject* cell; if(cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(itemObject->getParentId()))) { // Stop playing if we pick up the (permanently placed) instrument we are playing if (item && (item->getItemFamily() == ItemFamily_Instrument)) { uint32 instrumentType = item->getItemType(); if ((instrumentType == ItemType_Nalargon) || (instrumentType == ItemType_omni_box) || (instrumentType == ItemType_nalargon_max_reebo)) { // It's a placeable original instrument. // Are we targeting the instrument we actually play on? if (playerObject->getActiveInstrumentId() == item->getId()) { gEntertainerManager->stopEntertaining(playerObject); } } } //we *cannot* remove static tangibles like the structureterminal!!!! if(tangible->getStatic()) { return false; } // Remove object from cell. cell->removeObject(itemObject); return true; } //some other container ... hopper backpack chest etc TangibleObject* containingContainer = dynamic_cast<TangibleObject*>(gWorldManager->getObjectById(tangible->getParentId())); if(containingContainer && containingContainer->removeObject(itemObject)) { return true; } return false; }
void ObjectController::handleDataTransformWithParent(Message* message,bool inRangeUpdate) { // FIXME: for now assume we only get messages from players PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); glm::vec3 pos; glm::quat dir; uint32 inMoveCount; uint32 tickCount; uint64 parentId; float speed; bool updateAll = false; // get tick and move counters tickCount = message->getUint32(); inMoveCount = message->getUint32(); // only process if its in sequence if (player->getInMoveCount() <= inMoveCount) { uint64 oldParentId = player->getParentId(); //uint32 ticks = tickCount - player->getClientTickCount(); // update tick and move counters player->setClientTickCount(tickCount); player->setInMoveCount(inMoveCount); // get new direction, position, parent and speed parentId = message->getUint64(); dir.x = message->getFloat(); dir.y = message->getFloat(); dir.z = message->getFloat(); dir.w = message->getFloat(); pos.x = message->getFloat(); pos.y = message->getFloat(); pos.z = message->getFloat(); speed = message->getFloat(); // gLogger->logMsgF("Position inside = %f, %f, %f",MSG_NORMAL, pos.x, pos.y, pos.z); // gLogger->logMsgF("Direction = %f, %f, %f, %f",MSG_NORMAL, dir.x, dir.y, dir.z, dir.w); // stop entertaining, if we were if(player->getPerformingState() != PlayerPerformance_None && player->getPosture() != CreaturePosture_SkillAnimating) { gEntertainerManager->stopEntertaining(player); } // if we changed cell if (oldParentId != parentId) { CellObject* cell = NULL; // gLogger->logMsgF("We changed cell from (%"PRIu64") to (%"PRIu64")",MSG_NORMAL, oldParentId, parentId); // Remove us from whatever we where in before. // (4 for add and 0 for remove) gMessageLib->broadcastContainmentMessage(player->getId(),oldParentId,0,player); // only remove us from si, if we just entered the building if (oldParentId != 0) { if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(oldParentId)))) { cell->removeObject(player); // Done above.. gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player); } else { gLogger->logMsgF("Error removing %"PRIu64" from cell(%"PRIu64")",MSG_NORMAL,player->getId(),oldParentId); } } else { updateAll = true; // We just entered the building. // remove us from qt if(player->getSubZoneId()) { if(QTRegion* region = gWorldManager->getQTRegion(player->getSubZoneId())) { player->setSubZoneId(0); region->mTree->removeObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->setSubZoneId(0); region->mTree->removeObject(player->getMount()); //Can't ride into a building with a mount! :-p //However, its easy to do so we have handling incase the client is tricked. // the vehicle is the INTANGIBLE Datapad Controller // the *vehicle* itself is the BODY if(Vehicle* datapad_pet = dynamic_cast<Vehicle*>(gWorldManager->getObjectById(player->getMount()->getPetController()))) { datapad_pet->dismountPlayer(); datapad_pet->store(); } } } } } // put us into new one gMessageLib->broadcastContainmentMessage(player->getId(),parentId,4,player); if((cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(parentId)))) { cell->addObjectSecure(player); // Inform tutorial about cell change. if (gWorldConfig->isTutorial()) { player->getTutorial()->setCellId(parentId); // gLogger->logMsgF("handleDataTransformWithParent: Adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId); } } else { gLogger->logMsgF("Error adding %"PRIu64" to cell(%"PRIu64")",MSG_NORMAL,player->getId(),parentId); } } // update the player player->setParentId(parentId); player->mDirection = dir; player->mPosition = pos; player->setCurrentSpeed(speed); // destroy the instanced instrument if out of range if (player->getPlacedInstrumentId()) { if (!gWorldManager->objectsInRange(player->getId(), player->getPlacedInstrumentId(), 5.0)) { if (Item* item = dynamic_cast<Item*>(gWorldManager->getObjectById(player->getPlacedInstrumentId()))) { destroyObject(item->getId()); } } } // Terminate active conversation with npc if to far away (trainers only so far). ActiveConversation* ac = gConversationManager->getActiveConversation(player->getId()); if (ac != NULL) { // We do have a npc conversation going. if (!gWorldManager->objectsInRange(player->getId(), (ac->getNpc())->getId(), 11.0)) { // Terminate conversation, since we are out of range. gMessageLib->sendSystemMessage(player,L"","system_msg","out_of_range"); gConversationManager->stopConversation(player, true); // We will get the current dialog text in a chat bubble, only seen by me. Impressive :) } } if (updateAll) { // Update our world. playerWorldUpdate(true); // Speed up the timed update, if any pending. gWorldManager->addPlayerMovementUpdateTime(player, 250); } else { if (!gWorldConfig->isInstance()) { // send out updates gMessageLib->sendUpdateTransformMessageWithParent(player); } else { // send out position updates to known players in group or self only gMessageLib->sendUpdateTransformMessageWithParent(player, player); } } } }