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);
}
Ejemplo n.º 3
0
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);
        }
    }
}