1 /*
2 Copyright (C) 2000/2001 Xavier Hosxe <xhosxe@free.fr>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 #include <stdio.h>
21 #include <GL/glut.h>
22
23 #include "ship1.hpp"
24 #include "fire.hpp"
25 #include "modeles/ship1.c"
26
27
28 #define ABS(x) (x<0?-x:x)
29 #define SIGN(x) (x<0?-1:1)
30
31 int Ship1::list_;
32
Ship1(List * list,float x,float z,float speed,int power)33 Ship1::Ship1(List *list, float x,float z,float speed, int power)
34 : Sprite(list,TYPE_SHIP1 ,x,.5,70)
35 {
36 int nb=random()%5;
37 state_=ARRIVING;
38 sizex_ = 1;
39 sizey_ = 1;
40 sizez_ = 1.8;
41 rotate_=180.0;
42
43 centerX_ = ((float)(random()%100)/10.0)-5.0;
44 centerZ_=25;
45 rayX_=((float)(random()%70)/10)+3;
46 rayZ_=12;
47 position_=0;
48 power_=power;
49 x_=centerX_-rayX_;
50 bRealEnemy=true;
51 }
52
initList()53 void Ship1::initList()
54 {
55
56 int i,j;
57
58 // average normal.....
59 int nbVertex = 134*3;
60 int *bTested = new int[nbVertex];
61 for (i=0;i<nbVertex;i++) {
62 bTested[i] = 0;
63 }
64 int nb;
65 GLfloat aNormal[3];
66
67 for (i=0;i<nbVertex;i++) {
68 if (bTested[i]==0) {
69 bTested[i] = 2;
70 nb=1;
71 aNormal[0] = bandit1_meshes[i*8+3];
72 aNormal[1] = bandit1_meshes[i*8+4];
73 aNormal[2] = bandit1_meshes[i*8+5];
74 for (j=i+1;j<nbVertex;j++) {
75 if ((bTested[j]==0) && ((bandit1_meshes[i*8+0]-bandit1_meshes[j*8+0])<.01) && ((bandit1_meshes[i*8+1]-bandit1_meshes[j*8+1])<.01) && ((bandit1_meshes[i*8+2]-bandit1_meshes[j*8+2])<.01) && ((bandit1_meshes[i*8+0]-bandit1_meshes[j*8+0])>-.01) && ((bandit1_meshes[i*8+1]-bandit1_meshes[j*8+1])>-.01) && ((bandit1_meshes[i*8+2]-bandit1_meshes[j*8+2])>-.01) ) {
76 bTested[j]=2;
77 nb++;
78 aNormal[0]+= bandit1_meshes[j*8+3];
79 aNormal[1]+= bandit1_meshes[j*8+4];
80 aNormal[2]+= bandit1_meshes[j*8+5];
81 }
82 }
83 aNormal[0] /= nb;
84 aNormal[1] /= nb;
85 aNormal[2] /= nb;
86 for (j=i;j<nbVertex;j++) {
87 if (bTested[j]==2) {
88 bandit1_meshes[j*8+3] = aNormal[0];
89 bandit1_meshes[j*8+4] = aNormal[1];
90 bandit1_meshes[j*8+5] = aNormal[2];
91 bTested[j]=1;
92 }
93 }
94 }
95 }
96
97 for (i=0;i<134;i++) {
98 bandit1_meshes[i*24]/=100;
99 bandit1_meshes[i*24+1]/=100;
100 bandit1_meshes[i*24+2]/=100;
101
102 bandit1_meshes[i*24+8]/=100;
103 bandit1_meshes[i*24+1+8]/=100;
104 bandit1_meshes[i*24+2+8]/=100;
105
106 bandit1_meshes[i*24+16]/=100;
107 bandit1_meshes[i*24+1+16]/=100;
108 bandit1_meshes[i*24+2+16]/=100;
109 }
110
111 list_ = glGenLists(2);
112
113 glNewList(list_,GL_COMPILE);
114 {
115 glEnable(GL_TEXTURE_2D);
116 glBindTexture(GL_TEXTURE_2D, GLvar->texture_bandit1);
117 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GLvar->blanc_diffuse);
118 glDisable(GL_BLEND);
119 glEnable(GL_LIGHTING);
120
121 glTranslatef(0,.2,0);
122 glRotatef(90,1,0,0);
123 glRotatef(190,0,1,0);
124
125 glEnableClientState(GL_VERTEX_ARRAY);
126 glEnableClientState(GL_NORMAL_ARRAY);
127 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
128
129 glVertexPointer(3,GL_FLOAT,32,bandit1_meshes);
130 glNormalPointer(GL_FLOAT,32,bandit1_meshes+3);
131 glTexCoordPointer(2,GL_FLOAT,32,bandit1_meshes+6);
132
133 glDrawArrays(GL_TRIANGLES,0,134*3);
134
135 glDisableClientState(GL_VERTEX_ARRAY);
136 glDisableClientState(GL_NORMAL_ARRAY);
137 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
138
139 }
140 glEndList();
141
142
143 glNewList(list_+1,GL_COMPILE);
144 {
145 glRotatef(90,1,0,0);
146 glRotatef(190,0,1,0);
147 glEnableClientState(GL_VERTEX_ARRAY);
148 glVertexPointer(3,GL_FLOAT,32,bandit1_meshes);
149
150 glDrawArrays(GL_TRIANGLES,0,133*3+2);
151
152 glDisableClientState(GL_VERTEX_ARRAY);
153 }
154 glEndList();
155
156 delete []bTested;
157 }
158
159
drawShadowable()160 void Ship1::drawShadowable()
161 {
162
163 glPushMatrix();
164 glTranslatef(x_,y_,z_);
165 if (state_==MOVING_2) {
166 glRotatef(rotate_+90,1,0,0);
167 // glRotatef(rotate_*4,0,0,-1);
168 }
169
170 glCallList(list_+1);
171 glPopMatrix();
172
173 }
174
175
draw()176 void Ship1::draw()
177 {
178
179 glPushMatrix();
180 glTranslatef(x_,y_,z_);
181 if (state_==MOVING_2) {
182 glRotatef(rotate_+90,1,0,0);
183 // glRotatef(rotate_*4,0,0,-1);
184 }
185
186 glCallList(list_);
187 glPopMatrix();
188 }
189
190
move()191 void Ship1::move()
192 {
193 switch(state_) {
194 case MOVING_1:
195 {
196 rotate_+=1.0*GLvar->global_timeadjustment;
197
198
199 if (GLvar->mySpaceShip!=NULL) {
200 if ((rotate_>360.0) && (position_==3)) {
201 rotate_-=360.0;
202 position_=0;
203 if (GLvar->mySpaceShip->getZ()>z_) {
204 rayZ_ = ((centerZ_-GLvar->mySpaceShip->getZ()<0)?-centerZ_+GLvar->mySpaceShip->getZ():centerZ_-GLvar->mySpaceShip->getZ());
205 }
206 rayX_ = (x_-GLvar->mySpaceShip->getX())/2;
207 centerX_ = (GLvar->mySpaceShip->getX()+x_)/2;
208 }
209 if ((rotate_>90.0)&&(position_==0)) {
210 position_=1;
211 if (GLvar->mySpaceShip->getZ()<z_) {
212 rayZ_ = (z_-GLvar->mySpaceShip->getZ())/2;
213 centerZ_ = (GLvar->mySpaceShip->getZ()+z_)/2;
214 } else {
215 rayZ_ = (GLvar->mySpaceShip->getZ()-z_)/2;
216 centerZ_ = (GLvar->mySpaceShip->getZ()+z_)/2;
217 rayX_=-rayX_;
218 rotate_=270.0;
219 position_ = 3;
220
221 }
222
223 }
224 if ((rotate_>180.0) && (position_==1)) {
225 if (((random()%20)==0) && (rayZ_>0))
226 {
227 state_=LEAVING;
228 break;
229 }
230 position_=2;
231 if (GLvar->mySpaceShip->getZ()<z_) {
232 rayZ_ = ((centerZ_-GLvar->mySpaceShip->getZ()<0)?-centerZ_+GLvar->mySpaceShip->getZ():centerZ_-GLvar->mySpaceShip->getZ());
233 }
234 rayX_ = (GLvar->mySpaceShip->getX()-x_)/2;
235 centerX_ = (GLvar->mySpaceShip->getX()+x_)/2;
236 }
237
238 if ((rotate_>270.0)&&(position_==2)) {
239 position_=3;
240 if (GLvar->mySpaceShip->getZ()>z_) {
241 centerZ_ = (GLvar->mySpaceShip->getZ()+z_)/2;
242 rayZ_ = (GLvar->mySpaceShip->getZ()-z_)/2;
243 } else {
244 rayZ_ = (z_-GLvar->mySpaceShip->getZ())/2;
245 centerZ_ = (GLvar->mySpaceShip->getZ()+z_)/2;
246 rayX_=-rayX_;
247 rotate_=90.0;
248 position_ = 1;
249 }
250 }
251 }
252
253
254 x_=centerX_+cos(rotate_*PI/180.0)*rayX_;
255 z_=centerZ_+sin(rotate_*PI/180.0)*rayZ_;
256
257
258 // if (z_<-5) dead_=1;
259 if (GLvar->myRandom(128))
260 {
261 Ship1Fire *newFire;
262 newFire= new Ship1Fire(mlist,this);
263 mlist->Add(newFire);
264
265 }
266 break;
267 }
268 case ARRIVING:
269 {
270 dz_=-.4;
271 if (z_<centerZ_) {
272 if (random()&1) {
273 state_=MOVING_1;
274 rotate_=180;
275 position_=2;
276 } else {
277 rotate_=-90;
278 centerX_=4.5;
279 centerZ_ = z_;
280 state_=MOVING_2;
281 }
282 } else {
283 Sprite::move();
284 }
285 }
286 break;
287 case LEAVING:
288 {
289 rotate_=180;
290 dz_=-.4;
291 if (z_<-3) {
292 dead_=1;
293 }
294 Sprite::move();
295 }
296 break;
297 case MOVING_2:
298 {
299 rotate_+=4.0*GLvar->global_timeadjustment;
300
301 z_=centerZ_-cos(rotate_*PI/180.0)*4.0;
302 y_=centerX_+sin(rotate_*PI/180.0)*4.0;
303
304 if (GLvar->mySpaceShip!=NULL) {
305 x_=x_ + (x_>GLvar->mySpaceShip->getX()?-.05:.05) *GLvar->global_timeadjustment;
306
307 if (rotate_>270) {
308 rayX_ = (GLvar->mySpaceShip->getX()-x_)/2;
309 centerX_ = (GLvar->mySpaceShip->getX()+x_)/2;
310 state_=MOVING_1;
311 rotate_=180.0;
312 position_=2;
313 centerZ_=z_;
314 rayZ_=0;
315 y_=.5;
316 }
317 } else {
318 state_=LEAVING;
319 }
320
321 break;
322 }
323
324 }
325 }
326
327
collision(Sprite * contact)328 void Ship1::collision(Sprite*contact)
329 {
330
331 switch(contact->getType())
332 {
333 case TYPE_CUBE:
334 break;
335 case TYPE_SHIP1:
336 if ((z_<contact->getZ()) && (state_!=MOVING_2) && (((Ship1*)contact)->getState()!=MOVING_2)) {
337 rotate_=-90;
338 centerX_=4.5;
339 centerZ_ = z_;
340 state_=MOVING_2;
341 }
342 // x_=centerX_+cos(rotate_*PI/180.0)*rayX_;
343 break;
344 case TYPE_MY_SPACE_SHIP:
345 case TYPE_MY_FIRE2:
346 power_=0;
347 case TYPE_MY_FIRE1:
348 case TYPE_SPIRALE:
349 {
350 Explosion *explode;
351 if ((--power_<=0) && (dead_==0)) {
352 explode= new Explosion(this,7);
353 mlist->Add(explode);
354 dead_=1;
355 contact->score(250);
356
357 }
358
359 break;
360 }
361 }
362
363 }
364
365
366 /* +================================+
367 | Ship1Fire |
368 +================================+
369 */
drawShadowable()370 void Ship1Fire::drawShadowable()
371 {
372
373 glPushMatrix();
374 glTranslatef(x_ , y_ , z_);
375
376 glBegin(GL_TRIANGLE_FAN);
377
378 glVertex3f(0 ,0,0);
379 glVertex3f(.1 , 0 ,.35);
380 glVertex3f(-.1 , 0 ,.35);
381 glVertex3f(0 , .1 ,.35);
382 glVertex3f(0,-.1 ,.35);
383
384 glEnd();
385
386 glPopMatrix();
387 }
388
389
draw()390 void Ship1Fire::draw()
391 {
392
393 glPushMatrix();
394 glTranslatef(x_ , y_ , z_);
395 glRotatef(tetay_ ,0,0,1);
396
397 glDisable(GL_TEXTURE_2D);
398 glDisable(GL_LIGHTING);
399
400 glEnable(GL_BLEND);
401 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
402 glDepthMask(0);
403
404 glBegin(GL_TRIANGLE_FAN);
405
406 glColor4f(1 , 1 , 1 , 1);
407
408 glVertex3f(0 ,0,0);
409
410 glColor4f(1 , 1 ,0 , 0.0);
411 glVertex3f(.1 , 0 ,.35);
412 glVertex3f(-.1 , 0 ,.35);
413 glVertex3f(0 , .1 ,.35);
414 glVertex3f(0,-.1 ,.35);
415
416 glEnd();
417
418
419 glDepthMask(1);
420 glDisable(GL_BLEND);
421 glEnable(GL_LIGHTING);
422 glEnable(GL_TEXTURE_2D);
423
424 glColor4f(1,1,1,1);
425 glPopMatrix();
426 }
427
428
move()429 void Ship1Fire::move()
430 {
431 Sprite::move();
432
433 tetay_ += (10*GLvar->global_timeadjustment)>20 ? 20:(10*GLvar->global_timeadjustment);
434
435 if (tetay_>360)
436 tetay_=tetay_-360;
437
438 if (z_<0)
439 {
440 dead_=1;
441 }
442 }
443
444
collision(Sprite * contact)445 void Ship1Fire::collision(Sprite*contact)
446 {
447 switch(contact->getType())
448 {
449 case TYPE_MY_SPACE_SHIP:
450 case TYPE_MY_FIRE2:
451 case TYPE_MY_FIRE1:
452 // case TYPE_CUBE:
453 {
454 Sprite *explode;
455 explode= new Explosion(this,2,1,0);
456 mlist->Add(explode);
457
458 dead_=1;
459 break;
460 }
461 }
462 }
463