/*****************************/
/* Inside The Machine - MKS  */
/*****************************/

#include "eHeroCat.h"
#include "../WorldManager.h"
//GFX
//#include "Hero_Spritesheet.h"

eHeroCat::eHeroCat()
{
   //Maj de variables
   type = 0;
   genre = 0;
   real = true;      //Subit les collisions
   stat = false;     //Subit la gravité
   velx = vely = 0;  //Vitesse par défaut
   maxvely = 512;
   isJumperColl = false;
   isCanMove = false; //Définit si l'entité peut bouger
   isCanHMove = true;//Définit si l'entité peut bouger horizontalement
   sensH = true;     //définit le sens horizontal de l'entité
   isFalling = true;
   isJumping = false;
   isOnTheFloor = false;
   isCrounch = false;
   isCanJump = true;
   isGroundBattle = false;
   actif = true;
   toDelete = false;
   displayLand = displayRun = false;
   
   jumpGrav = VELJUMP;
   decreaseVely = false;
   speed = 0;
   jumpH = 0;
   jumpPower = 1;
   lives = 3;
   life = 32;
   energy = FIX(64);
   distanceX = depth = 0;
   nextBulletID = bulletInterval = 0;
   comboCoup = comboNextCoup = 0;
   comboFrameCounter = -1;
   dontMoveTime = -1;
   dontHitTime = -1;
   displayEffectTimer = displayEffectTimer2 = -1;
	
	//Renseignement de l'hitbox
	hitbox.xUp = 15, hitbox.yUp = 5;
	hitbox.xDown = 15, hitbox.yDown = 31;
	hitbox.xLeft = 0, hitbox.yLeft = 25;
	hitbox.xRight = 31, hitbox.yRight = 25;
	
	hitbox.xJumpRightDown = 26, hitbox.yJumpRightDown = 2;
	hitbox.xJumpRightUp = 26, hitbox.yJumpRightUp = 30;
	hitbox.xJumpLeftDown = 5, hitbox.yJumpLeftDown = 2;
	hitbox.xJumpLeftUp = 5, hitbox.yJumpLeftUp = 30;
	
	//Renseignement des battle hitboxes
	rectBattleRight.x1 = 18, rectBattleRight.y1 = 20;
	rectBattleRight.x2 = 28, rectBattleRight.y2 = 28;
	
	rectBattleLeft.x1 = 13, rectBattleLeft.y1 = 20;
	rectBattleLeft.x2 = 3, rectBattleLeft.y2 = 28;
	
	rect.x1 = 8;
	rect.y1 = 12;
	rect.x2 = 24;
	rect.y2 = 28;
	
	for(int k = 0; k < BULLETMAX; k++)
	{
		bullets[k].actif = false;
		bullets[k].rect.x1 = 2; 
		bullets[k].rect.y1 = 2; 
		bullets[k].rect.x2 = 6; 
		bullets[k].rect.y2 = 6; 
	}
	
}   
   	
eHeroCat::~eHeroCat()
{
   
}

void eHeroCat::Load()
{
   //Chargement du spritesheet
   ulSetTransparentColor(RGB15(31, 0, 31));
	spr.assign(worldMan->resMan->LoadImage("efs:/Hero_Spritesheet.png", UL_IN_VRAM, UL_PF_PAL4));
	bullet.assign(worldMan->resMan->LoadImage("efs:/Boss1_Ball.png", UL_IN_VRAM, UL_PF_PAL2));
	landEffect.assign(worldMan->resMan->LoadImage("efs:/FX_Land_1.png", UL_IN_VRAM, UL_PF_PAL2));
	runEffect.assign(worldMan->resMan->LoadImage("efs:/FX_Run_1.png", UL_IN_VRAM, UL_PF_PAL2));
	sprfx3.assign(worldMan->resMan->LoadImage("efs:/FX_Power_1.png", UL_IN_VRAM, UL_PF_PAL2));
	ulDisableTransparentColor();
	
	//Paramètrage des animations
	spr.setFrameWH(32, 32);
	spr.addAnim(0, 0, 3, 5);     //Anim par defaut : Idle - Left
	spr.addAnim(0, 4, 3, 5);     //Anim par defaut : Idle - Right
	spr.addAnim(1, 0, 4, 7);     //Anim : Course - Left
	spr.addAnim(2, 0, 4, 7);     //Anim : Course - Right
	spr.addAnim(1, 5, 0, 1);     //Anim : Couché - Left
	spr.addAnim(2, 5, 0, 1);     //Anim : Couché - Right
	spr.addAnim(1, 6, 1, 5);     //Anim : Saut - Left
	spr.addAnim(2, 6, 1, 5);     //Anim : Saut - Right
	spr.addAnim(3, 0, 1, 5);     //Anim : Chute - Left
	spr.addAnim(3, 2, 1, 5);     //Anim : Chute - Right
	//Battle Anims
	spr.addAnim(4, 0, 3, 3);     //Anim : Coup - Right
	spr.addAnim(4, 1, 2, 3);     //Anim : Coup2 - Right
	spr.addAnim(4, 4, 3, 3);     //Anim : Coup3 - Right
	spr.addAnim(4, 5, 2, 3);     //Anim : Coup4 - Right
	spr.addAnim(6, 4, 3, 3);     //Anim : Coup5 - Right
	spr.addAnim(5, 0, 3, 3);     //Anim : Coup - Right
	spr.addAnim(5, 1, 2, 3);     //Anim : Coup2 - Right
	spr.addAnim(5, 4, 3, 3);     //Anim : Coup3 - Right
	spr.addAnim(5, 5, 2, 3);     //Anim : Coup4 - Right
	spr.addAnim(6, 0, 3, 3);     //Anim : Coup5 - Right
	
	sprfx3.setFrameWH(16, 16);
	sprfx3.addAnim(0, 0, 2, 3);
	sprfx3.animLoop(0);
	sprfx3.setAlpha(true, 15);
	sprfx3.setRotCenter(8, 8); 
	//Lecture de l'animation par défaut
	//spr.animLoop(0);
}   

void eHeroCat::Draw(int layer)
{
   if(layer == 0)
   {
	   //On affiche le sprite
	   spr.setXY(x_screen, y_screen);
	   //Alpha
	   if(dontHitTime != -1)
	   	spr.setAlpha(true, 20);
	   else
	   	spr.setAlpha(false, 31);
	   spr.play();
	   spr.draw();
	   //Effets
	   if(displayRun)
	   {
	      runEffect.setAlpha(true, 15);
	      if(sensH)
	      {
	      	runEffect.setXY(x_screen, y_screen+16);
	      	runEffect.mirror(false, false);
	   	}   
	      else
	      {
	      	runEffect.setXY(x_screen+16, y_screen+16);
	      	runEffect.mirror(true, false);
	   	}
			runEffect.draw(); 	 
	   }
		if(displayLand && velx == 0)
		{
			landEffect.setAlpha(true, 15);
			landEffect.setXY(x_screen+8, y_screen+16);
			landEffect.draw();	
		}			   
	   
	   //Hitboxes
	   /*if(sensH)
	   	ulDrawRect(x_screen + rectBattleRight.x1, y_screen + rectBattleRight.y1, x_screen + rectBattleRight.x2, y_screen + rectBattleRight.y2, RGB15(31, 0, 0) );
	   else
	   	ulDrawRect(x_screen + rectBattleLeft.x1, y_screen + rectBattleLeft.y1, x_screen + rectBattleLeft.x2, y_screen + rectBattleLeft.y2, RGB15(31, 0, 0) );*/
	   	
	   //On affiche les bullets
		for(int k = 0; k < BULLETMAX; k++)
		{
		   if(bullets[k].actif)
		   {
		      //On calcule la position écran et on affiche
		      bullet.setXY(bullets[k].x - worldMan->curLevel->map->scrollX, bullets[k].y - worldMan->curLevel->map->scrollY);
		      bullet.draw();
				sprfx3.rotate(bullets[k].angle);
				sprfx3.setXY(bullets[k].x - worldMan->curLevel->map->scrollX + 4, bullets[k].y - worldMan->curLevel->map->scrollY + 4);
				sprfx3.play();
				sprfx3.draw();
		   }   
		}
	}	
}
   
void eHeroCat::Update()
{
   //Mouvement au PAD ?
	//Décrementation du dontMoveTime et dontHitTime
	if(dontMoveTime != -1)
	{
	   //Théoriquement, on peut peux pas bouger donc :
	   velx = 0;
	   //vely = 0;
		dontMoveTime--;
	}
	if(dontHitTime != -1)
	{
		dontHitTime--;
	}
	
	//Désactivation des effets
	if(displayEffectTimer > 2)
	{
		displayEffectTimer = -1;
		displayRun = false;
	}
	else
		displayEffectTimer++;
	
	if(displayEffectTimer2 > 2)
	{
		displayEffectTimer2 = -1;
		displayLand = false;
	}
	else
		displayEffectTimer2++;	
		
   //Mouvement Horizontal
   if(isCanMove && dontMoveTime == -1)
   {
      //On remet la vitesse à 0 et le h move à true
      velx = 0;
      isCanHMove = true;
      
 		//Position couchée (activation)
 		if(ul_keys.pressed.down && vely == 256)
 		{
 		   //On désactivement le mouvement horizontal
 		   isCanHMove = false;
 		   isCrounch = true;
 		   //On change les paramètres de la hitbox up
 		   hitbox.yUp = 21;
 		   //Si on est au sol on peut se coucher
 			if(sensH)
 				spr.animLoop(4);
 			else
 				spr.animLoop(5);
 		}
 		//Position couchée (désactivation)
 		if(ul_keys.released.down && vely == 256)
 		{
 			//On réactive le mvt horizontal
			isCanHMove = true;
			isCrounch = false;
			//On remet l'animation d'idle
			if(sensH)
 				spr.animLoop(0);
 			else
 				spr.animLoop(1);
 		}
 		//Tir	
		if(ul_keys.pressed.X)
 		{
 			//Le joueur tire, on ajoute un bullet si possible
 			if(bulletInterval == 0 && energy > 0)
 			{
 			   //Son fireball
 			   AS_SoundDefaultPlay(sndFire, 43776, soundVolume, 64, 0, 1);
 			   
 			 	//On règle les param de la bullet
 			 	bullets[nextBulletID].x = UNFIX(x-velx) + 16;
 			 	bullets[nextBulletID].y = UNFIX(y) + 16;
 			 	
 			 	//Vecteur de déplacement du bullet
 			 	if(sensH)
 			 	{
 			 		bullets[nextBulletID].vx = BULLETSPEED;
 			 		bullets[nextBulletID].angle = 0;
 			 		if(ul_keys.held.up)
 			 		{
 			 			bullets[nextBulletID].vy = -BULLETSPEED;
 			 			bullets[nextBulletID].angle = 512-64;
 			 		}			
 			 		else if(ul_keys.held.down)
 			 		{
 			 			bullets[nextBulletID].vy = BULLETSPEED;
 			 			bullets[nextBulletID].angle = 64;
 			 		}			
 			 		else
 			 			bullets[nextBulletID].vy = 0;
 			 		//Calcul de l'angle
 			 		
 				}	 	
				else
				{
					bullets[nextBulletID].vx = -BULLETSPEED;
					bullets[nextBulletID].angle = 256;
					if(ul_keys.held.up)
					{
 			 			bullets[nextBulletID].vy = -BULLETSPEED;
 			 			bullets[nextBulletID].angle = 256+64;
 			 		}			
 			 		else if(ul_keys.held.down)
 			 		{
 			 			bullets[nextBulletID].vy = BULLETSPEED;
 			 			bullets[nextBulletID].angle = 256-64;
 			 		}			
 			 		else
 			 			bullets[nextBulletID].vy = 0;
				}			
 			 	bullets[nextBulletID].life = 64;
 			 	bullets[nextBulletID].actif = true;
 			 	energy -= FIX(8);
 			   nextBulletID++;
 			}
		}
		
		//Courrir
		if(ul_keys.held.Y)
		{
			//Augmentation de la vitesse du personnage 
			if(speed < VELMOVING*2)
			   speed += 16;
			else
			   speed = VELMOVING*2;
			spr.setAnimSpeed(3, 4);
			spr.setAnimSpeed(2, 4); 
		}
		else
		{
			speed = VELMOVING;
			spr.setAnimSpeed(3, 7);
			spr.setAnimSpeed(2, 7);   
		}									
			
 		//Course gauche
   	if(ul_keys.held.left && isCanHMove)
   	{
   	   //On stoppe l'anim d'un coup
 		   comboCoup = 0;
 		   comboFrameCounter = -1;
 		   isGroundBattle = false;
   	   if(!isJumping)
   	   	hitbox.yUp = 15;
   		velx = -speed;
   		spr.animLoop(3);
   		sensH = false;
   		isCrounch = false;
 		}
 		if(ul_keys.pressed.left || ul_keys.pressed.right)
 		{
 			if(isOnTheFloor)
 			{
				displayRun = true;
				displayEffectTimer = 0;
			}			
 		}   
		//Course droite	
   	if(ul_keys.held.right && isCanHMove)
   	{
   	   //On stoppe l'anim d'un coup
 		   comboCoup = 0;
 		   comboFrameCounter = -1;
 		   isGroundBattle = false;
   	   if(!isJumping)
   	   	hitbox.yUp = 15;
   		velx = speed;
   		spr.animLoop(2);
   		sensH = true;
   		isCrounch = false;
 		}
 		//Saut
		if(ul_keys.held.B && isCanJump)
 		{
 		   //On stoppe l'anim d'un coup
 		   comboCoup = 0;
 		   comboFrameCounter = -1;
 		   isGroundBattle = false;
 		   //On saute
 			vely = -jumpGrav;
 			jumpH += VELJUMP;
 			isJumping = true;
 			isOnTheFloor = false;
 			isCrounch = false;
 			decreaseVely = true;
 			/*if(jumpH > JUMPMAX*jumpPower)
 				isCanJump = false;*/
		}
		if(ul_keys.released.B)
 		{
 		   vely = 256;
 			isCanJump = false;
 			isJumping = false;
 			decreaseVely = false;
		}
		//Attaque Simple
		if(ul_keys.pressed.A && !isFalling && !isJumping)
		{
		   //On fait le premier coup
		   if(comboCoup == 0)
		   {
		   	comboCoup = 1;         //1er coup
				comboFrameCounter = 0; //Démarrage du compteur
		   }
		   //Autres coups du combo
			if(comboCoup > 0)
			{
			   //On vérifie si le framecounter compris entre 9 et 30
				if(comboFrameCounter > 9 && comboFrameCounter < 30)
				{
					//On porte un nouveau coup
					if(comboCoup < 5)
					{
						comboCoup++;           //Prochain coup
						comboFrameCounter = 0; //Redemarrage du compteur
					}   
				}   
			} 
		}   
   }
   else
   {
    	velx = 0;
		//vely = 0;  
   }   
	
	//On met a jour les bullets
	for(int k = 0; k < BULLETMAX; k++)
	{
	   if(bullets[k].actif)
	   {
	      //On fait baisser la vie
	      bullets[k].life--;
	      //On update la position
	      bullets[k].x += bullets[k].vx;
	      bullets[k].y += bullets[k].vy;
	      //On vérifie si on doit détruire la boulette 
	      if(bullets[k].life < 0)
	      	bullets[k].actif = false;
	   }   
	}
	
	//On teste si on peu re-tirer une fireball
	/*if(bulletInterval > BULLETINT)
		bulletInterval = 0;*/
	if(nextBulletID >= BULLETMAX)
		nextBulletID = 0;
	   
	
	//On fait baisser la puissance du saut
	if(decreaseVely == true)
	{
	   jumpGrav -= 8;
	   if(jumpGrav <= 0)
	   	jumpGrav = 0;
	}
	   
   //Vérification de collisions
   if(UNFIX(y)+hitbox.yDown+2 < worldMan->curLevel->ly*16)
		CheckCollisions();
	else
		y += 256;
	
	//On vérifie si on dois perdre
	if(y > FIX(worldMan->curLevel->ly*16) || life < 0)
	{
		worldMan->toRestart = true;
	}   
	
   //On définit les états
   //Si on commence a tomber on est plus état de en saut
   if(vely >= 0)
   	isJumping = false;
   	
   //Si on est au sol on réautorise le saut
   if(isOnTheFloor && !ul_keys.held.B)
   {
      //On remet les états par défaut
      isCanJump = true;
      jumpH = 0;
 		decreaseVely = false;
 		
 		//On paramètre la puissance du saut
 		if(isJumperColl)
      	jumpGrav = VELJUMPGEYSER;
      else
      	jumpGrav = VELJUMP;
   }
	
	//Effet de fumée a la réception au sol
	if(isWasOnTheFloor == false && isOnTheFloor == true)
	{
		displayLand = true;
		displayEffectTimer2 = 0;   
	}		   
   	
   //On paramètres l'animation en conséquence
   if(isJumping)
   {
      hitbox.yUp = 2;
      /*hitbox.xLeft = 6;
      hitbox.xRight = 25;*/
   	if(sensH)
			spr.animLoop(6);
		else
			spr.animLoop(7);  
   }
	else if(isFalling && isWasOnThePente == false)
	{
	   hitbox.xLeft = 6;
      hitbox.xRight = 25;
	   hitbox.yDown = 31;
	   isCanJump = false;
	   if(sensH)
			spr.animLoop(8);
		else
			spr.animLoop(9);
	}		   
   
   //Setting de l'animation par défaut
   if(sensH == false && isOnTheFloor && velx == 0 && !isCrounch && comboCoup == 0)
   {
   	spr.animLoop(1); //Idle Left
   	/*hitbox.xLeft = 0;
		hitbox.xRight = 31;*/
	}   
	if(sensH == true && isOnTheFloor && velx == 0 && !isCrounch && comboCoup == 0)
	{
	  /* hitbox.xLeft = 0;
		hitbox.xRight = 31;*/
   	spr.animLoop(0); //Idle Right
 	} 
	
	//On calcule la distance parcourue en X au sol
   if(oldx < x && isOnTheFloor)
   	distanceX += x-oldx;
   if(oldx == x)
   	distanceX = 0;
   if(oldx > x && isOnTheFloor)
   	distanceX -= oldx-x; 
	
	//Gestion des combos
	if(comboCoup > 0 && !isJumping && !isFalling && velx == 0)
	{
	   //Application du coup
	   if(comboFrameCounter < 10)
	   {
	      //Update du framecounter
			isGroundBattle = true;
	   }
	   else
	   {
	     	isGroundBattle = false;
	   }   
	   //Vérifiction du framecounter
	   if(comboFrameCounter < 30)
	   {
	      //Update du framecounter
			comboFrameCounter++;
	   }
		else
		{
			comboFrameCounter = -1;
			comboCoup = 0; 
		}
		
		//Affichage des coups
		if(comboCoup == 1)
		{
		   if(sensH)
				spr.anim(10);
			else
				spr.anim(15);  
		}
		if(comboCoup == 2)
		{
		   if(sensH)
				spr.anim(11);
			else
				spr.anim(16);   
		}
		if(comboCoup == 3)
		{
		   if(sensH)
				spr.anim(12);
			else
				spr.anim(17);   
		}	
		if(comboCoup == 4)
		{
		   if(sensH)
				spr.anim(13);
			else
				spr.anim(18);  
		}
		if(comboCoup == 5)
		{
		   if(sensH)
				spr.anim(14);
			else
				spr.anim(19);   
		}							  
	}   
	
	//Gestion vie et energie
	if(life > 64)
		life = 64;
	//On monte l'énergie tout le temps
	energy += 16;
	if(energy > FIX(64) )
		energy = FIX(64);
	
	//Ajustemment de la position de l'entité en fonction du scrolling
	x_screen = UNFIX(x - FIX(worldMan->curLevel->map->scrollX));
	y_screen = UNFIX(y - FIX(worldMan->curLevel->map->scrollY));
}

void eHeroCat::CheckInteractions()
{
   
}

void eHeroCat::CheckCollisions()
{
	//1ère Etape : Prédiction de collisions avec les bords de la map
	if(x < 0)
		x = 0;
	if(x > FIX((worldMan->curLevel->lx*16) - 32))
		x = FIX((worldMan->curLevel->lx*16) - 32);
	if(y < 0)
		y = 0;
	/*if(y > FIX(worldMan->curLevel->ly*16) )
		y = FIX(worldMan->curLevel->ly*16);*/

		
	isWasOnTheFloor = isOnTheFloor;
	//2ème Etape : Prediction de collisions avec les pentes
	bool isPenteFound = false;
	isWasOnThePente = isOnThePente;
	isOnThePente = false;
	if(vely > 0)
	{
		//On déclare des variables pour le point de test des collisions
		hitbox.yDown = 32;
		int testx = UNFIX(x + velx) + hitbox.xDown;
		int testy = UNFIX(y + vely) + hitbox.yDown-1;
		
		//On récupère le tile qui comprends le point de test
		u16 tile = 0;
		
		//On déclare une structure temporaire
		PenteInfo val;
		
		//On teste si le prochain pixel est bleu (le pixel juste en face)
		if(uGetMapPixel(worldMan->curLevel->map_coll, testx, testy, &tile, NULL, NULL) == 3)
		{
			val.v = 0;
			val.v = worldMan->pentes[tile].v;
			//On vérifie si le tile est une pente (attention optimisation, le passage de structure par copie)
			if(val.v != 0)
				isPenteFound = true;
			
			//Si on a trouvé une pente
			if(isPenteFound)
			{
			   //Définit qu'on est sur une pente
			   isOnThePente = true;
			   speed = 224;
				//On récupère la position x du personnage sur le tile (attention modulo...)
				u8 diff = testx%16;				
				//On déplace le personnage a la position maxy de la pente
				int maxy = worldMan->pentes[tile].hauteur[diff];
				//On calcule les coordonnées en haut du tile en y 
				int tpy = (testy>>4)<<4;
				y = FIX(tpy-hitbox.yDown+maxy);
				x = x + velx;
				vely = 256;
				isOnTheFloor = true;
				isFalling = false;			
			}		
		}
		else if(uGetMapPixel(worldMan->curLevel->map_coll, testx, testy-1, &tile, NULL, NULL) == 3)
		{
		   //On fait un 2ème test sur le pixel juste au dessus
		   testy = testy-1;
			//On déclare une structure temporaire
			val.v = 0;
			val.v = worldMan->pentes[tile].v;
			//On vérifie si le tile est une pente (attention optimisation, le passage de structure par copie)
			if(val.v != 0)
				isPenteFound = true;
			
			//Si on a trouvé une pente
			if(isPenteFound)
			{
			   //Définit qu'on est sur une pente
			   isOnThePente = true;
			   speed = 224;
				//On récupère la position x du personnage sur le tile (attention modulo...)
				u8 diff = testx%16;
				//On déplace le personnage a la position maxy de la pente
				int maxy = worldMan->pentes[tile].hauteur[diff];
				//On calcule les coordonnées en haut du tile en y 
				int tpy = (testy>>4)<<4;
				y = FIX(tpy-hitbox.yDown+maxy);
				x = x + velx;
				vely = 256;
				isOnTheFloor = true;
				isFalling = false;			
			}	
		}
		else if(uGetMapPixel(worldMan->curLevel->map_coll, testx + 1, testy, &tile, NULL, NULL) == 3)
		{
		   //On fait un 2ème test sur le pixel juste à côté
		   testy = testy;
		   testx = testx + 1;
			//On déclare une structure temporaire
			val.v = 0;
			val.v = worldMan->pentes[tile].v;
			//On vérifie si le tile est une pente (attention optimisation, le passage de structure par copie)
			if(val.v != 0)
				isPenteFound = true;
			
			//Si on a trouvé une pente
			if(isPenteFound)
			{
			   //Définit qu'on est sur une pente
			   isOnThePente = true;
			   speed = 224;
				//On récupère la position x du personnage sur le tile (attention modulo...)
				u8 diff = testx%16;
				//On déplace le personnage a la position maxy de la pente
				int maxy = worldMan->pentes[tile].hauteur[diff];
				//On calcule les coordonnées en haut du tile en y 
				int tpy = (testy>>4)<<4;
				y = FIX(tpy-hitbox.yDown+maxy);
				x = x + velx;
				vely = 256;
				isOnTheFloor = true;
				isFalling = false;			
			}	
		}
		else if(uGetMapPixel(worldMan->curLevel->map_coll, testx - 1, testy, &tile, NULL, NULL) == 3)
		{
		   //On fait un 2ème test sur le pixel juste à côté
		   testy = testy;
		   testx = testx - 1;
			//On déclare une structure temporaire
			val.v = 0;
			val.v = worldMan->pentes[tile].v;
			//On vérifie si le tile est une pente (attention optimisation, le passage de structure par copie)
			if(val.v != 0)
				isPenteFound = true;
			
			//Si on a trouvé une pente
			if(isPenteFound)
			{
			   //Définit qu'on est sur une pente
			   isOnThePente = true;
			   speed = 224;
				//On récupère la position x du personnage sur le tile (attention modulo...)
				u8 diff = testx%16;
				//On déplace le personnage a la position maxy de la pente
				int maxy = worldMan->pentes[tile].hauteur[diff];
				//On calcule les coordonnées en haut du tile en y 
				int tpy = (testy>>4)<<4;
				y = FIX(tpy-hitbox.yDown+maxy);
				x = x + velx;
				vely = 256;
				isOnTheFloor = true;
				isFalling = false;			
			}	
		}
	}
	   
	//3ème Etape : Prédiction de collisions avec les côtés
	if(isPenteFound == false)
	{
	   hitbox.yDown = 31;
		if(velx > 0)
		{
		   if(!isJumping && !isFalling)
		   {
				if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xRight, UNFIX(y) + hitbox.yRight, NULL, NULL, NULL) == 2)
					x = oldx;
				else
					x += velx;
			}
			else
			{
			   //On saute ou on tombe, on teste donc 2 points de collisions a droite
			   if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xJumpRightDown, UNFIX(y) + hitbox.yJumpRightDown, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xJumpRightUp, UNFIX(y) + hitbox.yJumpRightUp, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xRight, UNFIX(y) + hitbox.yRight, NULL, NULL, NULL) == 2)
					x = oldx;
				else
					x += velx;
			}						
		}   
		if(velx < 0)
		{
		   if(!isJumping && !isFalling)
		   {
				if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xLeft, UNFIX(y) + hitbox.yLeft, NULL, NULL, NULL) == 2)
					x = oldx;
				else
					x += velx;
			}
			else
			{
			   //On saute ou on tombe, on teste donc 2 points de collisions a gauche
			   if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xJumpLeftDown, UNFIX(y) + hitbox.yJumpLeftDown, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xJumpLeftUp, UNFIX(y) + hitbox.yJumpLeftUp, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x + velx) + hitbox.xLeft, UNFIX(y) + hitbox.yLeft, NULL, NULL, NULL) == 2)
					x = oldx;
				else
					x += velx;
			}						 
		}
		
		//4ème Etape : Prédiction de collisions avec le sol et le plafond
		if(vely < 0)
		{
		   if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x) + hitbox.xUp, UNFIX(y + vely) + hitbox.yUp, NULL, NULL, NULL) == 2)
		   {
				//y = oldy;
				vely = 0;
				isJumping = false;
				isFalling = true;
				isOnTheFloor = false;
			}		
			else
			{
			   isFalling = true;
			   isOnTheFloor = false;
				y += vely;
				vely += worldMan->curLevel->vgy;
				if(vely >=maxvely)
					vely = maxvely;
			}		
		}
		else
		{
		   if(uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x) + hitbox.xDown, UNFIX(y + vely) + hitbox.yDown, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x) + hitbox.xDown-1, UNFIX(y + vely) + hitbox.yDown, NULL, NULL, NULL) == 2 || uGetMapPixel(worldMan->curLevel->map_coll, UNFIX(x) + hitbox.xDown+1, UNFIX(y + vely) + hitbox.yDown, NULL, NULL, NULL) == 2)
		   {
				y = oldy;
				vely = 256;
				isJumping = false;
				isFalling = false;
				isOnTheFloor = true;
				//On teste le pixel juste au dessus
				/*if(uGetMapPixel(worldMan->curLevel->map_coll, x + hitbox.xDown, y + vely + hitbox.yDown -1, NULL, NULL, NULL) == 2)
		   	{
		   	   y--;
		   	} */  
			}	
			else
			{
			   if(isWasOnThePente)
			   	isFalling = false;
			   else
			   	isFalling = true;
			   isOnTheFloor = false;
				y += vely;
				vely += worldMan->curLevel->vgy;
				if(vely >= maxvely)
					vely = maxvely;
			}
		}
	}
}

void eHeroCat::Destroy()
{
   
}  
