/* ----------------------------------------------- GTASC - GTA adaptation for TI Calculators ----------------------------------------------- Programmed by : Olivier SANGALA Version : 1.2 License : Free under GNU General Public License ( see "gpl.txt" ) Release Date : 05/01/2007 Platform : TI89/TI92+/V200 Website : http://olivier.sangala.free.fr Email : olivier_sangala@hotmail.com ---------- License ---------- Copyright (C) 2002-2007 Olivier SANGALA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ //----------------------------------------------------------------------------- /* functions that test collisions between objects and tilemap */ #include // Include All Header Files #include // TestCollide #include "defines.h" //-------------------------------------------------------------------------- // extern extern TGame*Game; extern unsigned short * TileData; //-------------------------------------------------------------------------- extern byte gates_pos[8]; extern byte secrets_pos[10][2]; extern byte races_checkpoints[6][10][2]; //-------------------------------------------------------------------------- /* ********************** ***** COLLISIONS ***** ********************** ***** OBJECTS ***** ( PED , VEH , TILES , BULLET ) ***** TESTS ***** GATES PED -> TILES PED -> EDGES VEH -> TILES VEH -> EDGES VEH -> PED VEH -> VEH (dont test the sames) BULLET -> TILES BULLET -> EDGES BULLET -> PED BULLET -> VEH */ //-------------------------------------------------------------------------- TTileCollData TileCollData; unsigned short TD8x16[16]= { 0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, }; unsigned short TDCollide16[16]= { 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF, 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF, }; //-------------------------------------------------------------------------- void TC_TestALL(void) { if (!Game->Save.gates_open) { if (TC_Gates2()) { if (Game->motion_type==MT_PED) Game->MainPed->flag_stepback=1; else Game->MainVeh->flag_stepback=1; } } TC_Ped_ALL(); TC_Veh_ALL(); } //--------------------------------------------------------------------------- // function to step back colliding objects void TC_StepBack(void) { TPed*P=Game->Peds; int a=0; for (a=0;aflag_stepback) { P->flag_stepback=0; P->MD=P->MD2; P->MD.speed=0; P->flag_collideCC=1; } TVeh*V=Game->Vehs; a=0; for (a=0;aflag_stepback) { V->flag_stepback=0; V->MD=V->MD2; V->MD.speed=0; V->flag_collideCC=1; Veh_LoadTD(V); } } //--------------------------------------------------------------------------- // test collision of main ped/veh with gates int TC_Gates2(void) { int a=0; for (a=0;a<8;a++) { int y2=MUL16((int)gates_pos[a]); int x2=1888; // 118*16 if (Game->motion_type==MT_PED) { int x1=Game->MainPed->MD.Pos.x; int y1=Game->MainPed->MD.Pos.y; int r = (abs(y2-y1+4)<12 && abs(x2-x1+4)<12); if (r) { return 1; } } else { int x1=Game->MainVeh->MD.Pos.x; int y1=Game->MainVeh->MD.Pos.y; int r = (abs(y2-y1)<16 && abs(x2-x1)<16); if (r) { return 1; } } } return 0; } //--------------------------------------------------------------------------- void TC_Ped_ALL(void) { TPed*P=Game->Peds; int a=0; for (a=0;aenable && P->health && !Ped_IsIntoVeh(P)) { // PED -> TILES if (TC_Ped_Tiles2(P)) P->flag_stepback=1; // ped -> edges if (TC_Ped_Edges2(P)) P->flag_stepback=1; } } //--------------------------------------------------------------------------- int TC_Ped_Flip(TPed*P) { // PED -> TILES : OK (PRE-TESTED) // PED -> VEH : OK (DISTINCT MOVING AREA) // NO COLLISION TO TEST return 0; } //--------------------------------------------------------------------------- int TC_Ped_Edges2(TPed*P) { // EDGES int x1=P->MD.Pos.x; int y1=P->MD.Pos.y; int x2=x1+7; int y2=y1+7; if (x1<0) return 1; if (y1<0) return 1; if (x2>=MUL16((int)Game->TMSizeX)) return 1; if (y2>=MUL16((int)Game->TMSizeY)) return 1; return 0; } //--------------------------------------------------------------------------- int TC_Ped_Tiles2(TPed*P) { // TILES TileCollData.P = P->MD.Pos; TileCollData.type = 8; return TC_Tiles(); } //--------------------------------------------------------------------------- // test if ped gone out of veh is colliding int TC_Ped_VehOut(TPed*P) { // PED -> TILES int r=TC_Ped_Edges2(P); if (r) return 1; // PED -> TILES int c=TC_Ped_Tiles2(P); if (c) return 1; // PED -> VEHS TVeh*V=Game->Vehs; int a=0; for (a=0;aenable) { if (TC_Veh_Ped2(V,P)) return 1; } // ELSE return 0; } //--------------------------------------------------------------------------- void TC_Veh_ALL(void) { TVeh*V=Game->Vehs; int a=0; for (a=0;aenable) { // veh -> edges if (TC_Veh_Edges2(V)) { V->flag_stepback=1; } // VEH -> TILES if (TC_Veh_Tiles2(V)) { V->flag_stepback=1; if (V->MD.speed>VEH_SPEED_DAMAGE) V->flag_damage=1; } // VEH -> VEH // WARNING : (V,V2) = (V2,V) -> TEST ONLY FOR (V TEST (V!=V2) TVeh*V2=Game->Vehs; int b=0; for (b=0;bV) if (V2->enable) if (TC_Veh_Veh2(V,V2)) { V->flag_stepback=1; V2->flag_stepback=1; if (V->MD.speed>VEH_SPEED_DAMAGE || V2->MD.speed>VEH_SPEED_DAMAGE) if (V==Game->MainVeh || V2==Game->MainVeh) // cant damage between computer vehicles { if (V->MD.speed>V2->MD.speed) { V->flag_damage=1; V2->flag_damage=2; } else { V->flag_damage=2; V2->flag_damage=1; } } } // VEH -> PED TPed*P=Game->Peds; int c=0; for (c=0;cenable && P->health && !Ped_IsIntoVeh(P)) if (TC_Veh_Ped2(V,P)) { // computer vehicle cant damage int run_over = (V->MD.speed>=1 && V==Game->MainVeh); if (run_over) { P->flag_runover=1; } else { V->flag_stepback=1; P->flag_stepback=1; // Veh_GoInto if (P==Game->MainPed) Game->MainVeh2 = V; } } } } //--------------------------------------------------------------------------- int TC_Veh_Flip(TVeh*V) { // VEH -> TILES : OK (PRE-TESTED) // VEH -> PED : OK (DISTINCT MOVING AREA) // VEH -> VEH : ***** TO BE TESTED ***** // VEH -> VEH // WARNING : (V,V) not to be tested -> TEST (V!=V2) TVeh*V2=Game->Vehs; int b=0; for (b=0;benable) { int dx=V2->MD.Pos.x-V->MD.Pos.x; int dy=V2->MD.Pos.y-V->MD.Pos.y; int r=(abs(dx)<24 && abs(dy)<24); if (r) return 1; } // else return 0; } //--------------------------------------------------------------------------- int TC_Veh_Edges2(TVeh*V) { // EDGES int x1=V->MD.Pos.x; int y1=V->MD.Pos.y; int x2=x1+15; int y2=y1+15; if (x1<0) return 1; if (y1<0) return 1; if (x2>=MUL16((int)Game->TMSizeX)) return 1; if (y2>=MUL16((int)Game->TMSizeY)) return 1; return 0; } //--------------------------------------------------------------------------- int TC_Veh_Tiles2(TVeh*V) { // TILES TileCollData.P = V->MD.Pos; TileCollData.type = 16; TileCollData.src16 = V->TileData2; return TC_Tiles(); } //--------------------------------------------------------------------------- int TC_Veh_Veh2(TVeh*VA,TVeh*VB) { int r=TestCollide16P(VA->MD.Pos,VB->MD.Pos,VA->TileData2,VB->TileData2); return (r); } //--------------------------------------------------------------------------- int TC_Veh_Ped2(TVeh*V,TPed*P) { int r=TestCollide16P(P->MD.Pos,V->MD.Pos,TD8x16,V->TileData2); return r; } //--------------------------------------------------------------------------- void TC_Bullet_ALL(void) { TBullet*B=Game->Bullets; int a=0; for (a=0;aenable) { TPed*Shooter=B->Shooter; // BULLET -> TILES if (TC_Bullet_Edges2(B)) { B->flag_hit=1; } if (TC_Bullet_Tiles2(B)) { B->flag_hit=1; } // BULLET -> VEH TVeh*V=Game->Vehs; int b; for (b=0;benable && V->health) if (TC_Bullet_Veh2(B,V)) { B->flag_hit=1; if (!(Shooter!=Game->MainPed && V!=Game->MainVeh)) // CC shooters dont hit CC vehs V->flag_bullet=1; } // BULLET -> PED TPed*P=Game->Peds; int c; for (c=0;cenable && P->health && !Ped_IsIntoVeh(P)) if (Shooter!=P) // DONT BE HIT BY OWN WEAPON !!! if (TC_Bullet_Ped2(B,P)) { B->flag_hit=1; if (!(Shooter!=Game->MainPed && P!=Game->MainPed)) // CC shooters dont hit CC peds P->flag_bullet=1; } } } //--------------------------------------------------------------------------- int TC_Bullet_Edges2(TBullet*B) { // EDGES int x1=B->MD.Pos.x; int y1=B->MD.Pos.y; int x2=x1+7; int y2=y1+7; if (x1<0) return 1; if (y1<0) return 1; if (x2>=MUL16((int)Game->TMSizeX)) return 1; if (y2>=MUL16((int)Game->TMSizeY)) return 1; return 0; } //--------------------------------------------------------------------------- int TC_Bullet_Tiles2(TBullet*B) { // TILES TileCollData.P = B->MD.Pos; TileCollData.type = 8; return TC_Tiles(); } //--------------------------------------------------------------------------- int TC_Bullet_Veh2(TBullet*B,TVeh*V) { int r=TestCollide16P(B->MD.Pos,V->MD.Pos,TD8x16,V->TileData2); return r; } //--------------------------------------------------------------------------- int TC_Bullet_Ped2(TBullet*B,TPed*P) { int dx=(B->MD.Pos.x-P->MD.Pos.x); int dy=(B->MD.Pos.y-P->MD.Pos.y); int r = (abs(dx)<8 && abs(dy)<8); return r; } //--------------------------------------------------------------------------- void TC_Secret(void) { // secret if (Game->motion_type==MT_PED) if (Game->Save.progress_secrets<10) { int sy=MUL16(secrets_pos[Game->Save.progress_secrets][0]); int sx=MUL16(secrets_pos[Game->Save.progress_secrets][1]); int px=Game->MainPed->MD.Pos.x; int py=Game->MainPed->MD.Pos.y; int r=(abs(sy-py+4)<12 && abs(sx-px+4)<12); if (r) Game->flag_secret=1; } // race if (Game->motion_type==MT_VEH) if (Game->Save.progress_races<6) { int sy=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][0]); int sx=MUL16(races_checkpoints[Game->Save.progress_races][Game->race_cpindex][1]); int px=Game->MainVeh->MD.Pos.x; int py=Game->MainVeh->MD.Pos.y; int r=(abs(sy-py)<16 && abs(sx-px)<16); if (r) Game->flag_race=1; } } //--------------------------------------------------------------------------- void TC_Target(void) { TMission*Miss=&Game->Miss; if (!Miss->target_enable) return; if (Miss->target_type!=TT_PLACE) return; int r=0; int speed=0; if (Game->motion_type==MT_PED) { TPed*P=Game->MainPed; int dx=(Miss->target_PP.x-P->MD.Pos.x+4); int dy=(Miss->target_PP.y-P->MD.Pos.y+4); r=(abs(dx)<12 && abs(dy)<12); // MISSIONS FLAGS if (r) Game->Miss.flag_placeover_ped=1; if (r && P->MD.speed==0) Game->Miss.flag_placestop_ped=1; } else if (Game->motion_type==MT_VEH) { TVeh*V=Game->MainVeh; r=TestCollide16P(Miss->target_PP,V->MD.Pos,TDCollide16,V->TileData2); // MISSIONS FLAGS if (r) Game->Miss.flag_placeover_veh=1; if (r && V->MD.speed==0) Game->Miss.flag_placestop_veh=1; } } //--------------------------------------------------------------------------- int TC_Tiles(void) { // debug //return 0; byte x = QUOT16(TileCollData.P.x); byte y = QUOT16(TileCollData.P.y); // TILES POSITION : // 0 - 1 // | | // 2 - 3 byte*ptr=GET_PTR(x,y); byte*ptr2=TileCollData.tn; *(ptr2++)=*ptr; ptr++; *(ptr2++)=*ptr; ptr+=(Game->TMSizeX-1); *(ptr2++)=*ptr; ptr++; *(ptr2++)=*ptr; // REM16 TileCollData.xx=REM16(TileCollData.P.x); TileCollData.yy=REM16(TileCollData.P.y); int PosType=0; if (TileCollData.yy) PosType|=2; if (TileCollData.xx) PosType|=1; /* PosType : 0 - TILES 0 1 - TILES 0,1 2 - TILES 0,2 3 - TILES 0,1,2,3 */ // TILES TEST if (TC_Tiles2(0)) return 1; if (PosType==1 || PosType==3) if (TC_Tiles2(1)) return 1; if (PosType==2 || PosType==3) if (TC_Tiles2(2)) return 1; if (PosType==3) if (TC_Tiles2(3)) return 1; // else return 0; } //--------------------------------------------------------------------------- int TC_Tiles2(int num) { // TILES POSITION : // 0 - 1 // | | // 2 - 3 TPoint P1; P1.x=TileCollData.xx; P1.y=TileCollData.yy; TPoint P2; P2.y=(num&2?16:0); P2.x=(num&1?16:0); byte tn=TileCollData.tn[num]; unsigned short*src1 = (TileCollData.type==8?TD8x16:TileCollData.src16); unsigned short*src2 = TDCollide16; // if obstacle // if collision // return collision if (ISTILEMOVE_OBSTACLE(tn)) { if (TestCollide16P(P1,P2,src1,src2)) return 1; } // else return 0; } //--------------------------------------------------------------------------- int TestCollide16P(TPoint P0,TPoint P1,unsigned short*src0,unsigned short*src1) { return TestCollide16(P0.x,P0.y,P1.x,P1.y,16,src0,src1); } //---------------------------------------------------------------------------