/*#include <allegro.h>
#include <string.h>
#include <math.h>
#include "aldumb.h"
#include "standards.h"
#include "rotk2.h"
#include "sounds.h"*/

#include "CCharacter.h"

void CCharacter::reset(void)
{
    restore_life();
    
    anim.stop_anim();
    x=0;
    y=0;
    dy=0;
    dx=0;
    invinc_counter=0;
    
    jumped=5;
    
    jump_height=norm_jump_height;
    
    charging_state=OFF;
    charging_time_left=0;
    
    flamed=false;
}

//returns the number of the proj that is hitting the character
int CCharacter::check_col_with_projs(CProjectiles *projs)
{
    int ret=-1;

    if(projs && exist==true && consumed==false)
    {
        ret=projs->check_col_with_object(this);
    
    }
    
    if(ret!=-1)
    {
        exist=false;
    }
    
    
    return ret;
}

SAMPLE* CCharacter::ret_sample(int num)
{
   return (SAMPLE*)sounds[num].dat;
} 

void CCharacter::draw_p(BITMAP *backgr, int s_x, int s_y)
{

    //calls the drawing function from the map object part of the class
    
    if(exist==true && curpic)
    {
    
        if(DEBUG==1)
            textprintf_ex(backgr,font,100,100,makecol(0,0,0),-1,"Touching Ground: %d, Jumped: %d",touching_ground,jumped);

        x-= (curpic->w -iWidth )/2;
        y+=5;
    
        if(exist==true && consumed==false)
            draw(backgr,s_x,s_y);
        
        y-=5;
        x+= (curpic->w -iWidth )/2;
    }
}

void CCharacter::reset_to_start(void)
{
    restore_life();
    x=startX;
    y=startY;
    dying=false;
    

    dir=LEFT;
    
    anim.set_looping(true);
}

void CCharacter::play_dying(void)
{
    invinc_counter=0;

    dx=0;
    dy=0;
    
    anim.set_looping(false);
    
    dying=true;
    //anim.set_bounds(1,5);
}   

void CCharacter::adjust_web_length(int dir)
{
    length+=dir*5;

    if(length<20)
        length=20;
}

void CCharacter::set_web_left(int n)
{
    web_left = n;
}


void CCharacter::start_pivot(Point pivot)
{
    set_up_pivot(pivot);
}

int CCharacter::check_col_with_objects(CMapObjects *obs, CParts *parts,CDialog *dialog/*, BITMAP *bmpPart*/)
{
    int ret=-1;
    int return_value=-1;
    RGB c={200,0,0};
    ob *obInfo;
    
    
    if(exist==true && consumed==false && curpic)
    {
    ret = obs->check_col_with_object(this,parts,dialog);  //return the number of the object its touching
    //ret=2;

    if(ret!=-1) //it is touching something
        {
        obInfo = obs->return_object_status(ret);   //returns the info for the object

        if(obInfo->pickup_type!=-1)  //it is a pickup
            {
            if(obInfo->pickup_type==1)   //its a star
                {
                invinc_counter=obInfo->pickup_value;
      //          play_sample((SAMPLE*)sounds[invincible].dat,100,125,1000,TRUE);
                }
                
                
            else if(obInfo->pickup_type==2)   //its a heart
                {
                life+=obInfo->pickup_value;
                if(life>max_life)
                    life=max_life;
                }
            else if(obInfo->pickup_type==3)   //its a fry
            {
                //return 1 tells the player class that a fry was picked up
                return_value=1;
            }
            else if(obInfo->pickup_type==4)  //its a cheese
            {
                //return 2 tells the player class that a cheese was picked up
                return_value=2;
            }
            else if(obInfo->pickup_type==5)  //its a trampoline
            {
                dy=-20;
                return_value=3;
            }
            else if(obInfo->pickup_type==6)  //its lava
            {
                dy=-20;
                life_down(obInfo->pickup_value, parts);
                return_value=4;
                
                flamed=true;
                //choose anim for flaming butt
                //play sound for getting flamed
            }
            else if(obInfo->pickup_type==7)  //its a left or right pointing speed arrow
            {

                dx+=obInfo->pickup_value;
                odx=dx;
                return_value=5;

                //pushes the character out of the arrow so that its dx cannot be altered more than once
                while(check_col_with_object(obs->return_object(ret),parts,dialog)==1)
                    x+=obInfo->pickup_value;
            }
            else if(obInfo->pickup_type==8)  //its an item for score
            {
                return_value=8;
            
            }
            if(obInfo->consumable==true)   //it is consumable
                {
                obs->use_up_object(ret);
                parts->create_colour_burst(obs->ret_cenx(ret),obs->ret_ceny(ret),200,3,"all",1);
                }

            }
        }
    }
        
    return return_value;
}

int CCharacter::return_life(void)
{
    return life;
}

int CCharacter::return_max_life(void)
{
    return max_life;
}

void CCharacter::life_down(int n, CParts *parts)
{
    if(invinc_counter==0 && curpic)
    {
        life-=n;
        invinc_counter=60;
        parts->create_colour_burst(x+iWidth/2,y+iHeight/2,300,3,"red",2);
        
        play_sample((SAMPLE*)data[sound01].dat,100,155,1000,FALSE);
        
        if(life<=0)
            invinc_counter=0;
    }
}

int CCharacter::check_col_with_character(CCharacter *c, CParts *parts, CDialog *dialog)
{
    int ret=-1;
    CMapObject *tempO=this;



    if(c->exist==true && exist==true && consumed==false && curpic && c->curpic)
    {
        if(check_col_with_bitmap(iWidth,iHeight,c->iWidth,c->iHeight,x,y,c->x,c->y)==true)
            ret=1;
           
     //   if(obInfo.enim_type==2)
    //    {        
            
            
        if(has_script)
            script.check_condition(tempO,c,parts,dialog,ingameCin);
            
    //    }
    }



    return ret;
}


void CCharacter::change_dir(void)
{
    if(dir==LEFT)
        dir=RIGHT;
    else if(dir==RIGHT)
        dir=LEFT;
}


void CCharacter::set_movement_to_object(CMapObject *ob)
{
    if(ob->exist==true)
    {
        if(ob->dx!=0)
            pdx= ob->dx * (ob->speed) ;

        if(ob->dy!=0)
        {
            pdy= ob->dy * (ob->speed) ;

     //       if(ob->dy>0)
     //           pdy*=2;
        }

    }
}

float CCharacter::ret_x(void)
{
    return x;
}

float CCharacter::ret_y(void)
{
    return y;
}

void CCharacter::key_left(void)
{
    if(ducked==false)
    {
        not_moving=false;

        key_value=LEFT;
        if(dx > -max_speed)
        {
            //if(fTileFriction<=.9)
                //dx-=0.58;
                dx-=x_accel;
            //else if(fTileFriction>.9)
            //    dx-=0.13;
        }
        
        //if(charging_state==AB_CHARGE1)
        //    dx=-max_speed*3;
    }

}

void CCharacter::key_right(void)
{
    if(ducked==false)
    {
        not_moving=false;
    
        key_value=RIGHT;
        if(dx < max_speed)
        {              
            //if(fTileFriction<=.9)
                //dx+=0.58;
                dx+=x_accel;
            //else if(fTileFriction>.9)
            //    dx+=0.13;
        } 
        
        //if(charging_state==AB_CHARGE1)
        //    dx=max_speed*3;
    }
}

void CCharacter::key_up(void)
{
    if(in_water==false)
        startJump(jump_height);
    else
    {
        if(jumped==-1)                      //not jumping
        {
            dy=-7;
            jumped++;
        }
    }
}

void CCharacter::apply_friction(float modifier)
{
    if(head_touching==false)
    {
        if((float)abval(dx)-(float)fTileFriction>0)
        {
            if(dx>0)
                dx-=fTileFriction*modifier;          //for friction
            else 
                dx+=fTileFriction*modifier;
        }
        else
            dx=0;
    }
}

void CCharacter::not_left_or_right(void)
{
    if(head_touching==false)
    {
        if(not_moving==false)
            not_moving=true;
        
        if(swinging==false)
        {
            apply_friction();
    
        }
    }
    //dx*=fTileFriction;

    //key_value=-1;
}

void CCharacter::startJump(float power)
{
    if(jumped<=0 && start_jump==0 && touching_ground==true)
    {   
        if(obInfo.type==0)  //its a player
            start_jump=4;          //number of cycles to wait
        else
            start_jump=1;           //enemies should jump immeditaly
            
        jump_power = power; 
    }
}

bool CCharacter::check_down(CMap *map, CMapObjects *objects, CParts *parts)
{
    int hit=0,iTemp=-1,iNum=-1;
    ob *returnInfo;
    bool touching_ground=false;
    float touching_object=-1;

    pdx=0;
    pdy=0;
    
    float yy=0,xx=0;
    
    for(yy=0 ; yy < ceil(dy) ; yy++)
    {
        hit=0;

        for(xx=curpic->w/4 ; xx <  pic->w-pic->w/4 ; xx++)
        {
            //returns the info for the tile at that position
            iTemp=-1;
            iNum=-1;
//            if(obInfo.enim_type==-1)    //it is not an enemy
            {
                iNum=objects->return_object_num(x+xx,y+pic->h+yy/*+pdy*/);
           // iNum=-1;


                if(iNum!=-1)    //he is touching an object
                {
                    returnInfo=objects->return_object_status(iNum);
                    iTemp=returnInfo->tile_type;
                    
                    if(returnInfo->tile_type==2 && returnInfo->moving==true)    //moving platform type 2
                    {
                        set_movement_to_object(objects->return_object(iNum));

                        hit=true;
                        
                        if(touching_platform==false /*&& pdy<0*/)
                            y+=3;
                        touching_platform=true;
                        
                        break;

                    }
                    else
                    {
                        //touching_platform=false;
                    }
                }
                else
                {
                    pdx=0;
                    pdy=0;
                    //touching_platform=false;
                }
            }


            if(iTemp==-1)   //if was not touching an object
            {
                //touching_platform=false;
                iTemp=map->return_tile_status(x+xx,y+pic->h+yy+5);
            }
        

            //reset the amout of friction back to the standard value
            //tile_friction_value=.90;      //standard friction


            if(iTemp==3)    //its spikes
            {
                if(obInfo.type==0)  //its a player
                    life_down(200,parts);
            }
            else if(iTemp==4)   //its icey
            {
         //       tile_friction_value=.97;         //icey friction
            }

            //if the character is inside there ground, push him up onto
            //the top        
            while(map->return_tile_status(x+xx,y+yy+pic->h-2)!=-1 )
                y-=1;

            if(iTemp!=-1) //hitting ground
            {
                y+=yy;
                hit=1;
                if(pdy==0)
                    dy=0;         
                break;
            }
        }

        if(hit==1)
        {
            dy=0;
            //ody=0;
            touching_ground=true;
            break;
        }
        else
            y++;
            
        if(touching_platform==true)
            break;
    }

    return touching_ground;
}

bool CCharacter::check_up(CMap *map)
{
    bool touching_ground=false;
    int hit=0,iTemp;
    
    touching_platform=false;
    
    for(int yy=0 ; yy > ceil(dy) ; yy--)
    {
        hit=0;
        for(int xx=pic->w/4 ; xx < pic->w-pic->w/4 ; xx++)
        {
            iTemp=map->return_tile_status(x+xx,y+yy);
            if(iTemp==1 || iTemp==3 || iTemp==4 || iTemp==POSITIVE_SLOPE) //hitting ground
            {
                hit=1;
                break;
            }
        }
        if(hit==1)
        {
            dy=0;
            ody=0;
            hit=1;
            
            touching_ground=false;
            break;
        }
        else
            y--;
    }
    return touching_ground;
}

void CCharacter::check_right(CMap *map)
{
    int hit=0,iTemp;
    


    
    for(int xx=0 ; xx < ceil(dx) ; xx++)
    {
        hit=0;
        for(int yy=0 ; yy < pic->h-7 ; yy++)
        {
    
            iTemp=map->return_tile_status(x+/*((picture_type==USEANIM) ? anim.ret_widest() : pic->w)*/pic->w+xx,y+yy);

            if(iTemp==1 || iTemp==3 || iTemp==4) //hitting ground
            {
                x+=xx;
                hit=1;
                
                //int iTemp2

                do
                {
                    iTemp = map->return_tile_status(x+pic->w,y+yy);
                    x--;
                } while(iTemp==1 || iTemp==3 || iTemp==4);
                
                break;

            }
            else if(iTemp==POSITIVE_SLOPE)
            {
                y -=dx/1.5;
                
                //if(abval(dx>1))
                //    dx-=2;
                break;
            }
            else if(iTemp==NEGATIVE_SLOPE)
            {
                y+=dx/1.5;
                //if(abval(dx>1))
                //    dx+=2;
                break;
            }
            
        }
        if(hit==1)
        {
            if(obInfo.enim_type!=-1)  //it is an enemy
            {
                dx*=-1;
                change_dir();
            }
            else
                dx=0;

            angle_vel*=-1;
            angle_acc*=-1;
            odx=0;
            break;
        }
    }
    if(hit==0)
        x+=dx;
}

void CCharacter::check_left(CMap *map)
{
    int hit=0,iTemp;
    for(int xx=0 ; xx > ceil(dx)-1 ; xx--)
    {
        hit=0,iTemp;
        for(int yy=0 ; yy < pic->h-1 ; yy+=3)
        {
            iTemp=map->return_tile_status(x+xx,y+yy);

            if(iTemp==1 || iTemp==3 || iTemp==4) //hitting ground
            {
                x+=xx;
                hit=1;
                break;
            }
            else if(iTemp==POSITIVE_SLOPE)
            {
                y -=dx/1.5;
                
                //if(abval(dx>1))
                //    dx-=2;
                break;
            }
            else if(iTemp==NEGATIVE_SLOPE)
            {
                y+=dx/1.5;
                //if(abval(dx>1))
                //    dx+=2;
                break;
            }
        }
        if(hit==1)
        {

            if(obInfo.enim_type!=-1)  //it is an enemy
            {
                //change the direction when it hits a wall
                dx*=-1;
                change_dir();
            }
            else
                dx=0;

            angle_vel*=-1;
            angle_acc*=-1;

            odx=0;
            break;
        }
    }
    if(hit==0)
        x+=dx;
}



bool CCharacter::moveLeft(CMap *map)
{
    CObject tileAt;
    int xx=0,yy=0;
    
    if(exist==true && curpic)
    {
        x-=5;
        for(xx=0 ; xx > dx-3 ; xx--)
        {
            if(x+xx<=0)
            {
                x+=5;
                return true;
            }
            
            for(yy=4 ; yy< iHeight-4 ; yy+=16)
            {
                int ts = map->return_tile_status(x,y+yy);
                if(ts!=EMPTY && ts!=FROM_BELOW)
                {
                    map->retTileAt(&tileAt, x , y+yy,1);
                    if(check_col(&tileAt)==true)
                    {
                        //x+=3;
                        /*while(check_col(&tileAt)==true)
                        {
                            x++;
                            map->retTileAt(&tileAt,x,y+yy,1); 
                        }*/
                
                        //x++;
                        dx=0;
                    
                        x+=5;
                        return true;
                    }
                }
            }
            x--;
        }
        
        x+=5;

    }
    return false;
}

bool CCharacter::moveRight(CMap *map)
{
    CObject tileAt;
    int xx=0,yy=0;
    
    if(exist==true && curpic)
    {    
    
        x+=5;
        
        for(xx=0 ; xx< dx+3 ; xx++)
        {
            for(yy=4 ; yy < iHeight-4 ; yy+=16)
            {
                int ts = map->return_tile_status(x+iWidth,y+yy);
                if(ts != EMPTY &&  ts!=FROM_BELOW)
                {
                    map->retTileAt(&tileAt, x+iWidth , y+yy,1);  
    
                    if(check_col(&tileAt)==true)
                    {
                        //x-=3;
                        /*while(check_col(&tileAt)==true)
                        {
                            x--;
                            map->retTileAt(&tileAt, x+pic->w , y+yy,1); 
                        }*/
                    
                        //x--;
                        dx=0;
                        x-=5;
                        return true;
                    }
                }
            }
            x++;
        }
        //x+=xx;
        x-=5;
    }
    return false;
}

void CCharacter::moveUp(CMap *map)
{
    CObject tileAt;
    int xx=0, yy=0;
    float oldY=y;
    
    head_touching=false;
    
    
    if(exist==true && curpic)
    {
    
        for(yy=0 ; yy>dy - ducked==true?12:0 ; yy--)
        {
            for(xx=2 ; xx <iWidth-2 ; xx+=16)
            {
                int ts = map->return_tile_status(x+xx,y);
                if(ts != EMPTY && ts != FROM_BELOW)
                {
                    map->retTileAt(&tileAt, x+xx,y,1);
                    
                    if(check_col(&tileAt)==true)
                    {
                        //y+=yy;
                        dy=0;
                        //if(touching_ground==true)
                        //    key_down();
                            //ducked=true;
                        head_touching=true;
                        return;
                    }
                    //delete(tileAt);       
                }   
            }
            y--;
        }
    }
    
    //if it is ducked, do not actually move the guy up
    //if(ducked==false)
    //    y=oldY;
}

void CCharacter::moveDown(CMap *map,CMapObjects *objects, CParts *parts)
{
    CObject tileAt;
    int xx=0,yy=0;
    int ts; //tile status
//    y+=2;
    if(exist==true && curpic)
    {
        for(yy=0 ; yy<dy+1 ; yy++)    
        {
            for(xx=2 ; xx <iWidth-2 ; xx+=16)
            {
                ts = map->return_tile_status(x+xx,y+iHeight+1);
                if(ts != EMPTY)
                {
                
                    map->retTileAt(&tileAt, x+xx,y+iHeight+1,1);  
                
                    if(check_col(&tileAt)==true)
                    {
                        while(check_col(&tileAt)==true)
                        {
                            y--;
                            map->retTileAt(&tileAt, x+xx,y+iHeight+1,1); 
                        }
                        y++;
                        //y+=2;
                        
                        
                        dy=0;
                        setTouchingGround(true);
                        fTileFriction = map->retFrictionAt(x+xx,y+iHeight+1);
                        
                        if(ts==3)    //its spikes
                        {
                            if(obInfo.type==0)  //its a player
                                life_down(200,parts);
                        }
                        
    //                    y-=2;
                        return;
                    }
                }
            }
            if(touching_ground==false)
                y++;
        }
        
        jumped++;
    }
}

void CCharacter::moveJump(void)
{
    if(start_jump==1)
    {
        jumped++;
        
        //if(obInfo.type==0 && sounds)
        //    play_sample((SAMPLE*)sounds[ketchup_jump].dat,100,125,1000,FALSE);
        
        if(ducked==true)
        {
            not_key_down();     //stop it from being ducked
            
            if(skills.ability[AB_DUCKJUMP]==true)
                jump_power*=1.15;   //jump a bit higher
        }
        dy=-jump_power;
        
    }     
    if(start_jump>0)
        start_jump--; 

    //if it is a player or a player dependant jumping enemy
    if(obInfo.type==0 || obInfo.enim_type==4)
    {
        //add code to make it not jump as high if not holding the UP key
        if(!key[KEY_UP] && jumped>3 && dy<0 && flamed==false)
            dy+=1.5;  

    }
}

void CCharacter::moveEnim(void)
{
    //type 1 enemy is a jumping enemy
    //type 2 enemy is a falling rock enemy
    //type 3 enemy is a walking enemy
    //type 4 enemy is a player-dependant jumping enemy (ie jumps when player jumps)
    //type 5 enemy is a swooping enemy (eg bird)
    //type 6 enemy is a flying enemy (moves like a platform)

    if((obInfo.enim_type==1 || obInfo.enim_type==3 || obInfo.enim_type==4 || obInfo.enim_type==5))
    {
        fTileFriction=.5;
        x_accel=fTileFriction*1.5;  
        if(obInfo.enim_type==1 || obInfo.enim_type==4)    //a jumping enemy
        {
            if(jumped==-1)   //so make it jump
            {
                jumped++;
                dy=0;
                dy-=obInfo.pickup_value;
            }
            if(obInfo.grav==true)
                y_accel=gravity;
        }
        else if(obInfo.enim_type==3)    //a walking enemy
        {
            //interpret the pickup value as it max speed
            max_speed = obInfo.pickup_value;
        }
        else if(obInfo.enim_type==5)    //a swooping enemy
        {
            max_speed = obInfo.pickup_value;
            
            if(y>p1.y+(p2.y-p1.y)/3)  
                y_accel=-.9;
        }    

        if(obInfo.grav==true)
        {
            if((int)p1.x==(int)p2.x)
            {
                dx=0;
                angle=0;
            }  
            else if(dir==RIGHT)
                key_right();
            else if(dir==LEFT)
                key_left();
        }
    }
}

void CCharacter::move(CMap *map, CMapObjects *objects, CParts *parts, float s_x, float s_y)
{
    bool hitWallL,hitWallR;
    if(exist==1 && consumed==false && still==false && curpic)
    {
        if( obInfo.moving==true )
        {
            if( x-s_x>-250 && x-s_x<1050 && y-s_y>-250 && y-s_y<850)
            {
                if(x<=15)
                    x=16;
    
    
                move_mo();
                //dir=LEFT;
                
                if(obInfo.grav==true)
                {
                    moveJump();
                    
                    if(touching_ground==false)
                        dy+=y_accel;           
    
        
                    touching_ground=false;
                
                    if(obInfo.type==0)      //it is a player
                        checkColWithPlatforms(objects);
                  
                    if(charging_time_left>0)
                    {
                        charging_time_left--;
                        if(charging_time_left==0)
                        {
                            stopCharging();
                        }
                    }
                            
                    if(obInfo.enim_type==5)
                    {          
                        x+=dx;
                        y+=dy;
                        hitWallL=false;
                        hitWallR=false;
                    
                    }
                    else
                    { 
                            
                        moveUp(map);
                        if(head_touching==true && abval(dx)<max_speed*.75 && ducked==true)
                        {
                                dx = -dx;
                                x+=dx;
                        }
                        
                        /*if(charging_state==AB_CHARGE1)
                            if(dy>0)
                                dy=0;*/
                                
                        moveDown(map,objects,parts);
                          
                        x_accel=fTileFriction*1.5;  
                        
                        if(charging_state==AB_CHARGE1)
                            dx=max_speed*3* (dir==LEFT?-1:1);  //x_accel=max_speed*3;
                        
                        
                        hitWallL=moveLeft(map);
                        hitWallR=moveRight(map);
    
                    }    
    
                    if(hitWallL==true || hitWallR==true)
                    {
                        stopCharging();   
                    }
    
                    if(ducked==true)
                    {
                        int ts = map->return_tile_status(x+iWidth/2,y-10);
    //                    if(ts == EMPTY || ts == FROM_BELOW)
    //                        dx*=fTileFriction;          //for friction
                    }
        
    //                if(abval(dx)<=0.005)
    //                    dx=0;
    
                    if(charging_state!=AB_CHARGE1)
                    if(abval(dx)>max_speed)    //if the speed is bigger than its max speed
                        apply_friction();
                        //dx*=(fTileFriction-.01);      //apply the friction to ketchup
                }
                 
                if(invinc_counter>0)
                    invinc_counter--;
            }
            if(obInfo.enim_type!=-1)    //it is an enemy
            {
                if(hitWallL==true || hitWallR==true)
                    change_dir();
                moveEnim();
            }  
        }
        else
        {
            if(picture_type==USEANIM /*&& anim_on==true*/ )
                move_anim(); 
        }    
    }    
}


void CCharacter::checkColWithPlatforms(CMapObjects *objects)
{
    int tx,ty,bx,by;    //collision rectangle around ketchup's feet
    
    if(exist==true && curpic)
    {
        tx=(int)x; ty=(int)y+iHeight;
        bx=(int)x+iWidth ; by=(int)y+iHeight+(int)dy;
        
        int ans = objects->check_platform_col_with_bbox(tx,ty,bx,by);
        
        if(ans!=-1)
        {
            setTouchingGround(true);
            
            CMapObject *temp = objects->return_object(ans);
     
           dy=0;
            
            if(temp)
            {
                float plat_speed=temp->speed;
                
                while(objects->check_platform_col_with_bbox((int)x,(int)y+iHeight,(int)x+iWidth,(int)y+iHeight)!=-1)
                {
                    y--;
                }
                y+=plat_speed;
                
                y += temp->dy*plat_speed;
                x += temp->dx*plat_speed;
            }
        }
    }
}

/*
void CCharacter::move(CMap *map, CMapObjects *objects, CParts *parts, float s_x, float s_y)
{
  int hit=0;
  int iTemp=-1;
  pdx=0; pdy=0;

  touching_ground=false;
  if(exist==1 && consumed==false && still==false)
    {
    if( x-s_x>-150 && x-s_x<800 && y-s_y>-150 && y-s_y<700)
        {
        move_mo();
             
         if(obInfo.grav==true)
         {
        if(start_jump==1)
        {
            jumped++;
        
            if(obInfo.type==0 && sounds)
                play_sample((SAMPLE*)sounds[ketchup_jump].dat,100,125,1000,FALSE);
        
            dy=-jump_power;
        }     
        if(start_jump>0)
            start_jump--;     
             
        //if it is an enemy then the movement must be automated
        //type 1 enemy is a jumping enemy
        //type 2 enemy is a falling rock enemy
        //type 3 enemy is a walking enemy
        if((obInfo.enim_type==1 || obInfo.enim_type==3))
        {
            if(obInfo.enim_type==1)     //a jumping enemy
            {
                if(jumped==-1)   //so make it jump
                {
                    jumped++;
                    dy=0;
                    dy-=obInfo.pickup_value;
                }
            }
            else if(obInfo.enim_type==3)    //a walking enemy
            {
                //interpret the pickup value as it max speed
                max_speed = obInfo.pickup_value;
            }


            if((int)p1.x==(int)p2.x)
            {
                dx=0;
                angle=0;
            }
            else if(dir==RIGHT)
                key_right();
            else if(dir==LEFT)
                key_left();
        }

        if(obInfo.type==0)         // a player
        {
          if(!key[KEY_UP] && jumped>3 && dy<0 && flamed==false)
               dy+=1.5;           
        }
           
        if(dy>term_vel)
           dy=term_vel;   

        if(swinging==false)
        {

            if(in_water==false && touching_platform==false)
                dy+= gravity;
            else
                dy+=.1;
         //   dx*=tile_friction_value;          //for friction
        }

        odx=dx;
        ody=dy;

        if((dy>0 || dy==0) )
        {
            //when heading back down, he is no longer flamed
            if(flamed==true)
                flamed=false;
                
            if(check_down(map,objects,parts)==true)
                touching_ground=true;
            else
                touching_platform=false;
        }

        dx+=pdx;
        y+=pdy;

        if(dy<0)
        {
            if(check_up(map)==true)
                touching_ground=true;
        }

        if(dx>0 )
        {
            check_right(map);
        }

        else if(dx<0)
        {
            check_left(map);
        }

     //   x+=dx;

        dx=odx;
        dy=ody;
        
        if(touching_ground==true)
        {
            if(jumped>-1)
            {
                if(obInfo.type==0 && sounds && landing==0)
                {
                    play_sample((SAMPLE*)sounds[ketchup_land].dat,100,125,1000,FALSE);
                    landing=5;
                }
                jumped=-1;
            }                
            swinging=false;
            dy=0;
        }
        else
        {
            jumped++;
            if(landing>0)
                landing--;
        }

        if(x<0)
        {
            x=0;
            dx=0;
        }
        if(y<0)
        {
            y=0;
            dy=0;
        }


        swing_pos_x = x+pic->w/2;

        swing_pos_y = y+pic->h/2;

        if(abval(dx)<=0.1)
            dx=0;

        if(invinc_counter>0)
        {
            invinc_counter--;
        
        }    
        

        if(in_water==true)
        {
            tile_friction_value=.97;

            if(dy>-.5)
                jumped=-1;
        }
        }
    }
    }
}*/


void CCharacter::init_c(void)
{
    init_mo();
    key_value=-1;
    dy=0;
    dx=0;
    max_speed=4.5;
    dir=LEFT;
    pdx=0;
    pdy=0;
    life=1;
    web_left=0;

    jumped=5;
    
    x_accel=0;
    y_accel=gravity;
    
    flamed=false;
    start_jump=0;

    in_water=false;
    landing=0;
    touching_ground=true;
    head_touching=false;
    
    charging_state=OFF;
    charging_time_left=0;
    
    norm_jump_height=16;
    jump_height=norm_jump_height;

    for(int n=0 ; n<MAX_ABILITIES ; n++)
        skills.ability[n]=false;
    skills.ability[AB_CHARGE1]=true;
    
    startX=0;
    startY=0;
    
    //this means we're not using the new screen values
    new_screen_x=-1;
    new_screen_y=-1;
    
    dying=false;
}

void CCharacter::create_c(ob _obInfo, DATAFILE *d, DATAFILE *_sounds, float _x, float _y, int _life, CCinematic *_ingameCin)
{
    Point pTemp={_x,_y};

    init_c();
    //creates the object section of the character
    create_mo(_obInfo, d, _x, _y, pTemp,_ingameCin);
    life = _life;
    max_life=life;
    
    sounds=_sounds;
    
    dir=LEFT;
}

void CCharacter::create_c(CMapObject *ob)
{
    init_c();
    create_mo(ob);
    exist=true;
}

void CCharacter::setTouchingGround(bool state)
{
    touching_ground=state;
    if(state==true)
    {
        jumped=-1;
        dy=0;
        //start_jump=0;
    }
    flamed=false;
}

void CCharacter::key_down(void)
{
    if(ducked==false && touching_ground==true)
    {
        ducked=true; 
        //y+=30;
        iHeight-=12;
        y+=12;

    }

    apply_friction(.5);
    if(dx==0)
        if(not_moving==false)
            not_moving=true;
}

void CCharacter::not_key_down(void) 
{
    if(ducked==true)
    {
        if(head_touching==false)
        {
            ducked=false; 
            iHeight+=12;
            y-=12;
        }
    }
}

void CCharacter::startCharge1(void)
{
    skills.ability[AB_CHARGE1]=true;
    if(skills.ability[AB_CHARGE1]==true)
    {
        charging_state=AB_CHARGE1;
        
        charging_time_left = 20;
        jump_height=20;
    }
}

void CCharacter::stopCharge1(void)
{
    jump_height=norm_jump_height;;
}

void CCharacter::stopCharging(void)
{
    charging_time_left=0;
    switch(charging_state)
    {
    case AB_CHARGE1:
        stopCharge1();
        break;
    default:
        break;
    
    }
    
    charging_state=OFF;
}
