]> git.jsancho.org Git - lugaru.git/blob - Source/Weapons.cpp
Weapon clean up.
[lugaru.git] / Source / Weapons.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
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.
10
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.
14
15 See the GNU General Public License for more details.
16
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.
20 */
21
22 /**> HEADER FILES <**/
23 #include "Weapons.h"
24 #include "openal_wrapper.h"
25 #include "Animation.h"
26 #include "Sounds.h"
27 #include "Game.h"
28 #include "Awards.h"
29
30 extern float multiplier;
31 extern Terrain terrain;
32 extern float gravity;
33 extern int environment;
34 extern int detail;
35 extern FRUSTUM frustum;
36 extern XYZ viewer;
37 extern float realmultiplier;
38 extern int slomo;
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;
45 extern bool osx;
46 extern bool autoslomo;
47 extern float camerashake;
48 extern float woozy;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
52 extern bool freeze;
53 extern int tutoriallevel;
54 extern int numthrowkill;
55
56 Model Weapon::throwingknifemodel;
57 GLuint Weapon::knifetextureptr = 0;
58 GLuint Weapon::lightbloodknifetextureptr = 0;
59 GLuint Weapon::bloodknifetextureptr = 0;
60
61 Model Weapon::swordmodel;
62 GLuint Weapon::swordtextureptr = 0;
63 GLuint Weapon::lightbloodswordtextureptr = 0;
64 GLuint Weapon::bloodswordtextureptr = 0;
65
66 Model Weapon::staffmodel;
67 GLuint Weapon::stafftextureptr = 0;
68
69 Weapon::Weapon(int t, int o) : owner(o) {
70         setType(t);
71         bloody=0;
72         blooddrip=0;
73         blooddripdelay=0;
74         onfire=0;
75         flamedelay=0;
76         damage=0;
77         position=-1000;
78         tippoint=-1000;
79 }
80
81 void Weapon::setType(int t) {
82         type = t;
83         if(type==sword){
84                 mass=1.5;
85                 tipmass=1;
86                 length=.8;
87         }
88         if(type==staff){
89                 mass=2;
90                 tipmass=1;
91                 length=1.5;
92         }
93         if(type==knife){
94                 mass=1;
95                 tipmass=1.2;
96                 length=.25;
97         }
98 }
99
100 void Weapon::DoStuff() {
101         static int i,whichpatchx,whichpatchz,j,k,whichhit,m;
102         static XYZ start,end,colpoint,normalrot,footvel,footpoint;
103         static XYZ terrainnormal;
104         static XYZ vel;
105         static XYZ midp;
106         static XYZ newpoint1,newpoint2;
107         static float friction=3.5;
108         static float elasticity=.4;
109         static XYZ bounceness;
110         static float frictionness;
111         static float moveamount;
112         int closestline;
113         static float closestdistance;
114         static float distance;
115         static XYZ point[3];
116         static XYZ closestpoint;
117         static XYZ closestswordpoint;
118         static XYZ extramove;
119         static float proportion;
120         static float tempmult;
121         
122         if(owner!=-1){
123                 oldowner=owner;
124         }
125         if(damage>=2&&type==staff&&owner!=-1){
126                 emit_sound_at(staffbreaksound, tippoint);
127                 XYZ tempvel;
128                 XYZ speed;
129                 //speed=(tippoint-oldtippoint)/multiplier/6;
130                 speed=0;
131                 for(j=0;j<40;j++){
132                         tempvel.x=float(abs(Random()%100)-50)/20;
133                         tempvel.y=float(abs(Random()%100)-50)/20;
134                         tempvel.z=float(abs(Random()%100)-50)/20;
135                         tempvel+=speed;
136                         Sprite::MakeSprite(splintersprite, position+(tippoint-position)*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
137                 }
138                 int tempowner;
139                 tempowner=owner;
140                 owner=-1;
141                 hitsomething=0;
142                 missed=1;
143                 freetime=0;
144                 firstfree=1;
145                 position=0;
146                 physics=0;
147                 if(tempowner!=-1){
148                         player[tempowner].num_weapons--;
149                         if(player[tempowner].num_weapons){
150                                 player[tempowner].weaponids[0]=player[tempowner].weaponids[player[tempowner].num_weapons];
151                                 if(player[tempowner].weaponstuck==player[tempowner].num_weapons)player[tempowner].weaponstuck=0;
152                         }
153                         player[tempowner].weaponactive=-1;
154                 }
155         }
156         oldposition=position;
157         oldtippoint=tippoint;
158         if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&!physics){
159                 position+=velocity*multiplier;
160                 tippoint+=velocity*multiplier;
161                 whichpatchx=position.x/(terrain.size/subdivision*terrain.scale);
162                 whichpatchz=position.z/(terrain.size/subdivision*terrain.scale);
163                 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
164                         if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
165                                 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
166                                         k=terrain.patchobjects[whichpatchx][whichpatchz][j];
167                                         start=oldtippoint;
168                                         end=tippoint;
169                                         whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
170                                         if(whichhit!=-1){
171                                                 if(objects.type[k]==treetrunktype){
172                                                         objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),.1,1,Random()%360);
173                                                         normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0);
174                                                         velocity=0;
175                                                         if(type==knife)position=colpoint-normalrot*.1;
176                                                         if(type==sword)position=colpoint-normalrot*.2;
177                                                         if(type==staff)position=colpoint-normalrot*.2;
178                                                         XYZ temppoint1,temppoint2,tempforward;
179                                                         float distance;
180
181                                                         temppoint1=0;
182                                                         temppoint2=normalrot;
183                                                         distance=findDistance(&temppoint1,&temppoint2);
184                                                         rotation2=asin((temppoint1.y-temppoint2.y)/distance);
185                                                         rotation2*=360/6.28;
186                                                         temppoint1.y=0;
187                                                         temppoint2.y=0;
188                                                         rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
189                                                         rotation1*=360/6.28;
190                                                         if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
191
192                                                         rotation3=0;
193                                                         smallrotation=90;
194                                                         smallrotation2=0;
195                                                         bigtilt=0;
196                                                         bigtilt2=0;
197                                                         bigrotation=0;
198
199                                                         emit_sound_at(knifesheathesound, position, 128.);
200
201                                                         bloody=0;
202
203                                                         Sprite::MakeSprite(cloudimpactsprite, position,velocity, 1,1,1, .8, .3);
204                                                 }
205                                                 else {
206                                                         physics=1;
207                                                         firstfree=1;
208                                                         position-=velocity*multiplier;
209                                                         tippoint-=velocity*multiplier;
210                                                         tipvelocity=velocity;
211                                                 }
212                                         }
213                                 }
214                         }
215                         if(velocity.x||velocity.y||velocity.z)
216                                 for(j=0;j<numplayers;j++){
217                                         footvel=0;
218                                         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;
219                                         if(owner==-1&&findDistancefastflat(&position,&player[j].coords)<1.5&&findDistancefast(&position,&player[j].coords)<4&&player[j].weaponstuck==-1&&!player[j].skeleton.free&&j!=oldowner){
220                                                 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){
221                                                         bool caught=0;
222                                                         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)){
223                                                                 emit_sound_at(knifedrawsound, player[j].coords, 128.);
224
225                                                                 player[j].weaponactive=0;
226                                                                 player[j].targetanimation=removeknifeanim;
227                                                                 player[j].targetframe=1;
228                                                                 player[j].target=1;
229                                                                 owner=player[j].id;
230                                                                 if(player[j].num_weapons>0){
231                                                                         player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
232                                                                 }
233                                                                 player[j].num_weapons++;
234                                                                 player[j].weaponids[0]=i;
235
236                                                                 player[j].aitype=attacktypecutoff;
237                                                         }
238                                                         else {
239                                                                 if(j!=0)numthrowkill++;
240                                                                 player[j].num_weapons++;
241                                                                 player[j].weaponstuck=player[j].num_weapons-1;
242                                                                 if(normaldotproduct(player[j].facing,velocity)>0)player[j].weaponstuckwhere=1;
243                                                                 else player[j].weaponstuckwhere=0;
244
245                                                                 player[j].weaponids[player[j].num_weapons-1]=i;
246
247                                                                 player[j].RagDoll(0);
248                                                                 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity*2;
249                                                                 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity*2;
250                                                                 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity*2;
251                                                                 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity*2;
252                                                                 //player[j].Puff(abdomen);
253                                                                 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
254                                                                 if(tutoriallevel==1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
255                                                                 footvel=tippoint-position;
256                                                                 Normalise(&footvel);
257                                                                 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
258
259                                                                 if(tutoriallevel!=1){
260                                                                         if(player[j].weaponstuckwhere==0)player[j].DoBloodBig(2,205);
261                                                                         if(player[j].weaponstuckwhere==1)player[j].DoBloodBig(2,200);
262                                                                         player[j].damage+=200/player[j].armorhigh;
263                                                                         player[j].deathbleeding=1;
264                                                                         player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
265                                                                         owner=j;
266                                                                         bloody=2;
267                                                                         blooddrip=5;
268                                                                 }
269
270                                                                 emit_sound_at(fleshstabsound, position, 128.);
271
272                                                                 if(animation[player[0].targetanimation].height==highheight)
273                                                                   award_bonus(0, ninja);
274                                                                 else
275                                                                   award_bonus(0, Bullseyebonus);
276                                                         }
277                                                 }
278                                                 else missed=1;
279                                         }
280                                 }
281                                 if(position.y<terrain.getHeight(position.x,position.z)){
282                                         if(terrain.getOpacity(position.x,position.z)<.2){
283                                                 velocity=0;
284                                                 if(terrain.lineTerrain(oldposition,position,&colpoint)!=-1){
285                                                         position=colpoint*terrain.scale;
286                                                 }
287                                                 else position.y=terrain.getHeight(position.x,position.z);
288
289                                                 terrain.MakeDecal(shadowdecalpermanent,position,.06,.5,0);
290                                                 normalrot=terrain.getNormal(position.x,position.z)*-1;
291                                                 velocity=0;
292                                                 //position-=normalrot*.1;
293                                                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
294                                                 glPushMatrix();
295                                                         GLfloat M[16];
296                                                         glLoadIdentity();
297                                                         glRotatef(bigrotation,0,1,0);
298                                                         glRotatef(bigtilt2,1,0,0);
299                                                         glRotatef(bigtilt,0,0,1);
300                                                         glRotatef(-rotation1+90,0,1,0);
301                                                         glRotatef(-rotation2+90,0,0,1);
302                                                         glRotatef(-rotation3,0,1,0);
303                                                         glRotatef(smallrotation,1,0,0);
304                                                         glRotatef(smallrotation2,0,1,0);
305                                                         glTranslatef(0,0,1);
306                                                         glGetFloatv(GL_MODELVIEW_MATRIX,M);
307                                                         tippoint.x=M[12];
308                                                         tippoint.y=M[13];
309                                                         tippoint.z=M[14];
310                                                 glPopMatrix();
311                                                 position-=tippoint*.15;
312                                                 XYZ temppoint1,temppoint2,tempforward;
313                                                 float distance;
314
315                                                 rotation3=0;
316                                                 smallrotation=90;
317                                                 smallrotation2=0;
318                                                 bigtilt=0;
319                                                 bigtilt2=0;
320                                                 bigrotation=0;
321
322                                                 emit_sound_at(knifesheathesound, position, 128.);
323
324                                                 XYZ terrainlight;
325                                                 terrainlight=terrain.getLighting(position.x,position.z);
326                                                 if(environment==snowyenvironment){
327                                                         if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
328                                                 }
329                                                 else if(environment==grassyenvironment){
330                                                         if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
331                                                 }
332                                                 else if(environment==desertenvironment){
333                                                         if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
334                                                 }
335
336                                                 bloody=0;
337                                         }
338                                         else {
339                                                 physics=1;
340                                                 firstfree=1;
341                                                 position-=velocity*multiplier;
342                                                 tippoint-=velocity*multiplier;
343                                                 tipvelocity=velocity;
344                                         }
345                                 }
346                                 if(velocity.x!=0||velocity.z!=0||velocity.y!=0){
347                                         velocity.y+=gravity*multiplier;
348
349                                         XYZ temppoint1,temppoint2,tempforward;
350                                         float distance;
351
352                                         temppoint1=0;
353                                         temppoint2=velocity;
354                                         distance=findDistance(&temppoint1,&temppoint2);
355                                         rotation2=asin((temppoint1.y-temppoint2.y)/distance);
356                                         rotation2*=360/6.28;
357                                         temppoint1.y=0;
358                                         temppoint2.y=0;
359                                         rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
360                                         rotation1*=360/6.28;
361                                         rotation3=0;
362                                         smallrotation=90;
363                                         smallrotation2=0;
364                                         bigtilt=0;
365                                         bigtilt2=0;
366                                         bigrotation=0;
367                                         if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
368                                 }
369         }
370         //Sword physics
371         XYZ mid;
372         XYZ oldmid;
373         XYZ oldmid2;
374
375         tempmult=multiplier;
376         multiplier/=10;
377         for(int l=0;l<10;l++){
378                 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&physics){
379                         //move
380                         position+=velocity*multiplier;
381                         tippoint+=tipvelocity*multiplier;
382
383                         //Length constrain
384                         midp=(position*mass+tippoint*tipmass)/(mass+tipmass);
385                         vel=tippoint-midp;
386                         Normalise(&vel);
387                         newpoint1=midp-vel*length*(tipmass/(mass+tipmass));
388                         newpoint2=midp+vel*length*(mass/(mass+tipmass));
389                         if(!freeze){
390                                 if(freetime>.04)velocity=velocity+(newpoint1-position)/multiplier;
391                                 if(freetime>.04)tipvelocity=tipvelocity+(newpoint2-tippoint)/multiplier;
392                         }
393                         position=newpoint1;
394                         tippoint=newpoint2;
395
396
397                         //Object collisions
398                         whichpatchx=(position.x)/(terrain.size/subdivision*terrain.scale);
399                         whichpatchz=(position.z)/(terrain.size/subdivision*terrain.scale);
400                         if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
401                                 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
402                                         for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
403                                                 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
404
405                                                 if(firstfree){
406                                                         if(type!=staff){
407                                                                 start=position-(tippoint-position)/5;
408                                                                 end=tippoint+(tippoint-position)/30;
409                                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
410                                                                 if(whichhit!=-1){
411                                                                         XYZ diff;
412                                                                         diff=(colpoint-tippoint);
413                                                                         Normalise(&diff);
414                                                                         hitsomething=1;
415
416                                                                         position+=(colpoint-tippoint)+diff*.05;
417                                                                         tippoint=colpoint+diff*.05;
418                                                                         oldposition=position;
419                                                                         oldtippoint=tippoint;
420                                                                 }
421                                                         }
422                                                         if(type==staff){
423                                                                 start=tippoint-(position-tippoint)/5;
424                                                                 end=position+(position-tippoint)/30;
425                                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
426                                                                 if(whichhit!=-1){
427                                                                         XYZ diff;
428                                                                         diff=(colpoint-position);
429                                                                         Normalise(&diff);
430                                                                         hitsomething=1;
431
432                                                                         tippoint+=(colpoint-position)+diff*.05;
433                                                                         position=colpoint+diff*.05;
434                                                                         oldtippoint=tippoint;
435                                                                         oldposition=tippoint;
436                                                                 }
437                                                         }
438                                                 }
439
440                                                 start=oldposition;
441                                                 end=position;
442                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
443                                                 if(whichhit!=-1){
444                                                         hitsomething=1;
445                                                         position=colpoint;
446                                                         terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
447                                                         ReflectVector(&velocity,&terrainnormal);
448                                                         position+=terrainnormal*.002;
449
450                                                         bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
451                                                         if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
452                                                         frictionness=abs(normaldotproduct(velocity,terrainnormal));
453                                                         velocity-=bounceness;
454                                                         if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
455                                                         else velocity=0;
456                                                         velocity+=bounceness*elasticity;
457
458                                                         if(findLengthfast(&bounceness)>1){
459                                                                 int whichsound;
460                                                                 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
461                                                                 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
462                                                                 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
463                                                         }
464                                                 }
465                                                 start=oldtippoint;
466                                                 end=tippoint;
467                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
468                                                 if(whichhit!=-1){
469                                                         hitsomething=1;
470                                                         tippoint=colpoint;
471                                                         terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
472                                                         ReflectVector(&tipvelocity,&terrainnormal);
473                                                         tippoint+=terrainnormal*.002;
474
475                                                         bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
476                                                         if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
477                                                         frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
478                                                         tipvelocity-=bounceness;
479                                                         if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
480                                                         else tipvelocity=0;
481                                                         tipvelocity+=bounceness*elasticity;
482
483                                                         if(findLengthfast(&bounceness)>1){
484                                                                 int whichsound;
485                                                                 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
486                                                                 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
487                                                                 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
488                                                         }
489                                                 }
490
491                                                 if((objects.type[k]!=boxtype&&objects.type[k]!=platformtype&&objects.type[k]!=walltype&&objects.type[k]!=weirdtype)||objects.rotation2[k]!=0)
492                                                         for(m=0;m<2;m++){
493                                                                 mid=(position*(21+(float)m*10)+tippoint*(19-(float)m*10))/40;
494                                                                 oldmid2=mid;
495                                                                 oldmid=(oldposition*(21+(float)m*10)+oldtippoint*(19-(float)m*10))/40;
496
497                                                                 start=oldmid;
498                                                                 end=mid;
499                                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
500                                                                 if(whichhit!=-1){
501                                                                         hitsomething=1;
502                                                                         mid=colpoint;
503                                                                         terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
504                                                                         ReflectVector(&velocity,&terrainnormal);
505
506                                                                         bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
507                                                                         if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
508                                                                         frictionness=abs(normaldotproduct(velocity,terrainnormal));
509                                                                         velocity-=bounceness;
510                                                                         if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
511                                                                         else velocity=0;
512                                                                         velocity+=bounceness*elasticity;
513
514                                                                         if(findLengthfast(&bounceness)>1){
515                                                                                 int whichsound;
516                                                                                 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
517                                                                                 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
518                                                                                 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
519                                                                         }
520                                                                         position+=(mid-oldmid2)*(20/(1+(float)m*10));
521                                                                 }
522
523                                                                 mid=(position*(19-(float)m*10)+tippoint*(21+(float)m*10))/40;
524                                                                 oldmid2=mid;
525                                                                 oldmid=(oldposition*(19-(float)m*10)+oldtippoint*(21+(float)m*10))/40;
526
527                                                                 start=oldmid;
528                                                                 end=mid;
529                                                                 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
530                                                                 if(whichhit!=-1){
531                                                                         hitsomething=1;
532                                                                         mid=colpoint;
533                                                                         terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
534                                                                         ReflectVector(&tipvelocity,&terrainnormal);
535
536                                                                         bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
537                                                                         if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
538                                                                         frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
539                                                                         tipvelocity-=bounceness;
540                                                                         if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
541                                                                         else tipvelocity=0;
542                                                                         tipvelocity+=bounceness*elasticity;
543
544                                                                         if(findLengthfast(&bounceness)>1){
545                                                                                 int whichsound;
546                                                                                 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
547                                                                                 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
548                                                                                 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
549                                                                         }
550                                                                         tippoint+=(mid-oldmid2)*(20/(1+(float)m*10));
551                                                                 }
552                                                         }
553                                                 else
554                                                 {
555                                                         start=position;
556                                                         end=tippoint;
557                                                         whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
558                                                         if(whichhit!=-1){
559                                                                 hitsomething=1;
560                                                                 closestdistance=-1;
561                                                                 closestswordpoint=colpoint;//(position+tippoint)/2;
562                                                                 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.rotation[k],0)+objects.position[k];
563                                                                 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.rotation[k],0)+objects.position[k];
564                                                                 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.rotation[k],0)+objects.position[k];
565                                                                 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint ))
566                                                                         if(distance<closestdistance||closestdistance==-1){
567                                                                                 closestpoint=colpoint;
568                                                                                 closestdistance=distance;
569                                                                                 closestline=0;
570                                                                         }
571                                                                         if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint ))
572                                                                                 if(distance<closestdistance||closestdistance==-1){
573                                                                                         closestpoint=colpoint;
574                                                                                         closestdistance=distance;
575                                                                                         closestline=1;
576                                                                                 }
577                                                                                 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint ))
578                                                                                         if(distance<closestdistance||closestdistance==-1){
579                                                                                                 closestpoint=colpoint;
580                                                                                                 closestdistance=distance;
581                                                                                                 closestline=2;
582                                                                                         }
583                                                                                         if(closestdistance!=-1&&isnormal(closestdistance)){
584                                                                                                 if(DistancePointLine(&closestpoint, &position, &tippoint, &distance,&colpoint )){
585                                                                                                         closestswordpoint=colpoint;
586                                                                                                         velocity+=(closestpoint-closestswordpoint);
587                                                                                                         tipvelocity+=(closestpoint-closestswordpoint);
588                                                                                                         position+=(closestpoint-closestswordpoint);
589                                                                                                         tippoint+=(closestpoint-closestswordpoint);
590                                                                                                 }
591                                                                                         }
592                                                         }
593                                                 }
594
595                                         }
596                                 }
597                                 //Terrain collisions
598                                 whichhit=terrain.lineTerrain(oldposition,position,&colpoint);
599                                 if(whichhit!=-1||position.y<terrain.getHeight(position.x,position.z)){
600                                         hitsomething=1;
601                                         if(whichhit!=-1)position=colpoint*terrain.scale;
602                                         else position.y=terrain.getHeight(position.x,position.z);
603
604                                         terrainnormal=terrain.getNormal(position.x,position.z);
605                                         ReflectVector(&velocity,&terrainnormal);
606                                         position+=terrainnormal*.002;
607                                         bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
608                                         if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
609                                         frictionness=abs(normaldotproduct(velocity,terrainnormal));
610                                         velocity-=bounceness;
611                                         if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
612                                         else velocity=0;
613                                         if(terrain.getOpacity(position.x,position.z)<.2)velocity+=bounceness*elasticity*.3;
614                                         else velocity+=bounceness*elasticity;
615 //if (type==knife) printf("velocity of knife %d now %f,%f,%f.\n", i, velocity.x, velocity.y, velocity.z);
616                                         if(findLengthfast(&bounceness)>1){
617                                                 int whichsound;
618                                                 if(terrain.getOpacity(position.x,position.z)>.2){
619                                                         if(type==staff)whichsound=footstepsound3+abs(Random()%2);
620                                                         if(type!=staff)whichsound=clank1sound+abs(Random()%4);
621                                                 }
622                                                 else whichsound=footstepsound+abs(Random()%2);
623                                                 emit_sound_at(whichsound, position,
624                                                                   findLengthfast(&bounceness)
625                                                                   * (terrain.getOpacity(position.x,position.z) > .2
626                                                                  ? 128.
627                                                                  : 32.));
628
629                                                 if(terrain.getOpacity(position.x,position.z)<.2){
630                                                         XYZ terrainlight;
631                                                         terrainlight=terrain.getLighting(position.x,position.z);
632                                                         if(environment==snowyenvironment){
633                                                                 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
634                                                         }
635                                                         else if(environment==grassyenvironment){
636                                                                 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
637                                                         }
638                                                         else if(environment==desertenvironment){
639                                                                 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
640                                                         }
641                                                 }
642                                         }
643                                 }
644                                 whichhit=terrain.lineTerrain(oldtippoint,tippoint,&colpoint);
645                                 if(whichhit!=-1||tippoint.y<terrain.getHeight(tippoint.x,tippoint.z)){
646                                         if(whichhit!=-1)tippoint=colpoint*terrain.scale;
647                                         else tippoint.y=terrain.getHeight(tippoint.x,tippoint.z);
648
649                                         terrainnormal=terrain.getNormal(tippoint.x,tippoint.z);
650                                         ReflectVector(&tipvelocity,&terrainnormal);
651                                         tippoint+=terrainnormal*.002;
652                                         bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
653                                         if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
654                                         frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
655                                         tipvelocity-=bounceness;
656                                         if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
657                                         else tipvelocity=0;
658                                         if(terrain.getOpacity(tippoint.x,tippoint.z)<.2)tipvelocity+=bounceness*elasticity*.3;
659                                         else tipvelocity+=bounceness*elasticity;
660 //if (type==knife) printf("tipvelocity of knife %d now %f,%f,%f.\n", i, tipvelocity.x, tipvelocity.y, tipvelocity.z);
661
662                                         if(findLengthfast(&bounceness)>1){
663                                                 int whichsound;
664                                                 if(terrain.getOpacity(tippoint.x,tippoint.z)>.2){
665                                                         if(type==staff)whichsound=footstepsound3+abs(Random()%2);
666                                                         if(type!=staff)whichsound=clank1sound+abs(Random()%4);
667                                                 }
668                                                 else whichsound=footstepsound+abs(Random()%2);
669                                                 emit_sound_at(whichsound, tippoint,
670                                                                   findLengthfast(&bounceness)
671                                                                   * (terrain.getOpacity(tippoint.x,tippoint.z) > .2
672                                                                  ? 128.
673                                                                  : 32.));
674
675                                                 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2){
676                                                         XYZ terrainlight;
677                                                         terrainlight=terrain.getLighting(tippoint.x,tippoint.z);
678                                                         if(environment==snowyenvironment){
679                                                                 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
680                                                         }
681                                                         else if(environment==grassyenvironment){
682                                                                 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
683                                                         }
684                                                         else if(environment==desertenvironment){
685                                                                 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
686                                                         }
687                                                 }
688                                         }
689                                 }
690
691                                 //Edges
692                                 mid=position+tippoint;
693                                 mid/=2;
694                                 mid+=(position-mid)/20;
695                                 oldmid=mid;
696                                 if(mid.y<terrain.getHeight(mid.x,mid.z)){
697                                         hitsomething=1;
698                                         mid.y=terrain.getHeight(mid.x,mid.z);
699
700                                         terrainnormal=terrain.getNormal(mid.x,mid.z);
701                                         ReflectVector(&velocity,&terrainnormal);
702                                         //mid+=terrainnormal*.002;
703                                         bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
704                                         if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
705                                         frictionness=abs(normaldotproduct(velocity,terrainnormal));
706                                         velocity-=bounceness;
707                                         if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
708                                         else velocity=0;
709                                         if(terrain.getOpacity(mid.x,mid.z)<.2)velocity+=bounceness*elasticity*.3;
710                                         else velocity+=bounceness*elasticity;
711
712                                         if(findLengthfast(&bounceness)>1){
713                                                 int whichsound;
714                                                 if(terrain.getOpacity(mid.x,mid.z)>.2){
715                                                         if(type==staff)whichsound=footstepsound3+abs(Random()%2);
716                                                         if(type!=staff)whichsound=clank1sound+abs(Random()%4);
717                                                 }
718                                                 else whichsound=footstepsound+abs(Random()%2);
719                                                 emit_sound_at(whichsound, mid,
720                                                                   findLengthfast(&bounceness)
721                                                                   * (terrain.getOpacity(position.x,position.z) > .2
722                                                                  ? 128.
723                                                                  : 32.));
724                                         }
725                                         position+=(mid-oldmid)*20;
726                                 }
727
728                                 mid=position+tippoint;
729                                 mid/=2;
730                                 mid+=(tippoint-mid)/20;
731                                 oldmid=mid;
732                                 if(mid.y<terrain.getHeight(mid.x,mid.z)){
733                                         hitsomething=1;
734                                         mid.y=terrain.getHeight(mid.x,mid.z);
735
736                                         terrainnormal=terrain.getNormal(mid.x,mid.z);
737                                         ReflectVector(&tipvelocity,&terrainnormal);
738                                         //mid+=terrainnormal*.002;
739                                         bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
740                                         if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
741                                         frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
742                                         tipvelocity-=bounceness;
743                                         if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
744                                         else tipvelocity=0;
745                                         if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity+=bounceness*elasticity*.3;
746                                         else tipvelocity+=bounceness*elasticity;
747
748                                         if(findLengthfast(&bounceness)>1){
749                                                 int whichsound;
750                                                 if(terrain.getOpacity(mid.x,mid.z)>.2){
751                                                         if(type==staff)whichsound=footstepsound3+abs(Random()%2);
752                                                         if(type!=staff)whichsound=clank1sound+abs(Random()%4);
753                                                 }
754                                                 else whichsound=footstepsound+abs(Random()%2);
755                                                 emit_sound_at(whichsound, mid,
756                                                                   findLengthfast(&bounceness)
757                                                                   * (terrain.getOpacity(position.x,position.z) > .2
758                                                                  ? 128.
759                                                                  : 32.));
760                                         }
761                                         tippoint+=(mid-oldmid)*20;
762                                 }
763                                 //Gravity
764                                 velocity.y+=gravity*multiplier;
765                                 tipvelocity.y+=gravity*multiplier;
766                                 //position.y+=gravity*multiplier*multiplier;
767                                 //tippoint.y+=gravity*multiplier*multiplier;
768
769                                 //Rotation
770                                 XYZ temppoint1,temppoint2,tempforward;
771                                 float distance;
772
773                                 temppoint1=position;
774                                 temppoint2=tippoint;
775                                 distance=findDistance(&temppoint1,&temppoint2);
776                                 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
777                                 rotation2*=360/6.28;
778                                 temppoint1.y=0;
779                                 temppoint2.y=0;
780                                 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
781                                 rotation1*=360/6.28;
782                                 rotation3=0;
783                                 smallrotation=90;
784                                 smallrotation2=0;
785                                 bigtilt=0;
786                                 bigtilt2=0;
787                                 bigrotation=0;
788                                 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
789
790                                 //Stop moving
791                                 if(findLengthfast(&velocity)<.3&&findLengthfast(&tipvelocity)<.3&&hitsomething){
792                                         freetime+=multiplier;
793                                 }
794
795                                 //velocity=(position-oldposition)/multiplier;
796                                 //tipvelocity==(tippoint[i-+oldtippoint)/multiplier;
797                                 if(freetime>.4){
798                                         velocity=0;
799                                         tipvelocity=0;
800                                 }
801                                 firstfree=0;
802                 }
803         }
804         multiplier=tempmult;
805         if(blooddrip&&bloody){
806                 blooddripdelay-=blooddrip*multiplier/2;
807                 blooddrip-=multiplier;
808                 if(blooddrip<0)blooddrip=0;
809                 if(blooddrip>5)blooddrip=5;
810                 if(blooddripdelay<0&&bloodtoggle){
811                         blooddripdelay=1;
812                         XYZ bloodvel;
813                         XYZ bloodloc;
814                         bloodloc=position+(tippoint-position)*.7;
815                         bloodloc.y-=.05;
816                         if(bloodtoggle){
817                                 bloodvel=0;
818                                 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
819                         }
820                 }
821         }
822         if(onfire){
823                 flamedelay-=multiplier;
824                 if(onfire&&flamedelay<=0){
825                         flamedelay=.020;
826                         flamedelay-=multiplier;
827                         normalrot=0;
828                         if(owner!=-1){
829                                 normalrot=player[owner].velocity;
830                         }
831                         normalrot.y+=1;
832                         if(owner!=-1){
833                                 if(player[owner].onterrain){
834                                         normalrot.y=1;
835                                 }
836                         }
837                         Sprite::MakeSprite(weaponflamesprite, position+tippoint*(((float)abs(Random()%100))/600+.05),normalrot, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*1/3, 1);
838                         Sprite::setLastSpriteSpeed(4);
839                         Sprite::setLastSpriteAlivetime(.3);
840                 }
841         }
842
843         if(!onfire&&owner==-1&&type!=staff){
844                 flamedelay-=multiplier;
845                 if(flamedelay<=0){
846                         flamedelay=.020;
847                         flamedelay-=multiplier;
848                         normalrot=0;
849                         if(Random()%50==0&&findDistancefast(&position,&viewer)>80){
850                                 XYZ shinepoint;
851                                 shinepoint=position+(tippoint-position)*(((float)abs(Random()%100))/100);
852                                 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
853                                 Sprite::setLastSpriteSpeed(4);
854                                 Sprite::setLastSpriteAlivetime(.3);
855                         }
856                 }
857         }
858 }
859
860 void Weapons::DoStuff() {
861         //Move
862         for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
863                 weapon->DoStuff();
864         }
865 }
866
867 void Weapon::Draw() {
868         static int i,j;
869         static XYZ terrainlight;
870         static GLfloat M[16];
871         static bool draw;
872         
873         if((frustum.SphereInFrustum(position.x,position.y,position.z,1)&&findDistancefast(&viewer,&position)<viewdistance*viewdistance))
874         {
875                 draw=0;
876                 if(owner==-1)
877                 {
878                         draw=1;
879                         if(velocity.x&&!physics)drawhowmany=10;
880                         else drawhowmany=1;
881                 }
882                 if(owner!=-1)
883                 {
884                         if(player[owner].occluded<25)
885                                 if((frustum.SphereInFrustum(player[owner].coords.x,player[owner].coords.y+player[owner].scale*3,player[owner].coords.z,player[owner].scale*8)&&findDistancefast(&viewer,&player[owner].coords)<viewdistance*viewdistance)||player[owner].skeleton.free==3)
886                                         draw=1;
887                         if((player[owner].targetanimation==knifeslashstartanim||player[owner].targetanimation==swordsneakattackanim||(player[owner].currentanimation==staffhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffgroundsmashanim&&player[owner].currentframe>1)||(player[owner].targetanimation==swordslashanim&&player[owner].targetframe<7)||player[owner].targetanimation==crouchstabanim||player[owner].targetanimation==swordslashreversalanim||player[owner].targetanimation==swordslashreversedanim||player[owner].targetanimation==knifefollowanim||player[owner].targetanimation==swordgroundstabanim||player[owner].targetanimation==knifethrowanim)&&player[owner].targetanimation==lastdrawnanim&&!player[owner].skeleton.free)
888                         {
889                                 drawhowmany=10;
890                         }
891                         else drawhowmany=1;
892                         if(player[owner].targetanimation==swordgroundstabanim)
893                         {
894                                 lastdrawnrotation1=rotation1;
895                                 lastdrawnrotation2=rotation2;
896                                 lastdrawnrotation3=rotation3;
897                                 lastdrawnbigrotation=bigrotation;
898                                 lastdrawnbigtilt=bigtilt;
899                                 lastdrawnbigtilt2=bigtilt2;
900                                 lastdrawnsmallrotation=smallrotation;
901                                 lastdrawnsmallrotation2=smallrotation2;
902                         }
903                 }
904                 if(draw)
905                 {
906                         terrainlight=terrain.getLighting(position.x,position.z);
907                         if(drawhowmany>0)
908                         {
909                                 glAlphaFunc(GL_GREATER, 0.01);
910                         }
911                         for(j=drawhowmany;j>0;j--)
912                         {
913                                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
914                                 glPushMatrix();
915                                         glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany);
916                                         if(owner!=-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)-.02+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
917                                         if(owner==-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
918                                         //glTranslatef(position.x,position.y-.02,position.z);
919                                         glRotatef(bigrotation*(((float)(j))/drawhowmany)+lastdrawnbigrotation*(1-((float)(j))/drawhowmany),0,1,0);
920                                         glRotatef(bigtilt2*(((float)(j))/drawhowmany)+lastdrawnbigtilt2*(1-((float)(j))/drawhowmany),1,0,0);
921                                         glRotatef(bigtilt*(((float)(j))/drawhowmany)+lastdrawnbigtilt*(1-((float)(j))/drawhowmany),0,0,1);
922                                         glRotatef(-rotation1*(((float)(j))/drawhowmany)-lastdrawnrotation1*(1-((float)(j))/drawhowmany)+90,0,1,0);
923                                         glRotatef(-rotation2*(((float)(j))/drawhowmany)-lastdrawnrotation2*(1-((float)(j))/drawhowmany)+90,0,0,1);
924                                         glRotatef(-rotation3*(((float)(j))/drawhowmany)-lastdrawnrotation3*(1-((float)(j))/drawhowmany),0,1,0);
925                                         glRotatef(smallrotation*(((float)(j))/drawhowmany)+lastdrawnsmallrotation*(1-((float)(j))/drawhowmany),1,0,0);
926                                         glRotatef(smallrotation2*(((float)(j))/drawhowmany)+lastdrawnsmallrotation2*(1-((float)(j))/drawhowmany),0,1,0);
927
928                                         if(owner!=-1)
929                                         {
930                                                 if(player[owner].targetanimation==staffhitanim||player[owner].currentanimation==staffhitanim||player[owner].targetanimation==staffhitreversedanim||player[owner].currentanimation==staffhitreversedanim)
931                                                 {
932                                                         glTranslatef(0,0,-.3);
933                                                 }
934                                                 if(player[owner].targetanimation==staffgroundsmashanim||player[owner].currentanimation==staffgroundsmashanim||player[owner].targetanimation==staffspinhitreversedanim||player[owner].currentanimation==staffspinhitreversedanim||player[owner].targetanimation==staffspinhitanim||player[owner].currentanimation==staffspinhitanim)
935                                                 {
936                                                         glTranslatef(0,0,-.1);
937                                                 }
938                                         }
939
940                                         glEnable(GL_LIGHTING);
941                                         switch(type) {
942                                                 case knife:
943                                                         if(!bloody||!bloodtoggle)
944                                                                 throwingknifemodel.drawdifftex(knifetextureptr);
945                                                         if(bloodtoggle)
946                                                         {
947                                                                 if(bloody==1)
948                                                                         throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
949                                                                 if(bloody==2)
950                                                                         throwingknifemodel.drawdifftex(bloodknifetextureptr);
951                                                         }
952                                                         break;
953                                                 case sword:
954                                                         if(!bloody||!bloodtoggle)
955                                                                 swordmodel.drawdifftex(swordtextureptr);
956                                                         if(bloodtoggle)
957                                                         {
958                                                                 if(bloody==1)
959                                                                         swordmodel.drawdifftex(lightbloodswordtextureptr);
960                                                                 if(bloody==2)
961                                                                         swordmodel.drawdifftex(bloodswordtextureptr);
962                                                         }
963                                                         break;
964                                                 case staff:
965                                                         staffmodel.drawdifftex(stafftextureptr);
966                                                         break;
967                                         }
968
969                                 glPopMatrix();
970                         }
971
972                         lastdrawnposition=position;
973                         lastdrawntippoint=tippoint;
974                         lastdrawnrotation1=rotation1;
975                         lastdrawnrotation2=rotation2;
976                         lastdrawnrotation3=rotation3;
977                         lastdrawnbigrotation=bigrotation;
978                         lastdrawnbigtilt=bigtilt;
979                         lastdrawnbigtilt2=bigtilt2;
980                         lastdrawnsmallrotation=smallrotation;
981                         lastdrawnsmallrotation2=smallrotation2;
982                         if(owner!=-1)lastdrawnanim=player[owner].currentanimation;
983                 }
984                 if(owner!=-1)
985                 {
986                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
987                         glPushMatrix();
988                                 glLoadIdentity();
989                                 glTranslatef(position.x,position.y-.02,position.z);
990                                 glRotatef(bigrotation,0,1,0);
991                                 glRotatef(bigtilt2,1,0,0);
992                                 glRotatef(bigtilt,0,0,1);
993                                 glRotatef(-rotation1+90,0,1,0);
994                                 glRotatef(-rotation2+90,0,0,1);
995                                 glRotatef(-rotation3,0,1,0);
996                                 glRotatef(smallrotation,1,0,0);
997                                 glRotatef(smallrotation2,0,1,0);
998                                 glTranslatef(0,0,length);
999                                 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1000                                 tippoint.x=M[12];
1001                                 tippoint.y=M[13];
1002                                 tippoint.z=M[14];
1003                         glPopMatrix();
1004                 }
1005         }
1006 }
1007
1008 int Weapons::Draw()
1009 {
1010         glAlphaFunc(GL_GREATER, 0.9);
1011         glEnable(GL_TEXTURE_2D);
1012         glEnable(GL_BLEND);
1013         glEnable(GL_CULL_FACE);
1014         glCullFace(GL_FRONT);
1015         glDepthMask(1);
1016         
1017         for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1018                 weapon->Draw();
1019         }
1020         return 0;
1021 }
1022
1023 Weapons::Weapons()
1024 {
1025 }
1026
1027 Weapons::~Weapons()
1028 {
1029         if (Weapon::stafftextureptr) glDeleteTextures( 1, &Weapon::stafftextureptr );
1030         if (Weapon::knifetextureptr) glDeleteTextures( 1, &Weapon::knifetextureptr );
1031         if (Weapon::lightbloodknifetextureptr) glDeleteTextures( 1, &Weapon::lightbloodknifetextureptr );
1032         if (Weapon::bloodknifetextureptr) glDeleteTextures( 1, &Weapon::bloodknifetextureptr );
1033         if (Weapon::swordtextureptr) glDeleteTextures( 1, &Weapon::swordtextureptr );
1034         if (Weapon::lightbloodswordtextureptr) glDeleteTextures( 1, &Weapon::lightbloodswordtextureptr );
1035         if (Weapon::bloodswordtextureptr) glDeleteTextures( 1, &Weapon::bloodswordtextureptr );
1036 }
1037