void Character::Update(double aDelta)
    {
        int temp = m_Health;
        
        if(m_DestroyPlayer == true && m_Destroyed == false)
        {
            if (m_Timer != nullptr)
            {
                m_Timer->Stop();
                SafeDelete(m_Timer);
                m_Timer = nullptr;
                
                StopSwing();
            }
            
            DestroyCharacter();
            m_DestroyPlayer = false;
            m_Destroyed = true;            
        }
        
        //Timer
        if (m_Timer != nullptr)
        {
            m_Timer->Update(aDelta);
            if (m_Timer->IsRunning() == false)
            {
                SafeDelete(m_Timer);
                m_Timer = nullptr;
                
                StopSwing();
            }
        }
        //Destruction Timer
        if (m_DamageTimer != nullptr)
        {
            m_DamageTimer->Update(aDelta);
            if (m_DamageTimer->IsRunning() == false)
            {
                SafeDelete(m_DamageTimer);
                m_DamageTimer = nullptr;
            }
        }

        for (int i = 0; i < m_Limbs.size(); i++)
        {
            m_Limbs.at(i)->Update(aDelta);
        }
        
        m_Weapon->Update(aDelta);
    }
void StageState::Input() {
	if ((InputManager::GetInstance().KeyPress(SDLK_ESCAPE)) || (InputManager::GetInstance().ShouldQuit())){
		PauseState *state = new PauseState();
		Game::GetInstance().Push(state);
	}

	if (InputManager::GetInstance().KeyPress(SDLK_c)){
		Point tile(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
		tile = tileMap.GetTile(tile.x, tile.y);
		CreateCharacter(tile.x, tile.y);
	}

	if (InputManager::GetInstance().KeyPress(SDLK_d)){
		DestroyCharacter(objectArray.size()-1);
	}

	if (InputManager::GetInstance().KeyPress(SDLK_RETURN)){
		CheatState *state = new CheatState(this, data);
		Game::GetInstance().Push(state);
	}
	if(InputManager::GetInstance().MouseRelease(SDL_BUTTON_LEFT)){

		switch (action){
		case NONE:
			ptile = tileMap.GetTile(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
			p = tileMap.GetTileCenter(ptile);
			//objectArray[0]->AddObjective(p.x, p.y, ptile);
			SelectCharacter();
			for (int i = 0; i < roomArray.size(); i++){
				roomArray[i]->EditRoom(false);
				for (int j = 0; j < objectArray.size(); j++){
					if (objectArray[j]->Is("Wall")){
						objectArray[j]->Editing(false);
					}
				}
			}
			break;
		case GUI_A:
			if(gui.BuildIconPressed()){
				click.Play(1);
				action = GUI_ROOM;
				gui.SetState(ROOMS);
            }
			else{
				if (gui.DestroyIconPressed()){
					click.Play(1);
					action = DESTROY_ROOM;
				}
				else{
					if (gui.BuyIconPressed()){
						click.Play(1);
						action = BUY;
					}
					else{
						if (gui.EditIconPressed()){
							click.Play(1);
							subGuiEdit.SetPositionSubGUI(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY());
							action = SUB_GUI_EDIT;
							subGuiEdit.SetState(EDIT);
						}
						else {
							action = NONE;
						}
					}
				}
			}
			break;
		case SUB_GUI_EDIT:
			if (subGuiEdit.DoorIconPressed()){
				click.Play(1);
				cout << "editando porta..." << endl;
				action = EDIT_DOOR;
			}
			else{
				if (subGuiEdit.WallIconPressed()){
					click.Play(1);
					cout << "editando parede..." << endl;
					action = EDIT_WALL;
				}
				else {
					action = NONE;
				}
			}
			break;
		case TILE_SELECT:
			break;
		case GUI_ROOM:
			if (!roomSheet.IsInside(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY())){
				action = NONE;
			}
			if (roomSheet.IsBuy(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY())){
				action = TILE_SELECT;
				roomAttributes = roomSheet.GetAttributes();
				selectionBox.SetSprite(roomAttributes.tileSprite);
			}
			gui.SetState(BASIC);

			break;
		case CONSTRUCT_ROOM:
			{
			action = NONE;
			Point aux;

			if (selectionBox.begin.y > selectionBox.end.y) {
				aux = selectionBox.begin;
				selectionBox.begin = selectionBox.end;
				selectionBox.end = aux;
			}

			if ((selectionBox.begin.x > selectionBox.end.x) && (selectionBox.begin.y < selectionBox.end.y)) {
				aux = selectionBox.begin;
				selectionBox.begin.x = selectionBox.end.x;
				selectionBox.end.x = aux.x;
			}
			RoomAttributes asd;
			asd.cost = 50;
			asd.tileSprite = "img/tileset/tile_madeira.png";
			asd.type = "Pirate";
			Room *newRoom = new Room(selectionBox.begin, selectionBox.end, &tileMap, &objectArray, roomArray.size(), roomAttributes);
			data->money -= newRoom->cost;
            roomArray.emplace_back(newRoom);
			vector<int> heuristc = occupancyMap.CreateHeuristic(&tileMap, roomArray[roomArray.size() - 1]->GetDoor());
			heuristicsArray.emplace(newRoom->GetID(),heuristc);
			obstacleMap = occupancyMap.Update(&tileMap, &objectArray);
			//Point tileC = tileMap.GetTile(objectArray[0]->box.x + objectArray[0]->box.w / 2, objectArray[0]->box.y + objectArray[0]->box.h);
			//vector<int> path = PathAStar(tileC.x, tileC.y, newRoom->GetID());
			//objectArray[0]->AddObjective(path);
			}
			break;
		case DESTROY_ROOM:
			for (int i = 0; i < roomArray.size(); i++){
				p = tileMap.GetTile(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
				if (roomArray[i]->IsInside(p)){
					heuristicsArray.erase(roomArray[i]->GetID());
					cout << "Destroying..." << endl;
					DestroyRoom(roomArray[i]->GetID());
					roomArray.erase(roomArray.begin() + i);
					i = roomArray.size();
				}
				
			}
			action = NONE;
			break;
		case BUY:
			if (!buySheet.IsInside(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY())){
				action = NONE;
			}
			if (buySheet.IsBuy(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY())){
				Point Tiles = Point(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
				Tiles = tileMap.GetTileCenterFromScreen(Tiles);
				Object* object = new Object(Tiles.x, Tiles.y, buySheet.GetAttributes(), tileMap);
				selectedObject = objectArray.size();
				objectArray.emplace_back(object);
				action = EDIT_OBJECT;
			}
			//data->money -= 100;
			break;
		case AREA_SELECT:
			break;
		case EDIT_DOOR:
			for (int i = 0; i < roomArray.size(); i++){
				p = tileMap.GetTile(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
				if (roomArray[i]->IsInside(p)){
					roomArray[i]->EditRoom(true);
					for (int j = 0; j < objectArray.size(); j++){
						if (objectArray[j]->Is("Wall")){
							if ((p.x == objectArray[j]->tile.x) && (p.y == objectArray[j]->tile.y))
								roomArray[i]->SetDoor(p.x, p.y, roomArray[i]->GetID(), &objectArray);
						}
					}
					
					for (int j = 0; j < objectArray.size(); j++){
						if (objectArray[j]->Is("Wall")){
							if (objectArray[j]->roomID == roomArray[i]->GetID()) {
								objectArray[j]->Editing(true);
								if (objectArray[j]->tile.DisPoints(objectArray[j]->tile, roomArray[i]->GetDoor()) == 0) {
									objectArray.erase(objectArray.begin() + j); 
								}
							}
						}
					}
					vector<int> heuristc = occupancyMap.CreateHeuristic(&tileMap, roomArray[i]->GetDoor());
					heuristicsArray[roomArray[i]->GetID()] = heuristc;
					obstacleMap = occupancyMap.Update(&tileMap, &objectArray);
					obstacleMap = occupancyMap.CleanTile(&tileMap, roomArray[i]->GetDoor());
				}
			}
			action = NONE;
			break;
		case EDIT_WALL:
			for (int i = 0; i < roomArray.size(); i++){
				p = tileMap.GetTile(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
				if (roomArray[i]->IsInside(p)){
					roomArray[i]->EditRoom(true);
					for (int j = 0; j < objectArray.size(); j++){
						if (objectArray[j]->Is("Wall")){
							if (objectArray[j]->roomID == roomArray[i]->GetID()) {
								objectArray[j]->Editing(true);
							}
						}
					}
				}
			}
			action = NONE;
			break;
		case EDIT_OBJECT:
			if (objectArray[selectedObject]->SettlePos(obstacleMap)){
				obstacleMap = occupancyMap.Update(&tileMap, &objectArray);
				action = NONE;
			}
		default:
			break;
		}

	}

	if(InputManager::GetInstance().MousePress(SDL_BUTTON_RIGHT)){
		if (sheet.GetRender() || objSheet.GetRender()){
			if (!sheet.GetBox().IsInside(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY())){
				sheet.SetRender(false);
				Camera::Unfollow();
			}

			if (!objSheet.GetBox().IsInside(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY()))
				objSheet.SetRender(false);
		}
		else{
			switch (action)
			{
			case NONE:
				gui.SetPosition(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY());
				action = GUI_A;
				break;
			case TILE_SELECT:
				break;
			case CONSTRUCT_ROOM:
				break;
			case DESTROY_ROOM:
				break;
			case AREA_SELECT:
				break;
			case GUI_A:
				gui.SetPosition(InputManager::GetInstance().GetMouseX(), InputManager::GetInstance().GetMouseY());
				break;
			case SUB_GUI_EDIT:
				action = NONE;
				break;
			default:
				break;
			}
		}
	}

	if(InputManager::GetInstance().IsMouseDown(SDL_BUTTON_LEFT)){

		switch (action){
		case NONE:
			break;
		case TILE_SELECT:
			action = CONSTRUCT_ROOM;
			break;
		case CONSTRUCT_ROOM:
			break;
		case DESTROY_ROOM:
			break;
		case AREA_SELECT:
			break;
		default:
			break;
		}

	}

	if(InputManager::GetInstance().MouseRelease(SDL_BUTTON_RIGHT)){

		switch (action){
		case NONE:
			//action = TILE_SELECT;
			break;
		case TILE_SELECT:
			break;
		case CONSTRUCT_ROOM:
			break;
		case DESTROY_ROOM:
			break;
		case AREA_SELECT:
			break;
		default:
			break;
		}

	}
	
}
bool CPHMovementControl:: ActivateBoxDynamic(DWORD id,int num_it/*=8*/,int num_steps/*5*/,float resolve_depth/*=0.01f*/)
{
	bool  character_exist=CharacterExist();
	if(character_exist&&trying_times[id]!=u32(-1))
	{
		Fvector dif;dif.sub(trying_poses[id],cast_fv(dBodyGetPosition(m_character->get_body())));
		if(Device.dwTimeGlobal-trying_times[id]<500&&dif.magnitude()<0.05f)
																	return false;
	}
	if(!m_character||m_character->PhysicsRefObject()->PPhysicsShell())return false;
	DWORD old_id=BoxID();

	bool  character_disabled=character_exist && !m_character->IsEnabled();
	if(character_exist&&id==old_id)return true;

	if(!character_exist)
	{
		CreateCharacter();
	}

	//m_PhysicMovementControl->ActivateBox(id);
	m_character->CPHObject::activate();
	ph_world->Freeze();
	UnFreeze();

	saved_callback=ObjectContactCallback();
	SetOjectContactCallback(TestDepthCallback);
	SetFootCallBack(TestFootDepthCallback);
	max_depth=0.f;



	//////////////////////////////////pars///////////////////////////////////////////
//	int		num_it=8;
//	int		num_steps=5;
//	float	resolve_depth=0.01f;

	
	if(!character_exist)
	{
		num_it=20;
		num_steps=1;		
		resolve_depth=0.1f;
	}
	///////////////////////////////////////////////////////////////////////
	float	fnum_it=float(num_it);
	float	fnum_steps=float(num_steps);
	float	fnum_steps_r=1.f/fnum_steps;

	Fvector vel;
	Fvector pos;
	GetCharacterVelocity(vel);
	GetCharacterPosition(pos);
	//const Fbox& box =Box();
	float pass=	character_exist ? _abs(Box().getradius()-boxes[id].getradius()) : boxes[id].getradius();
	float max_vel=pass/2.f/fnum_it/fnum_steps/fixed_step;
	float max_a_vel=M_PI/8.f/fnum_it/fnum_steps/fixed_step;
	dBodySetForce(GetBody(),0.f,0.f,0.f);
	dBodySetLinearVel(GetBody(),0.f,0.f,0.f);
	Calculate(Fvector().set(0,0,0),Fvector().set(1,0,0),0,0,0,0);
	CVelocityLimiter vl(GetBody(),max_vel,max_vel);
	max_vel=1.f/fnum_it/fnum_steps/fixed_step;

	bool	ret=false;
	m_character->SwitchOFFInitContact();
	vl.Activate();
	vl.l_limit*=(fnum_it*fnum_steps/5.f);
	vl.y_limit=vl.l_limit;
////////////////////////////////////
	for(int m=0;30>m;++m)
	{
		Calculate(Fvector().set(0,0,0),Fvector().set(1,0,0),0,0,0,0);
		EnableCharacter();
		m_character->ApplyForce(0,ph_world->Gravity()*m_character->Mass(),0);
		max_depth=0.f;
		ph_world->Step();
		if(max_depth	<	resolve_depth) 
		{
			break;
		}	
		ph_world->CutVelocity(max_vel,max_a_vel);
	}
	vl.l_limit/=(fnum_it*fnum_steps/5.f);
	vl.y_limit=vl.l_limit;
/////////////////////////////////////

	for(int m=0;num_steps>m;++m)
	{
		float param =fnum_steps_r*(1+m);
		InterpolateBox(id,param);
		ret=false;
		for(int i=0;num_it>i;++i){
			max_depth=0.f;
			Calculate(Fvector().set(0,0,0),Fvector().set(1,0,0),0,0,0,0);
			EnableCharacter();
			m_character->ApplyForce(0,ph_world->Gravity()*m_character->Mass(),0);
			ph_world->Step();
			ph_world->CutVelocity(max_vel,max_a_vel);
			if(max_depth	<	resolve_depth) 
			{
				ret=true;
				break;
			}	
		}
		if(!ret) break;
	}
	m_character->SwitchInInitContact();
	vl.Deactivate();

	ph_world->UnFreeze();
	if(!ret)
	{	
		if(!character_exist)DestroyCharacter();
		else if(character_disabled)m_character->Disable();
		ActivateBox(old_id);
		SetVelocity(vel);
		dBodyID b=GetBody();
		if(b)
		{
			dMatrix3 R;
			dRSetIdentity (R);
			dBodySetAngularVel(b,0.f,0.f,0.f);
			dBodySetRotation(b,R);
		}
		SetPosition(pos);
		
		//Msg("can not activate!");
	}
	else
	{
		ActivateBox(id);
		//Msg("activate!");
	}

	SetOjectContactCallback(saved_callback);
	SetVelocity(vel);
	saved_callback=0;
	if(!ret&&character_exist)
	{
		trying_times[id]=Device.dwTimeGlobal;
		trying_poses[id].set(cast_fv(dBodyGetPosition(m_character->get_body())));
	}
	else
	{
		trying_times[id]=u32(-1);
	}
	return ret;
}
void StageState::Update(float dt) {
	if (music.isOverInd){
		cMusic++;
		if (cMusic == musicNames.size()){
			cMusic = 0;
		}
		music.Open(musicNames[cMusic]);
		music.Play(1);
	}
	
	int size = 0;
	int cost = 0;
	Input();
	creationTimer.Update(dt);
	switch (action)	{
	case NONE:
		break;
	case TILE_SELECT:
		p = tileMap.GetTile(InputManager::GetInstance().GetMouseX()-Camera::pos.x,InputManager::GetInstance().GetMouseY()-Camera::pos.y);
        selectionBox.SetBegin(p);
		selectionBox.Update(&tileMap);
        p = tileMap.GetTileCenter(p);
		break;
	case GUI_ROOM:
		roomSheet.UpdateObjectSheet();
		break;
	case CONSTRUCT_ROOM:
		selectionBox.Update(&tileMap);
		size = (abs(selectionBox.end.x - selectionBox.begin.x) + 1)*(abs(selectionBox.end.y - selectionBox.begin.y) + 1);
		cost = size * 5;
		break;
	case DESTROY_ROOM:
		break;
	case AREA_SELECT:
		break;
	case BUY:
		buySheet.UpdateObjectSheet();
		break;
	case EDIT_OBJECT:{
		Point tiles = Point(InputManager::GetInstance().GetMouseX() - Camera::pos.x, InputManager::GetInstance().GetMouseY() - Camera::pos.y);
		tiles = tileMap.GetTileCenterFromScreen(tiles);
		objectArray[selectedObject]->MoveTo(tiles.x, tiles.y);
	}
		break;
	default:
		break;
	}
	

	for (unsigned int i = 0; i < objectArray.size(); i++) {
		if (objectArray[i]->IsDead()) {
			DestroyCharacter(i);
			for (unsigned int j = 0; j < objectArray.size(); j++) {
				if (objectArray[j]->IsCharacter()) {
					objectArray[j]->ChangeSelection(i);
				}
			}
			i--;
		}
	}

	UpdateArray(dt, &tileMap);
	
	for (int i = 0; i < objectArray.size(); i++){

		if (objectArray[i]->IsCharacter()){
			if (objectArray[i]->GetAction() == DECIDING_ROOM){
				charChoice = objectArray[i]->GetChoice();
				charRoom = charChoice;

				if (!roomArray.empty()){
					for (int j = 0; j < roomArray.size(); j++){
						if ((roomArray[j]->GetState() == charRoom) && (roomArray[j]->roomState != Room::EDITING)){
							int x, y;
							Point t;
							x = objectArray[i]->box.x + objectArray[i]->box.w / 2;
							y = objectArray[i]->box.y + objectArray[i]->box.h;
							t = tileMap.GetTile(x, y);
							vector<int> path = PathAStar(t.x, t.y, roomArray[j]->GetDoor(), heuristicsArray[roomArray[j]->GetID()]);
							if (!path.empty())
								objectArray[i]->AddObjective(path);
							else
								cout << "No path!!!!" << endl;
						}
					}
				}
			}
			else{
				if (objectArray[i]->GetAction() == DECIDING_OBJECT){
					int objectIndex = objectArray[i]->GetObjectIndex();
					if (objectIndex != -1){
						Point objective = Point(objectArray[objectIndex]->GetTile().x, objectArray[objectIndex]->GetTile().y - 1);
						Point t = objectArray[i]->GetTile();
						cout << endl << "Debug action DO" << endl << endl;
						cout << "X,Y : " << t.x << "," << t.y << endl;
						cout << "Object index : " << objectIndex << endl;
						cout << objectArray[objectIndex]->GetHeuristic(0).size() << endl;
						vector<int> path = PathAStar(t.x, t.y, objective, objectArray[objectIndex]->GetHeuristic(0));
						if (!path.empty())
							objectArray[i]->AddObjective(path);
						else
							cout << "No path!!!!" << endl;
					}
				}
				else{
					if (objectArray[i]->GetAction() == EXITING){
						cout << "Entrou exitting!!!!!!!!!!" << endl;
						int objectIndex = objectArray[i]->GetObjectIndex();
						if (objectIndex != -1){
							Point objective = Point(objectArray[objectIndex]->GetTile().x, objectArray[objectIndex]->GetTile().y - 1);
							Point t = objectArray[i]->GetTile();
							vector<int> path = PathAStar(t.x, t.y, objective, objectArray[objectIndex]->GetHeuristic(0));
							if (!path.empty())
								objectArray[i]->AddObjective(path);
							else
								cout << "No path!!!!" << endl;
						}
					}

				}
			}
		}
	}
	if (creationTimer.Get() > 10){
		CreateCharacter(5, 5);
		creationTimer.Restart();
	}
	if (cost > 0)
		costText.SetText(to_string(-cost));
	else
		costText.SetText(" ");
	costText.SetPos(InputManager::GetInstance().GetMouseX() + 10, InputManager::GetInstance().GetMouseY() + 5, false, false);
	
}