1 // Apricots falling object collision routine
2 // Author: M.D.Snellgrove
3 // Date: 25/3/2002
4 // History:
5 
6 #include "apricots.h"
7 
fall_collision(gamedata & g,falltype & fall)8 bool fall_collision(gamedata &g, falltype &fall){
9 
10 // Check for ground collision
11   if ((g.gamemap.ground.collide(0,0,
12         g.images[fall.image],(int)fall.x,(int)fall.y)) ||
13         (int(fall.x) < -16) || (int(fall.x) > GAME_WIDTH) ||
14         (int(fall.y) > GAME_HEIGHT)){
15     switch(fall.type){
16       case 1: // Shrapnel
17         { int px = limit(int((fall.x+18.0)/32),0,MAP_W-1);
18           if ((g.gamemap.groundheight[px] == GAME_HEIGHT - 2) &&
19               (fall.y > GAME_HEIGHT - 11)){ // hits sea
20             firetype splash;
21             splash.x = int(fall.x) - 5;
22             splash.y = GAME_HEIGHT - 20;
23             splash.time = 0;
24             splash.type = 4;
25             g.explosion.add(splash);
26           }else{ // hits land
27             firetype boom;
28             boom.x = int(fall.x);
29             boom.y = int(fall.y);
30             boom.time = 0;
31             boom.type = 2;
32             g.explosion.add(boom);
33           }
34         }
35         break;
36 
37       case 2: case 3: // Large bits and bombs
38         if (fall.type == 3) fall.x -= 5;
39         { int px = limit(int((fall.x+24.0)/32),0,MAP_W-1);
40           if ((g.gamemap.groundheight[px] == GAME_HEIGHT - 2) &&
41               (fall.y > GAME_HEIGHT - 21)){ // hits sea
42             firetype splash;
43             splash.x = int(fall.x);
44             splash.y = GAME_HEIGHT - 20;
45             splash.time = 0;
46             splash.type = 3;
47             g.explosion.add(splash);
48             g.sound.play(SOUND_SPLASH);
49           }else{ // hits land
50             firetype boom;
51             boom.x = int(fall.x);
52             boom.y = int(fall.y);
53             boom.time = 0;
54             boom.type = 0;
55             g.explosion.add(boom);
56             g.sound.play(SOUND_GROUNDHIT);
57           }
58         }
59         break;
60 
61     }
62     return true;
63   }
64 
65 // Check for drak mothership collision
66 
67   if ((g.drakms.exist == 1) && (g.images[318].collide((int)g.drakms.x,(int)g.drakms.y,
68         g.images[fall.image],(int)fall.x,(int)fall.y))){
69     switch(fall.type){
70       case 1: // Shrapnel
71         { firetype boom;
72           boom.x = int(fall.x);
73           boom.y = int(fall.y);
74           boom.time = 0;
75           boom.type = 2;
76           g.explosion.add(boom);
77         }
78         break;
79 
80       case 2: case 3: // Large bits and bombs
81         if (fall.type == 3) fall.x -= 5;
82         { firetype boom;
83           boom.x = int(fall.x);
84           boom.y = int(fall.y);
85           boom.time = 0;
86           boom.type = 0;
87           g.explosion.add(boom);
88         }
89         g.sound.play(SOUND_GROUNDHIT);
90 // Damage mothership
91         g.drakms.damage += 2;
92 // Find which plane (if any) the fall belongs to
93         if (fall.side > 0){
94           g.p.reset();
95           while (g.p.next()){
96             if (fall.side == g.p().side){
97 
98 // Add to score
99               g.p().score += 40;
100             }
101           }
102         }
103         break;
104 
105     }
106     return true;
107   }
108 
109   if (fall.type < 2) return false;
110 
111 // Check for building etc collisions
112   int px = int((fall.x+8)/16);
113   for (int x=px;x<=px+1;x++){
114     switch(g.gamemap.b[x].type){
115       case 1: case 3: case 4: case 5:// buildings and trees
116         if (g.images[g.gamemap.b[x].image].collide(g.gamemap.b[x].x,
117             g.gamemap.b[x].y,g.images[fall.image],(int)fall.x,(int)fall.y)){
118 
119 // Find which plane (if any) the fall belongs to
120           if ((fall.side > 0) && (fall.side != g.gamemap.b[x].side)){
121             g.p.reset();
122             while (g.p.next()){
123               if (fall.side == g.p().side){
124 // Add 25% of points value for crashing into building (or full value if -ve)
125                 if ((g.gamemap.b[x].points > 0) && (fall.type == 2)){
126                   g.p().score += int(g.gamemap.b[x].points * 0.25);
127                 }else{
128                   g.p().score += g.gamemap.b[x].points;
129                 }
130               }
131             }
132           }
133           killbuilding(g, g.gamemap.b[x]);
134           return true;
135         }
136         break;
137 
138       case 2: // towers
139         { int ty = limit(int(fall.y),
140                     g.gamemap.b[x].y -g.gamemap.b[x].towersize*16,int(fall.y));
141           if (g.images[197].collide(g.gamemap.b[x].x,ty,
142               g.images[fall.image],(int)fall.x,(int)fall.y)){
143 // Calculate height of tower strike
144             int h = limit(int((g.gamemap.b[x].y - fall.y)/16),0,100);
145 // Find which plane (if any) the fall belongs to
146             if (fall.side > 0){
147               g.p.reset();
148               while (g.p.next()){
149                 if (fall.side == g.p().side){
150 // Knock off score
151                   g.p().score -= 40 * (g.gamemap.b[x].towersize + 1 - h);
152                 }
153               }
154             }
155             killtower(g, g.gamemap.b[x], fall.xs*0.25, fall.ys*0.25, h, fall.side);
156 	    return true;
157           }
158         }
159         break;
160     }
161   }
162 
163 // Drak gun collisions
164   if (g.drakms.exist == 1){
165     g.drakgun.reset();
166     while (g.drakgun.next()){
167       if (g.images[g.drakgun().image[g.drakgun().d]].collide(
168             (int)g.drakms.x+g.drakgun().x, (int)g.drakms.y+g.drakgun().y,
169             g.images[fall.image], (int)fall.x, (int)fall.y)){
170 // Find out which plane the fall belongs to
171         if (fall.side > 0){
172           g.p.reset();
173           while (g.p.next()){
174             if (fall.side == g.p().side){
175 // Add to score
176               g.p().score += 200;
177             }
178           }
179         }
180 // Explosion
181         firetype boom;
182         boom.x = int(fall.x);
183         boom.y = int(fall.y);
184         boom.time = 0;
185         boom.type = 0;
186         g.explosion.add(boom);
187 // Remove laser flags
188         if (g.drakgun().type == -1) g.drakms.lgun = false;
189         if (g.drakgun().type == 1) g.drakms.rgun = false;
190 // Kill the gun
191         g.drakgun.kill();
192         g.sound.play(SOUND_EXPLODE);
193         return true;
194       }
195     }
196   }
197 
198   return false;
199 
200 }
201