/*********************************** Sandstorm COLLIDE.C ************************************/ /**** INCLUDES ****/ #include #include "main.h" #include "graphics.h" #include "pad.h" #include "control.h" #include "debug.h" #include "sprite.h" #include "collide.h" #include "fire.h" #include "ai.h" #include "cdread.h" #include "sound.h" /**** GLOBALS ****/ VECTOR f3a, f3b, f4a, f4b, f5a, f5b; int vis_3, vis_4, vis_5; int vis_3_count, vis_4_count, vis_5_count; /**** CHECKCOLLISION ****/ int CheckCollision( GsCOORDINATE2 *object, short radius, GsCOORDINATE2 *object2, short radius2 ) { if(object->coord.t[0] > (object2->coord.t[0] + radius2) || object2->coord.t[0] > (object->coord.t[0] + radius) || object->coord.t[2] > (object2->coord.t[2] + radius2) || object2->coord.t[2] > (object->coord.t[2] + radius) ) { return(0); //no collision } else { return(1); //COLLISION } } /**** CHECKCOLLISIONITEM ****/ int CheckCollisionItem( GsCOORDINATE2 *object, short radius, VECTOR *object2, short radius2 ) { if(object->coord.t[0] > (object2->vx + radius2) || object2->vx > (object->coord.t[0] + radius) || object->coord.t[2] > (object2->vz + radius2) || object2->vz > (object->coord.t[2] + radius) ) { return(0); //no collision } else { return(1); //COLLISION } } /**** DAMAGEHIT ****/ //**NOTE: int "type" parameter refers to the type of missile launched. //** 0-fire; 1-homing; 2-power; 3-fire2; 4-homing2; 5-power2; 6-fire3; 7-homing3; 8-power3 void HitMissile( int *actcounter, GsCOORDINATE2 *object, int radius, GsCOORDINATE2 *missilecoord, int radius2, int status, int type, GsBOXF *hitbox, int missilerot, int damage ) { static int counter; int rotcarnew; static int init_count; if(status==1){ if(missilerot>(179<<12)) rotcarnew=missilerot-(180<<12); if(missilerot<(180<<12)) rotcarnew=missilerot+(180<<12); if(CheckCollision(object, radius, missilecoord, radius2 ) ){ init_count=1; if(type==0) fire_m.obj.attribute|=(1<<31); if(type==1) homing_m.obj.attribute|=(1<<31); if(type==2) power_m.obj.attribute|=(1<<31); if(type==3) fire2_m.obj.attribute|=(1<<31); if(type==4) homing2_m.obj.attribute|=(1<<31); if(type==5) power2_m.obj.attribute|=(1<<31); if(type==6) fire3_m.obj.attribute |=(1<<31); if(type==7) homing3_m.obj.attribute |=(1<<31); if(type==8) power3_m.obj.attribute |=(1<<31); *actcounter=1; if(counter==1) hitbox->w-=damage; //check to see who is hit to display fire animation //greencar=100; redcar=101; whitecar==99 if(radius==100) //if greencar (p1) is hit vis_3=1; if(radius==101) vis_4=1; if(radius==99) vis_5=1; } if(*actcounter==1){ counter++; if(counter==40){ counter=0; *actcounter=0; if(type==0) fire_m_status=0; if(type==1) homing_m_status=0; if(type==2) power_m_status=0; if(type==3) fire2_m_status=0; if(type==4) homing2_m_status=0; if(type==5) power2_m_status=0; if(type==6) fire3_m_status=0; if(type==7) homing3_m_status=0; if(type==8) power3_m_status=0; } object->coord.t[0]+=((SLIDESPEED*SIN[missilerot>>12])>>12); object->coord.t[2]+=((SLIDESPEED*COS[missilerot>>12])>>12); } } } //end HITMISSILE /**** HITRBM ****/ //tests ricochet/bullet/mine collisions //**** actcounter1 for truck[1], actcounter2 for truck[2], actcounter3 for truck[0] (p1) //**NOTE: type parameter refers to type of weapon launched. //** 0-rico; 1-mine; 2-bullet void HitRBM( int *actcounter, GsCOORDINATE2 *object, int radius, VECTOR *vect, int radius2, int status, int type, GsBOXF *hitbox, int rot, int damage, int slide ) { static int counter; int rotcarnew; if(status==1){ //check only if fired to save CPU time if(CheckCollisionItem(object, radius, vect, radius2) ){ if(type==0) ricochet.attribute|=(1<<31); if(type==1) { mine_1.attribute|=(1<<31); mine_2.attribute|=(1<<31); mine_3.attribute|=(1<<31); } *actcounter=1; if(counter==1) hitbox->w-=damage; if(type==2) hitbox->w-=damage; } if(*actcounter==1){ counter++; if(counter==40){ counter=0; *actcounter=0; if(type==0) rico_status=0; if(type==1){ mine_status=0; detonate=0; expl_status=0; p1items.mine=0; } } object->coord.t[0]+=((slide*SIN[rot>>12])>>12); object->coord.t[2]+=((slide*COS[rot>>12])>>12); } } } //end HITMISSILE /**** TESTALLMISSILES ****/ void TestAllMissiles( void ) { //player missile to enemy 1 test HitMissile( &actcounter1, &truck[1].coord, redcar.radius, &fire_m.coord, missile.radius, fire_m_status, 0, &cpulife1, fire_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter1, &truck[1].coord, redcar.radius, &power_m.coord, missile.radius, power_m_status, 2, &cpulife1, power_m_dir, POWER_DAMAGE ); HitMissile( &actcounter1, &truck[1].coord, redcar.radius, &homing_m.coord, missile.radius, homing_m_status, 1, &cpulife1, homing_m_dir, HOMING_DAMAGE ); //player missile to enemy 2 test HitMissile( &actcounter2, &truck[2].coord, whitecar.radius, &fire_m.coord, missile.radius, fire_m_status, 0, &cpulife2, fire_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter2, &truck[2].coord, whitecar.radius, &power_m.coord, missile.radius, power_m_status, 2, &cpulife2, power_m_dir, POWER_DAMAGE ); HitMissile( &actcounter2, &truck[2].coord, whitecar.radius, &homing_m.coord, missile.radius, homing_m_status, 1, &cpulife2, homing_m_dir, HOMING_DAMAGE ); //enemy missile 1 to player test HitMissile( &actcounter3, &truck[0].coord, greencar.radius, &fire2_m.coord, missile.radius, fire2_m_status, 3, &life, fire2_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter3, &truck[0].coord, greencar.radius, &power2_m.coord, missile.radius, power2_m_status, 5, &life, power2_m_dir, POWER_DAMAGE ); HitMissile( &actcounter3, &truck[0].coord, greencar.radius, &homing2_m.coord, missile.radius, homing2_m_status, 4, &life, homing2_m_dir, HOMING_DAMAGE ); //enemy missile 1 to enemy 2 HitMissile( &actcounter5, &truck[2].coord, whitecar.radius, &fire2_m.coord, missile.radius, fire2_m_status, 3, &cpulife2, fire2_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter5, &truck[2].coord, whitecar.radius, &power2_m.coord, missile.radius, power2_m_status, 5, &cpulife2, power2_m_dir, POWER_DAMAGE ); HitMissile( &actcounter5, &truck[2].coord, whitecar.radius, &homing2_m.coord, missile.radius, homing2_m_status, 4, &cpulife2, homing2_m_dir, HOMING_DAMAGE ); //enemy missiles 2 to player collision test HitMissile( &actcounter4, &truck[0].coord, greencar.radius, &fire3_m.coord, missile.radius, fire3_m_status, 6, &life, fire3_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter4, &truck[0].coord, greencar.radius, &power3_m.coord, missile.radius, power3_m_status, 8, &life, power3_m_dir, POWER_DAMAGE ); HitMissile( &actcounter4, &truck[0].coord, greencar.radius, &homing3_m.coord, missile.radius, homing3_m_status, 7, &life, homing3_m_dir, HOMING_DAMAGE ); //enemy missiles 2 to enemy 1 HitMissile( &actcounter6, &truck[1].coord, redcar.radius, &fire3_m.coord, missile.radius, fire3_m_status, 6, &cpulife1, fire3_m_dir, FIRE_DAMAGE ); HitMissile( &actcounter6, &truck[1].coord, redcar.radius, &power3_m.coord, missile.radius, power3_m_status, 8, &cpulife1, power3_m_dir, POWER_DAMAGE ); HitMissile( &actcounter6, &truck[1].coord, redcar.radius, &homing3_m.coord, missile.radius, homing3_m_status, 7, &cpulife1, homing3_m_dir, HOMING_DAMAGE ); /**** RICOCHET COLLISION TEST ****/ //if rico hits truck[1] HitRBM( &actcounter1, &truck[1].coord, greencar.radius, &rico_pos, item.radius, rico_status, 0, &cpulife1, rico_dir, RICO_DAMAGE, SLIDESPEED ); //if rico hits truck[2] HitRBM( &actcounter2, &truck[2].coord, greencar.radius, &rico_pos, item.radius, rico_status, 0, &cpulife2, rico_dir, RICO_DAMAGE, SLIDESPEED ); } //end TESTALLMISSILES /**** ASSESSDAMAGE ****/ void AssessDamage( void ) { //keep life bars in proper range if(life.w>80) { life.w=0; p1destroyed=1; } if(cpulife1.w>40) { cpu1destroyed=1; cpulife1.w=0; } if(cpulife2.w>40) { cpu2destroyed=1; cpulife2.w=0; } //health recharges life if( p1items.hlt>0 ) { life.w+=HEALTH_PLUS; if(life.w>80) life.w=80; p1items.hlt=0; } if( (CheckCollisionItem(&truck[1].coord, greencar.radius, &hlt_ico_pos, item.radius)) && (spot[3]==1) ) { cpulife1.w+=HEALTH_PLUS; if(cpulife1.w>40) cpulife1.w=40; } if( (CheckCollisionItem(&truck[2].coord, greencar.radius, &hlt_ico_pos, item.radius)) && (spot[3]==1) ) { cpulife2.w+=HEALTH_PLUS; if(cpulife2.w>40) cpulife2.w=40; } } //end ASSESSDAMAGE /**** POSFIRECARS ****/ void PosFireCars( void ) { f3a.vx=f3b.vx=truck[0].coord.coord.t[0]; f3a.vz=f3b.vz=truck[0].coord.coord.t[2]; f4a.vx=f4b.vx=truck[1].coord.coord.t[0]; f4a.vz=f4b.vz=truck[1].coord.coord.t[2]; f5a.vx=f5b.vx=truck[2].coord.coord.t[0]; f5a.vz=f5b.vz=truck[2].coord.coord.t[2]; } /**** DRAWFIRECARS ****/ void DrawFireCars( void ) { static int counter; counter++; if(counter>100) counter=0; if(vis_3==1) { if(counter<50) draw_3dsprite(&fire3a, f3a, 10); else draw_3dsprite(&fire3b, f3b, 10); } if(vis_4==1) { if(counter<50) draw_3dsprite(&fire4a, f4a, 10); else draw_3dsprite(&fire4b, f4b, 10); } if(vis_5==1) { if(counter<50) draw_3dsprite(&fire5a, f5a, 10); else draw_3dsprite(&fire5b, f5b, 10); } } /**** HIDEFIRE ****/ void HideFire( void ) { if(vis_3==1) vis_3_count++; if(vis_3_count>100) { vis_3=0; vis_3_count=0; } if(vis_4==1) vis_4_count++; if(vis_4_count>100) { vis_4=0; vis_4_count=0; } if(vis_5==1) vis_5_count++; if(vis_5_count>100) { vis_5=0; vis_5_count=0; } } //end HIDEFIRE /**** LIMITAREA ****/ //prevents cars from moving off-screen void LimitArea( GsCOORDINATE2 *coord, GsCOORDINATE2 *oldcoord ) { if(coord->coord.t[0]<-2958) *coord=*oldcoord; if(coord->coord.t[0]>2998) *coord=*oldcoord; if(coord->coord.t[2]<-2900) *coord=*oldcoord; //make playable area larger after object passes middle pyramid if(coord->coord.t[0]<306) { if(coord->coord.t[2]>1075) *coord=*oldcoord; } else { if(coord->coord.t[2]>2203) *coord=*oldcoord; } } //end LIMITAREA /*** TESTCARCOLLISION ****/ //tests car-to-car collisionsfs void TestCarCollision( void ) { if(CheckCollision( &truck[0].coord, car_coll.radius, &truck[1].coord, car_coll.radius ) ) truck[0].coord=oldcoord0; if(CheckCollision( &truck[0].coord, car_coll.radius, &truck[2].coord, car_coll.radius ) ) truck[0].coord=oldcoord0; if(CheckCollision( &truck[1].coord, car_coll.radius, &truck[0].coord, car_coll.radius ) ) truck[1].coord=oldcoord1; if(CheckCollision( &truck[1].coord, car_coll.radius, &truck[2].coord, car_coll.radius ) ) truck[1].coord=oldcoord1; if(CheckCollision( &truck[2].coord, car_coll.radius, &truck[0].coord, car_coll.radius ) ) truck[2].coord=oldcoord2; if(CheckCollision( &truck[2].coord, car_coll.radius, &truck[1].coord, car_coll.radius ) ) truck[2].coord=oldcoord2; } //end TESTCARCOLLISION