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 closestdistance;
112 static float distance;
114 static XYZ closestpoint;
115 static XYZ closestswordpoint;
116 static XYZ extramove;
117 static float tempmult;
122 if(damage>=2&&type==staff&&owner!=-1){
123 emit_sound_at(staffbreaksound, tippoint);
126 //speed=(tippoint-oldtippoint)/multiplier/6;
129 tempvel.x=float(abs(Random()%100)-50)/20;
130 tempvel.y=float(abs(Random()%100)-50)/20;
131 tempvel.z=float(abs(Random()%100)-50)/20;
133 Sprite::MakeSprite(splintersprite, position+(tippoint-position)*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
145 player[tempowner].num_weapons--;
146 if(player[tempowner].num_weapons){
147 player[tempowner].weaponids[0]=player[tempowner].weaponids[player[tempowner].num_weapons];
148 if(player[tempowner].weaponstuck==player[tempowner].num_weapons)player[tempowner].weaponstuck=0;
150 player[tempowner].weaponactive=-1;
153 oldposition=position;
154 oldtippoint=tippoint;
155 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&!physics){
156 position+=velocity*multiplier;
157 tippoint+=velocity*multiplier;
158 whichpatchx=position.x/(terrain.size/subdivision*terrain.scale);
159 whichpatchz=position.z/(terrain.size/subdivision*terrain.scale);
160 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
161 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
162 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
163 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
166 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
168 if(objects.type[k]==treetrunktype){
169 objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),.1,1,Random()%360);
170 normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0);
172 if(type==knife)position=colpoint-normalrot*.1;
173 if(type==sword)position=colpoint-normalrot*.2;
174 if(type==staff)position=colpoint-normalrot*.2;
175 XYZ temppoint1,temppoint2,tempforward;
179 temppoint2=normalrot;
180 distance=findDistance(&temppoint1,&temppoint2);
181 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
185 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
187 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
196 emit_sound_at(knifesheathesound, position, 128.);
200 Sprite::MakeSprite(cloudimpactsprite, position,velocity, 1,1,1, .8, .3);
205 position-=velocity*multiplier;
206 tippoint-=velocity*multiplier;
207 tipvelocity=velocity;
212 if(velocity.x||velocity.y||velocity.z)
213 for(j=0;j<numplayers;j++){
215 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;
216 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){
217 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){
218 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)){
219 emit_sound_at(knifedrawsound, player[j].coords, 128.);
221 player[j].weaponactive=0;
222 player[j].targetanimation=removeknifeanim;
223 player[j].targetframe=1;
226 if(player[j].num_weapons>0){
227 player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
229 player[j].num_weapons++;
230 player[j].weaponids[0]=i;
232 player[j].aitype=attacktypecutoff;
235 if(j!=0)numthrowkill++;
236 player[j].num_weapons++;
237 player[j].weaponstuck=player[j].num_weapons-1;
238 if(normaldotproduct(player[j].facing,velocity)>0)player[j].weaponstuckwhere=1;
239 else player[j].weaponstuckwhere=0;
241 player[j].weaponids[player[j].num_weapons-1]=i;
243 player[j].RagDoll(0);
244 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity*2;
245 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity*2;
246 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity*2;
247 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity*2;
248 //player[j].Puff(abdomen);
249 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
250 if(tutoriallevel==1)Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
251 footvel=tippoint-position;
253 if(bloodtoggle&&tutoriallevel!=1)Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
255 if(tutoriallevel!=1){
256 if(player[j].weaponstuckwhere==0)player[j].DoBloodBig(2,205);
257 if(player[j].weaponstuckwhere==1)player[j].DoBloodBig(2,200);
258 player[j].damage+=200/player[j].armorhigh;
259 player[j].deathbleeding=1;
260 player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
266 emit_sound_at(fleshstabsound, position, 128.);
268 if(animation[player[0].targetanimation].height==highheight)
269 award_bonus(0, ninja);
271 award_bonus(0, Bullseyebonus);
277 if(position.y<terrain.getHeight(position.x,position.z)){
278 if(terrain.getOpacity(position.x,position.z)<.2){
280 if(terrain.lineTerrain(oldposition,position,&colpoint)!=-1){
281 position=colpoint*terrain.scale;
283 else position.y=terrain.getHeight(position.x,position.z);
285 terrain.MakeDecal(shadowdecalpermanent,position,.06,.5,0);
286 normalrot=terrain.getNormal(position.x,position.z)*-1;
288 //position-=normalrot*.1;
289 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
293 glRotatef(bigrotation,0,1,0);
294 glRotatef(bigtilt2,1,0,0);
295 glRotatef(bigtilt,0,0,1);
296 glRotatef(-rotation1+90,0,1,0);
297 glRotatef(-rotation2+90,0,0,1);
298 glRotatef(-rotation3,0,1,0);
299 glRotatef(smallrotation,1,0,0);
300 glRotatef(smallrotation2,0,1,0);
302 glGetFloatv(GL_MODELVIEW_MATRIX,M);
307 position-=tippoint*.15;
308 XYZ temppoint1,temppoint2,tempforward;
317 emit_sound_at(knifesheathesound, position, 128.);
320 terrainlight=terrain.getLighting(position.x,position.z);
321 if(environment==snowyenvironment){
322 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
324 else if(environment==grassyenvironment){
325 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);
327 else if(environment==desertenvironment){
328 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);
336 position-=velocity*multiplier;
337 tippoint-=velocity*multiplier;
338 tipvelocity=velocity;
341 if(velocity.x!=0||velocity.z!=0||velocity.y!=0){
342 velocity.y+=gravity*multiplier;
344 XYZ temppoint1,temppoint2,tempforward;
349 distance=findDistance(&temppoint1,&temppoint2);
350 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
354 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
362 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
372 for(int l=0;l<10;l++){
373 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&physics){
375 position+=velocity*multiplier;
376 tippoint+=tipvelocity*multiplier;
379 midp=(position*mass+tippoint*tipmass)/(mass+tipmass);
382 newpoint1=midp-vel*length*(tipmass/(mass+tipmass));
383 newpoint2=midp+vel*length*(mass/(mass+tipmass));
385 if(freetime>.04)velocity=velocity+(newpoint1-position)/multiplier;
386 if(freetime>.04)tipvelocity=tipvelocity+(newpoint2-tippoint)/multiplier;
393 whichpatchx=(position.x)/(terrain.size/subdivision*terrain.scale);
394 whichpatchz=(position.z)/(terrain.size/subdivision*terrain.scale);
395 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
396 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
397 for(j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
398 k=terrain.patchobjects[whichpatchx][whichpatchz][j];
402 start=position-(tippoint-position)/5;
403 end=tippoint+(tippoint-position)/30;
404 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
407 diff=(colpoint-tippoint);
411 position+=(colpoint-tippoint)+diff*.05;
412 tippoint=colpoint+diff*.05;
413 oldposition=position;
414 oldtippoint=tippoint;
418 start=tippoint-(position-tippoint)/5;
419 end=position+(position-tippoint)/30;
420 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
423 diff=(colpoint-position);
427 tippoint+=(colpoint-position)+diff*.05;
428 position=colpoint+diff*.05;
429 oldtippoint=tippoint;
430 oldposition=tippoint;
437 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
441 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
442 ReflectVector(&velocity,&terrainnormal);
443 position+=terrainnormal*.002;
445 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
446 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
447 frictionness=abs(normaldotproduct(velocity,terrainnormal));
448 velocity-=bounceness;
449 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
451 velocity+=bounceness*elasticity;
453 if(findLengthfast(&bounceness)>1){
455 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
456 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
457 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
462 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
466 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
467 ReflectVector(&tipvelocity,&terrainnormal);
468 tippoint+=terrainnormal*.002;
470 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
471 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
472 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
473 tipvelocity-=bounceness;
474 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
476 tipvelocity+=bounceness*elasticity;
478 if(findLengthfast(&bounceness)>1){
480 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
481 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
482 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
486 if((objects.type[k]!=boxtype&&objects.type[k]!=platformtype&&objects.type[k]!=walltype&&objects.type[k]!=weirdtype)||objects.rotation2[k]!=0)
488 mid=(position*(21+(float)m*10)+tippoint*(19-(float)m*10))/40;
490 oldmid=(oldposition*(21+(float)m*10)+oldtippoint*(19-(float)m*10))/40;
494 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
498 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
499 ReflectVector(&velocity,&terrainnormal);
501 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
502 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
503 frictionness=abs(normaldotproduct(velocity,terrainnormal));
504 velocity-=bounceness;
505 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
507 velocity+=bounceness*elasticity;
509 if(findLengthfast(&bounceness)>1){
511 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
512 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
513 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
515 position+=(mid-oldmid2)*(20/(1+(float)m*10));
518 mid=(position*(19-(float)m*10)+tippoint*(21+(float)m*10))/40;
520 oldmid=(oldposition*(19-(float)m*10)+oldtippoint*(21+(float)m*10))/40;
524 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
528 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
529 ReflectVector(&tipvelocity,&terrainnormal);
531 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
532 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
533 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
534 tipvelocity-=bounceness;
535 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
537 tipvelocity+=bounceness*elasticity;
539 if(findLengthfast(&bounceness)>1){
541 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
542 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
543 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
545 tippoint+=(mid-oldmid2)*(20/(1+(float)m*10));
552 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
556 closestswordpoint=colpoint;//(position+tippoint)/2;
557 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.rotation[k],0)+objects.position[k];
558 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.rotation[k],0)+objects.position[k];
559 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.rotation[k],0)+objects.position[k];
560 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint ))
561 if(distance<closestdistance||closestdistance==-1){
562 closestpoint=colpoint;
563 closestdistance=distance;
565 if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint ))
566 if(distance<closestdistance||closestdistance==-1){
567 closestpoint=colpoint;
568 closestdistance=distance;
570 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint ))
571 if(distance<closestdistance||closestdistance==-1){
572 closestpoint=colpoint;
573 closestdistance=distance;
575 if(closestdistance!=-1&&isnormal(closestdistance)){
576 if(DistancePointLine(&closestpoint, &position, &tippoint, &distance,&colpoint )){
577 closestswordpoint=colpoint;
578 velocity+=(closestpoint-closestswordpoint);
579 tipvelocity+=(closestpoint-closestswordpoint);
580 position+=(closestpoint-closestswordpoint);
581 tippoint+=(closestpoint-closestswordpoint);
590 whichhit=terrain.lineTerrain(oldposition,position,&colpoint);
591 if(whichhit!=-1||position.y<terrain.getHeight(position.x,position.z)){
593 if(whichhit!=-1)position=colpoint*terrain.scale;
594 else position.y=terrain.getHeight(position.x,position.z);
596 terrainnormal=terrain.getNormal(position.x,position.z);
597 ReflectVector(&velocity,&terrainnormal);
598 position+=terrainnormal*.002;
599 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
600 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
601 frictionness=abs(normaldotproduct(velocity,terrainnormal));
602 velocity-=bounceness;
603 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
605 if(terrain.getOpacity(position.x,position.z)<.2)velocity+=bounceness*elasticity*.3;
606 else velocity+=bounceness*elasticity;
607 //if (type==knife) printf("velocity of knife %d now %f,%f,%f.\n", i, velocity.x, velocity.y, velocity.z);
608 if(findLengthfast(&bounceness)>1){
610 if(terrain.getOpacity(position.x,position.z)>.2){
611 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
612 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
614 else whichsound=footstepsound+abs(Random()%2);
615 emit_sound_at(whichsound, position,
616 findLengthfast(&bounceness)
617 * (terrain.getOpacity(position.x,position.z) > .2
621 if(terrain.getOpacity(position.x,position.z)<.2){
623 terrainlight=terrain.getLighting(position.x,position.z);
624 if(environment==snowyenvironment){
625 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
627 else if(environment==grassyenvironment){
628 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);
630 else if(environment==desertenvironment){
631 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);
636 whichhit=terrain.lineTerrain(oldtippoint,tippoint,&colpoint);
637 if(whichhit!=-1||tippoint.y<terrain.getHeight(tippoint.x,tippoint.z)){
638 if(whichhit!=-1)tippoint=colpoint*terrain.scale;
639 else tippoint.y=terrain.getHeight(tippoint.x,tippoint.z);
641 terrainnormal=terrain.getNormal(tippoint.x,tippoint.z);
642 ReflectVector(&tipvelocity,&terrainnormal);
643 tippoint+=terrainnormal*.002;
644 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
645 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
646 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
647 tipvelocity-=bounceness;
648 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
650 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2)tipvelocity+=bounceness*elasticity*.3;
651 else tipvelocity+=bounceness*elasticity;
652 //if (type==knife) printf("tipvelocity of knife %d now %f,%f,%f.\n", i, tipvelocity.x, tipvelocity.y, tipvelocity.z);
654 if(findLengthfast(&bounceness)>1){
656 if(terrain.getOpacity(tippoint.x,tippoint.z)>.2){
657 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
658 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
660 else whichsound=footstepsound+abs(Random()%2);
661 emit_sound_at(whichsound, tippoint,
662 findLengthfast(&bounceness)
663 * (terrain.getOpacity(tippoint.x,tippoint.z) > .2
667 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2){
669 terrainlight=terrain.getLighting(tippoint.x,tippoint.z);
670 if(environment==snowyenvironment){
671 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
673 else if(environment==grassyenvironment){
674 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);
676 else if(environment==desertenvironment){
677 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);
684 mid=position+tippoint;
686 mid+=(position-mid)/20;
688 if(mid.y<terrain.getHeight(mid.x,mid.z)){
690 mid.y=terrain.getHeight(mid.x,mid.z);
692 terrainnormal=terrain.getNormal(mid.x,mid.z);
693 ReflectVector(&velocity,&terrainnormal);
694 //mid+=terrainnormal*.002;
695 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
696 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
697 frictionness=abs(normaldotproduct(velocity,terrainnormal));
698 velocity-=bounceness;
699 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
701 if(terrain.getOpacity(mid.x,mid.z)<.2)velocity+=bounceness*elasticity*.3;
702 else velocity+=bounceness*elasticity;
704 if(findLengthfast(&bounceness)>1){
706 if(terrain.getOpacity(mid.x,mid.z)>.2){
707 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
708 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
710 else whichsound=footstepsound+abs(Random()%2);
711 emit_sound_at(whichsound, mid,
712 findLengthfast(&bounceness)
713 * (terrain.getOpacity(position.x,position.z) > .2
717 position+=(mid-oldmid)*20;
720 mid=position+tippoint;
722 mid+=(tippoint-mid)/20;
724 if(mid.y<terrain.getHeight(mid.x,mid.z)){
726 mid.y=terrain.getHeight(mid.x,mid.z);
728 terrainnormal=terrain.getNormal(mid.x,mid.z);
729 ReflectVector(&tipvelocity,&terrainnormal);
730 //mid+=terrainnormal*.002;
731 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
732 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
733 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
734 tipvelocity-=bounceness;
735 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
737 if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity+=bounceness*elasticity*.3;
738 else tipvelocity+=bounceness*elasticity;
740 if(findLengthfast(&bounceness)>1){
742 if(terrain.getOpacity(mid.x,mid.z)>.2){
743 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
744 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
746 else whichsound=footstepsound+abs(Random()%2);
747 emit_sound_at(whichsound, mid,
748 findLengthfast(&bounceness)
749 * (terrain.getOpacity(position.x,position.z) > .2
753 tippoint+=(mid-oldmid)*20;
756 velocity.y+=gravity*multiplier;
757 tipvelocity.y+=gravity*multiplier;
758 //position.y+=gravity*multiplier*multiplier;
759 //tippoint.y+=gravity*multiplier*multiplier;
762 XYZ temppoint1,temppoint2,tempforward;
767 distance=findDistance(&temppoint1,&temppoint2);
768 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
772 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
780 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
783 if(findLengthfast(&velocity)<.3&&findLengthfast(&tipvelocity)<.3&&hitsomething){
784 freetime+=multiplier;
787 //velocity=(position-oldposition)/multiplier;
788 //tipvelocity==(tippoint[i-+oldtippoint)/multiplier;
797 if(blooddrip&&bloody){
798 blooddripdelay-=blooddrip*multiplier/2;
799 blooddrip-=multiplier;
800 if(blooddrip<0)blooddrip=0;
801 if(blooddrip>5)blooddrip=5;
802 if(blooddripdelay<0&&bloodtoggle){
806 bloodloc=position+(tippoint-position)*.7;
810 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
815 flamedelay-=multiplier;
816 if(onfire&&flamedelay<=0){
818 flamedelay-=multiplier;
821 normalrot=player[owner].velocity;
825 if(player[owner].onterrain){
829 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);
830 Sprite::setLastSpriteSpeed(4);
831 Sprite::setLastSpriteAlivetime(.3);
835 if(!onfire&&owner==-1&&type!=staff){
836 flamedelay-=multiplier;
839 flamedelay-=multiplier;
841 if(Random()%50==0&&findDistancefast(&position,&viewer)>80){
843 shinepoint=position+(tippoint-position)*(((float)abs(Random()%100))/100);
844 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
845 Sprite::setLastSpriteSpeed(4);
846 Sprite::setLastSpriteAlivetime(.3);
852 void Weapons::DoStuff() {
854 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
859 void Weapon::Draw() {
861 static XYZ terrainlight;
862 static GLfloat M[16];
865 if((frustum.SphereInFrustum(position.x,position.y,position.z,1)&&findDistancefast(&viewer,&position)<viewdistance*viewdistance))
871 if(velocity.x&&!physics)drawhowmany=10;
876 if(player[owner].occluded<25)
877 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)
879 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)
884 if(player[owner].targetanimation==swordgroundstabanim)
886 lastdrawnrotation1=rotation1;
887 lastdrawnrotation2=rotation2;
888 lastdrawnrotation3=rotation3;
889 lastdrawnbigrotation=bigrotation;
890 lastdrawnbigtilt=bigtilt;
891 lastdrawnbigtilt2=bigtilt2;
892 lastdrawnsmallrotation=smallrotation;
893 lastdrawnsmallrotation2=smallrotation2;
898 terrainlight=terrain.getLighting(position.x,position.z);
901 glAlphaFunc(GL_GREATER, 0.01);
903 for(j=drawhowmany;j>0;j--)
905 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
907 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany);
908 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));
909 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));
910 //glTranslatef(position.x,position.y-.02,position.z);
911 glRotatef(bigrotation*(((float)(j))/drawhowmany)+lastdrawnbigrotation*(1-((float)(j))/drawhowmany),0,1,0);
912 glRotatef(bigtilt2*(((float)(j))/drawhowmany)+lastdrawnbigtilt2*(1-((float)(j))/drawhowmany),1,0,0);
913 glRotatef(bigtilt*(((float)(j))/drawhowmany)+lastdrawnbigtilt*(1-((float)(j))/drawhowmany),0,0,1);
914 glRotatef(-rotation1*(((float)(j))/drawhowmany)-lastdrawnrotation1*(1-((float)(j))/drawhowmany)+90,0,1,0);
915 glRotatef(-rotation2*(((float)(j))/drawhowmany)-lastdrawnrotation2*(1-((float)(j))/drawhowmany)+90,0,0,1);
916 glRotatef(-rotation3*(((float)(j))/drawhowmany)-lastdrawnrotation3*(1-((float)(j))/drawhowmany),0,1,0);
917 glRotatef(smallrotation*(((float)(j))/drawhowmany)+lastdrawnsmallrotation*(1-((float)(j))/drawhowmany),1,0,0);
918 glRotatef(smallrotation2*(((float)(j))/drawhowmany)+lastdrawnsmallrotation2*(1-((float)(j))/drawhowmany),0,1,0);
922 if(player[owner].targetanimation==staffhitanim||player[owner].currentanimation==staffhitanim||player[owner].targetanimation==staffhitreversedanim||player[owner].currentanimation==staffhitreversedanim)
924 glTranslatef(0,0,-.3);
926 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)
928 glTranslatef(0,0,-.1);
932 glEnable(GL_LIGHTING);
935 if(!bloody||!bloodtoggle)
936 throwingknifemodel.drawdifftex(knifetextureptr);
940 throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
942 throwingknifemodel.drawdifftex(bloodknifetextureptr);
946 if(!bloody||!bloodtoggle)
947 swordmodel.drawdifftex(swordtextureptr);
951 swordmodel.drawdifftex(lightbloodswordtextureptr);
953 swordmodel.drawdifftex(bloodswordtextureptr);
957 staffmodel.drawdifftex(stafftextureptr);
964 lastdrawnposition=position;
965 lastdrawntippoint=tippoint;
966 lastdrawnrotation1=rotation1;
967 lastdrawnrotation2=rotation2;
968 lastdrawnrotation3=rotation3;
969 lastdrawnbigrotation=bigrotation;
970 lastdrawnbigtilt=bigtilt;
971 lastdrawnbigtilt2=bigtilt2;
972 lastdrawnsmallrotation=smallrotation;
973 lastdrawnsmallrotation2=smallrotation2;
974 if(owner!=-1)lastdrawnanim=player[owner].currentanimation;
978 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
981 glTranslatef(position.x,position.y-.02,position.z);
982 glRotatef(bigrotation,0,1,0);
983 glRotatef(bigtilt2,1,0,0);
984 glRotatef(bigtilt,0,0,1);
985 glRotatef(-rotation1+90,0,1,0);
986 glRotatef(-rotation2+90,0,0,1);
987 glRotatef(-rotation3,0,1,0);
988 glRotatef(smallrotation,1,0,0);
989 glRotatef(smallrotation2,0,1,0);
990 glTranslatef(0,0,length);
991 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1002 glAlphaFunc(GL_GREATER, 0.9);
1003 glEnable(GL_TEXTURE_2D);
1005 glEnable(GL_CULL_FACE);
1006 glCullFace(GL_FRONT);
1009 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1021 if (Weapon::stafftextureptr) glDeleteTextures( 1, &Weapon::stafftextureptr );
1022 if (Weapon::knifetextureptr) glDeleteTextures( 1, &Weapon::knifetextureptr );
1023 if (Weapon::lightbloodknifetextureptr) glDeleteTextures( 1, &Weapon::lightbloodknifetextureptr );
1024 if (Weapon::bloodknifetextureptr) glDeleteTextures( 1, &Weapon::bloodknifetextureptr );
1025 if (Weapon::swordtextureptr) glDeleteTextures( 1, &Weapon::swordtextureptr );
1026 if (Weapon::lightbloodswordtextureptr) glDeleteTextures( 1, &Weapon::lightbloodswordtextureptr );
1027 if (Weapon::bloodswordtextureptr) glDeleteTextures( 1, &Weapon::bloodswordtextureptr );