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 Texture Weapon::knifetextureptr;
58 Texture Weapon::lightbloodknifetextureptr;
59 Texture Weapon::bloodknifetextureptr;
61 Model Weapon::swordmodel;
62 Texture Weapon::swordtextureptr;
63 Texture Weapon::lightbloodswordtextureptr;
64 Texture Weapon::bloodswordtextureptr;
66 Model Weapon::staffmodel;
67 Texture Weapon::stafftextureptr;
69 Weapon::Weapon(int t, int o) : owner(o) {
81 void Weapon::setType(int t) {
100 void Weapon::DoStuff(int i) {
101 //~ cout << position.x << "," << position.y << "," << position.z << "|" << tippoint.x << "," << tippoint.y << "," << tippoint.z << endl;
102 static int whichpatchx,whichpatchz,whichhit;
103 static XYZ start,end,colpoint,normalrot,footvel,footpoint;
104 static XYZ terrainnormal;
107 static XYZ newpoint1,newpoint2;
108 static float friction=3.5;
109 static float elasticity=.4;
110 static XYZ bounceness;
111 static float frictionness;
112 static float closestdistance;
113 static float distance;
115 static XYZ closestpoint;
116 static XYZ closestswordpoint;
117 static XYZ extramove;
118 static float tempmult;
123 if(damage>=2 && type==staff && owner!=-1) { // the staff breaks
124 emit_sound_at(staffbreaksound, tippoint);
126 for(int j=0;j<40;j++) {
127 tempvel.x=float(abs(Random()%100)-50)/20;
128 tempvel.y=float(abs(Random()%100)-50)/20;
129 tempvel.z=float(abs(Random()%100)-50)/20;
130 Sprite::MakeSprite(splintersprite, position+(tippoint-position)*((float)j-8)/32,tempvel*.5, 115/255,73/255,12/255, .1, 1);
133 player[owner].weaponactive=-1;
134 player[owner].num_weapons--;
135 if(player[owner].num_weapons) {
136 player[owner].weaponids[0]=player[owner].weaponids[player[owner].num_weapons];
137 if(player[owner].weaponstuck==player[owner].num_weapons)
138 player[owner].weaponstuck=0;
149 oldposition=position;
150 oldtippoint=tippoint;
151 if(owner==-1 && (velocity.x||velocity.y||velocity.z) && !physics) { // if the weapon is flying
152 position+=velocity*multiplier;
153 tippoint+=velocity*multiplier;
154 whichpatchx=position.x/(terrain.size/subdivision*terrain.scale);
155 whichpatchz=position.z/(terrain.size/subdivision*terrain.scale);
156 if(whichpatchx>0 && whichpatchz>0 && whichpatchx<subdivision && whichpatchz<subdivision) {
157 if(terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are objects where the weapon is
158 for(int j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++) { // check for collision
159 int k=terrain.patchobjects[whichpatchx][whichpatchz][j];
162 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
164 if(objects.type[k]==treetrunktype){
165 objects.model[k].MakeDecal(breakdecal,DoRotation(colpoint-objects.position[k],0,-objects.yaw[k],0),.1,1,Random()%360);
166 normalrot=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0);
169 position=colpoint-normalrot*.1;
171 position=colpoint-normalrot*.2;
173 position=colpoint-normalrot*.2;
174 XYZ temppoint1,temppoint2,tempforward;
178 temppoint2=normalrot;
179 distance=findDistance(&temppoint1,&temppoint2);
180 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
184 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
186 if(temppoint1.x>temppoint2.x)
187 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;
214 if(velocity.x||velocity.y||velocity.z) {
215 for(int j=0;j<numplayers;j++) {
217 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].yaw,0)*player[j].scale+player[j].coords;
218 if(owner==-1 && distsqflat(&position,&player[j].coords)<1.5 &&
219 distsq(&position,&player[j].coords)<4 && player[j].weaponstuck==-1 &&
220 !player[j].skeleton.free && j!=oldowner) {
221 if((player[j].aitype!=attacktypecutoff||abs(Random()%6)==0||(player[j].animTarget!=backhandspringanim&&player[j].animTarget!=rollanim&&player[j].animTarget!=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].animTarget==walkanim))||
223 (player[j].creature==rabbittype && Random()%2==0 && player[j].aitype==attacktypecutoff && player[j].weaponactive==-1)) {
224 emit_sound_at(knifedrawsound, player[j].coords, 128.);
226 player[j].weaponactive=0;
227 player[j].animTarget=removeknifeanim;
228 player[j].frameTarget=1;
231 if(player[j].num_weapons>0){
232 player[j].weaponids[player[j].num_weapons]=player[j].weaponids[0];
234 player[j].num_weapons++;
235 player[j].weaponids[0]=i;
237 player[j].aitype=attacktypecutoff;
240 if(j!=0) numthrowkill++;
241 player[j].num_weapons++;
242 player[j].weaponstuck=player[j].num_weapons-1;
243 if(normaldotproduct(player[j].facing,velocity)>0)
244 player[j].weaponstuckwhere=1;
246 player[j].weaponstuckwhere=0;
248 player[j].weaponids[player[j].num_weapons-1]=i;
250 player[j].RagDoll(0);
251 player[j].skeleton.joints[player[j].skeleton.jointlabels[abdomen]].velocity+=velocity*2;
252 player[j].skeleton.joints[player[j].skeleton.jointlabels[neck]].velocity+=velocity*2;
253 player[j].skeleton.joints[player[j].skeleton.jointlabels[rightshoulder]].velocity+=velocity*2;
254 player[j].skeleton.joints[player[j].skeleton.jointlabels[leftshoulder]].velocity+=velocity*2;
255 if(bloodtoggle&&tutoriallevel!=1)
256 Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,0,0, .8, .3);
258 Sprite::MakeSprite(cloudimpactsprite, footpoint,footvel, 1,1,1, .8, .3);
259 footvel=tippoint-position;
261 if(bloodtoggle&&tutoriallevel!=1)
262 Sprite::MakeSprite(bloodflamesprite, footpoint,footvel*-1, 1,0,0, .6, 1);
264 if(tutoriallevel!=1) {
265 if(player[j].weaponstuckwhere==0)
266 player[j].DoBloodBig(2,205);
267 if(player[j].weaponstuckwhere==1)
268 player[j].DoBloodBig(2,200);
269 player[j].damage+=200/player[j].armorhigh;
270 player[j].deathbleeding=1;
271 player[j].bloodloss+=(200+abs((float)(Random()%40))-20)/player[j].armorhigh;
277 emit_sound_at(fleshstabsound, position, 128.);
279 if(animation[player[0].animTarget].height==highheight)
280 award_bonus(0, ninja);
282 award_bonus(0, Bullseyebonus);
289 if(position.y<terrain.getHeight(position.x,position.z)) {
290 if(terrain.getOpacity(position.x,position.z)<.2) {
292 if(terrain.lineTerrain(oldposition,position,&colpoint)!=-1) {
293 position=colpoint*terrain.scale;
295 position.y=terrain.getHeight(position.x,position.z);
298 terrain.MakeDecal(shadowdecalpermanent,position,.06,.5,0);
299 normalrot=terrain.getNormal(position.x,position.z)*-1;
301 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
305 glRotatef(bigrotation,0,1,0);
306 glRotatef(bigtilt2,1,0,0);
307 glRotatef(bigtilt,0,0,1);
308 glRotatef(-rotation1+90,0,1,0);
309 glRotatef(-rotation2+90,0,0,1);
310 glRotatef(-rotation3,0,1,0);
311 glRotatef(smallrotation,1,0,0);
312 glRotatef(smallrotation2,0,1,0);
314 glGetFloatv(GL_MODELVIEW_MATRIX,M);
319 position-=tippoint*.15;
320 XYZ temppoint1,temppoint2,tempforward;
329 emit_sound_at(knifesheathesound, position, 128.);
332 terrainlight=terrain.getLighting(position.x,position.z);
333 if(environment==snowyenvironment){
334 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
335 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
337 else if(environment==grassyenvironment){
338 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
339 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
341 else if(environment==desertenvironment){
342 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
343 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
351 position-=velocity*multiplier;
352 tippoint-=velocity*multiplier;
353 tipvelocity=velocity;
356 if(velocity.x!=0||velocity.z!=0||velocity.y!=0) {
357 velocity.y+=gravity*multiplier;
359 XYZ temppoint1,temppoint2,tempforward;
364 distance=findDistance(&temppoint1,&temppoint2);
365 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
369 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
377 if(temppoint1.x>temppoint2.x) rotation1=360-rotation1;
389 for(int l=0;l<10;l++) {
390 if(owner==-1&&(velocity.x||velocity.y||velocity.z)&&physics) {
392 position+=velocity*multiplier;
393 tippoint+=tipvelocity*multiplier;
396 midp=(position*mass+tippoint*tipmass)/(mass+tipmass);
399 newpoint1=midp-vel*length*(tipmass/(mass+tipmass));
400 newpoint2=midp+vel*length*(mass/(mass+tipmass));
403 velocity=velocity+(newpoint1-position)/multiplier;
404 tipvelocity=tipvelocity+(newpoint2-tippoint)/multiplier;
412 whichpatchx=(position.x)/(terrain.size/subdivision*terrain.scale);
413 whichpatchz=(position.z)/(terrain.size/subdivision*terrain.scale);
414 if(whichpatchx>0&&whichpatchz>0&&whichpatchx<subdivision&&whichpatchz<subdivision)
415 if(terrain.patchobjectnum[whichpatchx][whichpatchz]) {
416 for(int j=0;j<terrain.patchobjectnum[whichpatchx][whichpatchz];j++) {
417 int k=terrain.patchobjects[whichpatchx][whichpatchz][j];
421 start=tippoint-(position-tippoint)/5;
422 end=position+(position-tippoint)/30;
423 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
426 diff=(colpoint-position);
430 tippoint+=(colpoint-position)+diff*.05;
431 position=colpoint+diff*.05;
432 oldtippoint=tippoint;
433 oldposition=tippoint;
436 start=position-(tippoint-position)/5;
437 end=tippoint+(tippoint-position)/30;
438 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
441 diff=(colpoint-tippoint);
445 position+=(colpoint-tippoint)+diff*.05;
446 tippoint=colpoint+diff*.05;
447 oldposition=position;
448 oldtippoint=tippoint;
455 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
459 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0)*-1;
460 ReflectVector(&velocity,&terrainnormal);
461 position+=terrainnormal*.002;
463 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
464 if(findLengthfast(&velocity)<findLengthfast(&bounceness))
466 frictionness=abs(normaldotproduct(velocity,terrainnormal));
467 velocity-=bounceness;
468 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
470 velocity+=bounceness*elasticity;
472 if(findLengthfast(&bounceness)>1) {
475 whichsound=footstepsound3+abs(Random()%2);
477 whichsound=clank1sound+abs(Random()%4);
478 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
483 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
487 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0)*-1;
488 ReflectVector(&tipvelocity,&terrainnormal);
489 tippoint+=terrainnormal*.002;
491 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
492 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
493 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
494 tipvelocity-=bounceness;
495 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
497 tipvelocity+=bounceness*elasticity;
499 if(findLengthfast(&bounceness)>1){
502 whichsound=footstepsound3+abs(Random()%2);
504 whichsound=clank1sound+abs(Random()%4);
505 emit_sound_at(whichsound, position, 128*findLengthfast(&bounceness));
509 if((objects.type[k]!=boxtype && objects.type[k]!=platformtype && objects.type[k]!=walltype && objects.type[k]!=weirdtype)||objects.pitch[k]!=0)
510 for(int m=0;m<2;m++){
511 mid=(position*(21+(float)m*10)+tippoint*(19-(float)m*10))/40;
513 oldmid=(oldposition*(21+(float)m*10)+oldtippoint*(19-(float)m*10))/40;
517 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
521 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0)*-1;
522 ReflectVector(&velocity,&terrainnormal);
524 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
525 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
526 frictionness=abs(normaldotproduct(velocity,terrainnormal));
527 velocity-=bounceness;
528 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
530 velocity+=bounceness*elasticity;
532 if(findLengthfast(&bounceness)>1){
535 whichsound=footstepsound3+abs(Random()%2);
537 whichsound=clank1sound+abs(Random()%4);
538 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
540 position+=(mid-oldmid2)*(20/(1+(float)m*10));
543 mid=(position*(19-(float)m*10)+tippoint*(21+(float)m*10))/40;
545 oldmid=(oldposition*(19-(float)m*10)+oldtippoint*(21+(float)m*10))/40;
549 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
553 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0)*-1;
554 ReflectVector(&tipvelocity,&terrainnormal);
556 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
557 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
558 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
559 tipvelocity-=bounceness;
560 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
562 tipvelocity+=bounceness*elasticity;
564 if(findLengthfast(&bounceness)>1){
567 whichsound=footstepsound3+abs(Random()%2);
569 whichsound=clank1sound+abs(Random()%4);
570 emit_sound_at(whichsound, mid, 128*findLengthfast(&bounceness));
572 tippoint+=(mid-oldmid2)*(20/(1+(float)m*10));
579 whichhit=objects.model[k].LineCheck(&start,&end,&colpoint,&objects.position[k],&objects.yaw[k]);
583 closestswordpoint=colpoint;//(position+tippoint)/2;
584 point[0]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]],0,objects.yaw[k],0)+objects.position[k];
585 point[1]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]],0,objects.yaw[k],0)+objects.position[k];
586 point[2]=DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]],0,objects.yaw[k],0)+objects.position[k];
587 if(DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance,&colpoint )) {
588 if(distance<closestdistance||closestdistance==-1){
589 closestpoint=colpoint;
590 closestdistance=distance;
593 if(DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance,&colpoint )) {
594 if(distance<closestdistance||closestdistance==-1){
595 closestpoint=colpoint;
596 closestdistance=distance;
599 if(DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance,&colpoint )) {
600 if(distance<closestdistance||closestdistance==-1){
601 closestpoint=colpoint;
602 closestdistance=distance;
605 if(closestdistance!=-1 && isnormal(closestdistance)) {
606 if(DistancePointLine(&closestpoint, &position, &tippoint, &distance,&colpoint )) {
607 closestswordpoint=colpoint;
608 velocity+=(closestpoint-closestswordpoint);
609 tipvelocity+=(closestpoint-closestswordpoint);
610 position+=(closestpoint-closestswordpoint);
611 tippoint+=(closestpoint-closestswordpoint);
619 whichhit=terrain.lineTerrain(oldposition,position,&colpoint);
620 if(whichhit!=-1||position.y<terrain.getHeight(position.x,position.z)) {
623 position=colpoint*terrain.scale;
625 position.y=terrain.getHeight(position.x,position.z);
627 terrainnormal=terrain.getNormal(position.x,position.z);
628 ReflectVector(&velocity,&terrainnormal);
629 position+=terrainnormal*.002;
630 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
631 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
632 frictionness=abs(normaldotproduct(velocity,terrainnormal));
633 velocity-=bounceness;
634 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
636 if(terrain.getOpacity(position.x,position.z)<.2)velocity+=bounceness*elasticity*.3;
637 else velocity+=bounceness*elasticity;
639 if(findLengthfast(&bounceness)>1) {
641 if(terrain.getOpacity(position.x,position.z)>.2){
643 whichsound=footstepsound3+abs(Random()%2);
645 whichsound=clank1sound+abs(Random()%4);
647 whichsound=footstepsound+abs(Random()%2);
649 emit_sound_at(whichsound, position,
650 findLengthfast(&bounceness)
651 * (terrain.getOpacity(position.x,position.z) > .2 ? 128. : 32.));
653 if(terrain.getOpacity(position.x,position.z)<.2) {
655 terrainlight=terrain.getLighting(position.x,position.z);
656 if(environment==snowyenvironment){
657 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
658 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
660 else if(environment==grassyenvironment){
661 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
662 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
664 else if(environment==desertenvironment){
665 if(distsq(&position,&viewer)<viewdistance*viewdistance/4)
666 Sprite::MakeSprite(cloudsprite, position,velocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
671 whichhit=terrain.lineTerrain(oldtippoint,tippoint,&colpoint);
672 if(whichhit!=-1||tippoint.y<terrain.getHeight(tippoint.x,tippoint.z)) {
674 tippoint=colpoint*terrain.scale;
676 tippoint.y=terrain.getHeight(tippoint.x,tippoint.z);
678 terrainnormal=terrain.getNormal(tippoint.x,tippoint.z);
679 ReflectVector(&tipvelocity,&terrainnormal);
680 tippoint+=terrainnormal*.002;
681 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
682 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
683 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
684 tipvelocity-=bounceness;
685 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
687 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2)tipvelocity+=bounceness*elasticity*.3;
688 else tipvelocity+=bounceness*elasticity;
690 if(findLengthfast(&bounceness)>1){
692 if(terrain.getOpacity(tippoint.x,tippoint.z)>.2){
694 whichsound=footstepsound3+abs(Random()%2);
696 whichsound=clank1sound+abs(Random()%4);
698 whichsound=footstepsound+abs(Random()%2);
700 emit_sound_at(whichsound, tippoint,
701 findLengthfast(&bounceness)
702 * (terrain.getOpacity(tippoint.x,tippoint.z) > .2 ? 128. : 32.));
704 if(terrain.getOpacity(tippoint.x,tippoint.z)<.2) {
706 terrainlight=terrain.getLighting(tippoint.x,tippoint.z);
707 if(environment==snowyenvironment){
708 if(distsq(&tippoint,&viewer)<viewdistance*viewdistance/4)
709 Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
711 else if(environment==grassyenvironment){
712 if(distsq(&tippoint,&viewer)<viewdistance*viewdistance/4)
713 Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
715 else if(environment==desertenvironment){
716 if(distsq(&tippoint,&viewer)<viewdistance*viewdistance/4)
717 Sprite::MakeSprite(cloudsprite, tippoint,tipvelocity, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
724 mid=position+tippoint;
726 mid+=(position-mid)/20;
728 if(mid.y<terrain.getHeight(mid.x,mid.z)){
730 mid.y=terrain.getHeight(mid.x,mid.z);
732 terrainnormal=terrain.getNormal(mid.x,mid.z);
733 ReflectVector(&velocity,&terrainnormal);
734 //mid+=terrainnormal*.002;
735 bounceness=terrainnormal*findLength(&velocity)*(abs(normaldotproduct(velocity,terrainnormal)));
736 if(findLengthfast(&velocity)<findLengthfast(&bounceness))bounceness=0;
737 frictionness=abs(normaldotproduct(velocity,terrainnormal));
738 velocity-=bounceness;
739 if(1-friction*frictionness>0)velocity*=1-friction*frictionness;
741 if(terrain.getOpacity(mid.x,mid.z)<.2)velocity+=bounceness*elasticity*.3;
742 else velocity+=bounceness*elasticity;
744 if(findLengthfast(&bounceness)>1){
746 if(terrain.getOpacity(mid.x,mid.z)>.2){
747 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
748 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
750 else whichsound=footstepsound+abs(Random()%2);
751 emit_sound_at(whichsound, mid,
752 findLengthfast(&bounceness)
753 * (terrain.getOpacity(position.x,position.z) > .2
757 position+=(mid-oldmid)*20;
760 mid=position+tippoint;
762 mid+=(tippoint-mid)/20;
764 if(mid.y<terrain.getHeight(mid.x,mid.z)){
766 mid.y=terrain.getHeight(mid.x,mid.z);
768 terrainnormal=terrain.getNormal(mid.x,mid.z);
769 ReflectVector(&tipvelocity,&terrainnormal);
770 //mid+=terrainnormal*.002;
771 bounceness=terrainnormal*findLength(&tipvelocity)*(abs(normaldotproduct(tipvelocity,terrainnormal)));
772 if(findLengthfast(&tipvelocity)<findLengthfast(&bounceness))bounceness=0;
773 frictionness=abs(normaldotproduct(tipvelocity,terrainnormal));
774 tipvelocity-=bounceness;
775 if(1-friction*frictionness>0)tipvelocity*=1-friction*frictionness;
777 if(terrain.getOpacity(mid.x,mid.z)<.2)tipvelocity+=bounceness*elasticity*.3;
778 else tipvelocity+=bounceness*elasticity;
780 if(findLengthfast(&bounceness)>1){
782 if(terrain.getOpacity(mid.x,mid.z)>.2){
783 if(type==staff)whichsound=footstepsound3+abs(Random()%2);
784 if(type!=staff)whichsound=clank1sound+abs(Random()%4);
786 else whichsound=footstepsound+abs(Random()%2);
787 emit_sound_at(whichsound, mid,
788 findLengthfast(&bounceness)
789 * (terrain.getOpacity(position.x,position.z) > .2
793 tippoint+=(mid-oldmid)*20;
796 velocity.y+=gravity*multiplier;
797 tipvelocity.y+=gravity*multiplier;
800 XYZ temppoint1,temppoint2,tempforward;
805 distance=findDistance(&temppoint1,&temppoint2);
806 rotation2=asin((temppoint1.y-temppoint2.y)/distance);
810 rotation1=acos((temppoint1.z-temppoint2.z)/findDistance(&temppoint1,&temppoint2));
818 if(temppoint1.x>temppoint2.x)rotation1=360-rotation1;
821 if(findLengthfast(&velocity)<.3&&findLengthfast(&tipvelocity)<.3&&hitsomething){
822 freetime+=multiplier;
833 if(blooddrip && bloody) {
834 blooddripdelay-=blooddrip*multiplier/2;
835 blooddrip-=multiplier;
836 if(blooddrip<0) blooddrip=0;
837 if(blooddrip>5) blooddrip=5;
838 if(blooddripdelay<0 && bloodtoggle) {
842 bloodloc=position+(tippoint-position)*.7;
846 Sprite::MakeSprite(bloodsprite, bloodloc,bloodvel, 1,1,1, .03, 1);
851 flamedelay-=multiplier;
852 if(onfire&&flamedelay<=0) {
854 flamedelay-=multiplier;
857 normalrot=player[owner].velocity;
861 if(player[owner].onterrain) {
865 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);
866 Sprite::setLastSpriteSpeed(4);
867 Sprite::setLastSpriteAlivetime(.3);
871 if(!onfire && owner==-1 && type!=staff) {
872 flamedelay-=multiplier;
875 flamedelay-=multiplier;
877 if(Random()%50==0&&distsq(&position,&viewer)>80) {
879 shinepoint=position+(tippoint-position)*(((float)abs(Random()%100))/100);
880 Sprite::MakeSprite(weaponshinesprite, shinepoint,normalrot, 1,1,1, (.1+(float)abs(Random()%100)/200-.25)*1/3*fast_sqrt(findDistance(&shinepoint,&viewer)), 1);
881 Sprite::setLastSpriteSpeed(4);
882 Sprite::setLastSpriteAlivetime(.3);
888 void Weapons::DoStuff() {
891 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
892 weapon->DoStuff(i++);
896 void Weapon::Draw() {
897 static XYZ terrainlight;
898 static GLfloat M[16];
900 if((frustum.SphereInFrustum(position.x,position.y,position.z,1)&&
901 distsq(&viewer,&position)<viewdistance*viewdistance))
907 if(velocity.x && !physics)
912 if(player[owner].occluded<25)
913 if((frustum.SphereInFrustum(player[owner].coords.x,player[owner].coords.y+player[owner].scale*3,player[owner].coords.z,player[owner].scale*8)&&distsq(&viewer,&player[owner].coords)<viewdistance*viewdistance)||player[owner].skeleton.free==3)
916 (player[owner].animTarget==knifeslashstartanim||
917 player[owner].animTarget==swordsneakattackanim||
918 (player[owner].animCurrent==staffhitanim && player[owner].frameCurrent>1)||
919 (player[owner].animCurrent==staffhitreversedanim && player[owner].frameCurrent>1)||
920 (player[owner].animCurrent==staffspinhitanim && player[owner].frameCurrent>1)||
921 (player[owner].animCurrent==staffspinhitreversedanim && player[owner].frameCurrent>1)||
922 (player[owner].animCurrent==staffgroundsmashanim && player[owner].frameCurrent>1)||
923 (player[owner].animTarget==swordslashanim && player[owner].frameTarget<7)||
924 player[owner].animTarget==crouchstabanim||
925 player[owner].animTarget==swordslashreversalanim||
926 player[owner].animTarget==swordslashreversedanim||
927 player[owner].animTarget==knifefollowanim||
928 player[owner].animTarget==swordgroundstabanim||
929 player[owner].animTarget==knifethrowanim)&&
930 player[owner].animTarget==lastdrawnanim&&
931 !player[owner].skeleton.free
938 if(player[owner].animTarget==swordgroundstabanim)
940 lastdrawnrotation1=rotation1;
941 lastdrawnrotation2=rotation2;
942 lastdrawnrotation3=rotation3;
943 lastdrawnbigrotation=bigrotation;
944 lastdrawnbigtilt=bigtilt;
945 lastdrawnbigtilt2=bigtilt2;
946 lastdrawnsmallrotation=smallrotation;
947 lastdrawnsmallrotation2=smallrotation2;
952 terrainlight=terrain.getLighting(position.x,position.z);
955 glAlphaFunc(GL_GREATER, 0.01);
957 for(int j=drawhowmany;j>0;j--)
959 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
961 glColor4f(terrainlight.x,terrainlight.y,terrainlight.z,j/drawhowmany);
963 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));
965 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));
966 glRotatef(bigrotation*(((float)(j))/drawhowmany)+lastdrawnbigrotation*(1-((float)(j))/drawhowmany),0,1,0);
967 glRotatef(bigtilt2*(((float)(j))/drawhowmany)+lastdrawnbigtilt2*(1-((float)(j))/drawhowmany),1,0,0);
968 glRotatef(bigtilt*(((float)(j))/drawhowmany)+lastdrawnbigtilt*(1-((float)(j))/drawhowmany),0,0,1);
969 glRotatef(-rotation1*(((float)(j))/drawhowmany)-lastdrawnrotation1*(1-((float)(j))/drawhowmany)+90,0,1,0);
970 glRotatef(-rotation2*(((float)(j))/drawhowmany)-lastdrawnrotation2*(1-((float)(j))/drawhowmany)+90,0,0,1);
971 glRotatef(-rotation3*(((float)(j))/drawhowmany)-lastdrawnrotation3*(1-((float)(j))/drawhowmany),0,1,0);
972 glRotatef(smallrotation*(((float)(j))/drawhowmany)+lastdrawnsmallrotation*(1-((float)(j))/drawhowmany),1,0,0);
973 glRotatef(smallrotation2*(((float)(j))/drawhowmany)+lastdrawnsmallrotation2*(1-((float)(j))/drawhowmany),0,1,0);
977 if(player[owner].animTarget==staffhitanim||player[owner].animCurrent==staffhitanim||player[owner].animTarget==staffhitreversedanim||player[owner].animCurrent==staffhitreversedanim)
979 glTranslatef(0,0,-.3);
981 if(player[owner].animTarget==staffgroundsmashanim||player[owner].animCurrent==staffgroundsmashanim||player[owner].animTarget==staffspinhitreversedanim||player[owner].animCurrent==staffspinhitreversedanim||player[owner].animTarget==staffspinhitanim||player[owner].animCurrent==staffspinhitanim)
983 glTranslatef(0,0,-.1);
987 glEnable(GL_LIGHTING);
990 if(!bloody||!bloodtoggle)
991 throwingknifemodel.drawdifftex(knifetextureptr);
995 throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
997 throwingknifemodel.drawdifftex(bloodknifetextureptr);
1001 if(!bloody||!bloodtoggle)
1002 swordmodel.drawdifftex(swordtextureptr);
1006 swordmodel.drawdifftex(lightbloodswordtextureptr);
1008 swordmodel.drawdifftex(bloodswordtextureptr);
1012 staffmodel.drawdifftex(stafftextureptr);
1019 lastdrawnposition=position;
1020 lastdrawntippoint=tippoint;
1021 lastdrawnrotation1=rotation1;
1022 lastdrawnrotation2=rotation2;
1023 lastdrawnrotation3=rotation3;
1024 lastdrawnbigrotation=bigrotation;
1025 lastdrawnbigtilt=bigtilt;
1026 lastdrawnbigtilt2=bigtilt2;
1027 lastdrawnsmallrotation=smallrotation;
1028 lastdrawnsmallrotation2=smallrotation2;
1029 if(owner!=-1)lastdrawnanim=player[owner].animCurrent;
1033 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1036 glTranslatef(position.x,position.y-.02,position.z);
1037 glRotatef(bigrotation,0,1,0);
1038 glRotatef(bigtilt2,1,0,0);
1039 glRotatef(bigtilt,0,0,1);
1040 glRotatef(-rotation1+90,0,1,0);
1041 glRotatef(-rotation2+90,0,0,1);
1042 glRotatef(-rotation3,0,1,0);
1043 glRotatef(smallrotation,1,0,0);
1044 glRotatef(smallrotation2,0,1,0);
1045 glTranslatef(0,0,length);
1046 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1057 glAlphaFunc(GL_GREATER, 0.9);
1058 glEnable(GL_TEXTURE_2D);
1060 glEnable(GL_CULL_FACE);
1061 glCullFace(GL_FRONT);
1064 for(std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1076 Weapon::stafftextureptr.destroy();
1077 Weapon::knifetextureptr.destroy();
1078 Weapon::lightbloodknifetextureptr.destroy();
1079 Weapon::bloodknifetextureptr.destroy();
1080 Weapon::swordtextureptr.destroy();
1081 Weapon::lightbloodswordtextureptr.destroy();
1082 Weapon::bloodswordtextureptr.destroy();