2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 extern float viewdistance;
26 extern float fadestart;
27 extern int environment;
28 extern float texscale;
30 extern float multiplier;
32 extern Terrain terrain;
33 extern Objects objects;
35 extern XYZ viewerfacing;
36 extern float terraindetail;
37 extern int bloodtoggle;
38 extern XYZ windvector;
39 extern int numplayers;
40 extern Person player[maxplayers];
48 static float distancemult;
50 static int lastspecial;
51 static int whichpatchx,whichpatchz;
52 static XYZ start,end,colpoint;
55 static float tempmult;
56 static XYZ difference;
57 static float lightcolor[3];
58 static float viewdistsquared=viewdistance*viewdistance;
59 static XYZ tempviewer;
61 tempviewer=viewer+viewerfacing*6;
64 lightcolor[0]=light.color[0]*.5+light.ambient[0];
65 lightcolor[1]=light.color[1]*.5+light.ambient[1];
66 lightcolor[2]=light.color[2]*.5+light.ambient[2];
68 checkdelay-=multiplier*10;
78 glDisable(GL_LIGHTING);
79 glDisable(GL_CULL_FACE);
80 glEnable(GL_TEXTURE_2D);
82 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
84 glAlphaFunc(GL_GREATER, 0.0001);
85 for(i=0;i<numsprites;i++){
86 if(type[i]==cloudsprite&&lasttype!=type[i]){
87 glBindTexture( GL_TEXTURE_2D, cloudtexture);
90 glAlphaFunc(GL_GREATER, 0.0001);
91 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
94 if(type[i]==cloudimpactsprite&&lasttype!=type[i]){
95 glBindTexture( GL_TEXTURE_2D, cloudimpacttexture);
98 glAlphaFunc(GL_GREATER, 0.0001);
99 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
102 if(type[i]==breathsprite&&lasttype!=type[i]){
103 glBindTexture( GL_TEXTURE_2D, cloudimpacttexture);
106 glAlphaFunc(GL_GREATER, 0.0001);
107 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
110 if(type[i]==smoketype&&lasttype!=type[i]){
111 glBindTexture( GL_TEXTURE_2D, smoketexture);
114 glAlphaFunc(GL_GREATER, 0.0001);
115 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
118 if(type[i]==bloodsprite&&lasttype!=type[i]){
119 glBindTexture( GL_TEXTURE_2D, bloodtexture);
122 glAlphaFunc(GL_GREATER, 0.0001);
123 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
126 if(type[i]==splintersprite&&(lasttype!=type[i]||lastspecial!=special[i])){
127 if(special[i]==0)glBindTexture( GL_TEXTURE_2D, splintertexture);
128 if(special[i]==1)glBindTexture( GL_TEXTURE_2D, leaftexture);
129 if(special[i]==2)glBindTexture( GL_TEXTURE_2D, snowflaketexture);
130 if(special[i]==3)glBindTexture( GL_TEXTURE_2D, toothtexture);
133 glAlphaFunc(GL_GREATER, 0.0001);
134 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
137 if(type[i]==snowsprite&&lasttype!=type[i]){
138 glBindTexture( GL_TEXTURE_2D, snowflaketexture);
141 glAlphaFunc(GL_GREATER, 0.0001);
142 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
145 if(type[i]==weaponshinesprite&&lasttype!=type[i]){
146 glBindTexture( GL_TEXTURE_2D, shinetexture);
149 glAlphaFunc(GL_GREATER, 0.001);
150 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
153 if((type[i]==flamesprite||type[i]==weaponflamesprite)&&lasttype!=type[i]){
154 glBindTexture( GL_TEXTURE_2D, flametexture);
155 if(blend||lasttype==bloodflamesprite){
157 glAlphaFunc(GL_GREATER, 0.3);
158 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
161 if((type[i]==bloodflamesprite)&&lasttype!=type[i]){
162 glBindTexture( GL_TEXTURE_2D, bloodflametexture);
165 glAlphaFunc(GL_GREATER, 0.3);
166 glBlendFunc(GL_ONE,GL_ZERO);
167 //glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
170 if(type[i]!=snowsprite)distancemult=(viewdistsquared-(findDistancefast(&viewer,&position[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
171 if(type[i]==snowsprite)distancemult=(144-(findDistancefast(&tempviewer,&position[i])-(144*fadestart))*(1/(1-fadestart)))/144;
172 if(type[i]!=flamesprite){
173 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]);
174 if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]*distancemult);
176 if(type[i]==flamesprite){
177 if(distancemult>=1)glColor4f(color[i][0],color[i][1],color[i][2],opacity[i]);
178 if(distancemult<1)glColor4f(color[i][0],color[i][1],color[i][2],opacity[i]*distancemult);
181 lastspecial=special[i];
182 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
184 glTranslatef(position[i].x,position[i].y,position[i].z);
185 if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite)){
186 difference=viewer-position[i];
187 Normalise(&difference);
188 glTranslatef(difference.x*size[i]/4, difference.y*size[i]/4, difference.z*size[i]/4);
190 if(type[i]==snowsprite){
191 glRotatef(rotation[i]*.2,0,.3,1);
194 glGetFloatv(GL_MODELVIEW_MATRIX,M);
199 glTranslatef(point.x, point.y, point.z);
201 glRotatef(rotation[i],0,0,1);
203 if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite)){
204 if(alivetime[i]<.14)glScalef(alivetime[i]/.14,alivetime[i]/.14,alivetime[i]/.14);
206 if(type[i]==smoketype||type[i]==snowsprite||type[i]==weaponshinesprite||type[i]==breathsprite){
208 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],opacity[i]*alivetime[i]/.3);
209 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);
212 if(type[i]==splintersprite&&special[i]>0&&special[i]!=3){
214 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],alivetime[i]/.2);
215 if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],distancemult*alivetime[i]/.2);
218 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
219 if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
222 if(type[i]==splintersprite&&(special[i]==0||special[i]==3)){
223 if(distancemult>=1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
224 if(distancemult<1)glColor4f(color[i][0]*lightcolor[0],color[i][1]*lightcolor[1],color[i][2]*lightcolor[2],1);
227 if(type[i]==snowsprite){
228 glRotatef(rotation[i],0,0,1);
232 glBegin(GL_TRIANGLES);
233 glTexCoord2f(1.0f, 1.0f); glVertex3f( .5*size[i], .5*size[i], 0.0f);
234 glTexCoord2f(0.0f, 1.0f); glVertex3f(-.5*size[i], .5*size[i], 0.0f);
235 glTexCoord2f(1.0f, 0.0f); glVertex3f( .5*size[i],-.5*size[i], 0.0f);
236 glTexCoord2f(0.0f, 0.0f); glVertex3f(-.5*size[i],-.5*size[i], 0.0f);
237 glTexCoord2f(1.0f, 0.0f); glVertex3f( .5*size[i], -.5*size[i], 0.0f);
238 glTexCoord2f(0.0f, 1.0f); glVertex3f(-.5*size[i], .5*size[i], 0.0f);
243 for(i=numsprites-1;i>=0;i--){
245 if(type[i]!=snowsprite)position[i]+=velocity[i]*multiplier;
246 if(type[i]!=snowsprite)velocity[i]+=windvector*multiplier;
247 if(type[i]==flamesprite||type[i]==smoketype)position[i]+=windvector*multiplier/2;
248 if((type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite))multiplier*=speed[i]*.7;
249 alivetime[i]+=multiplier;
251 if(type[i]==cloudsprite||type[i]==cloudimpactsprite){
252 opacity[i]-=multiplier/2;
253 size[i]+=multiplier/2;
254 velocity[i].y+=gravity*multiplier*.25;
256 if(type[i]==breathsprite){
257 opacity[i]-=multiplier/2;
258 size[i]+=multiplier/2;
259 if(findLength(&velocity[i])<=multiplier)velocity[i]=0;
262 slowdown=velocity[i]*-1;
263 Normalise(&slowdown);
264 slowdown*=multiplier;
265 velocity[i]+=slowdown;
268 if(type[i]==snowsprite){
269 size[i]-=multiplier/120;
270 rotation[i]+=multiplier*360;
271 position[i].y-=multiplier;
272 position[i]+=windvector*multiplier;
273 if(position[i].y<tempviewer.y-6)position[i].y+=12;
274 if(position[i].y>tempviewer.y+6)position[i].y-=12;
275 if(position[i].z<tempviewer.z-6)position[i].z+=12;
276 if(position[i].z>tempviewer.z+6)position[i].z-=12;
277 if(position[i].x<tempviewer.x-6)position[i].x+=12;
278 if(position[i].x>tempviewer.x+6)position[i].x-=12;
280 if(type[i]==bloodsprite){
282 rotation[i]+=multiplier*100;
283 velocity[i].y+=gravity*multiplier;
285 XYZ where,startpoint,endpoint,movepoint,footpoint;
289 for(j=0;j<numplayers;j++){
290 if(!spritehit&&player[j].dead&&alivetime[i]>.1){
291 where=oldposition[i];
292 where-=player[j].coords;
293 if(!player[j].skeleton.free)where=DoRotation(where,0,-player[j].rotation,0);
296 where-=player[j].coords;
297 if(!player[j].skeleton.free)where=DoRotation(where,0,-player[j].rotation,0);
302 whichtri=player[j].skeleton.drawmodel.LineCheck(&startpoint,&endpoint, &footpoint, &movepoint, &rotationpoint);
305 player[j].DoBloodBigWhere(0,160,oldposition[i]);
311 whichpatchx=position[i].x/(terrain.size/subdivision*terrain.scale*terraindetail);
312 whichpatchz=position[i].z/(terrain.size/subdivision*terrain.scale*terraindetail);
313 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
314 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
316 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
317 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
318 start=oldposition[i];
321 if(objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k])!=-1){
322 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);
329 if(position[i].y<terrain.getHeight(position[i].x,position[i].z)){
330 terrain.MakeDecal(blooddecalfast,position[i],size[i]*1.6/*+abs((float)(Random()%100))/2400*/,.6,Random()%360);
335 if(type[i]==splintersprite){
336 rotation[i]+=rotatespeed[i]*multiplier;
337 opacity[i]-=multiplier/2;
338 if(special[i]==0||special[i]==2||special[i]==3)velocity[i].y+=gravity*multiplier;
339 if(special[i]==1)velocity[i].y+=gravity*multiplier*.5;
341 if(type[i]==flamesprite||type[i]==weaponflamesprite||type[i]==weaponshinesprite||type[i]==bloodflamesprite){
342 rotation[i]+=multiplier*rotatespeed[i];
343 opacity[i]-=multiplier*5/4;
344 if(type[i]!=weaponshinesprite&&type[i]!=bloodflamesprite)
345 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);
346 if(alivetime[i]>.14&&(type[i]==flamesprite)){
351 /*if(type[i]==smoketype){
352 opacity[i]-=multiplier/3/initialsize[i];
356 rotation[i]+=multiplier*rotatespeed[i]/5;
358 if(type[i]==smoketype){
359 opacity[i]-=multiplier/3/initialsize[i];
360 color[i][0]-=multiplier;
361 color[i][1]-=multiplier;
362 color[i][2]-=multiplier;
363 if(color[i][0]<.6)color[i][0]=.6;
364 if(color[i][1]<.6)color[i][1]=.6;
365 if(color[i][2]<.6)color[i][2]=.6;
369 rotation[i]+=multiplier*rotatespeed[i]/5;
371 if(opacity[i]<=0||size[i]<=0)DeleteSprite(i);
374 for(i=numsprites-1;i>=0;i--){
375 oldposition[i]=position[i];
377 glAlphaFunc(GL_GREATER, 0.0001);
378 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
381 void Sprites::DeleteSprite(int which)
383 type[which]=type[numsprites-1];
384 rotation[which]=rotation[numsprites-1];
385 alivetime[which]=alivetime[numsprites-1];
386 opacity[which]=opacity[numsprites-1];
387 position[which]=position[numsprites-1];
388 velocity[which]=velocity[numsprites-1];
389 size[which]=size[numsprites-1];
390 speed[which]=speed[numsprites-1];
391 special[which]=special[numsprites-1];
392 color[which][0]=color[numsprites-1][0];
393 color[which][1]=color[numsprites-1][1];
394 color[which][2]=color[numsprites-1][2];
398 void Sprites::MakeSprite(int atype, XYZ where, XYZ avelocity, float red, float green, float blue, float asize, float aopacity){
399 if(numsprites<max_sprites-1){
400 if((atype!=bloodsprite&&atype!=bloodflamesprite)||bloodtoggle){
401 special[numsprites]=0;
402 type[numsprites]=atype;
403 position[numsprites]=where;
404 oldposition[numsprites]=where;
405 velocity[numsprites]=avelocity;
406 alivetime[numsprites]=0;
407 opacity[numsprites]=aopacity;
408 size[numsprites]=asize;
409 initialsize[numsprites]=asize;
410 color[numsprites][0]=red;
411 color[numsprites][1]=green;
412 color[numsprites][2]=blue;
413 rotatespeed[numsprites]=abs(Random()%720)-360;
414 speed[numsprites]=float(abs(Random()%100))/200+1.5;
423 cloudimpacttexture = 0;
426 bloodflametexture = 0;
428 snowflaketexture = 0;
434 memset(oldposition, 0, sizeof(oldposition));
435 memset(position, 0, sizeof(position));
436 memset(velocity, 0, sizeof(velocity));
437 memset(size, 0, sizeof(size));
438 memset(initialsize, 0, sizeof(initialsize));
439 memset(type, 0, sizeof(type));
440 memset(special, 0, sizeof(special));
441 memset(color, 0, sizeof(color));
442 memset(opacity, 0, sizeof(opacity));
443 memset(rotation, 0, sizeof(rotation));
444 memset(alivetime, 0, sizeof(alivetime));
445 memset(speed, 0, sizeof(speed));
446 memset(rotatespeed, 0, sizeof(rotatespeed));
453 if (toothtexture) glDeleteTextures( 1, &toothtexture );
454 if (cloudtexture) glDeleteTextures( 1, &cloudtexture );
455 if (cloudimpacttexture) glDeleteTextures( 1, &cloudimpacttexture );
456 if (bloodtexture) glDeleteTextures( 1, &bloodtexture );
457 if (flametexture) glDeleteTextures( 1, &flametexture );
458 if (bloodflametexture) glDeleteTextures( 1, &bloodflametexture );
459 if (smoketexture) glDeleteTextures( 1, &smoketexture );
460 if (snowflaketexture) glDeleteTextures( 1, &snowflaketexture );
461 if (shinetexture) glDeleteTextures( 1, &shinetexture );
462 if (splintertexture) glDeleteTextures( 1, &splintertexture );
463 if (leaftexture) glDeleteTextures( 1, &leaftexture );