Beispiel #1
0
void ObjectController::_handleCloseContainer(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject*	playerObject	= dynamic_cast<PlayerObject*>(mObject);

    if (gWorldConfig->isTutorial())
    {
        playerObject->getTutorial()->containerClose(targetId);
    }
}
Beispiel #2
0
void ObjectController::_handleNewbieSelectStartingLocation(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);
    // gLogger->hexDump(message->getData(),message->getSize());

    // Find the planet and position.
    if (gWorldConfig->isTutorial())
    {
        BString name;
        message->getStringUnicode16(name);

        if (!(name.getLength()))
        {
            return;
        }
        name.convert(BSTRType_ANSI);
        player->getTutorial()->warpToStartingLocation(name);
    }
}
void InsuranceTerminal::handleObjectMenuSelect(uint8 messageType,Object* srcObject)
{
	PlayerObject* playerObject = (PlayerObject*)srcObject;

	if (playerObject && playerObject->isConnected())
	{
		// Fetch all items that can be insured.
		BStringVector insuranceList;
		this->getUninsuredItems(playerObject, &insuranceList);

		if (gWorldConfig->isTutorial())
		{
			// We do a simpleified version of insurance when using the terminal in the Tutorial.
			if (this->getParentId() && gWorldManager->getObjectById(this->getParentId())->getParentId())
			{
				// We are located inside a building.

				// Insure all insurable items.
				if (mSortedInsuranceList.size() ==  0)
				{
					// You do not have any items that can be insured. BUT.. we ignore this for now when running the tutorial.
					// gMessageLib->sendSystemMessage(playerObject, L"", "terminal_ui", "no_insurable_items");
				}
				else
				{
					// Insure all the items.

					// Let's warn about the fatal error conditions first (object destroyed or invalid type),
					SortedInventoryItemList::iterator it = mSortedInsuranceList.begin();
					while (it != mSortedInsuranceList.end())
					{
						string selectedItemm = (*it).first;
						selectedItemm.convert(BSTRType_Unicode16);

						Object* object = gWorldManager->getObjectById((*it).second);
						if (!object)
						{
							// Invalid object, we send a warning about this error.
							gMessageLib->sendSystemMessage(playerObject, L"", "error_message", "insure_fail");
						}
						else 
						{
							TangibleObject* tangibleObject = dynamic_cast<TangibleObject*>(object);
							if (!tangibleObject)
							{
								// Not a tangible object, we send a warning about this error.
									gMessageLib->sendSystemMessage(playerObject, L"", "error_message", "insure_fail");
							}
							else if (!tangibleObject->hasInternalAttribute("insured"))
							{
								// This is not a fatal error, but should never happen.

								// [Insurance] Item uninsurable: %TT.
								gMessageLib->sendSystemMessage(playerObject,L"","error_message","prose_item_uninsurable", "","", L"", 0, "", "", selectedItemm);
							}
							else if (tangibleObject->getInternalAttribute<bool>("insured"))
							{
								// This is not a fatal error, but should never happen.

								// [Insurance] Item already insured: %TT. 
								gMessageLib->sendSystemMessage(playerObject,L"","error_message","prose_item_already_insured", "","", L"", 0, "", "", selectedItemm);
							}
							else
							{
								// Update attribute.
								tangibleObject->setInternalAttribute("insured","1");
								gWorldManager->getDatabase()->ExecuteSqlAsync(NULL,NULL,"UPDATE item_attributes SET value=1 WHERE item_id=%"PRIu64" AND attribute_id=%u",tangibleObject->getId(), 1270);

								tangibleObject->setTypeOptions(tangibleObject->getTypeOptions() | 4);

								// Update insurance status.
								(void)gMessageLib->sendUpdateTypeOption(tangibleObject, playerObject);
							}
						}
						it++;
					}
				}
				// Always display success when doing the tutorial.

				// Insurance transaction successfully completed. 
				gMessageLib->sendSystemMessage(playerObject,L"","base_player","insure_success");

				// Inform Tutorial about the insurance.
				playerObject->getTutorial()->tutorialResponse("insureItemsDone");
			}
		}
		else
		{
			switch(messageType)
			{
				case radId_itemUse:
				{
					if (playerObject->getNewPlayerExemptions())	
					{
						// player have free deatchs left.
						gUIManager->createNewMessageBox(this,"","@base_player:noob_confirm_insure_title","@base_player:noob_confirm_insure_prompt",playerObject, SUI_Window_Insurance_Newbie_MessageBox, SUI_MB_YESNO);
					}
					else
					{
						// We should display all uninsured items that can be insured, and that are wearing or carrying in our inventory.
						// Items in backpackage or in other containers within our inventory shall also be handled.
						gUIManager->createNewListBox(this,"insure","@sui:mnu_insure","Select an item to insure.",insuranceList,playerObject,SUI_Window_Insurance_ListBox, SUI_MB_OKCANCEL);
					}
				}
				break;

				case radId_Unknown:	// Insure All
				{
					if (insuranceList.size() == 0)
					{
						// You do not have any items that can be insured. 
						gMessageLib->sendSystemMessage(playerObject, L"", "terminal_ui", "no_insurable_items");
					}
					else
					{
						if (playerObject->getNewPlayerExemptions())	
						{
							// player have free deatchs left.
							gUIManager->createNewMessageBox(this,"","@base_player:noob_confirm_insure_title","@base_player:noob_confirm_insure_prompt",playerObject, SUI_Window_InsureAll_Newbie_MessageBox, SUI_MB_YESNO);
						}
						else
						{
							uint32 insuranceFee = insuranceList.size() * 100;
							int8 sql[256];
							sprintf(sql,"@terminal_ui:insure_all_d_prefix %u @terminal_ui:insure_all_d_suffix \n\n @terminal_ui:insure_all_confirm", insuranceFee);
							gUIManager->createNewMessageBox(this,"","@terminal_ui:insure_all_t",sql,playerObject, SUI_Window_InsuranceAll_MessageBox, SUI_MB_YESNO);
						}
					}
				}
				break;

				default:
				{
					gLogger->logMsgF("InsuranceTerminal::handleObjectMenuSelect Unhandled MenuSelect: %u",MSG_NORMAL,messageType);
				}
				break;
			}
		}
	}
}
Beispiel #4
0
void ObjectController::_handleGetAttributesBatch(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject*	playerObject	= dynamic_cast<PlayerObject*>(mObject);
    BString			requestStr;
    BStringVector	dataElements;
    BStringVector	dataElements2;
    uint16			elementCount;


    message->getStringUnicode16(requestStr);
    requestStr.convert(BSTRType_ANSI);
    requestStr.getRawData()[requestStr.getLength()] = 0;

    elementCount = requestStr.split(dataElements,' ');

    if(!elementCount)
    {
        return;
    }

    Message* newMessage;

    for(uint16 i = 0; i < elementCount; i++)
    {

        uint64 itemId	= boost::lexical_cast<uint64>(dataElements[i].getAnsi());
        Object* object	= gWorldManager->getObjectById(itemId);

        if(object == NULL)
        {
            // could be a resource
            Resource* resource = gResourceManager->getResourceById(itemId);

            if(resource != NULL)
            {
                resource->sendAttributes(playerObject);
                continue;
            }

            //could be a schematic!
            Datapad* datapad			= playerObject->getDataPad();
            ManufacturingSchematic* schem	= datapad->getManufacturingSchematicById(itemId);

            if(schem != NULL)
            {
                schem->sendAttributes(playerObject);
                continue;
            }

            MissionObject* mission			= datapad->getMissionById(itemId);
            if(mission != NULL)
            {
                mission->sendAttributes(playerObject);
                continue;
            }

            IntangibleObject* data = datapad->getDataById(itemId);
            if(data != NULL)
            {
                data->sendAttributes(playerObject);
                continue;
            }

            // TODO: check our datapad items
            if(playerObject->isConnected())
            {
                // default reply for schematics
                gMessageFactory->StartMessage();
                gMessageFactory->addUint32(opAttributeListMessage);
                gMessageFactory->addUint64(itemId);
                gMessageFactory->addUint32(0);
                //gMessageFactory->addUint16(0);
                //gMessageFactory->addUint32(40);

                newMessage = gMessageFactory->EndMessage();

                (playerObject->getClient())->SendChannelAUnreliable(newMessage, playerObject->getAccountId(),  CR_Client, 8);
            }

            //finally, when we are crafting this could be the new item, not yet added to the worldmanager??
            if(playerObject->getCraftingSession())
            {
                if(playerObject->getCraftingSession()->getItem()&&playerObject->getCraftingSession()->getItem()->getId() == itemId)
                {
                    playerObject->getCraftingSession()->getItem()->sendAttributes(playerObject);
                }
            }
        }
        else
        {
            // Tutorial: I (Eru) have to do some hacks here, since I don't know how to get the info of what object the client has selected (by single click) in the Inventory.
            if (gWorldConfig->isTutorial())
            {
                // Let's see if the actual object is the food item "Melon" in our inventory.
                if (dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))->getId() == object->getParentId())
                {
                    //uint64 id = object->getId();

                    // Is it an Item?
                    Item* item = dynamic_cast<Item*>(object);

                    // Check if this item is a food item.
                    if (item)
                    {
                        if (item->getItemFamily() == ItemFamily_Foods)
                        {
                            playerObject->getTutorial()->tutorialResponse("foodSelected");
                        }
                    }
                }
            }

            object->sendAttributes(playerObject);
        }
    }
}
Beispiel #5
0
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;
}
Beispiel #6
0
//=============================================================================
//
// open container
//
void ObjectController::_handleOpenContainer(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{

	PlayerObject*	playerObject	= dynamic_cast<PlayerObject*>(mObject);
	Object*			itemObject		= gWorldManager->getObjectById(targetId);

	if (itemObject)
	{
		if(glm::distance(playerObject->getWorldPosition(), itemObject->getWorldPosition()) > 10)
		{
			gMessageLib->SendSystemMessage(L"", playerObject, "system_msg", "out_of_range");
			return;
		}

		bool aContainer = false;

		if (gWorldConfig->isTutorial())
		{
			playerObject->getTutorial()->containerOpen(targetId);
		}

		if (itemObject->getType() == ObjType_Tangible)
		{
			TangibleObject* tangObj = dynamic_cast<TangibleObject*>(itemObject);
			if (tangObj->getTangibleGroup() == TanGroup_Container)
			{
				// Request container contents.
				gContainerFactory->requestObject(this,targetId,TanGroup_Container,0,playerObject->getClient());
				aContainer = true;
			}

			//this might be a backpack
			//or a chest - it needs to have a capacity to be a container!
			if (tangObj->getCapacity())
			{
				//checkContainingContainer checks the permission
				if(checkContainingContainer(tangObj->getId(),playerObject->getId()))
				{
					aContainer = true;
					
					//register the player to the container and create the content
					gContainerManager->registerPlayerToContainer(tangObj,playerObject);
				}
			}
		}
		//its not a Container* Object however in theory it still can be a backpack for example
		if (!aContainer)
		{
			// STF: container_error_message Key: container8 does not seem to be working, using this custom string temperary.
			gMessageLib->SendSystemMessage(L"You do not have permission to access that container.", playerObject);
		}
		else
		{
            gMessageLib->sendOpenedContainer(targetId, playerObject);
        }
    }
    else
    {
        DLOG(info) <<  "ObjectController::_handleOpenContainer: INVALID Object id " << targetId;
    }
}
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::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)
    {
        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);
        }
    }
}