void ConversationManager::updateConversation(uint32 selectId,PlayerObject* player) { ActiveConversation* av = getActiveConversation(player->getId()); if(!av) { gLogger->logMsgF("ConversationManager::updateConversation: could not find conversation for %"PRIu64,MSG_NORMAL,player->getId()); return; } av->updateCurrentPage(selectId); ConversationPage* currentPage = av->getCurrentPage(); if(!currentPage) { stopConversation(player,true); return; } if(currentPage->mAnimation) { if (gWorldConfig->isInstance()) { // We are running in an instance. gMessageLib->sendCreatureAnimation(av->getNpc(),gWorldManager->getNpcConverseAnimation(currentPage->mAnimation), player); } else { gMessageLib->sendCreatureAnimation(av->getNpc(),gWorldManager->getNpcConverseAnimation(currentPage->mAnimation)); } // gMessageLib->sendCreatureAnimation(av->getNpc(),gWorldManager->getNpcConverseAnimation(currentPage->mAnimation)); } gMessageLib->sendNPCDialogMessage(av,player); gMessageLib->sendNPCDialogOptions(av->getFilteredOptions(),player); // Post process npc conversation. av->postProcessCurrentPage(); }
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); } } } }
void ObjectController::handleDataTransform(Message* message,bool inRangeUpdate) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); if (!player) { gLogger->logMsgF("ObjectController::handleDataTransform Object is NOT A PLAYER, id = %"PRIu64"", MSG_HIGH, mObject->getId()); return; } glm::vec3 pos; glm::quat dir; uint32 inMoveCount; uint32 tickCount; float speed; bool updateAll = false; // get tick and move counters tickCount = message->getUint32(); inMoveCount = message->getUint32(); // gLogger->logMsg("ObjectController::handleDataTransform"); //uint64 localTimeStart = Anh_Utils::Clock::getSingleton()->getLocalTime(); // only process if its in sequence if(player->getInMoveCount() >= inMoveCount) { return; } //uint32 ticks = tickCount - player->getClientTickCount(); // update tick and move counters... player->setLastMoveTick(tickCount); player->setClientTickCount(tickCount); player->setInMoveCount(inMoveCount); if(player->checkIfMounted() && player->getMount()) { //Player is mounted lets update his mount too player->getMount()->setLastMoveTick(tickCount); //player->getMount()->setInMoveCount((inMoveCount+1)); player->getMount()->setInMoveCount((inMoveCount)); // + 1 or nor does not matter, as long as we update inMoveCount. } // get new direction, position and speed 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 outside = %.2f, %.2f, %.2f",MSG_NORMAL, pos.x, pos.y, pos.z); /* if (Heightmap::isHeightmapCacheAvaliable()) { gLogger->logMsgF("Heightmap value = %.2f",MSG_NORMAL, Heightmap::Instance()->getCachedHeightAt2DPosition(pos.x, pos.z)); } */ // gLogger->logMsgF("Direction = %f, %f, %f, %f",MSG_NORMAL, dir.x, dir.y, dir.z, dir.w); // stop entertaining, if we were // important is, that if we move we change our posture to NOT skill animating anymore! // so only stop entertaining when we are performing and NOT skillanimationg if(player->getPerformingState() != PlayerPerformance_None && player->getPosture() != CreaturePosture_SkillAnimating) { gEntertainerManager->stopEntertaining(player); } // if we just left a building if(player->getParentId() != 0) { updateAll = true; // Testing with 4 for add and 0 for remove. // Remove us from previous cell. gMessageLib->broadcastContainmentMessage(player->getId(),player->getParentId(),0,player); // remove us from the last cell we were in if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()))) { cell->removeObject(player); } else { gLogger->logMsgF("Error removing %"PRIu64" from cell(%"PRIu64")",MSG_HIGH,player->getId(),player->getParentId()); } // we are outside again player->setParentId(0); player->mPosition = pos; // Add us to the world. gMessageLib->broadcastContainmentMessage(player->getId(),0,4,player); // add us to the qtree if(QTRegion* newRegion = mSI->getQTRegion((double)pos.x,(double)pos.z)) { player->setSubZoneId((uint32)newRegion->getId()); newRegion->mTree->addObject(player); } else { // we should never get here ! gLogger->logMsg("ObjController::handleDataTransform: could not find zone region in map"); gLogger->logMsg("ObjController:: probably a bot : %i64u",static_cast<int>(player->getId())); // hammertime ! //muglies botter sometimes sends us weird positions //however other 3rd party tools might do the same gWorldManager->addDisconnectedPlayer(player); return; } // Inform tutorial about cell change. if (gWorldConfig->isTutorial()) { player->getTutorial()->setCellId(0); } } else //we are not in a building { // we should be in a qt at this point // get the qt of the new position if(QTRegion* newRegion = mSI->getQTRegion((double)pos.x,(double)pos.z)) { // we didnt change so update the old one if((uint32)newRegion->getId() == player->getSubZoneId()) { // this also updates the players position newRegion->mTree->updateObject(player,pos); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { newRegion->mTree->updateObject(player->getMount(),pos); } } else { updateAll = true; gLogger->logMsg("ObjController::DataTransform: Changing subzone"); // remove from old if(QTRegion* oldRegion = gWorldManager->getQTRegion(player->getSubZoneId())) { oldRegion->mTree->removeObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { oldRegion->mTree->removeObject(player->getMount()); } } // update players position player->mPosition = pos; //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->mPosition = pos; } // put into new player->setSubZoneId((uint32)newRegion->getId()); newRegion->mTree->addObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->setSubZoneId((uint32)newRegion->getId()); newRegion->mTree->addObject(player->getMount()); } } } else { // we should never get here ! gLogger->logMsg("ObjController::DataTransform: could not find zone region in map"); gLogger->logMsg("ObjController:: probably a bot : %I64u",static_cast<int>(player->getId())); // hammertime ! // muglies botter sometimes sends us weird positions with X or Y far out of possible regions // however other 3rd party tools might do the same // we need to get rid of the client at this point nad probably should ban the player / add him to // a monitoring list when the coordinates were indeed out of bounds gWorldManager->addDisconnectedPlayer(player); return; } } player->mDirection = dir; player->setCurrentSpeed(speed); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->mDirection = dir; player->getMount()->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()) { //If player is mounted... move his mount too! if(player->checkIfMounted() && player->getMount()) { //gMessageLib->sendDataTransform(player->getMount()); gMessageLib->sendUpdateTransformMessage(player->getMount()); } else { // send out position updates to known players // please note that these updates mess up our dance performance if(player->getPerformingState() == PlayerPerformance_None) { gMessageLib->sendUpdateTransformMessage(player); } } } else { // send out position updates to known players in group or self only gMessageLib->sendUpdateTransformMessage(player, player); } } //uint64 localTimeEnd = Anh_Utils::Clock::getSingleton()->getLocalTime(); //gLogger->logMsgF("Exec time PRId32",MSG_NORMAL, localTimeEnd - localTimeStart); }
void ObjectController::handleDataTransform(Message* message,bool inRangeUpdate) { PlayerObject* player = dynamic_cast<PlayerObject*>(mObject); if (!player) { return; } glm::vec3 pos; glm::quat dir; uint32 inMoveCount; uint32 tickCount; 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) { return; } //uint32 ticks = tickCount - player->getClientTickCount(); // update tick and move counters... player->setLastMoveTick(tickCount); player->setClientTickCount(tickCount); player->setInMoveCount(inMoveCount); // get new direction, position and speed 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(); // stop entertaining ??? // important is, that if we move we change our posture to NOT skill animating anymore! // so only stop entertaining when we are performing and NOT skillanimationg if(player->getPerformingState() != PlayerPerformance_None && player->states.getPosture() != CreaturePosture_SkillAnimating) { gEntertainerManager->stopEntertaining(player); } // if we just left a building if(player->getParentId() != 0) { updateAll = true; // Testing with 4 for add and 0 for remove. // Remove us from previous cell. gMessageLib->broadcastContainmentMessage(player->getId(),player->getParentId(),0,player); // remove us from the last cell we were in if(CellObject* cell = dynamic_cast<CellObject*>(gWorldManager->getObjectById(player->getParentId()))) { cell->removeObject(player); } else { DLOG(INFO) << "Error removing" << player->getId() << " from cell " << player->getParentId(); } // we are outside again player->setParentId(0); player->mPosition = pos; // Add us to the world. gMessageLib->broadcastContainmentMessage(player->getId(),0,4,player); // add us to the qtree if(QTRegion* newRegion = mSI->getQTRegion((double)pos.x,(double)pos.z)) { player->setSubZoneId((uint32)newRegion->getId()); player->setSubZone(newRegion); newRegion->mTree->addObject(player); } else { // we should never get here ! // it basically means we left the map DLOG(INFO) << "ObjController::handleDataTransform: could not find zone region in map"; DLOG(INFO) << "ObjController:: probably a bot : " << player->getId(); // hammertime ! //muglies botter sometimes sends us weird positions //however other 3rd party tools might do the same gWorldManager->addDisconnectedPlayer(player); return; } // Inform tutorial about cell change. if (gWorldConfig->isTutorial()) { player->getTutorial()->setCellId(0); } } else //we are not in a building { // we should be in a qt at this point check our qt if we still are inside its bounds // please note, that there is exactly *one* qtregion per planet and qtregions do *not* overlap // so there is no need to search the region everytime even if we should decide to add more qtregions // subzone is NULL however, when we just left a building if(player->getSubZone() && player->getSubZone()->checkPlayerPosition(pos.x, pos.z)) { // this also updates the players position player->getSubZone()->mTree->updateObject(player,pos); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getSubZone()->mTree->updateObject(player->getMount(),pos); } } else //do an intersectsWithQuery of objects in the si to find our new region - //CAVE shouldnt it be a contains query ? //what do we do if several regions overlap ? if(QTRegion* newRegion = mSI->getQTRegion((double)pos.x,(double)pos.z)) { updateAll = true; // remove from old if(QTRegion* oldRegion = player->getSubZone()) { oldRegion->mTree->removeObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { oldRegion->mTree->removeObject(player->getMount()); } } // update players position player->mPosition = pos; //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->mPosition = pos; } // put into new player->setSubZoneId((uint32)newRegion->getId()); player->setSubZone(newRegion); newRegion->mTree->addObject(player); //If our player is mounted lets update his mount aswell if(player->checkIfMounted() && player->getMount()) { player->getMount()->setSubZoneId((uint32)newRegion->getId()); newRegion->mTree->addObject(player->getMount()); } } else { // we should never get here ! DLOG(INFO) << "ObjController::handleDataTransform: could not find zone region in map"; DLOG(INFO) << "ObjController:: probably a bot : " << player->getId(); // hammertime ! // muglies botter sometimes sends us weird positions with X or Y far out of possible regions // however other 3rd party tools might do the same // we need to get rid of the client at this point nad probably should ban the player / add him to // a monitoring list when the coordinates were indeed out of bounds gWorldManager->addDisconnectedPlayer(player); return; } } player->mDirection = dir; 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(::common::OutOfBand("system_msg", "out_of_range"), player); 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()) { //If player is mounted... move his mount too! if(player->checkIfMounted() && player->getMount()) { //gMessageLib->sendDataTransform(player->getMount()); player->getMount()->mDirection = dir; player->getMount()->setCurrentSpeed(speed); player->getMount()->setLastMoveTick(tickCount); player->getMount()->setInMoveCount((inMoveCount)); // + 1 or nor does not matter, as long as we update inMoveCount. gMessageLib->sendUpdateTransformMessage(player->getMount()); } else { // send out position updates to known players // please note that these updates mess up our dance performance /*if(player->getPerformingState() == PlayerPerformance_None) {*/ gMessageLib->sendUpdateTransformMessage(player); //} } } else { // send out position updates to known players in group or self only gMessageLib->sendUpdateTransformMessage(player, player); } } }