//Header du moteur de depl

//Les defines
#define	TailleH	64
#define	TailleV	64

//Horizontalement (axe des X):
#define	DebutColH	6
#define	FinColH		57
//Verticalement (axe des Y):
#define	DebutColV	4
#define	FinColV		61

//Les vitesses :
#define	ACC_MARCHE_X	1.0
#define	ACC_MARCHE_Y	1.1

#define	FROX	0.9	//Coefficient des frottements horizontaux
#define	FROYM	0.01 //0.05	//Coefficient des frottements verticaux en montée
#define	FROYD	0.25	//Coefficient des frottements verticaux en descente

#define	CHAMP_PESANTEURD	1.25	//Coeff du champ de pesanteur (accélération du bonhomme vers le bas, quand c'est posible) 
#define	CHAMP_PESANTEURM	0.1	//Coeff du champ de pesanteur (accélération du bonhomme vers le bas, quand c'est posible) 
#define	MINI_VITESSE	0.1	//Vitesses minimum pour etre prise en compte
#define	ACC_SAUT	7.5	//Accélération au début du saut
#define	MINI_FROTTEMENT	1.0	//Minimum de vitesse pour la détection des frottements
#define	MINI_VIT_ETAT	1.0	//Minimum pour afficher l'�tat de depl a lieu de l'�tat immobile

//Defines pour l'accrochage :
#define	DIST_ACCROCH	30	//Distance entre le perso et la plaque sur laquelle on va s'accroch�e (horizontalement)
#define	HAUT_ACCROCH	60	//Distance entre le perso et le haut de la plaque libre

#define	PERTE_VIE_CARREAU	20 // Perte par carreau en chute libre au dessus d'un certain seuil

//Les fonctions inline
inline bool CPerso::DroitAcces(int px, int py) //La zone est-elle libre ? Peut-on accéder a cet endroit
{
	//Mise en place du procces de détection avec les quatres coins du carré
	return (Map.AutAcces(px + DebutColH, py + DebutColV) && Map.AutAcces(px + FinColH, py + DebutColV) && Map.AutAcces(px + DebutColH, py + FinColV) && Map.AutAcces(px + FinColH, py + FinColV));
}

inline bool CPerso::MortSiAcces(int px, int py) //La zone est-elle mortelle ? Peut-on mourrir a cet endroit
{
	//Mise en place du procces de détection avec les quatres coins du carré
	return (Map.DiedAcces(px + DebutColH, py + DebutColV) && Map.DiedAcces(px + FinColH, py + DebutColV) && Map.DiedAcces(px + DebutColH, py + FinColV) && Map.DiedAcces(px + FinColH, py + FinColV));
}


void CPerso::CalcDepl()
{
	//Calcul du Depl
	double AccX = 0.0, AccY = 0.0;
	int NewEtat = Etat;

	if(Etat == ACCROCHER) // traitement si accrocher
	{
		if(TouchesAppuyee[TOUCHE_BAS]) //si la touche du bas est activée, on le décroche
		{
			Etat = INDEFINI; //on ne sait pas dans quel état il est
		}
		if(TouchesAppuyee[TOUCHE_HAUT]) //si la touche du bas est activée, on le décroche
		{
			Etat = SAUT;
			AccY -= ACC_SAUT;
			VitY = 0.0;
			LastSaut = SDL_GetTicks();
			LastSaut += 1000;
		}
	}
	
	if(Etat == ATTAQUE)
	{
		if(DebutAnim + 1000 < SDL_GetTicks())
		{
			Etat = INDEFINI;
		}
		else
		{
			CPerso* perso;
			for(int i = 0; i <= Personnages.size(); ++i)
			{
				perso = (i == Personnages.size()) ? PersoPrincipal : Personnages[i];
				
				int px = PosX;
				if(VersLaDroite)	px += 32;
				else	px -= 32;
				
				if(sqrt((((px-perso->ReturnPosX())*(px-perso->ReturnPosX())) + ((PosY-perso->ReturnPosY())*(PosY-perso->ReturnPosY())))) < 32)
				{
					if(perso->CampAllie() != CampAllie())
					{
						perso->AnimDegat();
						perso->PerteVie(1);
					}
				}
			}

		}
	}
	
	if(Etat != ACCROCHER && Etat != ATTAQUE) //traitement plus général si pas accroché
	{
		if(Etat != MORT) // Bien entendu, il n'est pas mort!!!
		{
			if(TouchesAppuyee[TOUCHE_DROITE]) //A t-on appuyé sur la touche droite ?
			{
				//Gestion de l'accrochage ici!
				if(!DroitAcces(PosX + DIST_ACCROCH, PosY) && DroitAcces(PosX + DIST_ACCROCH, PosY - HAUT_ACCROCH) && !DroitAcces(PosX + DIST_ACCROCH, PosY - HAUT_ACCROCH + 5))
				{
					VitX = VitY = 0.0;
					div_t t = div(PosX + 32, 64);
					PosX = t.quot * 64;
					t = div(PosY, 64);
					PosY = t.quot * 64 + 64;
					Etat = ACCROCHER;
					DebutAnim = SDL_GetTicks();
					VersLaDroite = true;
					return;
				}

				if(DroitAcces(PosX + (int)(VitX + ACC_MARCHE_X), PosY + (int)(VitY + ACC_MARCHE_Y)) && (!DroitAcces(PosX, PosY + 3))) //Déplacement en bas à droite ?
				{
					AccX = ACC_MARCHE_X;
					AccY = ACC_MARCHE_Y;
				}
				else if(DroitAcces(PosX + (int)(VitX + ACC_MARCHE_X), PosY + (int)VitY)) //Déplacement à droite ?
				{
					AccX = ACC_MARCHE_X;
				}
				else if(DroitAcces(PosX + (int)(VitX + ACC_MARCHE_X), PosY - 2 + (int)(VitY - ACC_MARCHE_Y))) //Déplacement en haut à droite ?
				{
					AccX = ACC_MARCHE_X;
					AccY = -ACC_MARCHE_Y;
				}
			}

			if(TouchesAppuyee[TOUCHE_GAUCHE]) //A t-on appuyé sur la touche gauche ?
			{

				//Gestion de l'accrochage ici!
				if(!DroitAcces(PosX - DIST_ACCROCH, PosY) && DroitAcces(PosX - DIST_ACCROCH, PosY - HAUT_ACCROCH) && !DroitAcces(PosX - DIST_ACCROCH, PosY - HAUT_ACCROCH + 5))
				{
					VitX = VitY = 0.0;
					div_t t = div(PosX + 32, 64);
					PosX = t.quot * 64;
					t = div(PosY, 64);
					PosY = t.quot * 64 + 64;
					Etat = ACCROCHER;
					DebutAnim = SDL_GetTicks();
					VersLaDroite = false;
					return;
				}

				if(DroitAcces(PosX + (int)(VitX - ACC_MARCHE_X), PosY + (int)(VitY + ACC_MARCHE_Y)) && (!DroitAcces(PosX, PosY + 3))) //Déplacement en bas à gauche ?
				{
					AccX = -ACC_MARCHE_X;
					AccY = ACC_MARCHE_Y;
				}
				else if(DroitAcces(PosX + (int)(VitX - ACC_MARCHE_X), PosY + (int)VitY)) //Déplacement à gauche ?
				{
					AccX = -ACC_MARCHE_X;
				}
				else if(DroitAcces(PosX + (int)(VitX - ACC_MARCHE_X), PosY - 2 + (int)(VitY - ACC_MARCHE_Y))) //Déplacement en haut à gauche ?
				{
					AccX = -ACC_MARCHE_X;
					AccY = -ACC_MARCHE_Y;
				}
			}


			//Le saut ...
			if(TouchesAppuyee[TOUCHE_HAUT])
			{
				if((!DroitAcces(PosX, PosY + 3) && Etat != SAUT) || (LastSaut < SDL_GetTicks()))
				{
					AccY -= ACC_SAUT;
					VitY = 0.0;
					LastSaut = SDL_GetTicks();
					LastSaut += 1000;
				}
			}
		}
		
		//Le poids (si pas de réaction du sol)...
		if(DroitAcces(PosX, PosY + 3 + (int)(VitY + AccY + CHAMP_PESANTEURD)))
		{
			if(VitY > 0.0)
			{			
				AccY += CHAMP_PESANTEURD;
			}
			else
			{
				AccY += CHAMP_PESANTEURM;
			}
		}

		//Traitements des frottements
		if(!((VitX < MINI_FROTTEMENT) && (VitX > -MINI_FROTTEMENT)))
		{		
			AccX -= (VitX * FROX);
		}		
	
		if(!((VitY < MINI_FROTTEMENT) && (VitY > -MINI_FROTTEMENT)))
		{
			if(VitY > 0.0)
			{
				AccY -= (VitY * FROYD);
			}
			else
			{
				AccY -= (VitY * FROYM);
			}
		}


		//Traitement des obstacle		
		if(!DroitAcces(PosX + (int)(VitX + AccX), PosY + (int)(VitY + AccY)))
		{	
			//Depl horizontaux
			if(!DroitAcces(PosX + (int)(VitX + AccX), PosY))
			{			
				VitX = AccX = 0.0;
			}

			//Depl verticaux
			if(!DroitAcces(PosX, PosY - 1 + (int)(VitY + AccY)))
			{
				VitY = AccY = 0.0;
			}
		} 
	}

	VitX += AccX;
	VitY += AccY;

	if((VitX < MINI_VITESSE) && (VitX > -MINI_VITESSE))
	{
		VitX = 0.0;
	}

	if((VitY < MINI_VITESSE) && (VitY > -MINI_VITESSE))
	{
		VitY = 0.0;
	}
	
	//Ne pas sortir de la map
	if(VitX + PosX < 0)
	{
		VitX = 0.0;
	}

	if(VitY + PosY < 0)
	{
		VitY = 0.0;
	}

	PosX += (int)VitX;
	PosY += (int)VitY;
	
	if(VitY <= 0)
	{
		if(PosY - HauteurMax > 384)
		{
			HauteurMax = PosY - HauteurMax - 384;
			if(HauteurMax > 0) Vie -= (HauteurMax/64 * PERTE_VIE_CARREAU);
			if(Vie <= 0)
			{
				Vie = 0;
		 		DebutAnim = SDL_GetTicks();
				DebutAnim += 2000;
			}
		}
		HauteurMax = PosY;
	}

	if(PosY < HauteurMax) HauteurMax = PosY;

	//Calcul de l'état actuel
	if((Etat != ACCROCHER) && (Etat != MORT))
	{
		if((VitY*VitY) < 1.0 && (VitX*VitX) < 1.0 && Etat != ATTAQUE && TouchesAppuyee[TOUCHE_ATTAQUE])
		{
			NewEtat = ATTAQUE;
		}
		else if(Etat == ATTAQUE)
		{
			
		}
		else if(DroitAcces(PosX, PosY + 5))
		{
			NewEtat = SAUT;
			VersLaDroite = (VitX > 0.0);
		}
		else if(!((VitX < MINI_VIT_ETAT) && (VitX > -MINI_VIT_ETAT)))
		{
			NewEtat = MARCHE;
			VersLaDroite = (VitX > 0.0);
		}
		else if(MortSiAcces(PosX, PosY))
		{
			NewEtat = MORT;
			VersLaDroite = (VitX > 0.0);
		}
		else if(DroitAcces(PosX - 25, PosY + 29) || DroitAcces(PosX - 12, PosY + 16))
		{
			NewEtat = DEEQUILIBRE;
			VersLaDroite = false;
		}
		else if(DroitAcces(PosX + 25, PosY + 29) || DroitAcces(PosX + 12, PosY + 16))
		{
			NewEtat = DEEQUILIBRE;
			VersLaDroite = true;
		}
		else
		{
			NewEtat = IMMOBILE;
		}

		if(Etat != NewEtat)
		{
			Etat = NewEtat;
			DebutAnim = SDL_GetTicks();
		}
	}
}

void CPerso::CalcIA()
{
if(TypeIA == IA_AMI)
{
	TouchesAppuyee[TOUCHE_DROITE] = false;
	TouchesAppuyee[TOUCHE_GAUCHE] = false;
	TouchesAppuyee[TOUCHE_HAUT] = false;
	TouchesAppuyee[TOUCHE_BAS] = false;
	
	if(PersoPrincipal->ReturnPosX() + 50 < PosX) TouchesAppuyee[TOUCHE_GAUCHE] = true;
	if(PersoPrincipal->ReturnPosX() > PosX + 50) TouchesAppuyee[TOUCHE_DROITE] = true;
	if(PersoPrincipal->ReturnPosY() + 50 < PosY) TouchesAppuyee[TOUCHE_HAUT] = true;
	if(PersoPrincipal->ReturnPosY() > PosY+ 50) TouchesAppuyee[TOUCHE_BAS] = true;
}
}
