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