2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /**> HEADER FILES <**/
24 #include "openal_wrapper.h"
25 #include "Animation.h"
30 extern float multiplier;
31 extern Terrain terrain;
33 extern int environment;
35 extern FRUSTUM frustum;
37 extern float realmultiplier;
39 extern float slomodelay;
40 extern bool cellophane;
41 extern float texdetail;
42 extern GLubyte bloodText[512*512*3];
43 extern int bloodtoggle;
44 extern Objects objects;
46 extern bool autoslomo;
47 extern float camerashake;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
53 extern int tutoriallevel;
54 extern int numthrowkill;
56 Model Weapon::throwingknifemodel;
57 GLuint Weapon::knifetextureptr = 0;
58 GLuint Weapon::lightbloodknifetextureptr = 0;
59 GLuint Weapon::bloodknifetextureptr = 0;
61 Model Weapon::swordmodel;
62 GLuint Weapon::swordtextureptr = 0;
63 GLuint Weapon::lightbloodswordtextureptr = 0;
64 GLuint Weapon::bloodswordtextureptr = 0;
66 Model Weapon::staffmodel;
67 GLuint Weapon::stafftextureptr = 0;
69 Weapon::Weapon(int t, int o) : owner(o) {
81 void Weapon::setType(int t) {
100 void Weapon::DoStuff() {
101 static int i,whichpatchx,whichpatchz,j,k,whichhit,m;
102 static XYZ start,end,colpoint,normalrot,footvel,footpoint;
103 static XYZ terrainnormal;
106 static XYZ newpoint1,newpoint2;
107 static float friction=3.5;
108 static float elasticity=.4;
109 static XYZ bounceness;
110 static float frictionness;
111 static float moveamount;
113 static float closestdistance;
114 static float distance;
116 static XYZ closestpoint;
117 static XYZ closestswordpoint;
118 static XYZ extramove;
119 static float proportion;
120 static float tempmult;
125 if(damage>=2&&type==staff&&owner!=-1){
126 emit_sound_at(staffbreaksound, tippoint);
129 //speed=(tippoint-oldtippoint)/multiplier/6;
132 tempvel.x=float(abs(Random()%100)-50)/20;
133 tempvel.y=float(abs(Random()%100)-50)/20;
134 tempvel.z=float(abs(Random()%100)-50)/20;
136 Sprite::MakeSprite(splintersprite, position+(tippoint-position)*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
148 player[tempowner].num_weapons--;
149 if(player[tempowner].num_weapons){
150 player[tempowner].weaponids[0]=player[tempowner].weaponids[player[tempowner].num_weapons];
151 if(player[tempowner].weaponstuck==player[tempowner].num_weapons)player[tempowner].weaponstuck=0;
153 player[tempowner].weaponactive=-1;
156 oldposition=position;
157 oldtippoint=tippoint;
158 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&!physics){
159 position+=velocity*multiplier;
160 tippoint+=velocity*multiplier;
161 whichpatchx=position.x/(terrain.size/subdivision*terrain.scale);
162 whichpatchz=position.z/(terrain.size/subdivision*terrain.scale);
163 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
164 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
165 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
166 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
169 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
171 if(objects.type[k]==treetrunktype){
172 objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),.1,1,Random()%360);
173 normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0);
175 if(type==knife)position=colpoint-normalrot*.1;
176 if(type==sword)position=colpoint-normalrot*.2;
177 if(type==staff)position=colpoint-normalrot*.2;
178 XYZ temppoint1,temppoint2,tempforward;
182 temppoint2=normalrot;
183 distance=findDistance(&temppoint1,&temppoint2);
184 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
188 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
190 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
199 emit_sound_at(knifesheathesound, position, 128.);
203 Sprite::MakeSprite(cloudimpactsprite, position,velocity, 1,1,1, .8, .3);
208 position-=velocity*multiplier;
209 tippoint-=velocity*multiplier;
210 tipvelocity=velocity;
215 if(velocity.x||velocity.y||velocity.z)
216 for(j=0;j<numplayers;j++){
218 footpoint=DoRotation((player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].position+player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].position)/2,0,player[j].rotation,0)*player[j].scale+player[j].coords;
219 if(owner==-1&&findDistancefastflat(&position,&player[j].coords)<1.5&&findDistancefast(&position,&player[j].coords)<4&&player[j].weaponstuck==-1&&!player[j].skeleton.free&&j!=oldowner){
220 if((player[j].aitype!=attacktypecutoff||abs(Random()%6)==0||(player[j].targetanimation!=backhandspringanim&&player[j].targetanimation!=rollanim&&player[j].targetanimation!=flipanim&&Random()%2==0))&&!missed){
222 if((player[j].creature==wolftype&&Random()%3!=0&&player[j].weaponactive==-1&&(player[j].isIdle()||player[j].isRun()||player[j].targetanimation==walkanim))||(player[j].creature==rabbittype&&Random()%2==0&&player[j].aitype==attacktypecutoff&&player[j].weaponactive==-1)){
223 emit_sound_at(knifedrawsound, player[j].coords, 128.);
225 player[j].weaponactive=0;
226 player[j].targetanimation=removeknifeanim;
227 player[j].targetframe=1;
230 if(player[j].num_weapons>0){
231 player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
233 player[j].num_weapons++;
234 player[j].weaponids[0]=i;
236 player[j].aitype=attacktypecutoff;
239 if(j!=0)numthrowkill++;
240 player[j].num_weapons++;
241 player[j].weaponstuck=player[j].num_weapons-1;
242 if(normaldotproduct(player[j].facing,velocity)>0)player[j].weaponstuckwhere=1;
243 else player[j].weaponstuckwhere=0;
245 player[j].weaponids[player[j].num_weapons-1]=i;
247 player[j].RagDoll(0);
248 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity*2;
249 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity*2;
250 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity*2;
251 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity*2;
252 //player[j].Puff(abdomen);
253 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
254 if(tutoriallevel==1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
255 footvel=tippoint-position;
257 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
259 if(tutoriallevel!=1){
260 if(player[j].weaponstuckwhere==0)player[j].DoBloodBig(2,205);
261 if(player[j].weaponstuckwhere==1)player[j].DoBloodBig(2,200);
262 player[j].damage+=200/player[j].armorhigh;
263 player[j].deathbleeding=1;
264 player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
270 emit_sound_at(fleshstabsound, position, 128.);
272 if(animation[player[0].targetanimation].height==highheight)
273 award_bonus(0, ninja);
275 award_bonus(0, Bullseyebonus);
281 if(position.y<terrain.getHeight(position.x,position.z)){
282 if(terrain.getOpacity(position.x,position.z)<.2){
284 if(terrain.lineTerrain(oldposition,position,&colpoint)!=-1){
285 position=colpoint*terrain.scale;
287 else position.y=terrain.getHeight(position.x,position.z);
289 terrain.MakeDecal(shadowdecalpermanent,position,.06,.5,0);
290 normalrot=terrain.getNormal(position.x,position.z)*-1;
292 //position-=normalrot*.1;
293 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
297 glRotatef(bigrotation,0,1,0);
298 glRotatef(bigtilt2,1,0,0);
299 glRotatef(bigtilt,0,0,1);
300 glRotatef(-rotation1+90,0,1,0);
301 glRotatef(-rotation2+90,0,0,1);
302 glRotatef(-rotation3,0,1,0);
303 glRotatef(smallrotation,1,0,0);
304 glRotatef(smallrotation2,0,1,0);
306 glGetFloatv(GL_MODELVIEW_MATRIX,M);
311 position-=tippoint*.15;
312 XYZ temppoint1,temppoint2,tempforward;
322 emit_sound_at(knifesheathesound, position, 128.);
325 terrainlight=terrain.getLighting(position.x,position.z);
326 if(environment==snowyenvironment){
327 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
329 else if(environment==grassyenvironment){
330 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
332 else if(environment==desertenvironment){
333 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
341 position-=velocity*multiplier;
342 tippoint-=velocity*multiplier;
343 tipvelocity=velocity;
346 if(velocity.x!=0||velocity.z!=0||velocity.y!=0){
347 velocity.y+=gravity*multiplier;
349 XYZ temppoint1,temppoint2,tempforward;
354 distance=findDistance(&temppoint1,&temppoint2);
355 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
359 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
367 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
377 for(int l=0;l<10;l++){
378 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&physics){
380 position+=velocity*multiplier;
381 tippoint+=tipvelocity*multiplier;
384 midp=(position*mass+tippoint*tipmass)/(mass+tipmass);
387 newpoint1=midp-vel*length*(tipmass/(mass+tipmass));
388 newpoint2=midp+vel*length*(mass/(mass+tipmass));
390 if(freetime>.04)velocity=velocity+(newpoint1-position)/multiplier;
391 if(freetime>.04)tipvelocity=tipvelocity+(newpoint2-tippoint)/multiplier;
398 whichpatchx=(position.x)/(terrain.size/subdivision*terrain.scale);
399 whichpatchz=(position.z)/(terrain.size/subdivision*terrain.scale);
400 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
401 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
402 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
403 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
407 start=position-(tippoint-position)/5;
408 end=tippoint+(tippoint-position)/30;
409 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
412 diff=(colpoint-tippoint);
416 position+=(colpoint-tippoint)+diff*.05;
417 tippoint=colpoint+diff*.05;
418 oldposition=position;
419 oldtippoint=tippoint;
423 start=tippoint-(position-tippoint)/5;
424 end=position+(position-tippoint)/30;
425 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
428 diff=(colpoint-position);
432 tippoint+=(colpoint-position)+diff*.05;
433 position=colpoint+diff*.05;
434 oldtippoint=tippoint;
435 oldposition=tippoint;
442 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
446 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
447 ReflectVector(&velocity,&terrainnormal);
448 position+=terrainnormal*.002;
450 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
451 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
452 frictionness=abs(normaldotproduct(velocity,terrainnormal));
453 velocity-=bounceness;
454 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
456 velocity+=bounceness*elasticity;
458 if(findLengthfast(&bounceness)>1){
460 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
461 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
462 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
467 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
471 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
472 ReflectVector(&tipvelocity,&terrainnormal);
473 tippoint+=terrainnormal*.002;
475 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
476 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
477 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
478 tipvelocity-=bounceness;
479 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
481 tipvelocity+=bounceness*elasticity;
483 if(findLengthfast(&bounceness)>1){
485 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
486 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
487 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
491 if((objects.type[k]!=boxtype&&objects.type[k]!=platformtype&&objects.type[k]!=walltype&&objects.type[k]!=weirdtype)||objects.rotation2[k]!=0)
493 mid=(position*(21+(float)m*10)+tippoint*(19-(float)m*10))/40;
495 oldmid=(oldposition*(21+(float)m*10)+oldtippoint*(19-(float)m*10))/40;
499 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
503 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
504 ReflectVector(&velocity,&terrainnormal);
506 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
507 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
508 frictionness=abs(normaldotproduct(velocity,terrainnormal));
509 velocity-=bounceness;
510 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
512 velocity+=bounceness*elasticity;
514 if(findLengthfast(&bounceness)>1){
516 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
517 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
518 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
520 position+=(mid-oldmid2)*(20/(1+(float)m*10));
523 mid=(position*(19-(float)m*10)+tippoint*(21+(float)m*10))/40;
525 oldmid=(oldposition*(19-(float)m*10)+oldtippoint*(21+(float)m*10))/40;
529 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
533 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
534 ReflectVector(&tipvelocity,&terrainnormal);
536 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
537 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
538 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
539 tipvelocity-=bounceness;
540 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
542 tipvelocity+=bounceness*elasticity;
544 if(findLengthfast(&bounceness)>1){
546 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
547 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
548 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
550 tippoint+=(mid-oldmid2)*(20/(1+(float)m*10));
557 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
561 closestswordpoint=colpoint;//(position+tippoint)/2;
562 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.rotation[k],0)+objects.position[k];
563 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.rotation[k],0)+objects.position[k];
564 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.rotation[k],0)+objects.position[k];
565 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint ))
566 if(distance<closestdistance||closestdistance==-1){
567 closestpoint=colpoint;
568 closestdistance=distance;
571 if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint ))
572 if(distance<closestdistance||closestdistance==-1){
573 closestpoint=colpoint;
574 closestdistance=distance;
577 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint ))
578 if(distance<closestdistance||closestdistance==-1){
579 closestpoint=colpoint;
580 closestdistance=distance;
583 if(closestdistance!=-1&&isnormal(closestdistance)){
584 if(DistancePointLine(&closestpoint, &position, &tippoint, &distance,&colpoint )){
585 closestswordpoint=colpoint;
586 velocity+=(closestpoint-closestswordpoint);
587 tipvelocity+=(closestpoint-closestswordpoint);
588 position+=(closestpoint-closestswordpoint);
589 tippoint+=(closestpoint-closestswordpoint);
598 whichhit=terrain.lineTerrain(oldposition,position,&colpoint);
599 if(whichhit!=-1||position.y<terrain.getHeight(position.x,position.z)){
601 if(whichhit!=-1)position=colpoint*terrain.scale;
602 else position.y=terrain.getHeight(position.x,position.z);
604 terrainnormal=terrain.getNormal(position.x,position.z);
605 ReflectVector(&velocity,&terrainnormal);
606 position+=terrainnormal*.002;
607 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
608 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
609 frictionness=abs(normaldotproduct(velocity,terrainnormal));
610 velocity-=bounceness;
611 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
613 if(terrain.getOpacity(position.x,position.z)<.2)velocity+=bounceness*elasticity*.3;
614 else velocity+=bounceness*elasticity;
615 //if (type==knife) printf("velocity of knife %d now %f,%f,%f.\n", i, velocity.x, velocity.y, velocity.z);
616 if(findLengthfast(&bounceness)>1){
618 if(terrain.getOpacity(position.x,position.z)>.2){
619 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
620 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
622 else whichsound=footstepsound+abs(Random()%2);
623 emit_sound_at(whichsound, position,
624 findLengthfast(&bounceness)
625 * (terrain.getOpacity(position.x,position.z) > .2
629 if(terrain.getOpacity(position.x,position.z)<.2){
631 terrainlight=terrain.getLighting(position.x,position.z);
632 if(environment==snowyenvironment){
633 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
635 else if(environment==grassyenvironment){
636 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
638 else if(environment==desertenvironment){
639 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
644 whichhit=terrain.lineTerrain(oldtippoint,tippoint,&colpoint);
645 if(whichhit!=-1||tippoint.y<terrain.getHeight(tippoint.x,tippoint.z)){
646 if(whichhit!=-1)tippoint=colpoint*terrain.scale;
647 else tippoint.y=terrain.getHeight(tippoint.x,tippoint.z);
649 terrainnormal=terrain.getNormal(tippoint.x,tippoint.z);
650 ReflectVector(&tipvelocity,&terrainnormal);
651 tippoint+=terrainnormal*.002;
652 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
653 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
654 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
655 tipvelocity-=bounceness;
656 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
658 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2)tipvelocity+=bounceness*elasticity*.3;
659 else tipvelocity+=bounceness*elasticity;
660 //if (type==knife) printf("tipvelocity of knife %d now %f,%f,%f.\n", i, tipvelocity.x, tipvelocity.y, tipvelocity.z);
662 if(findLengthfast(&bounceness)>1){
664 if(terrain.getOpacity(tippoint.x,tippoint.z)>.2){
665 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
666 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
668 else whichsound=footstepsound+abs(Random()%2);
669 emit_sound_at(whichsound, tippoint,
670 findLengthfast(&bounceness)
671 * (terrain.getOpacity(tippoint.x,tippoint.z) > .2
675 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2){
677 terrainlight=terrain.getLighting(tippoint.x,tippoint.z);
678 if(environment==snowyenvironment){
679 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
681 else if(environment==grassyenvironment){
682 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
684 else if(environment==desertenvironment){
685 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
692 mid=position+tippoint;
694 mid+=(position-mid)/20;
696 if(mid.y<terrain.getHeight(mid.x,mid.z)){
698 mid.y=terrain.getHeight(mid.x,mid.z);
700 terrainnormal=terrain.getNormal(mid.x,mid.z);
701 ReflectVector(&velocity,&terrainnormal);
702 //mid+=terrainnormal*.002;
703 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
704 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
705 frictionness=abs(normaldotproduct(velocity,terrainnormal));
706 velocity-=bounceness;
707 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
709 if(terrain.getOpacity(mid.x,mid.z)<.2)velocity+=bounceness*elasticity*.3;
710 else velocity+=bounceness*elasticity;
712 if(findLengthfast(&bounceness)>1){
714 if(terrain.getOpacity(mid.x,mid.z)>.2){
715 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
716 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
718 else whichsound=footstepsound+abs(Random()%2);
719 emit_sound_at(whichsound, mid,
720 findLengthfast(&bounceness)
721 * (terrain.getOpacity(position.x,position.z) > .2
725 position+=(mid-oldmid)*20;
728 mid=position+tippoint;
730 mid+=(tippoint-mid)/20;
732 if(mid.y<terrain.getHeight(mid.x,mid.z)){
734 mid.y=terrain.getHeight(mid.x,mid.z);
736 terrainnormal=terrain.getNormal(mid.x,mid.z);
737 ReflectVector(&tipvelocity,&terrainnormal);
738 //mid+=terrainnormal*.002;
739 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
740 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
741 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
742 tipvelocity-=bounceness;
743 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
745 if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity+=bounceness*elasticity*.3;
746 else tipvelocity+=bounceness*elasticity;
748 if(findLengthfast(&bounceness)>1){
750 if(terrain.getOpacity(mid.x,mid.z)>.2){
751 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
752 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
754 else whichsound=footstepsound+abs(Random()%2);
755 emit_sound_at(whichsound, mid,
756 findLengthfast(&bounceness)
757 * (terrain.getOpacity(position.x,position.z) > .2
761 tippoint+=(mid-oldmid)*20;
764 velocity.y+=gravity*multiplier;
765 tipvelocity.y+=gravity*multiplier;
766 //position.y+=gravity*multiplier*multiplier;
767 //tippoint.y+=gravity*multiplier*multiplier;
770 XYZ temppoint1,temppoint2,tempforward;
775 distance=findDistance(&temppoint1,&temppoint2);
776 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
780 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
788 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
791 if(findLengthfast(&velocity)<.3&&findLengthfast(&tipvelocity)<.3&&hitsomething){
792 freetime+=multiplier;
795 //velocity=(position-oldposition)/multiplier;
796 //tipvelocity==(tippoint[i-+oldtippoint)/multiplier;
805 if(blooddrip&&bloody){
806 blooddripdelay-=blooddrip*multiplier/2;
807 blooddrip-=multiplier;
808 if(blooddrip<0)blooddrip=0;
809 if(blooddrip>5)blooddrip=5;
810 if(blooddripdelay<0&&bloodtoggle){
814 bloodloc=position+(tippoint-position)*.7;
818 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
823 flamedelay-=multiplier;
824 if(onfire&&flamedelay<=0){
826 flamedelay-=multiplier;
829 normalrot=player[owner].velocity;
833 if(player[owner].onterrain){
837 Sprite::MakeSprite(weaponflamesprite, position+tippoint*(((float)abs(Random()%100))/600+.05),normalrot, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*1/3, 1);
838 Sprite::setLastSpriteSpeed(4);
839 Sprite::setLastSpriteAlivetime(.3);
843 if(!onfire&&owner==-1&&type!=staff){
844 flamedelay-=multiplier;
847 flamedelay-=multiplier;
849 if(Random()%50==0&&findDistancefast(&position,&viewer)>80){
851 shinepoint=position+(tippoint-position)*(((float)abs(Random()%100))/100);
852 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
853 Sprite::setLastSpriteSpeed(4);
854 Sprite::setLastSpriteAlivetime(.3);
860 void Weapons::DoStuff() {
862 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
867 void Weapon::Draw() {
869 static XYZ terrainlight;
870 static GLfloat M[16];
873 if((frustum.SphereInFrustum(position.x,position.y,position.z,1)&&findDistancefast(&viewer,&position)<viewdistance*viewdistance))
879 if(velocity.x&&!physics)drawhowmany=10;
884 if(player[owner].occluded<25)
885 if((frustum.SphereInFrustum(player[owner].coords.x,player[owner].coords.y+player[owner].scale*3,player[owner].coords.z,player[owner].scale*8)&&findDistancefast(&viewer,&player[owner].coords)<viewdistance*viewdistance)||player[owner].skeleton.free==3)
887 if((player[owner].targetanimation==knifeslashstartanim||player[owner].targetanimation==swordsneakattackanim||(player[owner].currentanimation==staffhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffgroundsmashanim&&player[owner].currentframe>1)||(player[owner].targetanimation==swordslashanim&&player[owner].targetframe<7)||player[owner].targetanimation==crouchstabanim||player[owner].targetanimation==swordslashreversalanim||player[owner].targetanimation==swordslashreversedanim||player[owner].targetanimation==knifefollowanim||player[owner].targetanimation==swordgroundstabanim||player[owner].targetanimation==knifethrowanim)&&player[owner].targetanimation==lastdrawnanim&&!player[owner].skeleton.free)
892 if(player[owner].targetanimation==swordgroundstabanim)
894 lastdrawnrotation1=rotation1;
895 lastdrawnrotation2=rotation2;
896 lastdrawnrotation3=rotation3;
897 lastdrawnbigrotation=bigrotation;
898 lastdrawnbigtilt=bigtilt;
899 lastdrawnbigtilt2=bigtilt2;
900 lastdrawnsmallrotation=smallrotation;
901 lastdrawnsmallrotation2=smallrotation2;
906 terrainlight=terrain.getLighting(position.x,position.z);
909 glAlphaFunc(GL_GREATER, 0.01);
911 for(j=drawhowmany;j>0;j--)
913 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
915 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany);
916 if(owner!=-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)-.02+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
917 if(owner==-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
918 //glTranslatef(position.x,position.y-.02,position.z);
919 glRotatef(bigrotation*(((float)(j))/drawhowmany)+lastdrawnbigrotation*(1-((float)(j))/drawhowmany),0,1,0);
920 glRotatef(bigtilt2*(((float)(j))/drawhowmany)+lastdrawnbigtilt2*(1-((float)(j))/drawhowmany),1,0,0);
921 glRotatef(bigtilt*(((float)(j))/drawhowmany)+lastdrawnbigtilt*(1-((float)(j))/drawhowmany),0,0,1);
922 glRotatef(-rotation1*(((float)(j))/drawhowmany)-lastdrawnrotation1*(1-((float)(j))/drawhowmany)+90,0,1,0);
923 glRotatef(-rotation2*(((float)(j))/drawhowmany)-lastdrawnrotation2*(1-((float)(j))/drawhowmany)+90,0,0,1);
924 glRotatef(-rotation3*(((float)(j))/drawhowmany)-lastdrawnrotation3*(1-((float)(j))/drawhowmany),0,1,0);
925 glRotatef(smallrotation*(((float)(j))/drawhowmany)+lastdrawnsmallrotation*(1-((float)(j))/drawhowmany),1,0,0);
926 glRotatef(smallrotation2*(((float)(j))/drawhowmany)+lastdrawnsmallrotation2*(1-((float)(j))/drawhowmany),0,1,0);
930 if(player[owner].targetanimation==staffhitanim||player[owner].currentanimation==staffhitanim||player[owner].targetanimation==staffhitreversedanim||player[owner].currentanimation==staffhitreversedanim)
932 glTranslatef(0,0,-.3);
934 if(player[owner].targetanimation==staffgroundsmashanim||player[owner].currentanimation==staffgroundsmashanim||player[owner].targetanimation==staffspinhitreversedanim||player[owner].currentanimation==staffspinhitreversedanim||player[owner].targetanimation==staffspinhitanim||player[owner].currentanimation==staffspinhitanim)
936 glTranslatef(0,0,-.1);
940 glEnable(GL_LIGHTING);
943 if(!bloody||!bloodtoggle)
944 throwingknifemodel.drawdifftex(knifetextureptr);
948 throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
950 throwingknifemodel.drawdifftex(bloodknifetextureptr);
954 if(!bloody||!bloodtoggle)
955 swordmodel.drawdifftex(swordtextureptr);
959 swordmodel.drawdifftex(lightbloodswordtextureptr);
961 swordmodel.drawdifftex(bloodswordtextureptr);
965 staffmodel.drawdifftex(stafftextureptr);
972 lastdrawnposition=position;
973 lastdrawntippoint=tippoint;
974 lastdrawnrotation1=rotation1;
975 lastdrawnrotation2=rotation2;
976 lastdrawnrotation3=rotation3;
977 lastdrawnbigrotation=bigrotation;
978 lastdrawnbigtilt=bigtilt;
979 lastdrawnbigtilt2=bigtilt2;
980 lastdrawnsmallrotation=smallrotation;
981 lastdrawnsmallrotation2=smallrotation2;
982 if(owner!=-1)lastdrawnanim=player[owner].currentanimation;
986 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
989 glTranslatef(position.x,position.y-.02,position.z);
990 glRotatef(bigrotation,0,1,0);
991 glRotatef(bigtilt2,1,0,0);
992 glRotatef(bigtilt,0,0,1);
993 glRotatef(-rotation1+90,0,1,0);
994 glRotatef(-rotation2+90,0,0,1);
995 glRotatef(-rotation3,0,1,0);
996 glRotatef(smallrotation,1,0,0);
997 glRotatef(smallrotation2,0,1,0);
998 glTranslatef(0,0,length);
999 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1010 glAlphaFunc(GL_GREATER, 0.9);
1011 glEnable(GL_TEXTURE_2D);
1013 glEnable(GL_CULL_FACE);
1014 glCullFace(GL_FRONT);
1017 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1029 if (Weapon::stafftextureptr) glDeleteTextures( 1, &Weapon::stafftextureptr );
1030 if (Weapon::knifetextureptr) glDeleteTextures( 1, &Weapon::knifetextureptr );
1031 if (Weapon::lightbloodknifetextureptr) glDeleteTextures( 1, &Weapon::lightbloodknifetextureptr );
1032 if (Weapon::bloodknifetextureptr) glDeleteTextures( 1, &Weapon::bloodknifetextureptr );
1033 if (Weapon::swordtextureptr) glDeleteTextures( 1, &Weapon::swordtextureptr );
1034 if (Weapon::lightbloodswordtextureptr) glDeleteTextures( 1, &Weapon::lightbloodswordtextureptr );
1035 if (Weapon::bloodswordtextureptr) glDeleteTextures( 1, &Weapon::bloodswordtextureptr );