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