void Player::update(float deltaTime){

	getRigidBody()->activate();

	// modifying the speed based on the movement mode
	if (inputHandler.isKeyDown(KEY_LCONTROL)){
		// stealth movement
		_mod = 2.0f;
	}
	else
		// normal movement
		_mod = 5.0f;

	if (inputHandler.isKeyDown(KEY_LSHIFT))
		_mod *= 2.0f;

	//make noise unless crouched, more when sprinting
	if (inputHandler.isKeyDown(KEY_LSHIFT) && (inputHandler.isKeyDown(KEY_KEY_W) || inputHandler.isKeyDown(KEY_KEY_A) || inputHandler.isKeyDown(KEY_KEY_S) || inputHandler.isKeyDown(KEY_KEY_D))){
		_noiseAllowance -= 0.020f;
	}
	else if (!inputHandler.isKeyDown(KEY_LCONTROL) && (inputHandler.isKeyDown(KEY_KEY_W) || inputHandler.isKeyDown(KEY_KEY_A) || inputHandler.isKeyDown(KEY_KEY_S) || inputHandler.isKeyDown(KEY_KEY_D))){
		_noiseAllowance -= 0.005f;
	}


	/* SETTING UP THE DIRECTION MATRIX */

	// preparing the matrix
	matrix4 mat0;
	mat0.setRotationAxisRadians(_yaw, vector3df(0, 1, 0));

	matrix4 mat1;
	mat1.setRotationAxisRadians(_pitch, vector3df(1, 0, 0));

	matrix4 mat = IdentityMatrix;
	mat = mat0 * mat1;

	// transform direction vectors based on the orientation of the player
	vector3df backward(0.0f, 0.0f, -1.0f);
	vector3df toLeft(-1.0f, 0.0f, .0f);
	vector3df toRight(1.0f, 0.0f, 0.0f);
	vector3df forward(0.0f, 0.0f, 1.0f);
	vector3df up(0.0f, 1.0f, 0.0f);

	mat.transformVect(forward);
	mat.transformVect(backward);
	mat.transformVect(toLeft);
	mat.transformVect(toRight);

	setForward(forward);
	setUp(up);

	/* MOVEMENT */

	// setting key press events
	if (inputHandler.isKeyDown(KEY_KEY_D) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(toRight.X, 0.0f, -toRight.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_A) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(toLeft.X, 0.0f, -toLeft.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_S) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-backward.X, 0.0f, backward.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_W) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-forward.X, 0.0f, forward.Z)*_mod);
	}
	// setting double key press events
	if (inputHandler.isKeyDown(KEY_KEY_W) && inputHandler.isKeyDown(KEY_KEY_A) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-forward.X + toLeft.X, 0.0f, forward.Z - toLeft.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_W) && inputHandler.isKeyDown(KEY_KEY_D) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-forward.X + toRight.X, 0.0f, forward.Z - toRight.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_S) && inputHandler.isKeyDown(KEY_KEY_A) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-backward.X + toLeft.X, 0.0f, backward.Z - toLeft.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_KEY_S) && inputHandler.isKeyDown(KEY_KEY_D) && isDown()) {
		this->getRigidBody()->setLinearVelocity(btVector3(-backward.X + toRight.X, 0.0f, backward.Z - toRight.Z)*_mod);
	}

	// jump!
	if (inputHandler.isKeyDown(KEY_SPACE) && !inputHandler.wasKeyDown(KEY_SPACE) && isDown() && !isStealthActive()) {
		getRigidBody()->setLinearVelocity(btVector3(up.X, up.Y*_mod, up.Z));
		game.getAudioEngine()->play2D("sounds/common/jump.wav");
		_noiseAllowance -= 2.0f;
	}
	// TODO: fix the jumping and moving forward feature
	if (inputHandler.isKeyDown(KEY_SPACE) && inputHandler.isKeyDown(KEY_KEY_W) && isDown() && !isStealthActive()) {
		getRigidBody()->setLinearVelocity(btVector3(up.X - forward.X, up.Y, up.Z + forward.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_SPACE) && inputHandler.isKeyDown(KEY_KEY_S) && isDown() && !isStealthActive()) {
		getRigidBody()->setLinearVelocity(btVector3(up.X - backward.X, up.Y, up.Z + backward.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_SPACE) && inputHandler.isKeyDown(KEY_KEY_A) && isDown() && !isStealthActive()) {
		getRigidBody()->setLinearVelocity(btVector3(up.X + toLeft.X, up.Y, up.Z - toLeft.Z)*_mod);
	}
	if (inputHandler.isKeyDown(KEY_SPACE) && inputHandler.isKeyDown(KEY_KEY_D) && isDown() && !isStealthActive()) {
		getRigidBody()->setLinearVelocity(btVector3(up.X + toRight.X, up.Y, up.Z - toRight.Z)*_mod);
	}

	/* THROWABLE OBJECTS*/

	//action key
	if (inputHandler.isKeyDown(KEY_KEY_E) && !inputHandler.wasKeyDown(KEY_KEY_E)){
		if (_isCarrying){//dropping
			if (this->getCarriedItem() != NULL){
				this->_isCarrying = false;
				Message m(this->getCarriedItem(), "dropped", 0);
				MessageHandler::sendMessage(m);
				this->clearCarriedItem();
				_hasKey = false;
				_noiseAllowance -= 1.0f;
			}
		}
		else{//picking up
			std::list<Entity*>* objects = EntityManager::getNamedEntities("Object");
			vector3df playerPos = _node->getPosition();
			auto iter = objects->begin();
			while (iter != objects->end()){
				Object* obj = (Object*)(*iter);
				btVector3 hm = obj->getRigidBody()->getCenterOfMassPosition();
				vector3df objPos = vector3df(hm.getX(), hm.getY(), hm.getZ());
				vector3df toPlayer = playerPos - objPos;
				if (toPlayer.getLength() < 5 && (getCurrentRoom() == obj->getCurrentRoom())){
					if (obj->getItemName() == "key") {
						_hasKey = true;
						std::cout << _hasKey << std::endl;
					}					
					obj->setPickedUp(true);
					this->setCarriedItem(obj);
					this->_isCarrying = true;
					//does the player need a hint?
					HudManager* hud = (HudManager*)EntityManager::getNamedEntities("Hudman")->front();
					if (!hud->hasHintBeenShownFor("Throw")){
						hud->drawHintFor("Throw");
					}
					break;
				}
				iter++;
			}

		}
	}

	if (inputHandler.getCurrentMouse().LeftButton){
		if (_isCarrying){//dropping
			if (this->getCarriedItem() != NULL){
				this->_isCarrying = false;
				Message m(this->getCarriedItem(), "thrown", 0);
				MessageHandler::sendMessage(m);
				this->clearCarriedItem();
				_noiseAllowance -= 5.0f;
				//does the player need a hint?
				HudManager* hud = (HudManager*)EntityManager::getNamedEntities("Hudman")->front();
				if (!hud->hasHintBeenShownFor("Noise")){
					hud->drawHintFor("Noise");
				}
				_hasKey = false;
			}
		}
	}

	/* CHECKING THE DOORS */
	std::list<Entity*>* doors = EntityManager::getNamedEntities("Door");
	vector3df playerPos = _node->getPosition();
	auto doorIter = doors->begin();
	while (doorIter != doors->end()){

		Door* door = (Door*)(*doorIter);
		btVector3 btPos = door->getRigidBody()->getCenterOfMassPosition();
		vector3df doorPos = vector3df(btPos.x(), btPos.y(), btPos.z());
		vector3df toPlayer = playerPos - doorPos;

		if (toPlayer.getLength() < 3 && inputHandler.isKeyDown(KEY_KEY_F) && !inputHandler.wasKeyDown(KEY_KEY_F)) {
			btTransform transform = getRigidBody()->getCenterOfMassTransform();

			if (door->getDirection() == 1 && playerPos.X < doorPos.X && !door->isExit()) {
				transform.setOrigin(btVector3(doorPos.X + 2.0f, playerPos.Y, doorPos.Z));
			}
			else if (door->getDirection() == 2 && playerPos.X > doorPos.X && !door->isExit()) {
				transform.setOrigin(btVector3(doorPos.X - 2.0f, playerPos.Y, doorPos.Z));
			}
			else if (door->getDirection() == 3 && playerPos.Z < doorPos.Z && !door->isExit()) {
				transform.setOrigin(btVector3(doorPos.X, playerPos.Y, doorPos.Z + 2.0f));
			}
			else if (door->getDirection() == 4 && playerPos.Z > doorPos.Z && !door->isExit()) {
				transform.setOrigin(btVector3(doorPos.X, playerPos.Y, doorPos.Z - 2.0f));
			}
			else if (door->getDirection() == 2 && playerPos.X > doorPos.X && door->isExit() && _hasKey) {
				//exitdoor with key
				game.setEndCause((allItemsCollected() ? "win" : "fail"));
				game.setNoiseMade(_startingNoise - _noiseAllowance);
				inputHandler.setEnded(true);
			}
			else if (door->getDirection() == 2 && playerPos.X > doorPos.X && door->isExit() && !_hasKey){
				game.getAudioEngine()->play2D("sounds/common/locked_door.wav");
			}

			getRigidBody()->setCenterOfMassTransform(transform);
		}
		doorIter++;
	}
	/* GET THE ROOM THE PLAYER IS IN */
	std::list<Entity*>* rooms = EntityManager::getNamedEntities("Room");
	playerPos = _node->getPosition();
	auto iterator = rooms->begin();
	while (iterator != rooms->end()){

		Room* room = (Room*)(*iterator);
		vector3df roomPos = room->getPosition();
		vector3df roomScale = room->getScale();
		vector3df toPlayer = playerPos - roomPos;
		if (toPlayer.getLength() < roomScale.Z / 2)
			setCurrentRoom(room->getName());
		iterator++;
	}

	if (_noiseAllowance<0.0f){
		game.setEndCause("lose");
		inputHandler.setEnded(true);
	}
}