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.
22 /**> HEADER FILES <**/
24 #include "openal_wrapper.h"
25 #include "Animation.h"
30 extern float multiplier;
31 extern Terrain terrain;
33 extern int environment;
35 extern FRUSTUM frustum;
37 extern float realmultiplier;
39 extern float slomodelay;
40 extern bool cellophane;
41 extern float texdetail;
42 extern GLubyte bloodText[512*512*3];
43 extern int bloodtoggle;
44 extern Objects objects;
46 extern bool autoslomo;
47 extern float camerashake;
49 extern float terraindetail;
50 extern float viewdistance;
51 extern float blackout;
52 extern int difficulty;
54 extern int tutoriallevel;
55 extern int numthrowkill;
57 void Weapons::DoStuff(){
58 static int i,whichpatchx,whichpatchz,j,k,whichhit,m;
59 static XYZ start,end,colpoint,normalrot,footvel,footpoint;
60 static XYZ terrainnormal;
63 static XYZ newpoint1,newpoint2;
64 static float friction=3.5;
65 static float elasticity=.4;
66 static XYZ bounceness;
67 static float frictionness;
68 static float moveamount;
70 static float closestdistance;
71 static float distance;
73 static XYZ closestpoint;
74 static XYZ closestswordpoint;
76 static float proportion;
77 static float tempmult;
81 for(i=0;i<numweapons;i++){
85 if(damage[i]>=2&&type[i]==staff&&owner[i]!=-1){
86 emit_sound_at(staffbreaksound, tippoint[i]);
89 //speed=(tippoint[i]-oldtippoint[i])/multiplier/6;
92 tempvel.x=float(abs(Random()%100)-50)/20;
93 tempvel.y=float(abs(Random()%100)-50)/20;
94 tempvel.z=float(abs(Random()%100)-50)/20;
96 Sprite::MakeSprite(splintersprite, position[i]+(tippoint[i]-position[i])*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
108 player[tempowner].num_weapons--;
109 if(player[tempowner].num_weapons){
110 player[tempowner].weaponids[0]=player[tempowner].weaponids[player[tempowner].num_weapons];
111 if(player[tempowner].weaponstuck==player[tempowner].num_weapons)player[tempowner].weaponstuck=0;
113 player[tempowner].weaponactive=-1;
116 oldposition[i]=position[i];
117 oldtippoint[i]=tippoint[i];
118 if(owner[i]==-1&&(velocity[i].x||velocity[i].y||velocity[i].z)&&!physics[i]){
119 position[i]+=velocity[i]*multiplier;
120 tippoint[i]+=velocity[i]*multiplier;
121 whichpatchx=position[i].x/(terrain.size/subdivision*terrain.scale*terraindetail);
122 whichpatchz=position[i].z/(terrain.size/subdivision*terrain.scale*terraindetail);
123 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
124 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
125 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
126 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
127 start=oldtippoint[i];
129 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
131 if(objects.type[k]==treetrunktype){
132 objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),.1,1,Random()%360);
133 normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0);
135 if(type[i]==knife)position[i]=colpoint-normalrot*.1;
136 if(type[i]==sword)position[i]=colpoint-normalrot*.2;
137 if(type[i]==staff)position[i]=colpoint-normalrot*.2;
138 XYZ temppoint1,temppoint2,tempforward;
142 temppoint2=normalrot;
143 distance=findDistance(&temppoint1,&temppoint2);
144 rotation2[i]=asin((temppoint1.y-temppoint2.y)/distance);
145 rotation2[i]*=360/6.28;
148 rotation1[i]=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
149 rotation1[i]*=360/6.28;
150 if(temppoint1.x>temppoint2.x)rotation1[i]=360-rotation1[i];
159 emit_sound_at(knifesheathesound, position[i], 128.);
163 Sprite::MakeSprite(cloudimpactsprite, position[i],velocity[i], 1,1,1, .8, .3);
168 position[i]-=velocity[i]*multiplier;
169 tippoint[i]-=velocity[i]*multiplier;
170 tipvelocity[i]=velocity[i];
175 if(velocity[i].x||velocity[i].y||velocity[i].z)
176 for(j=0;j<numplayers;j++){
178 footpoint=DoRotation((player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].position+player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].position)/2,0,player[j].rotation,0)*player[j].scale+player[j].coords;
179 if(owner[i]==-1&&findDistancefastflat(&position[i],&player[j].coords)<1.5&&findDistancefast(&position[i],&player[j].coords)<4&&player[j].weaponstuck==-1&&!player[j].skeleton.free&&j!=oldowner[i]){
180 if((player[j].aitype!=attacktypecutoff||abs(Random()%6)==0||(player[j].targetanimation!=backhandspringanim&&player[j].targetanimation!=rollanim&&player[j].targetanimation!=flipanim&&Random()%2==0))&&!missed[i]){
182 if((player[j].creature==wolftype&&Random()%3!=0&&player[j].weaponactive==-1&&(player[j].isIdle()||player[j].isRun()||player[j].targetanimation==walkanim))||(player[j].creature==rabbittype&&Random()%2==0&&player[j].aitype==attacktypecutoff&&player[j].weaponactive==-1)){
183 emit_sound_at(knifedrawsound, player[j].coords, 128.);
185 player[j].weaponactive=0;
186 player[j].targetanimation=removeknifeanim;
187 player[j].targetframe=1;
189 owner[i]=player[j].id;
190 if(player[j].num_weapons>0){
191 player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
193 player[j].num_weapons++;
194 player[j].weaponids[0]=i;
196 player[j].aitype=attacktypecutoff;
199 if(j!=0)numthrowkill++;
200 player[j].num_weapons++;
201 player[j].weaponstuck=player[j].num_weapons-1;
202 if(normaldotproduct(player[j].facing,velocity[i])>0)player[j].weaponstuckwhere=1;
203 else player[j].weaponstuckwhere=0;
205 player[j].weaponids[player[j].num_weapons-1]=i;
207 player[j].RagDoll(0);
208 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity[i]*2;
209 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity[i]*2;
210 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity[i]*2;
211 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity[i]*2;
212 //player[j].Puff(abdomen);
213 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
214 if(tutoriallevel==1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
215 footvel=tippoint[i]-position[i];
217 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
219 if(tutoriallevel!=1){
220 if(player[j].weaponstuckwhere==0)player[j].DoBloodBig(2,205);
221 if(player[j].weaponstuckwhere==1)player[j].DoBloodBig(2,200);
222 player[j].damage+=200/player[j].armorhigh;
223 player[j].deathbleeding=1;
224 player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
230 emit_sound_at(fleshstabsound, position[i], 128.);
232 if(animation[player[0].targetanimation].height==highheight)
233 award_bonus(0, ninja);
235 award_bonus(0, Bullseyebonus);
241 if(position[i].y<terrain.getHeight(position[i].x,position[i].z)){
242 if(terrain.getOpacity(position[i].x,position[i].z)<.2){
244 if(terrain.lineTerrain(oldposition[i],position[i],&colpoint)!=-1){
245 position[i]=colpoint*terrain.scale;
247 else position[i].y=terrain.getHeight(position[i].x,position[i].z);
249 terrain.MakeDecal(shadowdecalpermanent,position[i],.06,.5,0);
250 normalrot=terrain.getNormal(position[i].x,position[i].z)*-1;
252 //position[i]-=normalrot*.1;
253 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
257 glRotatef(bigrotation[i],0,1,0);
258 glRotatef(bigtilt2[i],1,0,0);
259 glRotatef(bigtilt[i],0,0,1);
260 glRotatef(-rotation1[i]+90,0,1,0);
261 glRotatef(-rotation2[i]+90,0,0,1);
262 glRotatef(-rotation3[i],0,1,0);
263 glRotatef(smallrotation[i],1,0,0);
264 glRotatef(smallrotation2[i],0,1,0);
266 glGetFloatv(GL_MODELVIEW_MATRIX,M);
271 position[i]-=tippoint[i]*.15;
272 XYZ temppoint1,temppoint2,tempforward;
282 emit_sound_at(knifesheathesound, position[i], 128.);
285 terrainlight=terrain.getLighting(position[i].x,position[i].z);
286 if(environment==snowyenvironment){
287 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
289 else if(environment==grassyenvironment){
290 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
292 else if(environment==desertenvironment){
293 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
301 position[i]-=velocity[i]*multiplier;
302 tippoint[i]-=velocity[i]*multiplier;
303 tipvelocity[i]=velocity[i];
306 if(velocity[i].x!=0||velocity[i].z!=0||velocity[i].y!=0){
307 velocity[i].y+=gravity*multiplier;
309 XYZ temppoint1,temppoint2,tempforward;
313 temppoint2=velocity[i];
314 distance=findDistance(&temppoint1,&temppoint2);
315 rotation2[i]=asin((temppoint1.y-temppoint2.y)/distance);
316 rotation2[i]*=360/6.28;
319 rotation1[i]=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
320 rotation1[i]*=360/6.28;
327 if(temppoint1.x>temppoint2.x)rotation1[i]=360-rotation1[i];
337 for(int l=0;l<10;l++){
338 if(owner[i]==-1&&(velocity[i].x||velocity[i].y||velocity[i].z)&&physics[i]){
340 position[i]+=velocity[i]*multiplier;
341 tippoint[i]+=tipvelocity[i]*multiplier;
344 midp=(position[i]*mass[i]+tippoint[i]*tipmass[i])/(mass[i]+tipmass[i]);
345 vel=tippoint[i]-midp;
347 newpoint1=midp-vel*length[i]*(tipmass[i]/(mass[i]+tipmass[i]));
348 newpoint2=midp+vel*length[i]*(mass[i]/(mass[i]+tipmass[i]));
350 if(freetime[i]>.04)velocity[i]=velocity[i]+(newpoint1-position[i])/multiplier;
351 if(freetime[i]>.04)tipvelocity[i]=tipvelocity[i]+(newpoint2-tippoint[i])/multiplier;
353 position[i]=newpoint1;
354 tippoint[i]=newpoint2;
358 whichpatchx=(position[i].x)/(terrain.size/subdivision*terrain.scale*terraindetail);
359 whichpatchz=(position[i].z)/(terrain.size/subdivision*terrain.scale*terraindetail);
360 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
361 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
362 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
363 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
367 start=position[i]-(tippoint[i]-position[i])/5;
368 end=tippoint[i]+(tippoint[i]-position[i])/30;
369 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
372 diff=(colpoint-tippoint[i]);
376 position[i]+=(colpoint-tippoint[i])+diff*.05;
377 tippoint[i]=colpoint+diff*.05;
378 oldposition[i]=position[i];
379 oldtippoint[i]=tippoint[i];
383 start=tippoint[i]-(position[i]-tippoint[i])/5;
384 end=position[i]+(position[i]-tippoint[i])/30;
385 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
388 diff=(colpoint-position[i]);
392 tippoint[i]+=(colpoint-position[i])+diff*.05;
393 position[i]=colpoint+diff*.05;
394 oldtippoint[i]=tippoint[i];
395 oldposition[i]=tippoint[i];
400 start=oldposition[i];
402 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
405 position[i]=colpoint;
406 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
407 ReflectVector(&velocity[i],&terrainnormal);
408 position[i]+=terrainnormal*.002;
410 bounceness=terrainnormal*findLength(&velocity[i])*(abs(normaldotproduct(velocity[i],terrainnormal)));
411 if(findLengthfast(&velocity[i])<findLengthfast(&bounceness))bounceness=0;
412 frictionness=abs(normaldotproduct(velocity[i],terrainnormal));
413 velocity[i]-=bounceness;
414 if(1-friction*frictionness>0)velocity[i]*=1-friction*frictionness;
416 velocity[i]+=bounceness*elasticity;
418 if(findLengthfast(&bounceness)>1){
420 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
421 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
422 emit_sound_at(whichsound, position[i], 128*findLengthfast(&bounceness));
425 start=oldtippoint[i];
427 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
430 tippoint[i]=colpoint;
431 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
432 ReflectVector(&tipvelocity[i],&terrainnormal);
433 tippoint[i]+=terrainnormal*.002;
435 bounceness=terrainnormal*findLength(&tipvelocity[i])*(abs(normaldotproduct(tipvelocity[i],terrainnormal)));
436 if(findLengthfast(&tipvelocity[i])<findLengthfast(&bounceness))bounceness=0;
437 frictionness=abs(normaldotproduct(tipvelocity[i],terrainnormal));
438 tipvelocity[i]-=bounceness;
439 if(1-friction*frictionness>0)tipvelocity[i]*=1-friction*frictionness;
440 else tipvelocity[i]=0;
441 tipvelocity[i]+=bounceness*elasticity;
443 if(findLengthfast(&bounceness)>1){
445 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
446 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
447 emit_sound_at(whichsound, position[i], 128*findLengthfast(&bounceness));
451 if((objects.type[k]!=boxtype&&objects.type[k]!=platformtype&&objects.type[k]!=walltype&&objects.type[k]!=weirdtype)||objects.rotation2[k]!=0)
453 mid=(position[i]*(21+(float)m*10)+tippoint[i]*(19-(float)m*10))/40;
455 oldmid=(oldposition[i]*(21+(float)m*10)+oldtippoint[i]*(19-(float)m*10))/40;
459 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
463 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
464 ReflectVector(&velocity[i],&terrainnormal);
466 bounceness=terrainnormal*findLength(&velocity[i])*(abs(normaldotproduct(velocity[i],terrainnormal)));
467 if(findLengthfast(&velocity[i])<findLengthfast(&bounceness))bounceness=0;
468 frictionness=abs(normaldotproduct(velocity[i],terrainnormal));
469 velocity[i]-=bounceness;
470 if(1-friction*frictionness>0)velocity[i]*=1-friction*frictionness;
472 velocity[i]+=bounceness*elasticity;
474 if(findLengthfast(&bounceness)>1){
476 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
477 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
478 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
480 position[i]+=(mid-oldmid2)*(20/(1+(float)m*10));
483 mid=(position[i]*(19-(float)m*10)+tippoint[i]*(21+(float)m*10))/40;
485 oldmid=(oldposition[i]*(19-(float)m*10)+oldtippoint[i]*(21+(float)m*10))/40;
489 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
493 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
494 ReflectVector(&tipvelocity[i],&terrainnormal);
496 bounceness=terrainnormal*findLength(&tipvelocity[i])*(abs(normaldotproduct(tipvelocity[i],terrainnormal)));
497 if(findLengthfast(&tipvelocity[i])<findLengthfast(&bounceness))bounceness=0;
498 frictionness=abs(normaldotproduct(tipvelocity[i],terrainnormal));
499 tipvelocity[i]-=bounceness;
500 if(1-friction*frictionness>0)tipvelocity[i]*=1-friction*frictionness;
501 else tipvelocity[i]=0;
502 tipvelocity[i]+=bounceness*elasticity;
504 if(findLengthfast(&bounceness)>1){
506 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
507 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
508 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
510 tippoint[i]+=(mid-oldmid2)*(20/(1+(float)m*10));
517 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
521 closestswordpoint=colpoint;//(position[i]+tippoint[i])/2;
522 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.rotation[k],0)+objects.position[k];
523 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.rotation[k],0)+objects.position[k];
524 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.rotation[k],0)+objects.position[k];
525 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint ))
526 if(distance<closestdistance||closestdistance==-1){
527 closestpoint=colpoint;
528 closestdistance=distance;
531 if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint ))
532 if(distance<closestdistance||closestdistance==-1){
533 closestpoint=colpoint;
534 closestdistance=distance;
537 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint ))
538 if(distance<closestdistance||closestdistance==-1){
539 closestpoint=colpoint;
540 closestdistance=distance;
543 if(closestdistance!=-1&&isnormal(closestdistance)){
544 if(DistancePointLine(&closestpoint, &position[i], &tippoint[i], &distance,&colpoint )){
545 closestswordpoint=colpoint;
546 velocity[i]+=(closestpoint-closestswordpoint);
547 tipvelocity[i]+=(closestpoint-closestswordpoint);
548 position[i]+=(closestpoint-closestswordpoint);
549 tippoint[i]+=(closestpoint-closestswordpoint);
558 whichhit=terrain.lineTerrain(oldposition[i],position[i],&colpoint);
559 if(whichhit!=-1||position[i].y<terrain.getHeight(position[i].x,position[i].z)){
561 if(whichhit!=-1)position[i]=colpoint*terrain.scale;
562 else position[i].y=terrain.getHeight(position[i].x,position[i].z);
564 terrainnormal=terrain.getNormal(position[i].x,position[i].z);
565 ReflectVector(&velocity[i],&terrainnormal);
566 position[i]+=terrainnormal*.002;
567 bounceness=terrainnormal*findLength(&velocity[i])*(abs(normaldotproduct(velocity[i],terrainnormal)));
568 if(findLengthfast(&velocity[i])<findLengthfast(&bounceness))bounceness=0;
569 frictionness=abs(normaldotproduct(velocity[i],terrainnormal));
570 velocity[i]-=bounceness;
571 if(1-friction*frictionness>0)velocity[i]*=1-friction*frictionness;
573 if(terrain.getOpacity(position[i].x,position[i].z)<.2)velocity[i]+=bounceness*elasticity*.3;
574 else velocity[i]+=bounceness*elasticity;
575 //if (type[i]==knife) printf("velocity of knife %d now %f,%f,%f.\n", i, velocity[i].x, velocity[i].y, velocity[i].z);
576 if(findLengthfast(&bounceness)>1){
578 if(terrain.getOpacity(position[i].x,position[i].z)>.2){
579 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
580 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
582 else whichsound=footstepsound+abs(Random()%2);
583 emit_sound_at(whichsound, position[i],
584 findLengthfast(&bounceness)
585 * (terrain.getOpacity(position[i].x,position[i].z) > .2
589 if(terrain.getOpacity(position[i].x,position[i].z)<.2){
591 terrainlight=terrain.getLighting(position[i].x,position[i].z);
592 if(environment==snowyenvironment){
593 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
595 else if(environment==grassyenvironment){
596 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
598 else if(environment==desertenvironment){
599 if(findDistancefast(&position[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position[i],velocity[i], terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
604 whichhit=terrain.lineTerrain(oldtippoint[i],tippoint[i],&colpoint);
605 if(whichhit!=-1||tippoint[i].y<terrain.getHeight(tippoint[i].x,tippoint[i].z)){
606 if(whichhit!=-1)tippoint[i]=colpoint*terrain.scale;
607 else tippoint[i].y=terrain.getHeight(tippoint[i].x,tippoint[i].z);
609 terrainnormal=terrain.getNormal(tippoint[i].x,tippoint[i].z);
610 ReflectVector(&tipvelocity[i],&terrainnormal);
611 tippoint[i]+=terrainnormal*.002;
612 bounceness=terrainnormal*findLength(&tipvelocity[i])*(abs(normaldotproduct(tipvelocity[i],terrainnormal)));
613 if(findLengthfast(&tipvelocity[i])<findLengthfast(&bounceness))bounceness=0;
614 frictionness=abs(normaldotproduct(tipvelocity[i],terrainnormal));
615 tipvelocity[i]-=bounceness;
616 if(1-friction*frictionness>0)tipvelocity[i]*=1-friction*frictionness;
617 else tipvelocity[i]=0;
618 if(terrain.getOpacity(tippoint[i].x,tippoint[i].z)<.2)tipvelocity[i]+=bounceness*elasticity*.3;
619 else tipvelocity[i]+=bounceness*elasticity;
620 //if (type[i]==knife) printf("tipvelocity of knife %d now %f,%f,%f.\n", i, tipvelocity[i].x, tipvelocity[i].y, tipvelocity[i].z);
622 if(findLengthfast(&bounceness)>1){
624 if(terrain.getOpacity(tippoint[i].x,tippoint[i].z)>.2){
625 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
626 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
628 else whichsound=footstepsound+abs(Random()%2);
629 emit_sound_at(whichsound, tippoint[i],
630 findLengthfast(&bounceness)
631 * (terrain.getOpacity(tippoint[i].x,tippoint[i].z) > .2
635 if(terrain.getOpacity(tippoint[i].x,tippoint[i].z)<.2){
637 terrainlight=terrain.getLighting(tippoint[i].x,tippoint[i].z);
638 if(environment==snowyenvironment){
639 if(findDistancefast(&tippoint[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint[i],tipvelocity[i], terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
641 else if(environment==grassyenvironment){
642 if(findDistancefast(&tippoint[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint[i],tipvelocity[i], terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
644 else if(environment==desertenvironment){
645 if(findDistancefast(&tippoint[i],&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint[i],tipvelocity[i], terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
652 mid=position[i]+tippoint[i];
654 mid+=(position[i]-mid)/20;
656 if(mid.y<terrain.getHeight(mid.x,mid.z)){
658 mid.y=terrain.getHeight(mid.x,mid.z);
660 terrainnormal=terrain.getNormal(mid.x,mid.z);
661 ReflectVector(&velocity[i],&terrainnormal);
662 //mid+=terrainnormal*.002;
663 bounceness=terrainnormal*findLength(&velocity[i])*(abs(normaldotproduct(velocity[i],terrainnormal)));
664 if(findLengthfast(&velocity[i])<findLengthfast(&bounceness))bounceness=0;
665 frictionness=abs(normaldotproduct(velocity[i],terrainnormal));
666 velocity[i]-=bounceness;
667 if(1-friction*frictionness>0)velocity[i]*=1-friction*frictionness;
669 if(terrain.getOpacity(mid.x,mid.z)<.2)velocity[i]+=bounceness*elasticity*.3;
670 else velocity[i]+=bounceness*elasticity;
672 if(findLengthfast(&bounceness)>1){
674 if(terrain.getOpacity(mid.x,mid.z)>.2){
675 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
676 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
678 else whichsound=footstepsound+abs(Random()%2);
679 emit_sound_at(whichsound, mid,
680 findLengthfast(&bounceness)
681 * (terrain.getOpacity(position[i].x,position[i].z) > .2
685 position[i]+=(mid-oldmid)*20;
688 mid=position[i]+tippoint[i];
690 mid+=(tippoint[i]-mid)/20;
692 if(mid.y<terrain.getHeight(mid.x,mid.z)){
694 mid.y=terrain.getHeight(mid.x,mid.z);
696 terrainnormal=terrain.getNormal(mid.x,mid.z);
697 ReflectVector(&tipvelocity[i],&terrainnormal);
698 //mid+=terrainnormal*.002;
699 bounceness=terrainnormal*findLength(&tipvelocity[i])*(abs(normaldotproduct(tipvelocity[i],terrainnormal)));
700 if(findLengthfast(&tipvelocity[i])<findLengthfast(&bounceness))bounceness=0;
701 frictionness=abs(normaldotproduct(tipvelocity[i],terrainnormal));
702 tipvelocity[i]-=bounceness;
703 if(1-friction*frictionness>0)tipvelocity[i]*=1-friction*frictionness;
704 else tipvelocity[i]=0;
705 if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity[i]+=bounceness*elasticity*.3;
706 else tipvelocity[i]+=bounceness*elasticity;
708 if(findLengthfast(&bounceness)>1){
710 if(terrain.getOpacity(mid.x,mid.z)>.2){
711 if(type[i]==staff)whichsound=footstepsound3+abs(Random()%2);
712 if(type[i]!=staff)whichsound=clank1sound+abs(Random()%4);
714 else whichsound=footstepsound+abs(Random()%2);
715 emit_sound_at(whichsound, mid,
716 findLengthfast(&bounceness)
717 * (terrain.getOpacity(position[i].x,position[i].z) > .2
721 tippoint[i]+=(mid-oldmid)*20;
724 velocity[i].y+=gravity*multiplier;
725 tipvelocity[i].y+=gravity*multiplier;
726 //position[i].y+=gravity*multiplier*multiplier;
727 //tippoint[i].y+=gravity*multiplier*multiplier;
730 XYZ temppoint1,temppoint2,tempforward;
733 temppoint1=position[i];
734 temppoint2=tippoint[i];
735 distance=findDistance(&temppoint1,&temppoint2);
736 rotation2[i]=asin((temppoint1.y-temppoint2.y)/distance);
737 rotation2[i]*=360/6.28;
740 rotation1[i]=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
741 rotation1[i]*=360/6.28;
748 if(temppoint1.x>temppoint2.x)rotation1[i]=360-rotation1[i];
751 if(findLengthfast(&velocity[i])<.3&&findLengthfast(&tipvelocity[i])<.3&&hitsomething[i]){
752 freetime[i]+=multiplier;
755 //velocity[i]=(position[i]-oldposition[i])/multiplier;
756 //tipvelocity[i]==(tippoint[i-+oldtippoint[i])/multiplier;
765 if(blooddrip[i]&&bloody[i]){
766 blooddripdelay[i]-=blooddrip[i]*multiplier/2;
767 blooddrip[i]-=multiplier;
768 if(blooddrip[i]<0)blooddrip[i]=0;
769 if(blooddrip[i]>5)blooddrip[i]=5;
770 if(blooddripdelay[i]<0&&bloodtoggle){
774 bloodloc=position[i]+(tippoint[i]-position[i])*.7;
778 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
783 flamedelay[i]-=multiplier;
784 if(onfire[i]&&flamedelay[i]<=0){
786 flamedelay[i]-=multiplier;
789 normalrot=player[owner[i]].velocity;
793 if(player[owner[i]].onterrain){
797 Sprite::MakeSprite(weaponflamesprite, position[i]+tippoint[i]*(((float)abs(Random()%100))/600+.05),normalrot, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*1/3, 1);
798 Sprite::setLastSpriteSpeed(4);
799 Sprite::setLastSpriteAlivetime(.3);
803 if(!onfire[i]&&owner[i]==-1&&type[i]!=staff){
804 flamedelay[i]-=multiplier;
805 if(flamedelay[i]<=0){
807 flamedelay[i]-=multiplier;
809 if(Random()%50==0&&findDistancefast(&position[i],&viewer)>80){
811 shinepoint=position[i]+(tippoint[i]-position[i])*(((float)abs(Random()%100))/100);
812 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
813 Sprite::setLastSpriteSpeed(4);
814 Sprite::setLastSpriteAlivetime(.3);
824 static XYZ terrainlight;
825 static GLfloat M[16];
827 glAlphaFunc(GL_GREATER, 0.9);
828 glEnable(GL_TEXTURE_2D);
830 glEnable(GL_CULL_FACE);
831 glCullFace(GL_FRONT);
833 for(i=0;i<numweapons;i++)
835 if((frustum.SphereInFrustum(position[i].x,position[i].y,position[i].z,1)&&findDistancefast(&viewer,&position[i])<viewdistance*viewdistance))
841 if(velocity[i].x&&!physics[i])drawhowmany[i]=10;
842 else drawhowmany[i]=1;
846 if(player[owner[i]].occluded<25)
847 if((frustum.SphereInFrustum(player[owner[i]].coords.x,player[owner[i]].coords.y+player[owner[i]].scale*3,player[owner[i]].coords.z,player[owner[i]].scale*8)&&findDistancefast(&viewer,&player[owner[i]].coords)<viewdistance*viewdistance)||player[owner[i]].skeleton.free==3)
849 if((player[owner[i]].targetanimation==knifeslashstartanim||player[owner[i]].targetanimation==swordsneakattackanim||(player[owner[i]].currentanimation==staffhitanim&&player[owner[i]].currentframe>1)||(player[owner[i]].currentanimation==staffhitreversedanim&&player[owner[i]].currentframe>1)||(player[owner[i]].currentanimation==staffspinhitanim&&player[owner[i]].currentframe>1)||(player[owner[i]].currentanimation==staffspinhitreversedanim&&player[owner[i]].currentframe>1)||(player[owner[i]].currentanimation==staffgroundsmashanim&&player[owner[i]].currentframe>1)||(player[owner[i]].targetanimation==swordslashanim&&player[owner[i]].targetframe<7)||player[owner[i]].targetanimation==crouchstabanim||player[owner[i]].targetanimation==swordslashreversalanim||player[owner[i]].targetanimation==swordslashreversedanim||player[owner[i]].targetanimation==knifefollowanim||player[owner[i]].targetanimation==swordgroundstabanim||player[owner[i]].targetanimation==knifethrowanim)&&player[owner[i]].targetanimation==lastdrawnanim[i]&&!player[owner[i]].skeleton.free)
853 else drawhowmany[i]=1;
854 if(player[owner[i]].targetanimation==swordgroundstabanim)
856 lastdrawnrotation1[i]=rotation1[i];
857 lastdrawnrotation2[i]=rotation2[i];
858 lastdrawnrotation3[i]=rotation3[i];
859 lastdrawnbigrotation[i]=bigrotation[i];
860 lastdrawnbigtilt[i]=bigtilt[i];
861 lastdrawnbigtilt2[i]=bigtilt2[i];
862 lastdrawnsmallrotation[i]=smallrotation[i];
863 lastdrawnsmallrotation2[i]=smallrotation2[i];
868 terrainlight=terrain.getLighting(position[i].x,position[i].z);
871 glAlphaFunc(GL_GREATER, 0.01);
873 for(j=drawhowmany[i];j>0;j--)
875 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
877 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany[i]);
878 if(owner[i]!=-1)glTranslatef(position[i].x*(((float)(j))/drawhowmany[i])+lastdrawnposition[i].x*(1-((float)(j))/drawhowmany[i]),position[i].y*(((float)(j))/drawhowmany[i])-.02+lastdrawnposition[i].y*(1-((float)(j))/drawhowmany[i]),position[i].z*(((float)(j))/drawhowmany[i])+lastdrawnposition[i].z*(1-((float)(j))/drawhowmany[i]));
879 if(owner[i]==-1)glTranslatef(position[i].x*(((float)(j))/drawhowmany[i])+lastdrawnposition[i].x*(1-((float)(j))/drawhowmany[i]),position[i].y*(((float)(j))/drawhowmany[i])+lastdrawnposition[i].y*(1-((float)(j))/drawhowmany[i]),position[i].z*(((float)(j))/drawhowmany[i])+lastdrawnposition[i].z*(1-((float)(j))/drawhowmany[i]));
880 //glTranslatef(position[i].x,position[i].y-.02,position[i].z);
881 glRotatef(bigrotation[i]*(((float)(j))/drawhowmany[i])+lastdrawnbigrotation[i]*(1-((float)(j))/drawhowmany[i]),0,1,0);
882 glRotatef(bigtilt2[i]*(((float)(j))/drawhowmany[i])+lastdrawnbigtilt2[i]*(1-((float)(j))/drawhowmany[i]),1,0,0);
883 glRotatef(bigtilt[i]*(((float)(j))/drawhowmany[i])+lastdrawnbigtilt[i]*(1-((float)(j))/drawhowmany[i]),0,0,1);
884 glRotatef(-rotation1[i]*(((float)(j))/drawhowmany[i])-lastdrawnrotation1[i]*(1-((float)(j))/drawhowmany[i])+90,0,1,0);
885 glRotatef(-rotation2[i]*(((float)(j))/drawhowmany[i])-lastdrawnrotation2[i]*(1-((float)(j))/drawhowmany[i])+90,0,0,1);
886 glRotatef(-rotation3[i]*(((float)(j))/drawhowmany[i])-lastdrawnrotation3[i]*(1-((float)(j))/drawhowmany[i]),0,1,0);
887 glRotatef(smallrotation[i]*(((float)(j))/drawhowmany[i])+lastdrawnsmallrotation[i]*(1-((float)(j))/drawhowmany[i]),1,0,0);
888 glRotatef(smallrotation2[i]*(((float)(j))/drawhowmany[i])+lastdrawnsmallrotation2[i]*(1-((float)(j))/drawhowmany[i]),0,1,0);
892 if(player[owner[i]].targetanimation==staffhitanim||player[owner[i]].currentanimation==staffhitanim||player[owner[i]].targetanimation==staffhitreversedanim||player[owner[i]].currentanimation==staffhitreversedanim)
894 glTranslatef(0,0,-.3);
896 if(player[owner[i]].targetanimation==staffgroundsmashanim||player[owner[i]].currentanimation==staffgroundsmashanim||player[owner[i]].targetanimation==staffspinhitreversedanim||player[owner[i]].currentanimation==staffspinhitreversedanim||player[owner[i]].targetanimation==staffspinhitanim||player[owner[i]].currentanimation==staffspinhitanim)
898 glTranslatef(0,0,-.1);
901 /*if(type[i]==knife){
903 if(!physics[i]&&findDistance(&position[i],&oldposition[i])*5>1)glScalef(1,1,findDistance(&position[i],&oldposition[i])*5);
909 glEnable(GL_LIGHTING);
910 if(!bloody[i]||!bloodtoggle)throwingknifemodel.drawdifftex(knifetextureptr);
913 if(bloody[i]==1)throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
914 if(bloody[i]==2)throwingknifemodel.drawdifftex(bloodknifetextureptr);
919 glEnable(GL_LIGHTING);
920 if(!bloody[i]||!bloodtoggle)swordmodel.drawdifftex(swordtextureptr);
923 if(bloody[i]==1)swordmodel.drawdifftex(lightbloodswordtextureptr);
924 if(bloody[i]==2)swordmodel.drawdifftex(bloodswordtextureptr);
929 glEnable(GL_LIGHTING);
930 staffmodel.drawdifftex(stafftextureptr);
936 lastdrawnposition[i]=position[i];
937 lastdrawntippoint[i]=tippoint[i];
938 lastdrawnrotation1[i]=rotation1[i];
939 lastdrawnrotation2[i]=rotation2[i];
940 lastdrawnrotation3[i]=rotation3[i];
941 lastdrawnbigrotation[i]=bigrotation[i];
942 lastdrawnbigtilt[i]=bigtilt[i];
943 lastdrawnbigtilt2[i]=bigtilt2[i];
944 lastdrawnsmallrotation[i]=smallrotation[i];
945 lastdrawnsmallrotation2[i]=smallrotation2[i];
946 if(owner[i]!=-1)lastdrawnanim[i]=player[owner[i]].currentanimation;
950 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
953 glTranslatef(position[i].x,position[i].y-.02,position[i].z);
954 glRotatef(bigrotation[i],0,1,0);
955 glRotatef(bigtilt2[i],1,0,0);
956 glRotatef(bigtilt[i],0,0,1);
957 glRotatef(-rotation1[i]+90,0,1,0);
958 glRotatef(-rotation2[i]+90,0,0,1);
959 glRotatef(-rotation3[i],0,1,0);
960 glRotatef(smallrotation[i],1,0,0);
961 glRotatef(smallrotation2[i],0,1,0);
962 glTranslatef(0,0,length[i]);
963 glGetFloatv(GL_MODELVIEW_MATRIX,M);
972 shinepoint=position[i];
973 Sprite::MakeSprite(weaponshinesprite, shinepoint,nothingpoint, 1,1,1,multiplier*2, 1);
974 Sprite::speed[Sprite::numsprites-1]=4;
975 Sprite::alivetime[Sprite::numsprites-1]=.3;
976 shinepoint=tippoint[i];
977 Sprite::MakeSprite(weaponshinesprite, shinepoint,nothingpoint, 1,1,1,multiplier*2, 1);
978 Sprite::speed[Sprite::numsprites-1]=4;
979 Sprite::alivetime[Sprite::numsprites-1]=.3;*/
989 // Model throwingknifemodel;
991 lightbloodknifetextureptr = 0;
992 bloodknifetextureptr = 0;
996 lightbloodswordtextureptr = 0;
997 bloodswordtextureptr = 0;
1000 stafftextureptr = 0;
1005 if (stafftextureptr) glDeleteTextures( 1, &stafftextureptr );
1006 if (knifetextureptr) glDeleteTextures( 1, &knifetextureptr );
1007 if (lightbloodknifetextureptr) glDeleteTextures( 1, &lightbloodknifetextureptr );
1008 if (bloodknifetextureptr) glDeleteTextures( 1, &bloodknifetextureptr );
1009 if (swordtextureptr) glDeleteTextures( 1, &swordtextureptr );
1010 if (lightbloodswordtextureptr) glDeleteTextures( 1, &lightbloodswordtextureptr );
1011 if (bloodswordtextureptr) glDeleteTextures( 1, &bloodswordtextureptr );