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(int i) {
101 static int whichpatchx,whichpatchz,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);
125 for(int j=0;j<40;j++){
126 tempvel.x=float(abs(Random()%100)-50)/20;
127 tempvel.y=float(abs(Random()%100)-50)/20;
128 tempvel.z=float(abs(Random()%100)-50)/20;
129 Sprite::MakeSprite(splintersprite, position+(tippoint-position)*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
141 player[tempowner].num_weapons--;
142 if(player[tempowner].num_weapons) {
143 player[tempowner].weaponids[0]=player[tempowner].weaponids[player[tempowner].num_weapons];
144 if(player[tempowner].weaponstuck==player[tempowner].num_weapons)
145 player[tempowner].weaponstuck=0;
147 player[tempowner].weaponactive=-1;
150 oldposition=position;
151 oldtippoint=tippoint;
152 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&!physics){
153 position+=velocity*multiplier;
154 tippoint+=velocity*multiplier;
155 whichpatchx=position.x/(terrain.size/subdivision*terrain.scale);
156 whichpatchz=position.z/(terrain.size/subdivision*terrain.scale);
157 if(whichpatchx>0 && whichpatchz>0 && whichpatchx<subdivision && whichpatchz<subdivision)
158 if(terrain.patchobjectnum[whichpatchx][whichpatchz]) {
159 for(int j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
160 int k=terrain.patchobjects[whichpatchx][whichpatchz][j];
163 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
165 if(objects.type[k]==treetrunktype){
166 objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.rotation[k],0),.1,1,Random()%360);
167 normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0);
169 if(type==knife)position=colpoint-normalrot*.1;
170 if(type==sword)position=colpoint-normalrot*.2;
171 if(type==staff)position=colpoint-normalrot*.2;
172 XYZ temppoint1,temppoint2,tempforward;
176 temppoint2=normalrot;
177 distance=findDistance(&temppoint1,&temppoint2);
178 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
182 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
184 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
193 emit_sound_at(knifesheathesound, position, 128.);
197 Sprite::MakeSprite(cloudimpactsprite, position,velocity, 1,1,1, .8, .3);
202 position-=velocity*multiplier;
203 tippoint-=velocity*multiplier;
204 tipvelocity=velocity;
209 if(velocity.x||velocity.y||velocity.z)
210 for(int j=0;j<numplayers;j++){
212 footpoint=DoRotation((player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].position+player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].position)/2,0,player[j].rotation,0)*player[j].scale+player[j].coords;
213 if(owner==-1 && findDistancefastflat(&position,&player[j].coords)<1.5 &&
214 findDistancefast(&position,&player[j].coords)<4&&player[j].weaponstuck==-1&&
215 !player[j].skeleton.free&&j!=oldowner) {
216 if((player[j].aitype!=attacktypecutoff||abs(Random()%6)==0||(player[j].targetanimation!=backhandspringanim&&player[j].targetanimation!=rollanim&&player[j].targetanimation!=flipanim&&Random()%2==0))&&!missed){
217 if((player[j].creature==wolftype&&Random()%3!=0&&player[j].weaponactive==-1&&(player[j].isIdle()||player[j].isRun()||player[j].targetanimation==walkanim))||(player[j].creature==rabbittype&&Random()%2==0&&player[j].aitype==attacktypecutoff&&player[j].weaponactive==-1)){
218 emit_sound_at(knifedrawsound, player[j].coords, 128.);
220 player[j].weaponactive=0;
221 player[j].targetanimation=removeknifeanim;
222 player[j].targetframe=1;
225 if(player[j].num_weapons>0){
226 player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
228 player[j].num_weapons++;
229 player[j].weaponids[0]=i;
231 player[j].aitype=attacktypecutoff;
234 if(j!=0)numthrowkill++;
235 player[j].num_weapons++;
236 player[j].weaponstuck=player[j].num_weapons-1;
237 if(normaldotproduct(player[j].facing,velocity)>0)player[j].weaponstuckwhere=1;
238 else player[j].weaponstuckwhere=0;
240 player[j].weaponids[player[j].num_weapons-1]=i;
242 player[j].RagDoll(0);
243 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity*2;
244 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity*2;
245 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity*2;
246 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity*2;
247 if(bloodtoggle&&tutoriallevel!=1)
248 Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
250 Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
251 footvel=tippoint-position;
253 if(bloodtoggle&&tutoriallevel!=1)
254 Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
256 if(tutoriallevel!=1) {
257 if(player[j].weaponstuckwhere==0)
258 player[j].DoBloodBig(2,205);
259 if(player[j].weaponstuckwhere==1)
260 player[j].DoBloodBig(2,200);
261 player[j].damage+=200/player[j].armorhigh;
262 player[j].deathbleeding=1;
263 player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
269 emit_sound_at(fleshstabsound, position, 128.);
271 if(animation[player[0].targetanimation].height==highheight)
272 award_bonus(0, ninja);
274 award_bonus(0, Bullseyebonus);
280 if(position.y<terrain.getHeight(position.x,position.z)){
281 if(terrain.getOpacity(position.x,position.z)<.2){
283 if(terrain.lineTerrain(oldposition,position,&colpoint)!=-1){
284 position=colpoint*terrain.scale;
286 else position.y=terrain.getHeight(position.x,position.z);
288 terrain.MakeDecal(shadowdecalpermanent,position,.06,.5,0);
289 normalrot=terrain.getNormal(position.x,position.z)*-1;
291 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
295 glRotatef(bigrotation,0,1,0);
296 glRotatef(bigtilt2,1,0,0);
297 glRotatef(bigtilt,0,0,1);
298 glRotatef(-rotation1+90,0,1,0);
299 glRotatef(-rotation2+90,0,0,1);
300 glRotatef(-rotation3,0,1,0);
301 glRotatef(smallrotation,1,0,0);
302 glRotatef(smallrotation2,0,1,0);
304 glGetFloatv(GL_MODELVIEW_MATRIX,M);
309 position-=tippoint*.15;
310 XYZ temppoint1,temppoint2,tempforward;
319 emit_sound_at(knifesheathesound, position, 128.);
322 terrainlight=terrain.getLighting(position.x,position.z);
323 if(environment==snowyenvironment){
324 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
326 else if(environment==grassyenvironment){
327 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
329 else if(environment==desertenvironment){
330 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
338 position-=velocity*multiplier;
339 tippoint-=velocity*multiplier;
340 tipvelocity=velocity;
343 if(velocity.x!=0||velocity.z!=0||velocity.y!=0){
344 velocity.y+=gravity*multiplier;
346 XYZ temppoint1,temppoint2,tempforward;
351 distance=findDistance(&temppoint1,&temppoint2);
352 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
356 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
364 if(temppoint1.x>temppoint2.x) rotation1=360-rotation1;
374 for(int l=0;l<10;l++) {
375 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&physics) {
377 position+=velocity*multiplier;
378 tippoint+=tipvelocity*multiplier;
381 midp=(position*mass+tippoint*tipmass)/(mass+tipmass);
384 newpoint1=midp-vel*length*(tipmass/(mass+tipmass));
385 newpoint2=midp+vel*length*(mass/(mass+tipmass));
387 if(freetime>.04)velocity=velocity+(newpoint1-position)/multiplier;
388 if(freetime>.04)tipvelocity=tipvelocity+(newpoint2-tippoint)/multiplier;
395 whichpatchx=(position.x)/(terrain.size/subdivision*terrain.scale);
396 whichpatchz=(position.z)/(terrain.size/subdivision*terrain.scale);
397 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
398 if(terrain.patchobjectnum[whichpatchx][whichpatchz]){
399 for(int j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++){
400 int k=terrain.patchobjects[whichpatchx][whichpatchz][j];
404 start=position-(tippoint-position)/5;
405 end=tippoint+(tippoint-position)/30;
406 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
409 diff=(colpoint-tippoint);
413 position+=(colpoint-tippoint)+diff*.05;
414 tippoint=colpoint+diff*.05;
415 oldposition=position;
416 oldtippoint=tippoint;
420 start=tippoint-(position-tippoint)/5;
421 end=position+(position-tippoint)/30;
422 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
425 diff=(colpoint-position);
429 tippoint+=(colpoint-position)+diff*.05;
430 position=colpoint+diff*.05;
431 oldtippoint=tippoint;
432 oldposition=tippoint;
439 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
443 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
444 ReflectVector(&velocity,&terrainnormal);
445 position+=terrainnormal*.002;
447 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
448 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
449 frictionness=abs(normaldotproduct(velocity,terrainnormal));
450 velocity-=bounceness;
451 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
453 velocity+=bounceness*elasticity;
455 if(findLengthfast(&bounceness)>1){
457 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
458 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
459 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
464 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
468 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
469 ReflectVector(&tipvelocity,&terrainnormal);
470 tippoint+=terrainnormal*.002;
472 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
473 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
474 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
475 tipvelocity-=bounceness;
476 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
478 tipvelocity+=bounceness*elasticity;
480 if(findLengthfast(&bounceness)>1){
482 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
483 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
484 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
488 if((objects.type[k]!=boxtype&&objects.type[k]!=platformtype&&objects.type[k]!=walltype&&objects.type[k]!=weirdtype)||objects.rotation2[k]!=0)
490 mid=(position*(21+(float)m*10)+tippoint*(19-(float)m*10))/40;
492 oldmid=(oldposition*(21+(float)m*10)+oldtippoint*(19-(float)m*10))/40;
496 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
500 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
501 ReflectVector(&velocity,&terrainnormal);
503 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
504 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
505 frictionness=abs(normaldotproduct(velocity,terrainnormal));
506 velocity-=bounceness;
507 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
509 velocity+=bounceness*elasticity;
511 if(findLengthfast(&bounceness)>1){
513 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
514 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
515 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
517 position+=(mid-oldmid2)*(20/(1+(float)m*10));
520 mid=(position*(19-(float)m*10)+tippoint*(21+(float)m*10))/40;
522 oldmid=(oldposition*(19-(float)m*10)+oldtippoint*(21+(float)m*10))/40;
526 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
530 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
531 ReflectVector(&tipvelocity,&terrainnormal);
533 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
534 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
535 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
536 tipvelocity-=bounceness;
537 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
539 tipvelocity+=bounceness*elasticity;
541 if(findLengthfast(&bounceness)>1){
543 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
544 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
545 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
547 tippoint+=(mid-oldmid2)*(20/(1+(float)m*10));
554 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.rotation[k]);
558 closestswordpoint=colpoint;//(position+tippoint)/2;
559 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.rotation[k],0)+objects.position[k];
560 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.rotation[k],0)+objects.position[k];
561 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.rotation[k],0)+objects.position[k];
562 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint ))
563 if(distance<closestdistance||closestdistance==-1){
564 closestpoint=colpoint;
565 closestdistance=distance;
567 if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint ))
568 if(distance<closestdistance||closestdistance==-1){
569 closestpoint=colpoint;
570 closestdistance=distance;
572 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint ))
573 if(distance<closestdistance||closestdistance==-1){
574 closestpoint=colpoint;
575 closestdistance=distance;
577 if(closestdistance!=-1&&isnormal(closestdistance)){
578 if(DistancePointLine(&closestpoint, &position, &tippoint, &distance,&colpoint )){
579 closestswordpoint=colpoint;
580 velocity+=(closestpoint-closestswordpoint);
581 tipvelocity+=(closestpoint-closestswordpoint);
582 position+=(closestpoint-closestswordpoint);
583 tippoint+=(closestpoint-closestswordpoint);
592 whichhit=terrain.lineTerrain(oldposition,position,&colpoint);
593 if(whichhit!=-1||position.y<terrain.getHeight(position.x,position.z)){
595 if(whichhit!=-1)position=colpoint*terrain.scale;
596 else position.y=terrain.getHeight(position.x,position.z);
598 terrainnormal=terrain.getNormal(position.x,position.z);
599 ReflectVector(&velocity,&terrainnormal);
600 position+=terrainnormal*.002;
601 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
602 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
603 frictionness=abs(normaldotproduct(velocity,terrainnormal));
604 velocity-=bounceness;
605 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
607 if(terrain.getOpacity(position.x,position.z)<.2)velocity+=bounceness*elasticity*.3;
608 else velocity+=bounceness*elasticity;
609 //if (type==knife) printf("velocity of knife %d now %f,%f,%f.\n", i, velocity.x, velocity.y, velocity.z);
610 if(findLengthfast(&bounceness)>1){
612 if(terrain.getOpacity(position.x,position.z)>.2){
613 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
614 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
616 else whichsound=footstepsound+abs(Random()%2);
617 emit_sound_at(whichsound, position,
618 findLengthfast(&bounceness)
619 * (terrain.getOpacity(position.x,position.z) > .2
623 if(terrain.getOpacity(position.x,position.z)<.2){
625 terrainlight=terrain.getLighting(position.x,position.z);
626 if(environment==snowyenvironment){
627 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
629 else if(environment==grassyenvironment){
630 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
632 else if(environment==desertenvironment){
633 if(findDistancefast(&position,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
638 whichhit=terrain.lineTerrain(oldtippoint,tippoint,&colpoint);
639 if(whichhit!=-1||tippoint.y<terrain.getHeight(tippoint.x,tippoint.z)){
640 if(whichhit!=-1)tippoint=colpoint*terrain.scale;
641 else tippoint.y=terrain.getHeight(tippoint.x,tippoint.z);
643 terrainnormal=terrain.getNormal(tippoint.x,tippoint.z);
644 ReflectVector(&tipvelocity,&terrainnormal);
645 tippoint+=terrainnormal*.002;
646 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
647 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
648 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
649 tipvelocity-=bounceness;
650 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
652 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2)tipvelocity+=bounceness*elasticity*.3;
653 else tipvelocity+=bounceness*elasticity;
654 //if (type==knife) printf("tipvelocity of knife %d now %f,%f,%f.\n", i, tipvelocity.x, tipvelocity.y, tipvelocity.z);
656 if(findLengthfast(&bounceness)>1){
658 if(terrain.getOpacity(tippoint.x,tippoint.z)>.2){
659 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
660 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
662 else whichsound=footstepsound+abs(Random()%2);
663 emit_sound_at(whichsound, tippoint,
664 findLengthfast(&bounceness)
665 * (terrain.getOpacity(tippoint.x,tippoint.z) > .2
669 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2){
671 terrainlight=terrain.getLighting(tippoint.x,tippoint.z);
672 if(environment==snowyenvironment){
673 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
675 else if(environment==grassyenvironment){
676 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
678 else if(environment==desertenvironment){
679 if(findDistancefast(&tippoint,&viewer)<viewdistance*viewdistance/4)Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
686 mid=position+tippoint;
688 mid+=(position-mid)/20;
690 if(mid.y<terrain.getHeight(mid.x,mid.z)){
692 mid.y=terrain.getHeight(mid.x,mid.z);
694 terrainnormal=terrain.getNormal(mid.x,mid.z);
695 ReflectVector(&velocity,&terrainnormal);
696 //mid+=terrainnormal*.002;
697 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
698 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
699 frictionness=abs(normaldotproduct(velocity,terrainnormal));
700 velocity-=bounceness;
701 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
703 if(terrain.getOpacity(mid.x,mid.z)<.2)velocity+=bounceness*elasticity*.3;
704 else velocity+=bounceness*elasticity;
706 if(findLengthfast(&bounceness)>1){
708 if(terrain.getOpacity(mid.x,mid.z)>.2){
709 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
710 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
712 else whichsound=footstepsound+abs(Random()%2);
713 emit_sound_at(whichsound, mid,
714 findLengthfast(&bounceness)
715 * (terrain.getOpacity(position.x,position.z) > .2
719 position+=(mid-oldmid)*20;
722 mid=position+tippoint;
724 mid+=(tippoint-mid)/20;
726 if(mid.y<terrain.getHeight(mid.x,mid.z)){
728 mid.y=terrain.getHeight(mid.x,mid.z);
730 terrainnormal=terrain.getNormal(mid.x,mid.z);
731 ReflectVector(&tipvelocity,&terrainnormal);
732 //mid+=terrainnormal*.002;
733 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
734 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
735 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
736 tipvelocity-=bounceness;
737 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
739 if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity+=bounceness*elasticity*.3;
740 else tipvelocity+=bounceness*elasticity;
742 if(findLengthfast(&bounceness)>1){
744 if(terrain.getOpacity(mid.x,mid.z)>.2){
745 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
746 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
748 else whichsound=footstepsound+abs(Random()%2);
749 emit_sound_at(whichsound, mid,
750 findLengthfast(&bounceness)
751 * (terrain.getOpacity(position.x,position.z) > .2
755 tippoint+=(mid-oldmid)*20;
758 velocity.y+=gravity*multiplier;
759 tipvelocity.y+=gravity*multiplier;
760 //position.y+=gravity*multiplier*multiplier;
761 //tippoint.y+=gravity*multiplier*multiplier;
764 XYZ temppoint1,temppoint2,tempforward;
769 distance=findDistance(&temppoint1,&temppoint2);
770 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
774 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
782 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
785 if(findLengthfast(&velocity)<.3&&findLengthfast(&tipvelocity)<.3&&hitsomething){
786 freetime+=multiplier;
789 //velocity=(position-oldposition)/multiplier;
790 //tipvelocity==(tippoint[i-+oldtippoint)/multiplier;
799 if(blooddrip&&bloody){
800 blooddripdelay-=blooddrip*multiplier/2;
801 blooddrip-=multiplier;
802 if(blooddrip<0)blooddrip=0;
803 if(blooddrip>5)blooddrip=5;
804 if(blooddripdelay<0&&bloodtoggle){
808 bloodloc=position+(tippoint-position)*.7;
812 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
817 flamedelay-=multiplier;
818 if(onfire&&flamedelay<=0){
820 flamedelay-=multiplier;
823 normalrot=player[owner].velocity;
827 if(player[owner].onterrain){
831 Sprite::MakeSprite(weaponflamesprite, position+tippoint*(((float)abs(Random()%100))/600+.05),normalrot, 1,1,1, (.6+(float)abs(Random()%100)/200-.25)*1/3, 1);
832 Sprite::setLastSpriteSpeed(4);
833 Sprite::setLastSpriteAlivetime(.3);
837 if(!onfire&&owner==-1&&type!=staff){
838 flamedelay-=multiplier;
841 flamedelay-=multiplier;
843 if(Random()%50==0&&findDistancefast(&position,&viewer)>80){
845 shinepoint=position+(tippoint-position)*(((float)abs(Random()%100))/100);
846 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
847 Sprite::setLastSpriteSpeed(4);
848 Sprite::setLastSpriteAlivetime(.3);
854 void Weapons::DoStuff() {
857 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
858 weapon->DoStuff(i++);
862 void Weapon::Draw() {
864 static XYZ terrainlight;
865 static GLfloat M[16];
868 if((frustum.SphereInFrustum(position.x,position.y,position.z,1)&&findDistancefast(&viewer,&position)<viewdistance*viewdistance))
874 if(velocity.x&&!physics)drawhowmany=10;
879 if(player[owner].occluded<25)
880 if((frustum.SphereInFrustum(player[owner].coords.x,player[owner].coords.y+player[owner].scale*3,player[owner].coords.z,player[owner].scale*8)&&findDistancefast(&viewer,&player[owner].coords)<viewdistance*viewdistance)||player[owner].skeleton.free==3)
882 if((player[owner].targetanimation==knifeslashstartanim||player[owner].targetanimation==swordsneakattackanim||(player[owner].currentanimation==staffhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffspinhitreversedanim&&player[owner].currentframe>1)||(player[owner].currentanimation==staffgroundsmashanim&&player[owner].currentframe>1)||(player[owner].targetanimation==swordslashanim&&player[owner].targetframe<7)||player[owner].targetanimation==crouchstabanim||player[owner].targetanimation==swordslashreversalanim||player[owner].targetanimation==swordslashreversedanim||player[owner].targetanimation==knifefollowanim||player[owner].targetanimation==swordgroundstabanim||player[owner].targetanimation==knifethrowanim)&&player[owner].targetanimation==lastdrawnanim&&!player[owner].skeleton.free)
887 if(player[owner].targetanimation==swordgroundstabanim)
889 lastdrawnrotation1=rotation1;
890 lastdrawnrotation2=rotation2;
891 lastdrawnrotation3=rotation3;
892 lastdrawnbigrotation=bigrotation;
893 lastdrawnbigtilt=bigtilt;
894 lastdrawnbigtilt2=bigtilt2;
895 lastdrawnsmallrotation=smallrotation;
896 lastdrawnsmallrotation2=smallrotation2;
901 terrainlight=terrain.getLighting(position.x,position.z);
904 glAlphaFunc(GL_GREATER, 0.01);
906 for(j=drawhowmany;j>0;j--)
908 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
910 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany);
911 if(owner!=-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)-.02+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
912 if(owner==-1)glTranslatef(position.x*(((float)(j))/drawhowmany)+lastdrawnposition.x*(1-((float)(j))/drawhowmany),position.y*(((float)(j))/drawhowmany)+lastdrawnposition.y*(1-((float)(j))/drawhowmany),position.z*(((float)(j))/drawhowmany)+lastdrawnposition.z*(1-((float)(j))/drawhowmany));
913 //glTranslatef(position.x,position.y-.02,position.z);
914 glRotatef(bigrotation*(((float)(j))/drawhowmany)+lastdrawnbigrotation*(1-((float)(j))/drawhowmany),0,1,0);
915 glRotatef(bigtilt2*(((float)(j))/drawhowmany)+lastdrawnbigtilt2*(1-((float)(j))/drawhowmany),1,0,0);
916 glRotatef(bigtilt*(((float)(j))/drawhowmany)+lastdrawnbigtilt*(1-((float)(j))/drawhowmany),0,0,1);
917 glRotatef(-rotation1*(((float)(j))/drawhowmany)-lastdrawnrotation1*(1-((float)(j))/drawhowmany)+90,0,1,0);
918 glRotatef(-rotation2*(((float)(j))/drawhowmany)-lastdrawnrotation2*(1-((float)(j))/drawhowmany)+90,0,0,1);
919 glRotatef(-rotation3*(((float)(j))/drawhowmany)-lastdrawnrotation3*(1-((float)(j))/drawhowmany),0,1,0);
920 glRotatef(smallrotation*(((float)(j))/drawhowmany)+lastdrawnsmallrotation*(1-((float)(j))/drawhowmany),1,0,0);
921 glRotatef(smallrotation2*(((float)(j))/drawhowmany)+lastdrawnsmallrotation2*(1-((float)(j))/drawhowmany),0,1,0);
925 if(player[owner].targetanimation==staffhitanim||player[owner].currentanimation==staffhitanim||player[owner].targetanimation==staffhitreversedanim||player[owner].currentanimation==staffhitreversedanim)
927 glTranslatef(0,0,-.3);
929 if(player[owner].targetanimation==staffgroundsmashanim||player[owner].currentanimation==staffgroundsmashanim||player[owner].targetanimation==staffspinhitreversedanim||player[owner].currentanimation==staffspinhitreversedanim||player[owner].targetanimation==staffspinhitanim||player[owner].currentanimation==staffspinhitanim)
931 glTranslatef(0,0,-.1);
935 glEnable(GL_LIGHTING);
938 if(!bloody||!bloodtoggle)
939 throwingknifemodel.drawdifftex(knifetextureptr);
943 throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
945 throwingknifemodel.drawdifftex(bloodknifetextureptr);
949 if(!bloody||!bloodtoggle)
950 swordmodel.drawdifftex(swordtextureptr);
954 swordmodel.drawdifftex(lightbloodswordtextureptr);
956 swordmodel.drawdifftex(bloodswordtextureptr);
960 staffmodel.drawdifftex(stafftextureptr);
967 lastdrawnposition=position;
968 lastdrawntippoint=tippoint;
969 lastdrawnrotation1=rotation1;
970 lastdrawnrotation2=rotation2;
971 lastdrawnrotation3=rotation3;
972 lastdrawnbigrotation=bigrotation;
973 lastdrawnbigtilt=bigtilt;
974 lastdrawnbigtilt2=bigtilt2;
975 lastdrawnsmallrotation=smallrotation;
976 lastdrawnsmallrotation2=smallrotation2;
977 if(owner!=-1)lastdrawnanim=player[owner].currentanimation;
981 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
984 glTranslatef(position.x,position.y-.02,position.z);
985 glRotatef(bigrotation,0,1,0);
986 glRotatef(bigtilt2,1,0,0);
987 glRotatef(bigtilt,0,0,1);
988 glRotatef(-rotation1+90,0,1,0);
989 glRotatef(-rotation2+90,0,0,1);
990 glRotatef(-rotation3,0,1,0);
991 glRotatef(smallrotation,1,0,0);
992 glRotatef(smallrotation2,0,1,0);
993 glTranslatef(0,0,length);
994 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1005 glAlphaFunc(GL_GREATER, 0.9);
1006 glEnable(GL_TEXTURE_2D);
1008 glEnable(GL_CULL_FACE);
1009 glCullFace(GL_FRONT);
1012 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1024 if (Weapon::stafftextureptr) glDeleteTextures( 1, &Weapon::stafftextureptr );
1025 if (Weapon::knifetextureptr) glDeleteTextures( 1, &Weapon::knifetextureptr );
1026 if (Weapon::lightbloodknifetextureptr) glDeleteTextures( 1, &Weapon::lightbloodknifetextureptr );
1027 if (Weapon::bloodknifetextureptr) glDeleteTextures( 1, &Weapon::bloodknifetextureptr );
1028 if (Weapon::swordtextureptr) glDeleteTextures( 1, &Weapon::swordtextureptr );
1029 if (Weapon::lightbloodswordtextureptr) glDeleteTextures( 1, &Weapon::lightbloodswordtextureptr );
1030 if (Weapon::bloodswordtextureptr) glDeleteTextures( 1, &Weapon::bloodswordtextureptr );