1 #ifdef _WIN32
2 #include "windows.h"
3 #endif
4
5 #include "string.h"
6 #include "stdio.h"
7 #include "stdlib.h"
8 #include "math.h"
9
10 #include "GL/gl.h"
11 #include "GL/glu.h"
12 #include "GL/glut.h"
13 #include "SDL/SDL.h"
14 #include "SDL/SDL_mixer.h"
15
16 #include "list.h"
17 #include "vector.h"
18 #include "quaternion.h"
19 #include "cmc.h"
20 #include "3dobject.h"
21 #include "shadow3dobject.h"
22 #include "piece3dobject.h"
23 #include "myglutaux.h"
24 #include "nether.h"
25
26 #include "glprintf.h"
27
28
29 extern int detaillevel;
30
BULLET()31 BULLET::BULLET()
32 {
33 type=0;
34 step=0;
35 angle=0;
36 owner=0;
37 } /* BULLET::BULLET */
38
39
BULLET(int t,Vector p,int a,ROBOT * r)40 BULLET::BULLET(int t,Vector p,int a,ROBOT *r)
41 {
42 type=t;
43 step=0;
44 pos=p;
45 angle=a;
46 owner=r;
47 } /* BULLET::BULLET */
48
49
BulletCMC(BULLET * b)50 CMC NETHER::BulletCMC(BULLET *b)
51 {
52 CMC cmc;
53 float m[16]={1,0,0,0,
54 0,1,0,0,
55 0,0,1,0,
56 0,0,0,1};
57
58 /* compute CMC: */
59 switch(b->type) {
60 case 0:/* CANNON: */
61 m[13]=0.2;
62 cmc.expand(&(bullet_tile[0]->cmc),m);
63 m[13]=-0.2;
64 cmc.expand(&(bullet_tile[0]->cmc),m);
65 break;
66 case 1:/* MISSILES: */
67 {
68 Quaternion q;
69
70 q.from_axis_angle(Vector(0,0,1),3.141592f);
71 q.to_matrix(m);
72 m[13]+=0.33;
73 cmc.expand(&(bullet_tile[1]->cmc),m);
74 m[13]-=0.66;
75 cmc.expand(&(bullet_tile[1]->cmc),m);
76 }
77 break;
78 case 2:/* PHASERS: */
79 {
80 Quaternion q;
81
82 q.from_axis_angle(Vector(0,0,1),3.141592f/2);
83 q.to_matrix(m);
84 cmc.expand(&(bullet_tile[2]->cmc),m);
85 }
86 break;
87 } /* switch */
88
89 return cmc;
90 } /* BULLET::BULLET */
91
92
93
DrawBullet(BULLET * bullet,bool shadows)94 void NETHER::DrawBullet(BULLET *bullet,bool shadows)
95 {
96 switch(bullet->type) {
97 case 0:/* CANONS: */
98 if (!shadows) {
99 glPushMatrix();
100 glRotatef(bullet->angle,0,0,1);
101 glTranslatef(0,0.2,0);
102 bullet_tile[0]->draw(0.2f,0.2f,0.2f);
103 glTranslatef(0,-0.4,0);
104 bullet_tile[0]->draw(0.2f,0.2f,0.2f);
105 glPopMatrix();
106 } /* if */
107 break;
108 case 1:/* MISSILES: */
109 if (!shadows) {
110 glPushMatrix();
111 glRotatef(bullet->angle,0,0,1);
112 glRotatef(180,0,0,1);
113 glTranslatef(0,0.33,0);
114 bullet_tile[1]->draw(0.8f,0.8f,0.8f);
115 glTranslatef(0,-0.66,0);
116 bullet_tile[1]->draw(0.8f,0.8f,0.8f);
117 glPopMatrix();
118
119 /* TRACKS PARTICLES: */
120 if (detaillevel>=4) {
121 int i;
122 PARTICLE *p;
123 Vector pos,sp1;
124 float red,g,b;
125
126 for(i=0;i<10;i++) {
127 pos.x=bullet->pos.x+float(rand()%10)/100.0;
128 pos.y=bullet->pos.y+float(rand()%10)/100.0;
129 pos.z=bullet->pos.z;
130 red=0.9F+float(rand()%21-10)/100.0;
131 g=0.7F+float(rand()%21-10)/100.0;
132 b=0.5F+float(rand()%21-10)/100.0;
133 switch(bullet->angle) {
134 case 0:sp1=Vector(-0.05,float(rand()%9-4)/200.0,0);
135 pos.x-=0.25;
136 pos.y+=((rand()%2)==0 ? -0.33 : 0.33);
137 break;
138 case 90:sp1=Vector(float(rand()%9-4)/200.0,-0.05,0);
139 pos.y-=0.25;
140 pos.x+=((rand()%2)==0 ? -0.33 : 0.33);
141 break;
142 case 180:sp1=Vector(0.05,float(rand()%9-4)/200.0,0);
143 pos.x+=0.25;
144 pos.y+=((rand()%2)==0 ? -0.33 : 0.33);
145 break;
146 case 270:sp1=Vector(float(rand()%9-4)/200.0,0.05,0);
147 pos.y+=0.25;
148 pos.x+=((rand()%2)==0 ? -0.33 : 0.33);
149 break;
150 } /* switch */
151 p=new PARTICLE(pos,sp1,sp1,0,0.3, red,g,b, 1.0,0.0,10+(rand()%8));
152 particles.Add(p);
153 } /* for */
154 } /* if */
155
156 } /* if */
157 break;
158 case 2:/* PHASERS: */
159 if (!shadows) {
160 glPushMatrix();
161 glRotatef(bullet->angle,0,0,1);
162 glRotatef(90,0,0,1);
163
164 if ((rand()%4)!=0) bullet_tile[2]->draw_notexture(1.0f,0.5f,1.0f,0.9f);
165 else bullet_tile[2]->draw_notexture(1.0f,1.0f,1.0f,0.5f);
166
167 glPopMatrix();
168 } /* if */
169 break;
170 } /* switch */
171 } /* NETHER::DrawBullet */
172
173
BulletCollision(BULLET * bullet,ROBOT ** r)174 bool NETHER::BulletCollision(BULLET *bullet,ROBOT **r)
175 {
176 int i;
177 List<BUILDING> l;
178 BUILDING *b;
179 List<ROBOT> l2;
180 ROBOT *rt;
181 float m1[16]={1,0,0,0,
182 0,1,0,0,
183 0,0,1,0,
184 bullet->pos.x,bullet->pos.y,0.3,1};
185 float m2[16]={1,0,0,0,
186 0,1,0,0,
187 0,0,1,0,
188 0,0,0,1};
189
190 *r=0;
191
192 /* Collision with the ship: */
193 /* Bullets do not collide with SHIP!: */
194 /*
195 {
196 float m2[16]={1,0,0,0,
197 0,1,0,0,
198 0,0,1,0,
199 shipp.x,shipp.y,shipp.z,1};
200 if (bullet->cmc.collision_simple(m1,&(ship->cmc),m2)) return true;
201 }
202 */
203
204 /* Collision with buildings: */
205 l.Instance(buildings);
206 l.Rewind();
207 while(l.Iterate(b)) {
208 if (((b->pos.x-bullet->pos.x)*(b->pos.x-bullet->pos.x)+
209 (b->pos.y-bullet->pos.y)*(b->pos.y-bullet->pos.y)+
210 (b->pos.z-bullet->pos.z)*(b->pos.z-bullet->pos.z))<COLISION_TEST_THRESHOLD) {
211 m2[12]=b->pos.x;
212 m2[13]=b->pos.y;
213 m2[14]=b->pos.z;
214
215 switch(b->type) {
216 case B_FENCE:
217 if (bullet->cmc.collision_simple(m1,&(building_tile[5]->cmc),m2)) return true;
218 break;
219 case B_WALL1:
220 if (bullet->cmc.collision_simple(m1,&(building_tile[0]->cmc),m2)) return true;
221 break;
222 case B_WALL2:
223 if (bullet->cmc.collision_simple(m1,&(building_tile[1]->cmc),m2)) return true;
224 break;
225 case B_WALL3:
226 if (bullet->cmc.collision_simple(m1,&(building_tile[2]->cmc),m2)) return true;
227 break;
228 case B_WALL4:
229 if (bullet->cmc.collision_simple(m1,&(building_tile[3]->cmc),m2)) return true;
230 break;
231 case B_WALL5:
232 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
233 break;
234 case B_WALL6:
235 if (bullet->cmc.collision_simple(m1,&(building_tile[7]->cmc),m2)) return true;
236 break;
237 case B_WARBASE:
238 if (bullet->cmc.collision_simple(m1,&(building_tile[8]->cmc),m2)) return true;
239 //m2[13]=b->pos.y-2;
240 //m2[14]=b->pos.z+1;
241 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
242 break;
243 case B_FACTORY_ELECTRONICS:
244 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
245 m2[12]=b->pos.x+0.5;
246 m2[13]=b->pos.y+0.5;
247 m2[14]=b->pos.z+1;
248 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][7]->cmc),m2)) return true;
249 //m2[12]=b->pos.x;
250 //m2[13]=b->pos.y-1;
251 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
252 break;
253 case B_FACTORY_NUCLEAR:
254 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
255 m2[12]=b->pos.x+0.5;
256 m2[13]=b->pos.y+0.5;
257 m2[14]=b->pos.z+1;
258 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][6]->cmc),m2)) return true;
259 //m2[12]=b->pos.x;
260 //m2[13]=b->pos.y-1;
261 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
262 break;
263 case B_FACTORY_PHASERS:
264 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
265 m2[12]=b->pos.x+0.5;
266 m2[13]=b->pos.y+0.5;
267 m2[14]=b->pos.z+1;
268 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][5]->cmc),m2)) return true;
269 //m2[12]=b->pos.x;
270 //m2[13]=b->pos.y-1;
271 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
272 break;
273 case B_FACTORY_MISSILES:
274 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
275 m2[12]=b->pos.x+0.5;
276 m2[13]=b->pos.y+0.5;
277 m2[14]=b->pos.z+1;
278 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][4]->cmc),m2)) return true;
279 //m2[12]=b->pos.x;
280 //m2[13]=b->pos.y-1;
281 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
282 break;
283 case B_FACTORY_CANNONS:
284 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
285 m2[12]=b->pos.x+0.5;
286 m2[13]=b->pos.y+0.5;
287 m2[14]=b->pos.z+1;
288 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][3]->cmc),m2)) return true;
289 //m2[12]=b->pos.x;
290 //m2[13]=b->pos.y-1;
291 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
292 break;
293 case B_FACTORY_CHASSIS:
294 if (bullet->cmc.collision_simple(m1,&(building_tile[4]->cmc),m2)) return true;
295 m2[12]=b->pos.x+0.5;
296 m2[13]=b->pos.y+0.5;
297 m2[14]=b->pos.z+1;
298 if (bullet->cmc.collision_simple(m1,&(piece_tile[0][1]->cmc),m2)) return true;
299 //m2[12]=b->pos.x;
300 //m2[13]=b->pos.y-1;
301 //if (b->owner!=0) if (bullet->cmc.collision_simple(m1,&(building_tile[6]->cmc),m2)) return true;
302 break;
303 } /* switch */
304 } /* if */
305 } /* while */
306
307 /* Collision with the robots: */
308 for(i=0;i<2;i++) {
309 l2.Instance(robots[i]);
310 l2.Rewind();
311 while(l2.Iterate(rt)) {
312 if (((rt->pos.x-bullet->pos.x)*(rt->pos.x-bullet->pos.x)+
313 (rt->pos.y-bullet->pos.y)*(rt->pos.y-bullet->pos.y)+
314 (rt->pos.z-bullet->pos.z)*(rt->pos.z-bullet->pos.z))<COLISION_TEST_THRESHOLD) {
315 if (rt!=bullet->owner) {
316 m2[12]=rt->pos.x;
317 m2[13]=rt->pos.y;
318 m2[14]=rt->pos.z;
319 if (bullet->cmc.collision_simple(m1,&(rt->cmc),m2)) {
320 *r=rt;
321 return true;
322 } /* if */
323 } /* if */
324 } /* if */
325 } /* while */
326 } /* while */
327
328 return false;
329 } /* NETHER::BulletCollision */
330
331
EXPLOSION(void)332 EXPLOSION::EXPLOSION(void)
333 {
334 step=0;
335 size=0;
336 } /* NUCLEAR::NUCLEAR */
337
338
EXPLOSION(Vector p,int sz)339 EXPLOSION::EXPLOSION(Vector p,int sz)
340 {
341 pos=p;
342 step=0;
343 size=sz;
344 } /* NUCLEAR::NUCLEAR */
345