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