]> git.jsancho.org Git - lugaru.git/blob - Source/Weapons.cpp
144d9cc31334fbd1c3ae5c97947e3a3fc06ba4f1
[lugaru.git] / Source / Weapons.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 /**> HEADER FILES <**/
23 #include "Weapons.h"
24 #include "openal_wrapper.h"
25 #include "Animation.h"
26 #include "Sounds.h"
27 #include "Game.h"
28 #include "Awards.h"
29
30 extern float multiplier;
31 extern Terrain terrain;
32 extern float gravity;
33 extern int environment;
34 extern int detail;
35 extern FRUSTUM frustum;
36 extern XYZ viewer;
37 extern float realmultiplier;
38 extern int slomo;
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;
45 extern bool osx;
46 extern bool autoslomo;
47 extern float camerashake;
48 extern float woozy;
49 extern float viewdistance;
50 extern float blackout;
51 extern int difficulty;
52 extern bool freeze;
53 extern int tutoriallevel;
54 extern int numthrowkill;
55
56 Model Weapon::throwingknifemodel;
57 Texture Weapon::knifetextureptr;
58 Texture Weapon::lightbloodknifetextureptr;
59 Texture Weapon::bloodknifetextureptr;
60
61 Model Weapon::swordmodel;
62 Texture Weapon::swordtextureptr;
63 Texture Weapon::lightbloodswordtextureptr;
64 Texture Weapon::bloodswordtextureptr;
65
66 Model Weapon::staffmodel;
67 Texture Weapon::stafftextureptr;
68
69 Weapon::Weapon(int t, int o) : owner(o)
70 {
71     setType(t);
72     bloody = 0;
73     blooddrip = 0;
74     blooddripdelay = 0;
75     onfire = 0;
76     flamedelay = 0;
77     damage = 0;
78     position = -1000;
79     tippoint = -1000;
80 }
81
82 void Weapon::setType(int t)
83 {
84     type = t;
85     if (type == sword) {
86         mass = 1.5;
87         tipmass = 1;
88         length = .8;
89     }
90     if (type == staff) {
91         mass = 2;
92         tipmass = 1;
93         length = 1.5;
94     }
95     if (type == knife) {
96         mass = 1;
97         tipmass = 1.2;
98         length = .25;
99     }
100 }
101
102 void Weapon::DoStuff(int i)
103 {
104     //~ cout << position.x << "," << position.y << "," << position.z << "|" << tippoint.x << "," << tippoint.y << "," << tippoint.z << endl;
105     static int whichpatchx, whichpatchz, whichhit;
106     static XYZ start, end, colpoint, normalrot, footvel, footpoint;
107     static XYZ terrainnormal;
108     static XYZ vel;
109     static XYZ midp;
110     static XYZ newpoint1, newpoint2;
111     static float friction = 3.5;
112     static float elasticity = .4;
113     static XYZ bounceness;
114     static float frictionness;
115     static float closestdistance;
116     static float distance;
117     static XYZ point[3];
118     static XYZ closestpoint;
119     static XYZ closestswordpoint;
120     static XYZ extramove;
121     static float tempmult;
122
123     if (owner != -1) {
124         oldowner = owner;
125     }
126     if (damage >= 2 && type == staff && owner != -1) { // the staff breaks
127         emit_sound_at(staffbreaksound, tippoint);
128         XYZ tempvel;
129         for (int j = 0; j < 40; j++) {
130             tempvel.x = float(abs(Random() % 100) - 50) / 20;
131             tempvel.y = float(abs(Random() % 100) - 50) / 20;
132             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);
134         }
135         if (owner != -1) {
136             player[owner].weaponactive = -1;
137             player[owner].num_weapons--;
138             if (player[owner].num_weapons) {
139                 player[owner].weaponids[0] = player[owner].weaponids[player[owner].num_weapons];
140                 if (player[owner].weaponstuck == player[owner].num_weapons)
141                     player[owner].weaponstuck = 0;
142             }
143         }
144         owner = -1;
145         hitsomething = 0;
146         missed = 1;
147         freetime = 0;
148         firstfree = 1;
149         position = 0;
150         physics = 0;
151     }
152     oldposition = position;
153     oldtippoint = tippoint;
154     if (owner == -1 && (velocity.x || velocity.y || velocity.z) && !physics) { // if the weapon is flying
155         position += velocity * multiplier;
156         tippoint += velocity * multiplier;
157         whichpatchx = position.x / (terrain.size / subdivision * terrain.scale);
158         whichpatchz = position.z / (terrain.size / subdivision * terrain.scale);
159         if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision) {
160             if (terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are objects where the weapon is
161                 for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) { // check for collision
162                     int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
163                     start = oldtippoint;
164                     end = tippoint;
165                     whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
166                     if (whichhit != -1) {
167                         if (objects.type[k] == treetrunktype) {
168                             objects.model[k].MakeDecal(breakdecal, DoRotation(colpoint - objects.position[k], 0, -objects.yaw[k], 0), .1, 1, Random() % 360);
169                             normalrot = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0);
170                             velocity = 0;
171                             if (type == knife)
172                                 position = colpoint - normalrot * .1;
173                             else if (type == sword)
174                                 position = colpoint - normalrot * .2;
175                             else if (type == staff)
176                                 position = colpoint - normalrot * .2;
177                             XYZ temppoint1, temppoint2, tempforward;
178                             float distance;
179
180                             temppoint1 = 0;
181                             temppoint2 = normalrot;
182                             distance = findDistance(&temppoint1, &temppoint2);
183                             rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
184                             rotation2 *= 360 / 6.28;
185                             temppoint1.y = 0;
186                             temppoint2.y = 0;
187                             rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
188                             rotation1 *= 360 / 6.28;
189                             if (temppoint1.x > temppoint2.x)
190                                 rotation1 = 360 - rotation1;
191
192                             rotation3 = 0;
193                             smallrotation = 90;
194                             smallrotation2 = 0;
195                             bigtilt = 0;
196                             bigtilt2 = 0;
197                             bigrotation = 0;
198
199                             emit_sound_at(knifesheathesound, position, 128.);
200
201                             bloody = 0;
202
203                             Sprite::MakeSprite(cloudimpactsprite, position, velocity, 1, 1, 1, .8, .3);
204                         } else {
205                             physics = 1;
206                             firstfree = 1;
207                             position -= velocity * multiplier;
208                             tippoint -= velocity * multiplier;
209                             tipvelocity = velocity;
210                         }
211                     }
212                 }
213             }
214         }
215
216         if (velocity.x || velocity.y || velocity.z) {
217             for (int j = 0; j < numplayers; j++) {
218                 footvel = 0;
219                 footpoint = DoRotation((player[j].jointPos(abdomen) + player[j].jointPos(neck)) / 2, 0, player[j].yaw, 0) * player[j].scale + player[j].coords;
220                 if (owner == -1 && distsqflat(&position, &player[j].coords) < 1.5 &&
221                         distsq(&position, &player[j].coords) < 4 && player[j].weaponstuck == -1 &&
222                         !player[j].skeleton.free && j != oldowner) {
223                     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) {
224                         if ( (player[j].creature == wolftype    &&      Random() % 3 != 0 && player[j].weaponactive == -1 && (player[j].isIdle() || player[j].isRun() || player[j].animTarget == walkanim)) ||
225                                 (player[j].creature == rabbittype       &&      Random() % 2 == 0 && player[j].aitype == attacktypecutoff && player[j].weaponactive == -1)) {
226                             emit_sound_at(knifedrawsound, player[j].coords, 128.);
227
228                             player[j].weaponactive = 0;
229                             player[j].animTarget = removeknifeanim;
230                             player[j].frameTarget = 1;
231                             player[j].target = 1;
232                             owner = player[j].id;
233                             if (player[j].num_weapons > 0) {
234                                 player[j].weaponids[player[j].num_weapons] = player[j].weaponids[0];
235                             }
236                             player[j].num_weapons++;
237                             player[j].weaponids[0] = i;
238
239                             player[j].aitype = attacktypecutoff;
240                         } else {
241                             if (j != 0) numthrowkill++;
242                             player[j].num_weapons++;
243                             player[j].weaponstuck = player[j].num_weapons - 1;
244                             if (normaldotproduct(player[j].facing, velocity) > 0)
245                                 player[j].weaponstuckwhere = 1;
246                             else
247                                 player[j].weaponstuckwhere = 0;
248
249                             player[j].weaponids[player[j].num_weapons - 1] = i;
250
251                             player[j].RagDoll(0);
252                             player[j].jointVel(abdomen) += velocity * 2;
253                             player[j].jointVel(neck) += velocity * 2;
254                             player[j].jointVel(rightshoulder) += velocity * 2;
255                             player[j].jointVel(leftshoulder) += velocity * 2;
256                             if (bloodtoggle && tutoriallevel != 1)
257                                 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
258                             if (tutoriallevel == 1)
259                                 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .8, .3);
260                             footvel = tippoint - position;
261                             Normalise(&footvel);
262                             if (bloodtoggle && tutoriallevel != 1)
263                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * -1, 1, 0, 0, .6, 1);
264
265                             if (tutoriallevel != 1) {
266                                 if (player[j].weaponstuckwhere == 0)
267                                     player[j].DoBloodBig(2, 205);
268                                 if (player[j].weaponstuckwhere == 1)
269                                     player[j].DoBloodBig(2, 200);
270                                 player[j].damage += 200 / player[j].armorhigh;
271                                 player[j].deathbleeding = 1;
272                                 player[j].bloodloss += (200 + abs((float)(Random() % 40)) - 20) / player[j].armorhigh;
273                                 owner = j;
274                                 bloody = 2;
275                                 blooddrip = 5;
276                             }
277
278                             emit_sound_at(fleshstabsound, position, 128.);
279
280                             if (animation[player[0].animTarget].height == highheight)
281                                 award_bonus(0, ninja);
282                             else
283                                 award_bonus(0, Bullseyebonus);
284                         }
285                     } else missed = 1;
286                 }
287             }
288         }
289         if (position.y < terrain.getHeight(position.x, position.z)) {
290             if (terrain.getOpacity(position.x, position.z) < .2) {
291                 velocity = 0;
292                 if (terrain.lineTerrain(oldposition, position, &colpoint) != -1) {
293                     position = colpoint * terrain.scale;
294                 } else {
295                     position.y = terrain.getHeight(position.x, position.z);
296                 }
297
298                 terrain.MakeDecal(shadowdecalpermanent, position, .06, .5, 0);
299                 normalrot = terrain.getNormal(position.x, position.z) * -1;
300                 velocity = 0;
301                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
302                 glPushMatrix();
303                 GLfloat M[16];
304                 glLoadIdentity();
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);
313                 glTranslatef(0, 0, 1);
314                 glGetFloatv(GL_MODELVIEW_MATRIX, M);
315                 tippoint.x = M[12];
316                 tippoint.y = M[13];
317                 tippoint.z = M[14];
318                 glPopMatrix();
319                 position -= tippoint * .15;
320                 XYZ temppoint1, temppoint2, tempforward;
321
322                 rotation3 = 0;
323                 smallrotation = 90;
324                 smallrotation2 = 0;
325                 bigtilt = 0;
326                 bigtilt2 = 0;
327                 bigrotation = 0;
328
329                 emit_sound_at(knifesheathesound, position, 128.);
330
331                 XYZ terrainlight;
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);
336                 } else if (environment == grassyenvironment) {
337                     if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
338                         Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
339                 } else if (environment == desertenvironment) {
340                     if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
341                         Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
342                 }
343
344                 bloody = 0;
345             } else {
346                 physics = 1;
347                 firstfree = 1;
348                 position -= velocity * multiplier;
349                 tippoint -= velocity * multiplier;
350                 tipvelocity = velocity;
351             }
352         }
353         if (velocity.x != 0 || velocity.z != 0 || velocity.y != 0) {
354             velocity.y += gravity * multiplier;
355
356             XYZ temppoint1, temppoint2, tempforward;
357             float distance;
358
359             temppoint1 = 0;
360             temppoint2 = velocity;
361             distance = findDistance(&temppoint1, &temppoint2);
362             rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
363             rotation2 *= 360 / 6.28;
364             temppoint1.y = 0;
365             temppoint2.y = 0;
366             rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
367             rotation1 *= 360 / 6.28;
368             rotation3 = 0;
369             smallrotation = 90;
370             smallrotation2 = 0;
371             bigtilt = 0;
372             bigtilt2 = 0;
373             bigrotation = 0;
374             if (temppoint1.x > temppoint2.x) rotation1 = 360 - rotation1;
375         }
376
377     }
378
379     //Sword physics
380     XYZ mid;
381     XYZ oldmid;
382     XYZ oldmid2;
383
384     tempmult = multiplier;
385     multiplier /= 10;
386     for (int l = 0; l < 10; l++) {
387         if (owner == -1 && (velocity.x || velocity.y || velocity.z) && physics) {
388             //move
389             position += velocity * multiplier;
390             tippoint += tipvelocity * multiplier;
391
392             //Length constrain
393             midp = (position * mass + tippoint * tipmass) / (mass + tipmass);
394             vel = tippoint - midp;
395             Normalise(&vel);
396             newpoint1 = midp - vel * length * (tipmass / (mass + tipmass));
397             newpoint2 = midp + vel * length * (mass / (mass + tipmass));
398             if (!freeze) {
399                 if (freetime > .04) {
400                     velocity = velocity + (newpoint1 - position) / multiplier;
401                     tipvelocity = tipvelocity + (newpoint2 - tippoint) / multiplier;
402                 }
403             }
404             position = newpoint1;
405             tippoint = newpoint2;
406
407
408             //Object collisions
409             whichpatchx = (position.x) / (terrain.size / subdivision * terrain.scale);
410             whichpatchz = (position.z) / (terrain.size / subdivision * terrain.scale);
411             if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision)
412                 if (terrain.patchobjectnum[whichpatchx][whichpatchz]) {
413                     for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
414                         int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
415
416                         if (firstfree) {
417                             if (type == staff) {
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.yaw[k]);
421                                 if (whichhit != -1) {
422                                     XYZ diff;
423                                     diff = (colpoint - position);
424                                     Normalise(&diff);
425                                     hitsomething = 1;
426
427                                     tippoint += (colpoint - position) + diff * .05;
428                                     position = colpoint + diff * .05;
429                                     oldtippoint = tippoint;
430                                     oldposition = tippoint;
431                                 }
432                             } else {
433                                 start = position - (tippoint - position) / 5;
434                                 end = tippoint + (tippoint - position) / 30;
435                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
436                                 if (whichhit != -1) {
437                                     XYZ diff;
438                                     diff = (colpoint - tippoint);
439                                     Normalise(&diff);
440                                     hitsomething = 1;
441
442                                     position += (colpoint - tippoint) + diff * .05;
443                                     tippoint = colpoint + diff * .05;
444                                     oldposition = position;
445                                     oldtippoint = tippoint;
446                                 }
447                             }
448                         }
449
450                         start = oldposition;
451                         end = position;
452                         whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
453                         if (whichhit != -1) {
454                             hitsomething = 1;
455                             position = colpoint;
456                             terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
457                             ReflectVector(&velocity, &terrainnormal);
458                             position += terrainnormal * .002;
459
460                             bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
461                             if (findLengthfast(&velocity) < findLengthfast(&bounceness))
462                                 bounceness = 0;
463                             frictionness = abs(normaldotproduct(velocity, terrainnormal));
464                             velocity -= bounceness;
465                             if (1 - friction * frictionness > 0)velocity *= 1 - friction * frictionness;
466                             else velocity = 0;
467                             velocity += bounceness * elasticity;
468
469                             if (findLengthfast(&bounceness) > 1) {
470                                 int whichsound;
471                                 if (type == staff)
472                                     whichsound = footstepsound3 + abs(Random() % 2);
473                                 else
474                                     whichsound = clank1sound + abs(Random() % 4);
475                                 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
476                             }
477                         }
478                         start = oldtippoint;
479                         end = tippoint;
480                         whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
481                         if (whichhit != -1) {
482                             hitsomething = 1;
483                             tippoint = colpoint;
484                             terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
485                             ReflectVector(&tipvelocity, &terrainnormal);
486                             tippoint += terrainnormal * .002;
487
488                             bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
489                             if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))bounceness = 0;
490                             frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
491                             tipvelocity -= bounceness;
492                             if (1 - friction * frictionness > 0)tipvelocity *= 1 - friction * frictionness;
493                             else tipvelocity = 0;
494                             tipvelocity += bounceness * elasticity;
495
496                             if (findLengthfast(&bounceness) > 1) {
497                                 int whichsound;
498                                 if (type == staff)
499                                     whichsound = footstepsound3 + abs(Random() % 2);
500                                 else
501                                     whichsound = clank1sound + abs(Random() % 4);
502                                 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
503                             }
504                         }
505
506                         if ((objects.type[k] != boxtype && objects.type[k] != platformtype && objects.type[k] != walltype && objects.type[k] != weirdtype) || objects.pitch[k] != 0)
507                             for (int m = 0; m < 2; m++) {
508                                 mid = (position * (21 + (float)m * 10) + tippoint * (19 - (float)m * 10)) / 40;
509                                 oldmid2 = mid;
510                                 oldmid = (oldposition * (21 + (float)m * 10) + oldtippoint * (19 - (float)m * 10)) / 40;
511
512                                 start = oldmid;
513                                 end = mid;
514                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
515                                 if (whichhit != -1) {
516                                     hitsomething = 1;
517                                     mid = colpoint;
518                                     terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
519                                     ReflectVector(&velocity, &terrainnormal);
520
521                                     bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
522                                     if (findLengthfast(&velocity) < findLengthfast(&bounceness))bounceness = 0;
523                                     frictionness = abs(normaldotproduct(velocity, terrainnormal));
524                                     velocity -= bounceness;
525                                     if (1 - friction * frictionness > 0)velocity *= 1 - friction * frictionness;
526                                     else velocity = 0;
527                                     velocity += bounceness * elasticity;
528
529                                     if (findLengthfast(&bounceness) > 1) {
530                                         int whichsound;
531                                         if (type == staff)
532                                             whichsound = footstepsound3 + abs(Random() % 2);
533                                         else
534                                             whichsound = clank1sound + abs(Random() % 4);
535                                         emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
536                                     }
537                                     position += (mid - oldmid2) * (20 / (1 + (float)m * 10));
538                                 }
539
540                                 mid = (position * (19 - (float)m * 10) + tippoint * (21 + (float)m * 10)) / 40;
541                                 oldmid2 = mid;
542                                 oldmid = (oldposition * (19 - (float)m * 10) + oldtippoint * (21 + (float)m * 10)) / 40;
543
544                                 start = oldmid;
545                                 end = mid;
546                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
547                                 if (whichhit != -1) {
548                                     hitsomething = 1;
549                                     mid = colpoint;
550                                     terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
551                                     ReflectVector(&tipvelocity, &terrainnormal);
552
553                                     bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
554                                     if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))bounceness = 0;
555                                     frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
556                                     tipvelocity -= bounceness;
557                                     if (1 - friction * frictionness > 0)tipvelocity *= 1 - friction * frictionness;
558                                     else tipvelocity = 0;
559                                     tipvelocity += bounceness * elasticity;
560
561                                     if (findLengthfast(&bounceness) > 1) {
562                                         int whichsound;
563                                         if (type == staff)
564                                             whichsound = footstepsound3 + abs(Random() % 2);
565                                         else
566                                             whichsound = clank1sound + abs(Random() % 4);
567                                         emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
568                                     }
569                                     tippoint += (mid - oldmid2) * (20 / (1 + (float)m * 10));
570                                 }
571                             }
572                         else {
573                             start = position;
574                             end = tippoint;
575                             whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
576                             if (whichhit != -1) {
577                                 hitsomething = 1;
578                                 closestdistance = -1;
579                                 closestswordpoint = colpoint; //(position+tippoint)/2;
580                                 point[0] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]], 0, objects.yaw[k], 0) + objects.position[k];
581                                 point[1] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]], 0, objects.yaw[k], 0) + objects.position[k];
582                                 point[2] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]], 0, objects.yaw[k], 0) + objects.position[k];
583                                 if (DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance, &colpoint )) {
584                                     if (distance < closestdistance || closestdistance == -1) {
585                                         closestpoint = colpoint;
586                                         closestdistance = distance;
587                                     }
588                                 }
589                                 if (DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance, &colpoint )) {
590                                     if (distance < closestdistance || closestdistance == -1) {
591                                         closestpoint = colpoint;
592                                         closestdistance = distance;
593                                     }
594                                 }
595                                 if (DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance, &colpoint )) {
596                                     if (distance < closestdistance || closestdistance == -1) {
597                                         closestpoint = colpoint;
598                                         closestdistance = distance;
599                                     }
600                                 }
601                                 if (closestdistance != -1 && isnormal(closestdistance)) {
602                                     if (DistancePointLine(&closestpoint, &position, &tippoint, &distance, &colpoint )) {
603                                         closestswordpoint = colpoint;
604                                         velocity += (closestpoint - closestswordpoint);
605                                         tipvelocity += (closestpoint - closestswordpoint);
606                                         position += (closestpoint - closestswordpoint);
607                                         tippoint += (closestpoint - closestswordpoint);
608                                     }
609                                 }
610                             }
611                         }
612                     }
613                 }
614             //Terrain collisions
615             whichhit = terrain.lineTerrain(oldposition, position, &colpoint);
616             if (whichhit != -1 || position.y < terrain.getHeight(position.x, position.z)) {
617                 hitsomething = 1;
618                 if (whichhit != -1)
619                     position = colpoint * terrain.scale;
620                 else
621                     position.y = terrain.getHeight(position.x, position.z);
622
623                 terrainnormal = terrain.getNormal(position.x, position.z);
624                 ReflectVector(&velocity, &terrainnormal);
625                 position += terrainnormal * .002;
626                 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
627                 if (findLengthfast(&velocity) < findLengthfast(&bounceness))bounceness = 0;
628                 frictionness = abs(normaldotproduct(velocity, terrainnormal));
629                 velocity -= bounceness;
630                 if (1 - friction * frictionness > 0)velocity *= 1 - friction * frictionness;
631                 else velocity = 0;
632                 if (terrain.getOpacity(position.x, position.z) < .2)velocity += bounceness * elasticity * .3;
633                 else velocity += bounceness * elasticity;
634
635                 if (findLengthfast(&bounceness) > 1) {
636                     int whichsound;
637                     if (terrain.getOpacity(position.x, position.z) > .2) {
638                         if (type == staff)
639                             whichsound = footstepsound3 + abs(Random() % 2);
640                         else
641                             whichsound = clank1sound + abs(Random() % 4);
642                     } else {
643                         whichsound = footstepsound + abs(Random() % 2);
644                     }
645                     emit_sound_at(whichsound, position,
646                                   findLengthfast(&bounceness)
647                                   * (terrain.getOpacity(position.x, position.z) > .2 ? 128. : 32.));
648
649                     if (terrain.getOpacity(position.x, position.z) < .2) {
650                         XYZ terrainlight;
651                         terrainlight = terrain.getLighting(position.x, position.z);
652                         if (environment == snowyenvironment) {
653                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
654                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
655                         } else if (environment == grassyenvironment) {
656                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
657                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
658                         } else if (environment == desertenvironment) {
659                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
660                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
661                         }
662                     }
663                 }
664             }
665             whichhit = terrain.lineTerrain(oldtippoint, tippoint, &colpoint);
666             if (whichhit != -1 || tippoint.y < terrain.getHeight(tippoint.x, tippoint.z)) {
667                 if (whichhit != -1)
668                     tippoint = colpoint * terrain.scale;
669                 else
670                     tippoint.y = terrain.getHeight(tippoint.x, tippoint.z);
671
672                 terrainnormal = terrain.getNormal(tippoint.x, tippoint.z);
673                 ReflectVector(&tipvelocity, &terrainnormal);
674                 tippoint += terrainnormal * .002;
675                 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
676                 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))bounceness = 0;
677                 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
678                 tipvelocity -= bounceness;
679                 if (1 - friction * frictionness > 0)tipvelocity *= 1 - friction * frictionness;
680                 else tipvelocity = 0;
681                 if (terrain.getOpacity(tippoint.x, tippoint.z) < .2)tipvelocity += bounceness * elasticity * .3;
682                 else tipvelocity += bounceness * elasticity;
683
684                 if (findLengthfast(&bounceness) > 1) {
685                     int whichsound;
686                     if (terrain.getOpacity(tippoint.x, tippoint.z) > .2) {
687                         if (type == staff)
688                             whichsound = footstepsound3 + abs(Random() % 2);
689                         else
690                             whichsound = clank1sound + abs(Random() % 4);
691                     } else {
692                         whichsound = footstepsound + abs(Random() % 2);
693                     }
694                     emit_sound_at(whichsound, tippoint,
695                                   findLengthfast(&bounceness)
696                                   * (terrain.getOpacity(tippoint.x, tippoint.z) > .2  ? 128. : 32.));
697
698                     if (terrain.getOpacity(tippoint.x, tippoint.z) < .2) {
699                         XYZ terrainlight;
700                         terrainlight = terrain.getLighting(tippoint.x, tippoint.z);
701                         if (environment == snowyenvironment) {
702                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
703                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
704                         } else if (environment == grassyenvironment) {
705                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
706                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
707                         } else if (environment == desertenvironment) {
708                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
709                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
710                         }
711                     }
712                 }
713             }
714
715             //Edges
716             mid = position + tippoint;
717             mid /= 2;
718             mid += (position - mid) / 20;
719             oldmid = mid;
720             if (mid.y < terrain.getHeight(mid.x, mid.z)) {
721                 hitsomething = 1;
722                 mid.y = terrain.getHeight(mid.x, mid.z);
723
724                 terrainnormal = terrain.getNormal(mid.x, mid.z);
725                 ReflectVector(&velocity, &terrainnormal);
726                 //mid+=terrainnormal*.002;
727                 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
728                 if (findLengthfast(&velocity) < findLengthfast(&bounceness))bounceness = 0;
729                 frictionness = abs(normaldotproduct(velocity, terrainnormal));
730                 velocity -= bounceness;
731                 if (1 - friction * frictionness > 0)velocity *= 1 - friction * frictionness;
732                 else velocity = 0;
733                 if (terrain.getOpacity(mid.x, mid.z) < .2)velocity += bounceness * elasticity * .3;
734                 else velocity += bounceness * elasticity;
735
736                 if (findLengthfast(&bounceness) > 1) {
737                     int whichsound;
738                     if (terrain.getOpacity(mid.x, mid.z) > .2) {
739                         if (type == staff)whichsound = footstepsound3 + abs(Random() % 2);
740                         if (type != staff)whichsound = clank1sound + abs(Random() % 4);
741                     } else whichsound = footstepsound + abs(Random() % 2);
742                     emit_sound_at(whichsound, mid,
743                                   findLengthfast(&bounceness)
744                                   * (terrain.getOpacity(position.x, position.z) > .2
745                                      ? 128.
746                                      : 32.));
747                 }
748                 position += (mid - oldmid) * 20;
749             }
750
751             mid = position + tippoint;
752             mid /= 2;
753             mid += (tippoint - mid) / 20;
754             oldmid = mid;
755             if (mid.y < terrain.getHeight(mid.x, mid.z)) {
756                 hitsomething = 1;
757                 mid.y = terrain.getHeight(mid.x, mid.z);
758
759                 terrainnormal = terrain.getNormal(mid.x, mid.z);
760                 ReflectVector(&tipvelocity, &terrainnormal);
761                 //mid+=terrainnormal*.002;
762                 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
763                 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))bounceness = 0;
764                 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
765                 tipvelocity -= bounceness;
766                 if (1 - friction * frictionness > 0)tipvelocity *= 1 - friction * frictionness;
767                 else tipvelocity = 0;
768                 if (terrain.getOpacity(mid.x, mid.z) < .2)tipvelocity += bounceness * elasticity * .3;
769                 else tipvelocity += bounceness * elasticity;
770
771                 if (findLengthfast(&bounceness) > 1) {
772                     int whichsound;
773                     if (terrain.getOpacity(mid.x, mid.z) > .2) {
774                         if (type == staff)whichsound = footstepsound3 + abs(Random() % 2);
775                         if (type != staff)whichsound = clank1sound + abs(Random() % 4);
776                     } else whichsound = footstepsound + abs(Random() % 2);
777                     emit_sound_at(whichsound, mid,
778                                   findLengthfast(&bounceness)
779                                   * (terrain.getOpacity(position.x, position.z) > .2
780                                      ? 128.
781                                      : 32.));
782                 }
783                 tippoint += (mid - oldmid) * 20;
784             }
785             //Gravity
786             velocity.y += gravity * multiplier;
787             tipvelocity.y += gravity * multiplier;
788
789             //Rotation
790             XYZ temppoint1, temppoint2, tempforward;
791             float distance;
792
793             temppoint1 = position;
794             temppoint2 = tippoint;
795             distance = findDistance(&temppoint1, &temppoint2);
796             rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
797             rotation2 *= 360 / 6.28;
798             temppoint1.y = 0;
799             temppoint2.y = 0;
800             rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
801             rotation1 *= 360 / 6.28;
802             rotation3 = 0;
803             smallrotation = 90;
804             smallrotation2 = 0;
805             bigtilt = 0;
806             bigtilt2 = 0;
807             bigrotation = 0;
808             if (temppoint1.x > temppoint2.x)rotation1 = 360 - rotation1;
809
810             //Stop moving
811             if (findLengthfast(&velocity) < .3 && findLengthfast(&tipvelocity) < .3 && hitsomething) {
812                 freetime += multiplier;
813             }
814
815             if (freetime > .4) {
816                 velocity = 0;
817                 tipvelocity = 0;
818             }
819             firstfree = 0;
820         }
821     }
822     multiplier = tempmult;
823     if (blooddrip && bloody) {
824         blooddripdelay -= blooddrip * multiplier / 2;
825         blooddrip -= multiplier;
826         if (blooddrip < 0) blooddrip = 0;
827         if (blooddrip > 5) blooddrip = 5;
828         if (blooddripdelay < 0 && bloodtoggle) {
829             blooddripdelay = 1;
830             XYZ bloodvel;
831             XYZ bloodloc;
832             bloodloc = position + (tippoint - position) * .7;
833             bloodloc.y -= .05;
834             if (bloodtoggle) {
835                 bloodvel = 0;
836                 Sprite::MakeSprite(bloodsprite, bloodloc, bloodvel, 1, 1, 1, .03, 1);
837             }
838         }
839     }
840     if (onfire) {
841         flamedelay -= multiplier;
842         if (onfire && flamedelay <= 0) {
843             flamedelay = .020;
844             flamedelay -= multiplier;
845             normalrot = 0;
846             if (owner != -1) {
847                 normalrot = player[owner].velocity;
848             }
849             normalrot.y += 1;
850             if (owner != -1) {
851                 if (player[owner].onterrain) {
852                     normalrot.y = 1;
853                 }
854             }
855             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);
856             Sprite::setLastSpriteSpeed(4);
857             Sprite::setLastSpriteAlivetime(.3);
858         }
859     }
860
861     if (!onfire && owner == -1 && type != staff) {
862         flamedelay -= multiplier;
863         if (flamedelay <= 0) {
864             flamedelay = .020;
865             flamedelay -= multiplier;
866             normalrot = 0;
867             if (Random() % 50 == 0 && distsq(&position, &viewer) > 80) {
868                 XYZ shinepoint;
869                 shinepoint = position + (tippoint - position) * (((float)abs(Random() % 100)) / 100);
870                 Sprite::MakeSprite(weaponshinesprite, shinepoint, normalrot, 1, 1, 1, (.1 + (float)abs(Random() % 100) / 200 - .25) * 1 / 3 * fast_sqrt(findDistance(&shinepoint, &viewer)), 1);
871                 Sprite::setLastSpriteSpeed(4);
872                 Sprite::setLastSpriteAlivetime(.3);
873             }
874         }
875     }
876 }
877
878 void Weapons::DoStuff()
879 {
880     //Move
881     int i = 0;
882     for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
883         weapon->DoStuff(i++);
884     }
885 }
886
887 void Weapon::Draw()
888 {
889     static XYZ terrainlight;
890     static GLfloat M[16];
891
892     if ((frustum.SphereInFrustum(position.x, position.y, position.z, 1) &&
893             distsq(&viewer, &position) < viewdistance * viewdistance)) {
894         bool draw = false;
895         if (owner == -1) {
896             draw = true;
897             if (velocity.x && !physics)
898                 drawhowmany = 10;
899             else
900                 drawhowmany = 1;
901         } else {
902             if (player[owner].occluded < 25)
903                 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)
904                     draw = true;
905             if  (
906                 (player[owner].animTarget == knifeslashstartanim ||
907                  player[owner].animTarget == swordsneakattackanim ||
908                  (player[owner].animCurrent == staffhitanim     &&                              player[owner].frameCurrent > 1) ||
909                  (player[owner].animCurrent == staffhitreversedanim     &&              player[owner].frameCurrent > 1) ||
910                  (player[owner].animCurrent == staffspinhitanim &&                      player[owner].frameCurrent > 1) ||
911                  (player[owner].animCurrent == staffspinhitreversedanim &&      player[owner].frameCurrent > 1) ||
912                  (player[owner].animCurrent == staffgroundsmashanim     &&              player[owner].frameCurrent > 1) ||
913                  (player[owner].animTarget == swordslashanim    &&                              player[owner].frameTarget < 7) ||
914                  player[owner].animTarget == crouchstabanim ||
915                  player[owner].animTarget == swordslashreversalanim ||
916                  player[owner].animTarget == swordslashreversedanim ||
917                  player[owner].animTarget == knifefollowanim ||
918                  player[owner].animTarget == swordgroundstabanim ||
919                  player[owner].animTarget == knifethrowanim) &&
920                 player[owner].animTarget == lastdrawnanim &&
921                 !player[owner].skeleton.free
922             ) {
923                 drawhowmany = 10;
924             } else {
925                 drawhowmany = 1;
926             }
927             if (player[owner].animTarget == swordgroundstabanim) {
928                 lastdrawnrotation1 = rotation1;
929                 lastdrawnrotation2 = rotation2;
930                 lastdrawnrotation3 = rotation3;
931                 lastdrawnbigrotation = bigrotation;
932                 lastdrawnbigtilt = bigtilt;
933                 lastdrawnbigtilt2 = bigtilt2;
934                 lastdrawnsmallrotation = smallrotation;
935                 lastdrawnsmallrotation2 = smallrotation2;
936             }
937         }
938         if (draw) {
939             terrainlight = terrain.getLighting(position.x, position.z);
940             if (drawhowmany > 0) {
941                 glAlphaFunc(GL_GREATER, 0.01);
942             }
943             for (int j = drawhowmany; j > 0; j--) {
944                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
945                 glPushMatrix();
946                 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, j / drawhowmany);
947                 if (owner == -1)
948                     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));
949                 else
950                     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));
951                 glRotatef(bigrotation * (((float)(j)) / drawhowmany) + lastdrawnbigrotation * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
952                 glRotatef(bigtilt2 * (((float)(j)) / drawhowmany) + lastdrawnbigtilt2 * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
953                 glRotatef(bigtilt * (((float)(j)) / drawhowmany) + lastdrawnbigtilt * (1 - ((float)(j)) / drawhowmany), 0, 0, 1);
954                 glRotatef(-rotation1 * (((float)(j)) / drawhowmany) - lastdrawnrotation1 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 1, 0);
955                 glRotatef(-rotation2 * (((float)(j)) / drawhowmany) - lastdrawnrotation2 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 0, 1);
956                 glRotatef(-rotation3 * (((float)(j)) / drawhowmany) - lastdrawnrotation3 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
957                 glRotatef(smallrotation * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
958                 glRotatef(smallrotation2 * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation2 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
959
960                 if (owner != -1) {
961                     if (player[owner].animTarget == staffhitanim || player[owner].animCurrent == staffhitanim || player[owner].animTarget == staffhitreversedanim || player[owner].animCurrent == staffhitreversedanim) {
962                         glTranslatef(0, 0, -.3);
963                     }
964                     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) {
965                         glTranslatef(0, 0, -.1);
966                     }
967                 }
968
969                 glEnable(GL_LIGHTING);
970                 switch (type) {
971                 case knife:
972                     if (!bloody || !bloodtoggle)
973                         throwingknifemodel.drawdifftex(knifetextureptr);
974                     if (bloodtoggle) {
975                         if (bloody == 1)
976                             throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
977                         if (bloody == 2)
978                             throwingknifemodel.drawdifftex(bloodknifetextureptr);
979                     }
980                     break;
981                 case sword:
982                     if (!bloody || !bloodtoggle)
983                         swordmodel.drawdifftex(swordtextureptr);
984                     if (bloodtoggle) {
985                         if (bloody == 1)
986                             swordmodel.drawdifftex(lightbloodswordtextureptr);
987                         if (bloody == 2)
988                             swordmodel.drawdifftex(bloodswordtextureptr);
989                     }
990                     break;
991                 case staff:
992                     staffmodel.drawdifftex(stafftextureptr);
993                     break;
994                 }
995
996                 glPopMatrix();
997             }
998
999             lastdrawnposition = position;
1000             lastdrawntippoint = tippoint;
1001             lastdrawnrotation1 = rotation1;
1002             lastdrawnrotation2 = rotation2;
1003             lastdrawnrotation3 = rotation3;
1004             lastdrawnbigrotation = bigrotation;
1005             lastdrawnbigtilt = bigtilt;
1006             lastdrawnbigtilt2 = bigtilt2;
1007             lastdrawnsmallrotation = smallrotation;
1008             lastdrawnsmallrotation2 = smallrotation2;
1009             if (owner != -1)lastdrawnanim = player[owner].animCurrent;
1010         }
1011         if (owner != -1) {
1012             glMatrixMode(GL_MODELVIEW);                                                 // Select The Modelview Matrix
1013             glPushMatrix();
1014             glLoadIdentity();
1015             glTranslatef(position.x, position.y - .02, position.z);
1016             glRotatef(bigrotation, 0, 1, 0);
1017             glRotatef(bigtilt2, 1, 0, 0);
1018             glRotatef(bigtilt, 0, 0, 1);
1019             glRotatef(-rotation1 + 90, 0, 1, 0);
1020             glRotatef(-rotation2 + 90, 0, 0, 1);
1021             glRotatef(-rotation3, 0, 1, 0);
1022             glRotatef(smallrotation, 1, 0, 0);
1023             glRotatef(smallrotation2, 0, 1, 0);
1024             glTranslatef(0, 0, length);
1025             glGetFloatv(GL_MODELVIEW_MATRIX, M);
1026             tippoint.x = M[12];
1027             tippoint.y = M[13];
1028             tippoint.z = M[14];
1029             glPopMatrix();
1030         }
1031     }
1032 }
1033
1034 int Weapons::Draw()
1035 {
1036     glAlphaFunc(GL_GREATER, 0.9);
1037     glEnable(GL_TEXTURE_2D);
1038     glEnable(GL_BLEND);
1039     glEnable(GL_CULL_FACE);
1040     glCullFace(GL_FRONT);
1041     glDepthMask(1);
1042
1043     for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1044         weapon->Draw();
1045     }
1046     return 0;
1047 }
1048
1049 Weapons::Weapons()
1050 {
1051 }
1052
1053 Weapons::~Weapons()
1054 {
1055     Weapon::stafftextureptr.destroy();
1056     Weapon::knifetextureptr.destroy();
1057     Weapon::lightbloodknifetextureptr.destroy();
1058     Weapon::bloodknifetextureptr.destroy();
1059     Weapon::swordtextureptr.destroy();
1060     Weapon::lightbloodswordtextureptr.destroy();
1061     Weapon::bloodswordtextureptr.destroy();
1062 }
1063