]> git.jsancho.org Git - lugaru.git/blob - Source/Sprites.cpp
2d6d4a016e5da5e67d1971da18496ead2ce6fd0e
[lugaru.git] / Source / Sprites.cpp
1 #include "Sprites.h"
2 #include "Person.h"
3 extern XYZ viewer;
4 extern float viewdistance;
5 extern float fadestart;
6 extern int environment;
7 extern float texscale;
8 extern Light light;
9 extern float multiplier;
10 extern float gravity;
11 extern Terrain terrain;
12 extern Objects objects;
13 extern int detail;
14 extern XYZ viewerfacing;
15 extern float terraindetail;
16 extern int bloodtoggle;
17 extern XYZ windvector;
18 extern int numplayers;
19 extern Person player[maxplayers];
20 //Functions
21
22 void Sprites::Draw()
23 {
24         static int i,j,k;
25         static float M[16];
26         static XYZ point;
27         static float distancemult;
28         static int lasttype;
29         static int lastspecial;
30         static int whichpatchx,whichpatchz;
31         static XYZ start,end,colpoint;
32         static bool check;
33         static bool blend;
34         static float tempmult;
35         static XYZ difference;
36         static float lightcolor[3];
37         static float viewdistsquared=viewdistance*viewdistance;
38         static XYZ tempviewer;
39
40         tempviewer=viewer+viewerfacing*6;
41         check=0;
42
43         lightcolor[0]=light.color[0]*.5+light.ambient[0];
44         lightcolor[1]=light.color[1]*.5+light.ambient[1];
45         lightcolor[2]=light.color[2]*.5+light.ambient[2];
46
47         checkdelay-=multiplier*10;
48
49         if(checkdelay<=0){
50                 check=1;
51                 checkdelay=1;
52         }
53
54         lasttype=-1;
55         lastspecial=-1;
56         glEnable(GL_BLEND);
57         glDisable(GL_LIGHTING);
58         glDisable(GL_CULL_FACE);
59         glEnable(GL_TEXTURE_2D);
60         blend = 1;
61         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
62         glDepthMask(0);
63         glAlphaFunc(GL_GREATER, 0.0001);
64         for(i=0;i<numsprites;i++){
65                 if(type[i]==cloudsprite&&lasttype!=type[i]){
66                         glBindTexture( GL_TEXTURE_2D, cloudtexture);
67                         if(!blend){
68                                 blend=1;
69                                 glAlphaFunc(GL_GREATER, 0.0001);
70                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
71                         }
72                 }
73                 if(type[i]==cloudimpactsprite&&lasttype!=type[i]){
74                         glBindTexture( GL_TEXTURE_2D, cloudimpacttexture);
75                         if(!blend){
76                                 blend=1;
77                                 glAlphaFunc(GL_GREATER, 0.0001);
78                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
79                         }
80                 }
81                 if(type[i]==breathsprite&&lasttype!=type[i]){
82                         glBindTexture( GL_TEXTURE_2D, cloudimpacttexture);
83                         if(!blend){
84                                 blend=1;
85                                 glAlphaFunc(GL_GREATER, 0.0001);
86                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
87                         }
88                 }
89                 if(type[i]==smoketype&&lasttype!=type[i]){
90                         glBindTexture( GL_TEXTURE_2D, smoketexture);
91                         if(!blend){
92                                 blend=1;
93                                 glAlphaFunc(GL_GREATER, 0.0001);
94                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
95                         }
96                 }
97                 if(type[i]==bloodsprite&&lasttype!=type[i]){
98                         glBindTexture( GL_TEXTURE_2D, bloodtexture);
99                         if(!blend){
100                                 blend=1;
101                                 glAlphaFunc(GL_GREATER, 0.0001);
102                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
103                         }
104                 }
105                 if(type[i]==splintersprite&&(lasttype!=type[i]||lastspecial!=special[i])){
106                         if(special[i]==0)glBindTexture( GL_TEXTURE_2D, splintertexture);
107                         if(special[i]==1)glBindTexture( GL_TEXTURE_2D, leaftexture);
108                         if(special[i]==2)glBindTexture( GL_TEXTURE_2D, snowflaketexture);
109                         if(special[i]==3)glBindTexture( GL_TEXTURE_2D, toothtexture);
110                         if(!blend){
111                                 blend=1;
112                                 glAlphaFunc(GL_GREATER, 0.0001);
113                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
114                         }
115                 }
116                 if(type[i]==snowsprite&&lasttype!=type[i]){
117                         glBindTexture( GL_TEXTURE_2D, snowflaketexture);
118                         if(!blend){
119                                 blend=1;
120                                 glAlphaFunc(GL_GREATER, 0.0001);
121                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
122                         }
123                 }
124                 if(type[i]==weaponshinesprite&&lasttype!=type[i]){
125                         glBindTexture( GL_TEXTURE_2D, shinetexture);
126                         if(blend){
127                                 blend=0;
128                                 glAlphaFunc(GL_GREATER, 0.001);
129                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
130                         }
131                 }
132                 if((type[i]==flamesprite||type[i]==weaponflamesprite)&&lasttype!=type[i]){
133                         glBindTexture( GL_TEXTURE_2D, flametexture);
134                         if(blend||lasttype==bloodflamesprite){
135                                 blend=0;
136                                 glAlphaFunc(GL_GREATER, 0.3);
137                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
138                         }
139                 }
140                 if((type[i]==bloodflamesprite)&&lasttype!=type[i]){
141                         glBindTexture( GL_TEXTURE_2D, bloodflametexture);
142                         if(blend){
143                                 blend=0;
144                                 glAlphaFunc(GL_GREATER, 0.3);
145                                 glBlendFunc(GL_ONE,GL_ZERO);
146                                 //glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
147                         }
148                 }
149                 if(type[i]!=snowsprite)distancemult=(viewdistsquared-(findDistancefast(&viewer,&position[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
150                 if(type[i]==snowsprite)distancemult=(144-(findDistancefast(&tempviewer,&position[i])-(144*fadestart))*(1/(1-fadestart)))/144;
151                 if(type[i]!=flamesprite){
152                         if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]);
153                         if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]*distancemult);
154                 }
155                 if(type[i]==flamesprite){
156                         if(distancemult>=1)glColor4f(color[i][0],color[i][1],color[i][2],opacity[i]);
157                         if(distancemult<1)glColor4f(color[i][0],color[i][1],color[i][2],opacity[i]*distancemult);
158                 }
159                 lasttype=type[i];
160                 lastspecial=special[i];
161                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
162                 glPushMatrix();
163                         glTranslatef(position[i].x,position[i].y,position[i].z);
164                         if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite)){
165                                 difference=viewer-position[i];
166                                 Normalise(&difference);
167                                 glTranslatef(difference.x*size[i]/4, difference.y*size[i]/4, difference.z*size[i]/4);
168                         }
169                         if(type[i]==snowsprite){
170                                 glRotatef(rotation[i]*.2,0,.3,1);
171                                 glTranslatef(1,0,0);
172                         }
173                         glGetFloatv(GL_MODELVIEW_MATRIX,M);
174                         point.x=M[12];
175                         point.y=M[13];
176                         point.z=M[14];
177                         glLoadIdentity();
178                         glTranslatef(point.x, point.y, point.z);
179
180                         glRotatef(rotation[i],0,0,1);
181
182                         if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite)){
183                                 if(alivetime[i]<.14)glScalef(alivetime[i]/.14,alivetime[i]/.14,alivetime[i]/.14);
184                         }
185                         if(type[i]==smoketype||type[i]==snowsprite||type[i]==weaponshinesprite||type[i]==breathsprite){
186                                 if(alivetime[i]<.3){
187                                         if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]*alivetime[i]/.3);
188                                         if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]*distancemult*alivetime[i]/.3);
189                                 }
190                         }
191                         if(type[i]==splintersprite&&special[i]>0&&special[i]!=3){
192                                 if(alivetime[i]<.2){
193                                         if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],alivetime[i]/.2);
194                                         if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],distancemult*alivetime[i]/.2);
195                                 }
196                                 else{
197                                         if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
198                                         if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
199                                 }
200                         }
201                         if(type[i]==splintersprite&&(special[i]==0||special[i]==3)){
202                                 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
203                                 if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
204                         }
205                         /*
206                         if(type[i]==snowsprite){
207                         glRotatef(rotation[i],0,0,1);
208                         glTranslatef(1,0,0);
209                         }*/
210
211                         glBegin(GL_TRIANGLES);
212                         glTexCoord2f(1.0f, 1.0f); glVertex3f( .5*size[i], .5*size[i], 0.0f);
213                         glTexCoord2f(0.0f, 1.0f); glVertex3f(-.5*size[i], .5*size[i], 0.0f);
214                         glTexCoord2f(1.0f, 0.0f); glVertex3f( .5*size[i],-.5*size[i], 0.0f);
215                         glTexCoord2f(0.0f, 0.0f); glVertex3f(-.5*size[i],-.5*size[i], 0.0f);
216                         glTexCoord2f(1.0f, 0.0f); glVertex3f( .5*size[i], -.5*size[i], 0.0f);
217                         glTexCoord2f(0.0f, 1.0f); glVertex3f(-.5*size[i], .5*size[i], 0.0f);
218                         glEnd();
219                 glPopMatrix();
220         }
221         tempmult=multiplier;
222         for(i=numsprites-1;i>=0;i--){
223                 multiplier=tempmult;
224                 if(type[i]!=snowsprite)position[i]+=velocity[i]*multiplier;
225                 if(type[i]!=snowsprite)velocity[i]+=windvector*multiplier;
226                 if(type[i]==flamesprite||type[i]==smoketype)position[i]+=windvector*multiplier/2;
227                 if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite))multiplier*=speed[i]*.7;
228                 alivetime[i]+=multiplier;
229
230                 if(type[i]==cloudsprite||type[i]==cloudimpactsprite){
231                         opacity[i]-=multiplier/2;
232                         size[i]+=multiplier/2;
233                         velocity[i].y+=gravity*multiplier*.25;
234                 }
235                 if(type[i]==breathsprite){
236                         opacity[i]-=multiplier/2;
237                         size[i]+=multiplier/2;
238                         if(findLength(&velocity[i])<=multiplier)velocity[i]=0;
239                         else{
240                                 XYZ slowdown;
241                                 slowdown=velocity[i]*-1;
242                                 Normalise(&slowdown);
243                                 slowdown*=multiplier;
244                                 velocity[i]+=slowdown;
245                         }
246                 }
247                 if(type[i]==snowsprite){
248                         size[i]-=multiplier/120;
249                         rotation[i]+=multiplier*360;
250                         position[i].y-=multiplier;
251                         position[i]+=windvector*multiplier;
252                         if(position[i].y<tempviewer.y-6)position[i].y+=12;
253                         if(position[i].y>tempviewer.y+6)position[i].y-=12;
254                         if(position[i].z<tempviewer.z-6)position[i].z+=12;
255                         if(position[i].z>tempviewer.z+6)position[i].z-=12;
256                         if(position[i].x<tempviewer.x-6)position[i].x+=12;
257                         if(position[i].x>tempviewer.x+6)position[i].x-=12;
258                 }
259                 if(type[i]==bloodsprite){
260                         bool spritehit=0;
261                         rotation[i]+=multiplier*100;
262                         velocity[i].y+=gravity*multiplier;
263                         if(check){
264                                 XYZ where,startpoint,endpoint,movepoint,footpoint;
265                                 float rotationpoint;
266                                 int whichtri;
267
268                                 for(j=0;j<numplayers;j++){
269                                         if(!spritehit&&player[j].dead&&alivetime[i]>.1){
270                                                 where=oldposition[i];
271                                                 where-=player[j].coords;
272                                                 if(!player[j].skeleton.free)where=DoRotation(where,0,-player[j].rotation,0);
273                                                 startpoint=where;
274                                                 where=position[i];
275                                                 where-=player[j].coords;
276                                                 if(!player[j].skeleton.free)where=DoRotation(where,0,-player[j].rotation,0);
277                                                 endpoint=where;
278
279                                                 movepoint=0;
280                                                 rotationpoint=0;
281                                                 whichtri=player[j].skeleton.drawmodel.LineCheck(&startpoint,&endpoint, &footpoint, &movepoint, &rotationpoint);
282                                                 if(whichtri!=-1){
283                                                         spritehit=1;
284                                                         player[j].DoBloodBigWhere(0,160,oldposition[i]);
285                                                         DeleteSprite(i);
286                                                 }
287                                         }
288                                 }
289
290                                 whichpatchx=position[i].x/(terrain.size/subdivision*terrain.scale*terraindetail);
291                                 whichpatchz=position[i].z/(terrain.size/subdivision*terrain.scale*terraindetail);
292                                 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
293                                         if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
294                                                 if(!spritehit)
295                                                         for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
296                                                                 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
297                                                                 start=oldposition[i];
298                                                                 end=position[i];
299                                                                 if(!spritehit)
300                                                                         if(objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k])!=-1){
301                                                                                 if(detail==2||(detail==1&&abs(Random()%4)==0)||(detail==0&&abs(Random()%8)==0))objects.model[k].MakeDecal(blooddecalfast,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),size[i]*1.6/*+abs((float)(Random()%100))/2400*/,.5,Random()%360);
302                                                                                 DeleteSprite(i);
303                                                                                 spritehit=1;
304                                                                         }       
305                                                         }
306                                         }
307                                         if(!spritehit)
308                                                 if(position[i].y<terrain.getHeight(position[i].x,position[i].z)){
309                                                         terrain.MakeDecal(blooddecalfast,position[i],size[i]*1.6/*+abs((float)(Random()%100))/2400*/,.6,Random()%360);
310                                                         DeleteSprite(i);
311                                                 }
312                         }
313                 }
314                 if(type[i]==splintersprite){
315                         rotation[i]+=rotatespeed[i]*multiplier;
316                         opacity[i]-=multiplier/2;
317                         if(special[i]==0||special[i]==2||special[i]==3)velocity[i].y+=gravity*multiplier;
318                         if(special[i]==1)velocity[i].y+=gravity*multiplier*.5;
319                 }
320                 if(type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite){
321                         rotation[i]+=multiplier*rotatespeed[i];
322                         opacity[i]-=multiplier*5/4;
323                         if(type[i]!=weaponshinesprite&&type[i]!=bloodflamesprite)
324                                 if(opacity[i]<.5&&opacity[i]+multiplier*5/4>=.5&&(abs(Random()%4)==0||(initialsize[i]>2&&Random()%2==0)))MakeSprite(smoketype, position[i],velocity[i], .9,.9,.6, size[i]*1.2, .4);
325                         if(alivetime[i]>.14&&(type[i]==flamesprite)){
326                                 velocity[i]=0;
327                                 velocity[i].y=1.5;
328                         }
329                 }
330                 /*if(type[i]==smoketype){
331                 opacity[i]-=multiplier/3/initialsize[i];
332                 size[i]+=multiplier;
333                 velocity[i]=0;
334                 velocity[i].y=1.5;
335                 rotation[i]+=multiplier*rotatespeed[i]/5;
336                 }*/
337                 if(type[i]==smoketype){
338                         opacity[i]-=multiplier/3/initialsize[i];
339                         color[i][0]-=multiplier;
340                         color[i][1]-=multiplier;
341                         color[i][2]-=multiplier;
342                         if(color[i][0]<.6)color[i][0]=.6;
343                         if(color[i][1]<.6)color[i][1]=.6;
344                         if(color[i][2]<.6)color[i][2]=.6;
345                         size[i]+=multiplier;
346                         velocity[i]=0;
347                         velocity[i].y=1.5;
348                         rotation[i]+=multiplier*rotatespeed[i]/5;
349                 }
350                 if(opacity[i]<=0||size[i]<=0)DeleteSprite(i);
351         }
352         if(check)
353                 for(i=numsprites-1;i>=0;i--){
354                         oldposition[i]=position[i];
355                 }
356                 glAlphaFunc(GL_GREATER, 0.0001);
357                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
358 }
359
360 void Sprites::DeleteSprite(int which)
361 {
362         type[which]=type[numsprites-1];
363         rotation[which]=rotation[numsprites-1];
364         alivetime[which]=alivetime[numsprites-1];
365         opacity[which]=opacity[numsprites-1];
366         position[which]=position[numsprites-1];
367         velocity[which]=velocity[numsprites-1];
368         size[which]=size[numsprites-1];
369         speed[which]=speed[numsprites-1];
370         special[which]=special[numsprites-1];
371         color[which][0]=color[numsprites-1][0];
372         color[which][1]=color[numsprites-1][1];
373         color[which][2]=color[numsprites-1][2];
374         numsprites--;
375 }
376
377 void Sprites::MakeSprite(int atype, XYZ where, XYZ avelocity, float red, float green, float blue, float asize, float aopacity){
378         if(numsprites<max_sprites-1){
379                 if((atype!=bloodsprite&&atype!=bloodflamesprite)||bloodtoggle){
380                         special[numsprites]=0;
381                         type[numsprites]=atype;
382                         position[numsprites]=where;
383                         oldposition[numsprites]=where;
384                         velocity[numsprites]=avelocity;
385                         alivetime[numsprites]=0;
386                         opacity[numsprites]=aopacity;
387                         size[numsprites]=asize;
388                         initialsize[numsprites]=asize;
389                         color[numsprites][0]=red;
390                         color[numsprites][1]=green;
391                         color[numsprites][2]=blue;
392                         rotatespeed[numsprites]=abs(Random()%720)-360;
393                         speed[numsprites]=float(abs(Random()%100))/200+1.5;
394                 }               
395                 numsprites++;
396         }
397 }
398
399 Sprites::Sprites()
400 {
401         cloudtexture = 0;
402         cloudimpacttexture = 0;
403         bloodtexture = 0;
404         flametexture = 0;
405         bloodflametexture = 0;
406         smoketexture = 0;
407         snowflaketexture = 0;
408         shinetexture = 0;
409         splintertexture = 0;
410         leaftexture = 0;
411         toothtexture = 0;
412
413         memset(oldposition, 0, sizeof(oldposition));
414         memset(position, 0, sizeof(position));
415         memset(velocity, 0, sizeof(velocity));
416         memset(size, 0, sizeof(size));
417         memset(initialsize, 0, sizeof(initialsize));
418         memset(type, 0, sizeof(type));
419         memset(special, 0, sizeof(special));
420         memset(color, 0, sizeof(color));
421         memset(opacity, 0, sizeof(opacity));
422         memset(rotation, 0, sizeof(rotation));
423         memset(alivetime, 0, sizeof(alivetime));
424         memset(speed, 0, sizeof(speed));
425         memset(rotatespeed, 0, sizeof(rotatespeed));
426
427         checkdelay = 0;
428         numsprites = 0;
429 }
430 Sprites::~Sprites()
431 {
432         if (toothtexture) glDeleteTextures( 1, &toothtexture );
433         if (cloudtexture) glDeleteTextures( 1, &cloudtexture );
434         if (cloudimpacttexture) glDeleteTextures( 1, &cloudimpacttexture );
435         if (bloodtexture) glDeleteTextures( 1, &bloodtexture );
436         if (flametexture) glDeleteTextures( 1, &flametexture );
437         if (bloodflametexture) glDeleteTextures( 1, &bloodflametexture );
438         if (smoketexture) glDeleteTextures( 1, &smoketexture );
439         if (snowflaketexture) glDeleteTextures( 1, &snowflaketexture );
440         if (shinetexture) glDeleteTextures( 1, &shinetexture );
441         if (splintertexture) glDeleteTextures( 1, &splintertexture );
442         if (leaftexture) glDeleteTextures( 1, &leaftexture );
443 }
444