]> git.jsancho.org Git - lugaru.git/blob - Source/Weapons.cpp
player replaced by Person::players which is a vector of shared_ptr.
[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             Person::players[owner]->weaponactive = -1;
137             Person::players[owner]->num_weapons--;
138             if (Person::players[owner]->num_weapons) {
139                 Person::players[owner]->weaponids[0] = Person::players[owner]->weaponids[Person::players[owner]->num_weapons];
140                 if (Person::players[owner]->weaponstuck == Person::players[owner]->num_weapons)
141                     Person::players[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((Person::players[j]->jointPos(abdomen) + Person::players[j]->jointPos(neck)) / 2, 0, Person::players[j]->yaw, 0) * Person::players[j]->scale + Person::players[j]->coords;
220                 if (owner == -1 && distsqflat(&position, &Person::players[j]->coords) < 1.5 &&
221                         distsq(&position, &Person::players[j]->coords) < 4 && Person::players[j]->weaponstuck == -1 &&
222                         !Person::players[j]->skeleton.free && j != oldowner) {
223                     if ((Person::players[j]->aitype != attacktypecutoff || abs(Random() % 6) == 0 || (Person::players[j]->animTarget != backhandspringanim && Person::players[j]->animTarget != rollanim && Person::players[j]->animTarget != flipanim && Random() % 2 == 0)) && !missed) {
224                         if ( (Person::players[j]->creature == wolftype && Random() % 3 != 0 && Person::players[j]->weaponactive == -1 && (Person::players[j]->isIdle() || Person::players[j]->isRun() || Person::players[j]->animTarget == walkanim)) ||
225                                 (Person::players[j]->creature == rabbittype && Random() % 2 == 0 && Person::players[j]->aitype == attacktypecutoff && Person::players[j]->weaponactive == -1)) {
226                             emit_sound_at(knifedrawsound, Person::players[j]->coords, 128.);
227
228                             Person::players[j]->weaponactive = 0;
229                             Person::players[j]->animTarget = removeknifeanim;
230                             Person::players[j]->frameTarget = 1;
231                             Person::players[j]->target = 1;
232                             owner = Person::players[j]->id;
233                             if (Person::players[j]->num_weapons > 0) {
234                                 Person::players[j]->weaponids[Person::players[j]->num_weapons] = Person::players[j]->weaponids[0];
235                             }
236                             Person::players[j]->num_weapons++;
237                             Person::players[j]->weaponids[0] = i;
238
239                             Person::players[j]->aitype = attacktypecutoff;
240                         } else {
241                             if (j != 0)
242                                 numthrowkill++;
243                             Person::players[j]->num_weapons++;
244                             Person::players[j]->weaponstuck = Person::players[j]->num_weapons - 1;
245                             if (normaldotproduct(Person::players[j]->facing, velocity) > 0)
246                                 Person::players[j]->weaponstuckwhere = 1;
247                             else
248                                 Person::players[j]->weaponstuckwhere = 0;
249
250                             Person::players[j]->weaponids[Person::players[j]->num_weapons - 1] = i;
251
252                             Person::players[j]->RagDoll(0);
253                             Person::players[j]->jointVel(abdomen) += velocity * 2;
254                             Person::players[j]->jointVel(neck) += velocity * 2;
255                             Person::players[j]->jointVel(rightshoulder) += velocity * 2;
256                             Person::players[j]->jointVel(leftshoulder) += velocity * 2;
257                             if (bloodtoggle && tutoriallevel != 1)
258                                 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
259                             if (tutoriallevel == 1)
260                                 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 1, 1, .8, .3);
261                             footvel = tippoint - position;
262                             Normalise(&footvel);
263                             if (bloodtoggle && tutoriallevel != 1)
264                                 Sprite::MakeSprite(bloodflamesprite, footpoint, footvel * -1, 1, 0, 0, .6, 1);
265
266                             if (tutoriallevel != 1) {
267                                 if (Person::players[j]->weaponstuckwhere == 0)
268                                     Person::players[j]->DoBloodBig(2, 205);
269                                 if (Person::players[j]->weaponstuckwhere == 1)
270                                     Person::players[j]->DoBloodBig(2, 200);
271                                 Person::players[j]->damage += 200 / Person::players[j]->armorhigh;
272                                 Person::players[j]->deathbleeding = 1;
273                                 Person::players[j]->bloodloss += (200 + abs((float)(Random() % 40)) - 20) / Person::players[j]->armorhigh;
274                                 owner = j;
275                                 bloody = 2;
276                                 blooddrip = 5;
277                             }
278
279                             emit_sound_at(fleshstabsound, position, 128.);
280
281                             if (animation[Person::players[0]->animTarget].height == highheight)
282                                 award_bonus(0, ninja);
283                             else
284                                 award_bonus(0, Bullseyebonus);
285                         }
286                     } else {
287                         missed = 1;
288                     }
289                 }
290             }
291         }
292         if (position.y < terrain.getHeight(position.x, position.z)) {
293             if (terrain.getOpacity(position.x, position.z) < .2) {
294                 velocity = 0;
295                 if (terrain.lineTerrain(oldposition, position, &colpoint) != -1) {
296                     position = colpoint * terrain.scale;
297                 } else {
298                     position.y = terrain.getHeight(position.x, position.z);
299                 }
300
301                 terrain.MakeDecal(shadowdecalpermanent, position, .06, .5, 0);
302                 normalrot = terrain.getNormal(position.x, position.z) * -1;
303                 velocity = 0;
304                 glMatrixMode(GL_MODELVIEW);
305                 glPushMatrix();
306                 GLfloat M[16];
307                 glLoadIdentity();
308                 glRotatef(bigrotation, 0, 1, 0);
309                 glRotatef(bigtilt2, 1, 0, 0);
310                 glRotatef(bigtilt, 0, 0, 1);
311                 glRotatef(-rotation1 + 90, 0, 1, 0);
312                 glRotatef(-rotation2 + 90, 0, 0, 1);
313                 glRotatef(-rotation3, 0, 1, 0);
314                 glRotatef(smallrotation, 1, 0, 0);
315                 glRotatef(smallrotation2, 0, 1, 0);
316                 glTranslatef(0, 0, 1);
317                 glGetFloatv(GL_MODELVIEW_MATRIX, M);
318                 tippoint.x = M[12];
319                 tippoint.y = M[13];
320                 tippoint.z = M[14];
321                 glPopMatrix();
322                 position -= tippoint * .15;
323                 XYZ temppoint1, temppoint2, tempforward;
324
325                 rotation3 = 0;
326                 smallrotation = 90;
327                 smallrotation2 = 0;
328                 bigtilt = 0;
329                 bigtilt2 = 0;
330                 bigrotation = 0;
331
332                 emit_sound_at(knifesheathesound, position, 128.);
333
334                 XYZ terrainlight;
335                 terrainlight = terrain.getLighting(position.x, position.z);
336                 if (environment == snowyenvironment) {
337                     if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
338                         Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
339                 } else if (environment == grassyenvironment) {
340                     if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
341                         Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
342                 } else if (environment == desertenvironment) {
343                     if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
344                         Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
345                 }
346
347                 bloody = 0;
348             } else {
349                 physics = 1;
350                 firstfree = 1;
351                 position -= velocity * multiplier;
352                 tippoint -= velocity * multiplier;
353                 tipvelocity = velocity;
354             }
355         }
356         if (velocity.x != 0 || velocity.z != 0 || velocity.y != 0) {
357             velocity.y += gravity * multiplier;
358
359             XYZ temppoint1, temppoint2, tempforward;
360             float distance;
361
362             temppoint1 = 0;
363             temppoint2 = velocity;
364             distance = findDistance(&temppoint1, &temppoint2);
365             rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
366             rotation2 *= 360 / 6.28;
367             temppoint1.y = 0;
368             temppoint2.y = 0;
369             rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
370             rotation1 *= 360 / 6.28;
371             rotation3 = 0;
372             smallrotation = 90;
373             smallrotation2 = 0;
374             bigtilt = 0;
375             bigtilt2 = 0;
376             bigrotation = 0;
377             if (temppoint1.x > temppoint2.x)
378                 rotation1 = 360 - rotation1;
379         }
380
381     }
382
383     //Sword physics
384     XYZ mid;
385     XYZ oldmid;
386     XYZ oldmid2;
387
388     tempmult = multiplier;
389     multiplier /= 10;
390     for (int l = 0; l < 10; l++) {
391         if (owner == -1 && (velocity.x || velocity.y || velocity.z) && physics) {
392             //move
393             position += velocity * multiplier;
394             tippoint += tipvelocity * multiplier;
395
396             //Length constrain
397             midp = (position * mass + tippoint * tipmass) / (mass + tipmass);
398             vel = tippoint - midp;
399             Normalise(&vel);
400             newpoint1 = midp - vel * length * (tipmass / (mass + tipmass));
401             newpoint2 = midp + vel * length * (mass / (mass + tipmass));
402             if (!freeze) {
403                 if (freetime > .04) {
404                     velocity = velocity + (newpoint1 - position) / multiplier;
405                     tipvelocity = tipvelocity + (newpoint2 - tippoint) / multiplier;
406                 }
407             }
408             position = newpoint1;
409             tippoint = newpoint2;
410
411
412             //Object collisions
413             whichpatchx = (position.x) / (terrain.size / subdivision * terrain.scale);
414             whichpatchz = (position.z) / (terrain.size / subdivision * terrain.scale);
415             if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision)
416                 if (terrain.patchobjectnum[whichpatchx][whichpatchz]) {
417                     for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
418                         int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
419
420                         if (firstfree) {
421                             if (type == staff) {
422                                 start = tippoint - (position - tippoint) / 5;
423                                 end = position + (position - tippoint) / 30;
424                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
425                                 if (whichhit != -1) {
426                                     XYZ diff;
427                                     diff = (colpoint - position);
428                                     Normalise(&diff);
429                                     hitsomething = 1;
430
431                                     tippoint += (colpoint - position) + diff * .05;
432                                     position = colpoint + diff * .05;
433                                     oldtippoint = tippoint;
434                                     oldposition = tippoint;
435                                 }
436                             } else {
437                                 start = position - (tippoint - position) / 5;
438                                 end = tippoint + (tippoint - position) / 30;
439                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
440                                 if (whichhit != -1) {
441                                     XYZ diff;
442                                     diff = (colpoint - tippoint);
443                                     Normalise(&diff);
444                                     hitsomething = 1;
445
446                                     position += (colpoint - tippoint) + diff * .05;
447                                     tippoint = colpoint + diff * .05;
448                                     oldposition = position;
449                                     oldtippoint = tippoint;
450                                 }
451                             }
452                         }
453
454                         start = oldposition;
455                         end = position;
456                         whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
457                         if (whichhit != -1) {
458                             hitsomething = 1;
459                             position = colpoint;
460                             terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
461                             ReflectVector(&velocity, &terrainnormal);
462                             position += terrainnormal * .002;
463
464                             bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
465                             if (findLengthfast(&velocity) < findLengthfast(&bounceness))
466                                 bounceness = 0;
467                             frictionness = abs(normaldotproduct(velocity, terrainnormal));
468                             velocity -= bounceness;
469                             if (1 - friction * frictionness > 0)
470                                 velocity *= 1 - friction * frictionness;
471                             else
472                                 velocity = 0;
473                             velocity += bounceness * elasticity;
474
475                             if (findLengthfast(&bounceness) > 1) {
476                                 int whichsound;
477                                 if (type == staff)
478                                     whichsound = footstepsound3 + abs(Random() % 2);
479                                 else
480                                     whichsound = clank1sound + abs(Random() % 4);
481                                 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
482                             }
483                         }
484                         start = oldtippoint;
485                         end = tippoint;
486                         whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
487                         if (whichhit != -1) {
488                             hitsomething = 1;
489                             tippoint = colpoint;
490                             terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
491                             ReflectVector(&tipvelocity, &terrainnormal);
492                             tippoint += terrainnormal * .002;
493
494                             bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
495                             if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
496                                 bounceness = 0;
497                             frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
498                             tipvelocity -= bounceness;
499                             if (1 - friction * frictionness > 0)
500                                 tipvelocity *= 1 - friction * frictionness;
501                             else
502                                 tipvelocity = 0;
503                             tipvelocity += bounceness * elasticity;
504
505                             if (findLengthfast(&bounceness) > 1) {
506                                 int whichsound;
507                                 if (type == staff)
508                                     whichsound = footstepsound3 + abs(Random() % 2);
509                                 else
510                                     whichsound = clank1sound + abs(Random() % 4);
511                                 emit_sound_at(whichsound, position, 128 * findLengthfast(&bounceness));
512                             }
513                         }
514
515                         if ((objects.type[k] != boxtype && objects.type[k] != platformtype && objects.type[k] != walltype && objects.type[k] != weirdtype) || objects.pitch[k] != 0)
516                             for (int m = 0; m < 2; m++) {
517                                 mid = (position * (21 + (float)m * 10) + tippoint * (19 - (float)m * 10)) / 40;
518                                 oldmid2 = mid;
519                                 oldmid = (oldposition * (21 + (float)m * 10) + oldtippoint * (19 - (float)m * 10)) / 40;
520
521                                 start = oldmid;
522                                 end = mid;
523                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
524                                 if (whichhit != -1) {
525                                     hitsomething = 1;
526                                     mid = colpoint;
527                                     terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
528                                     ReflectVector(&velocity, &terrainnormal);
529
530                                     bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
531                                     if (findLengthfast(&velocity) < findLengthfast(&bounceness))
532                                         bounceness = 0;
533                                     frictionness = abs(normaldotproduct(velocity, terrainnormal));
534                                     velocity -= bounceness;
535                                     if (1 - friction * frictionness > 0)
536                                         velocity *= 1 - friction * frictionness;
537                                     else
538                                         velocity = 0;
539                                     velocity += bounceness * elasticity;
540
541                                     if (findLengthfast(&bounceness) > 1) {
542                                         int whichsound;
543                                         if (type == staff)
544                                             whichsound = footstepsound3 + abs(Random() % 2);
545                                         else
546                                             whichsound = clank1sound + abs(Random() % 4);
547                                         emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
548                                     }
549                                     position += (mid - oldmid2) * (20 / (1 + (float)m * 10));
550                                 }
551
552                                 mid = (position * (19 - (float)m * 10) + tippoint * (21 + (float)m * 10)) / 40;
553                                 oldmid2 = mid;
554                                 oldmid = (oldposition * (19 - (float)m * 10) + oldtippoint * (21 + (float)m * 10)) / 40;
555
556                                 start = oldmid;
557                                 end = mid;
558                                 whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
559                                 if (whichhit != -1) {
560                                     hitsomething = 1;
561                                     mid = colpoint;
562                                     terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
563                                     ReflectVector(&tipvelocity, &terrainnormal);
564
565                                     bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
566                                     if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
567                                         bounceness = 0;
568                                     frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
569                                     tipvelocity -= bounceness;
570                                     if (1 - friction * frictionness > 0)
571                                         tipvelocity *= 1 - friction * frictionness;
572                                     else
573                                         tipvelocity = 0;
574                                     tipvelocity += bounceness * elasticity;
575
576                                     if (findLengthfast(&bounceness) > 1) {
577                                         int whichsound;
578                                         if (type == staff)
579                                             whichsound = footstepsound3 + abs(Random() % 2);
580                                         else
581                                             whichsound = clank1sound + abs(Random() % 4);
582                                         emit_sound_at(whichsound, mid, 128 * findLengthfast(&bounceness));
583                                     }
584                                     tippoint += (mid - oldmid2) * (20 / (1 + (float)m * 10));
585                                 }
586                             }
587                         else {
588                             start = position;
589                             end = tippoint;
590                             whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
591                             if (whichhit != -1) {
592                                 hitsomething = 1;
593                                 closestdistance = -1;
594                                 closestswordpoint = colpoint; //(position+tippoint)/2;
595                                 point[0] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]], 0, objects.yaw[k], 0) + objects.position[k];
596                                 point[1] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]], 0, objects.yaw[k], 0) + objects.position[k];
597                                 point[2] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]], 0, objects.yaw[k], 0) + objects.position[k];
598                                 if (DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance, &colpoint )) {
599                                     if (distance < closestdistance || closestdistance == -1) {
600                                         closestpoint = colpoint;
601                                         closestdistance = distance;
602                                     }
603                                 }
604                                 if (DistancePointLine(&closestswordpoint, &point[1], &point[2], &distance, &colpoint )) {
605                                     if (distance < closestdistance || closestdistance == -1) {
606                                         closestpoint = colpoint;
607                                         closestdistance = distance;
608                                     }
609                                 }
610                                 if (DistancePointLine(&closestswordpoint, &point[2], &point[0], &distance, &colpoint )) {
611                                     if (distance < closestdistance || closestdistance == -1) {
612                                         closestpoint = colpoint;
613                                         closestdistance = distance;
614                                     }
615                                 }
616                                 if (closestdistance != -1 && isnormal(closestdistance)) {
617                                     if (DistancePointLine(&closestpoint, &position, &tippoint, &distance, &colpoint )) {
618                                         closestswordpoint = colpoint;
619                                         velocity += (closestpoint - closestswordpoint);
620                                         tipvelocity += (closestpoint - closestswordpoint);
621                                         position += (closestpoint - closestswordpoint);
622                                         tippoint += (closestpoint - closestswordpoint);
623                                     }
624                                 }
625                             }
626                         }
627                     }
628                 }
629             //Terrain collisions
630             whichhit = terrain.lineTerrain(oldposition, position, &colpoint);
631             if (whichhit != -1 || position.y < terrain.getHeight(position.x, position.z)) {
632                 hitsomething = 1;
633                 if (whichhit != -1)
634                     position = colpoint * terrain.scale;
635                 else
636                     position.y = terrain.getHeight(position.x, position.z);
637
638                 terrainnormal = terrain.getNormal(position.x, position.z);
639                 ReflectVector(&velocity, &terrainnormal);
640                 position += terrainnormal * .002;
641                 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
642                 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
643                     bounceness = 0;
644                 frictionness = abs(normaldotproduct(velocity, terrainnormal));
645                 velocity -= bounceness;
646                 if (1 - friction * frictionness > 0)
647                     velocity *= 1 - friction * frictionness;
648                 else
649                     velocity = 0;
650                 if (terrain.getOpacity(position.x, position.z) < .2)
651                     velocity += bounceness * elasticity * .3;
652                 else
653                     velocity += bounceness * elasticity;
654
655                 if (findLengthfast(&bounceness) > 1) {
656                     int whichsound;
657                     if (terrain.getOpacity(position.x, position.z) > .2) {
658                         if (type == staff)
659                             whichsound = footstepsound3 + abs(Random() % 2);
660                         else
661                             whichsound = clank1sound + abs(Random() % 4);
662                     } else {
663                         whichsound = footstepsound + abs(Random() % 2);
664                     }
665                     emit_sound_at(whichsound, position,
666                                   findLengthfast(&bounceness)
667                                   * (terrain.getOpacity(position.x, position.z) > .2 ? 128. : 32.));
668
669                     if (terrain.getOpacity(position.x, position.z) < .2) {
670                         XYZ terrainlight;
671                         terrainlight = terrain.getLighting(position.x, position.z);
672                         if (environment == snowyenvironment) {
673                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
674                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
675                         } else if (environment == grassyenvironment) {
676                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
677                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
678                         } else if (environment == desertenvironment) {
679                             if (distsq(&position, &viewer) < viewdistance * viewdistance / 4)
680                                 Sprite::MakeSprite(cloudsprite, position, velocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
681                         }
682                     }
683                 }
684             }
685             whichhit = terrain.lineTerrain(oldtippoint, tippoint, &colpoint);
686             if (whichhit != -1 || tippoint.y < terrain.getHeight(tippoint.x, tippoint.z)) {
687                 if (whichhit != -1)
688                     tippoint = colpoint * terrain.scale;
689                 else
690                     tippoint.y = terrain.getHeight(tippoint.x, tippoint.z);
691
692                 terrainnormal = terrain.getNormal(tippoint.x, tippoint.z);
693                 ReflectVector(&tipvelocity, &terrainnormal);
694                 tippoint += terrainnormal * .002;
695                 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
696                 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
697                     bounceness = 0;
698                 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
699                 tipvelocity -= bounceness;
700                 if (1 - friction * frictionness > 0)
701                     tipvelocity *= 1 - friction * frictionness;
702                 else
703                     tipvelocity = 0;
704                 if (terrain.getOpacity(tippoint.x, tippoint.z) < .2)
705                     tipvelocity += bounceness * elasticity * .3;
706                 else
707                     tipvelocity += bounceness * elasticity;
708
709                 if (findLengthfast(&bounceness) > 1) {
710                     int whichsound;
711                     if (terrain.getOpacity(tippoint.x, tippoint.z) > .2) {
712                         if (type == staff)
713                             whichsound = footstepsound3 + abs(Random() % 2);
714                         else
715                             whichsound = clank1sound + abs(Random() % 4);
716                     } else {
717                         whichsound = footstepsound + abs(Random() % 2);
718                     }
719                     emit_sound_at(whichsound, tippoint,
720                                   findLengthfast(&bounceness)
721                                   * (terrain.getOpacity(tippoint.x, tippoint.z) > .2  ? 128. : 32.));
722
723                     if (terrain.getOpacity(tippoint.x, tippoint.z) < .2) {
724                         XYZ terrainlight;
725                         terrainlight = terrain.getLighting(tippoint.x, tippoint.z);
726                         if (environment == snowyenvironment) {
727                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
728                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
729                         } else if (environment == grassyenvironment) {
730                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
731                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 90 / 255, terrainlight.y * 70 / 255, terrainlight.z * 8 / 255, .5, .5);
732                         } else if (environment == desertenvironment) {
733                             if (distsq(&tippoint, &viewer) < viewdistance * viewdistance / 4)
734                                 Sprite::MakeSprite(cloudsprite, tippoint, tipvelocity, terrainlight.x * 190 / 255, terrainlight.y * 170 / 255, terrainlight.z * 108 / 255, .5, .7);
735                         }
736                     }
737                 }
738             }
739
740             //Edges
741             mid = position + tippoint;
742             mid /= 2;
743             mid += (position - mid) / 20;
744             oldmid = mid;
745             if (mid.y < terrain.getHeight(mid.x, mid.z)) {
746                 hitsomething = 1;
747                 mid.y = terrain.getHeight(mid.x, mid.z);
748
749                 terrainnormal = terrain.getNormal(mid.x, mid.z);
750                 ReflectVector(&velocity, &terrainnormal);
751                 //mid+=terrainnormal*.002;
752                 bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
753                 if (findLengthfast(&velocity) < findLengthfast(&bounceness))
754                     bounceness = 0;
755                 frictionness = abs(normaldotproduct(velocity, terrainnormal));
756                 velocity -= bounceness;
757                 if (1 - friction * frictionness > 0)
758                     velocity *= 1 - friction * frictionness;
759                 else
760                     velocity = 0;
761                 if (terrain.getOpacity(mid.x, mid.z) < .2)
762                     velocity += bounceness * elasticity * .3;
763                 else
764                     velocity += bounceness * elasticity;
765
766                 if (findLengthfast(&bounceness) > 1) {
767                     int whichsound;
768                     if (terrain.getOpacity(mid.x, mid.z) > .2) {
769                         if (type == staff)
770                             whichsound = footstepsound3 + abs(Random() % 2);
771                         if (type != staff)
772                             whichsound = clank1sound + abs(Random() % 4);
773                     } else {
774                         whichsound = footstepsound + abs(Random() % 2);
775                     }
776                     emit_sound_at(whichsound, mid,
777                                   findLengthfast(&bounceness)
778                                   * (terrain.getOpacity(position.x, position.z) > .2
779                                      ? 128.
780                                      : 32.));
781                 }
782                 position += (mid - oldmid) * 20;
783             }
784
785             mid = position + tippoint;
786             mid /= 2;
787             mid += (tippoint - mid) / 20;
788             oldmid = mid;
789             if (mid.y < terrain.getHeight(mid.x, mid.z)) {
790                 hitsomething = 1;
791                 mid.y = terrain.getHeight(mid.x, mid.z);
792
793                 terrainnormal = terrain.getNormal(mid.x, mid.z);
794                 ReflectVector(&tipvelocity, &terrainnormal);
795                 //mid+=terrainnormal*.002;
796                 bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
797                 if (findLengthfast(&tipvelocity) < findLengthfast(&bounceness))
798                     bounceness = 0;
799                 frictionness = abs(normaldotproduct(tipvelocity, terrainnormal));
800                 tipvelocity -= bounceness;
801                 if (1 - friction * frictionness > 0)
802                     tipvelocity *= 1 - friction * frictionness;
803                 else
804                     tipvelocity = 0;
805                 if (terrain.getOpacity(mid.x, mid.z) < .2)
806                     tipvelocity += bounceness * elasticity * .3;
807                 else
808                     tipvelocity += bounceness * elasticity;
809
810                 if (findLengthfast(&bounceness) > 1) {
811                     int whichsound;
812                     if (terrain.getOpacity(mid.x, mid.z) > .2) {
813                         if (type == staff)
814                             whichsound = footstepsound3 + abs(Random() % 2);
815                         if (type != staff)
816                             whichsound = clank1sound + abs(Random() % 4);
817                     } else {
818                         whichsound = footstepsound + abs(Random() % 2);
819                     }
820                     emit_sound_at(whichsound, mid,
821                                   findLengthfast(&bounceness)
822                                   * (terrain.getOpacity(position.x, position.z) > .2
823                                      ? 128.
824                                      : 32.));
825                 }
826                 tippoint += (mid - oldmid) * 20;
827             }
828             //Gravity
829             velocity.y += gravity * multiplier;
830             tipvelocity.y += gravity * multiplier;
831
832             //Rotation
833             XYZ temppoint1, temppoint2, tempforward;
834             float distance;
835
836             temppoint1 = position;
837             temppoint2 = tippoint;
838             distance = findDistance(&temppoint1, &temppoint2);
839             rotation2 = asin((temppoint1.y - temppoint2.y) / distance);
840             rotation2 *= 360 / 6.28;
841             temppoint1.y = 0;
842             temppoint2.y = 0;
843             rotation1 = acos((temppoint1.z - temppoint2.z) / findDistance(&temppoint1, &temppoint2));
844             rotation1 *= 360 / 6.28;
845             rotation3 = 0;
846             smallrotation = 90;
847             smallrotation2 = 0;
848             bigtilt = 0;
849             bigtilt2 = 0;
850             bigrotation = 0;
851             if (temppoint1.x > temppoint2.x)
852                 rotation1 = 360 - rotation1;
853
854             //Stop moving
855             if (findLengthfast(&velocity) < .3 && findLengthfast(&tipvelocity) < .3 && hitsomething) {
856                 freetime += multiplier;
857             }
858
859             if (freetime > .4) {
860                 velocity = 0;
861                 tipvelocity = 0;
862             }
863             firstfree = 0;
864         }
865     }
866     multiplier = tempmult;
867     if (blooddrip && bloody) {
868         blooddripdelay -= blooddrip * multiplier / 2;
869         blooddrip -= multiplier;
870         if (blooddrip < 0)
871             blooddrip = 0;
872         if (blooddrip > 5)
873             blooddrip = 5;
874         if (blooddripdelay < 0 && bloodtoggle) {
875             blooddripdelay = 1;
876             XYZ bloodvel;
877             XYZ bloodloc;
878             bloodloc = position + (tippoint - position) * .7;
879             bloodloc.y -= .05;
880             if (bloodtoggle) {
881                 bloodvel = 0;
882                 Sprite::MakeSprite(bloodsprite, bloodloc, bloodvel, 1, 1, 1, .03, 1);
883             }
884         }
885     }
886     if (onfire) {
887         flamedelay -= multiplier;
888         if (onfire && flamedelay <= 0) {
889             flamedelay = .020;
890             flamedelay -= multiplier;
891             normalrot = 0;
892             if (owner != -1) {
893                 normalrot = Person::players[owner]->velocity;
894             }
895             normalrot.y += 1;
896             if (owner != -1) {
897                 if (Person::players[owner]->onterrain) {
898                     normalrot.y = 1;
899                 }
900             }
901             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);
902             Sprite::setLastSpriteSpeed(4);
903             Sprite::setLastSpriteAlivetime(.3);
904         }
905     }
906
907     if (!onfire && owner == -1 && type != staff) {
908         flamedelay -= multiplier;
909         if (flamedelay <= 0) {
910             flamedelay = .020;
911             flamedelay -= multiplier;
912             normalrot = 0;
913             if (Random() % 50 == 0 && distsq(&position, &viewer) > 80) {
914                 XYZ shinepoint;
915                 shinepoint = position + (tippoint - position) * (((float)abs(Random() % 100)) / 100);
916                 Sprite::MakeSprite(weaponshinesprite, shinepoint, normalrot, 1, 1, 1, (.1 + (float)abs(Random() % 100) / 200 - .25) * 1 / 3 * fast_sqrt(findDistance(&shinepoint, &viewer)), 1);
917                 Sprite::setLastSpriteSpeed(4);
918                 Sprite::setLastSpriteAlivetime(.3);
919             }
920         }
921     }
922 }
923
924 void Weapons::DoStuff()
925 {
926     //Move
927     int i = 0;
928     for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
929         weapon->DoStuff(i++);
930     }
931 }
932
933 void Weapon::Draw()
934 {
935     static XYZ terrainlight;
936     static GLfloat M[16];
937
938     if ((frustum.SphereInFrustum(position.x, position.y, position.z, 1) &&
939             distsq(&viewer, &position) < viewdistance * viewdistance)) {
940         bool draw = false;
941         if (owner == -1) {
942             draw = true;
943             if (velocity.x && !physics)
944                 drawhowmany = 10;
945             else
946                 drawhowmany = 1;
947         } else {
948             if (Person::players[owner]->occluded < 25)
949                 if ((frustum.SphereInFrustum(Person::players[owner]->coords.x, Person::players[owner]->coords.y + Person::players[owner]->scale * 3, Person::players[owner]->coords.z, Person::players[owner]->scale * 8) && distsq(&viewer, &Person::players[owner]->coords) < viewdistance * viewdistance) || Person::players[owner]->skeleton.free == 3)
950                     draw = true;
951             if (
952                 (Person::players[owner]->animTarget == knifeslashstartanim ||
953                  Person::players[owner]->animTarget == swordsneakattackanim ||
954                  (Person::players[owner]->animCurrent == staffhitanim && Person::players[owner]->frameCurrent > 1) ||
955                  (Person::players[owner]->animCurrent == staffhitreversedanim && Person::players[owner]->frameCurrent > 1) ||
956                  (Person::players[owner]->animCurrent == staffspinhitanim && Person::players[owner]->frameCurrent > 1) ||
957                  (Person::players[owner]->animCurrent == staffspinhitreversedanim && Person::players[owner]->frameCurrent > 1) ||
958                  (Person::players[owner]->animCurrent == staffgroundsmashanim && Person::players[owner]->frameCurrent > 1) ||
959                  (Person::players[owner]->animTarget == swordslashanim && Person::players[owner]->frameTarget < 7) ||
960                  Person::players[owner]->animTarget == crouchstabanim ||
961                  Person::players[owner]->animTarget == swordslashreversalanim ||
962                  Person::players[owner]->animTarget == swordslashreversedanim ||
963                  Person::players[owner]->animTarget == knifefollowanim ||
964                  Person::players[owner]->animTarget == swordgroundstabanim ||
965                  Person::players[owner]->animTarget == knifethrowanim) &&
966                 Person::players[owner]->animTarget == lastdrawnanim &&
967                 !Person::players[owner]->skeleton.free
968             ) {
969                 drawhowmany = 10;
970             } else {
971                 drawhowmany = 1;
972             }
973             if (Person::players[owner]->animTarget == swordgroundstabanim) {
974                 lastdrawnrotation1 = rotation1;
975                 lastdrawnrotation2 = rotation2;
976                 lastdrawnrotation3 = rotation3;
977                 lastdrawnbigrotation = bigrotation;
978                 lastdrawnbigtilt = bigtilt;
979                 lastdrawnbigtilt2 = bigtilt2;
980                 lastdrawnsmallrotation = smallrotation;
981                 lastdrawnsmallrotation2 = smallrotation2;
982             }
983         }
984         if (draw) {
985             terrainlight = terrain.getLighting(position.x, position.z);
986             if (drawhowmany > 0) {
987                 glAlphaFunc(GL_GREATER, 0.01);
988             }
989             for (int j = drawhowmany; j > 0; j--) {
990                 glMatrixMode(GL_MODELVIEW);
991                 glPushMatrix();
992                 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, j / drawhowmany);
993                 if (owner == -1)
994                     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));
995                 else
996                     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));
997                 glRotatef(bigrotation * (((float)(j)) / drawhowmany) + lastdrawnbigrotation * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
998                 glRotatef(bigtilt2 * (((float)(j)) / drawhowmany) + lastdrawnbigtilt2 * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
999                 glRotatef(bigtilt * (((float)(j)) / drawhowmany) + lastdrawnbigtilt * (1 - ((float)(j)) / drawhowmany), 0, 0, 1);
1000                 glRotatef(-rotation1 * (((float)(j)) / drawhowmany) - lastdrawnrotation1 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 1, 0);
1001                 glRotatef(-rotation2 * (((float)(j)) / drawhowmany) - lastdrawnrotation2 * (1 - ((float)(j)) / drawhowmany) + 90, 0, 0, 1);
1002                 glRotatef(-rotation3 * (((float)(j)) / drawhowmany) - lastdrawnrotation3 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
1003                 glRotatef(smallrotation * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation * (1 - ((float)(j)) / drawhowmany), 1, 0, 0);
1004                 glRotatef(smallrotation2 * (((float)(j)) / drawhowmany) + lastdrawnsmallrotation2 * (1 - ((float)(j)) / drawhowmany), 0, 1, 0);
1005
1006                 if (owner != -1) {
1007                     if (Person::players[owner]->animTarget == staffhitanim || Person::players[owner]->animCurrent == staffhitanim || Person::players[owner]->animTarget == staffhitreversedanim || Person::players[owner]->animCurrent == staffhitreversedanim) {
1008                         glTranslatef(0, 0, -.3);
1009                     }
1010                     if (Person::players[owner]->animTarget == staffgroundsmashanim || Person::players[owner]->animCurrent == staffgroundsmashanim || Person::players[owner]->animTarget == staffspinhitreversedanim || Person::players[owner]->animCurrent == staffspinhitreversedanim || Person::players[owner]->animTarget == staffspinhitanim || Person::players[owner]->animCurrent == staffspinhitanim) {
1011                         glTranslatef(0, 0, -.1);
1012                     }
1013                 }
1014
1015                 glEnable(GL_LIGHTING);
1016                 switch (type) {
1017                 case knife:
1018                     if (!bloody || !bloodtoggle)
1019                         throwingknifemodel.drawdifftex(knifetextureptr);
1020                     if (bloodtoggle) {
1021                         if (bloody == 1)
1022                             throwingknifemodel.drawdifftex(lightbloodknifetextureptr);
1023                         if (bloody == 2)
1024                             throwingknifemodel.drawdifftex(bloodknifetextureptr);
1025                     }
1026                     break;
1027                 case sword:
1028                     if (!bloody || !bloodtoggle)
1029                         swordmodel.drawdifftex(swordtextureptr);
1030                     if (bloodtoggle) {
1031                         if (bloody == 1)
1032                             swordmodel.drawdifftex(lightbloodswordtextureptr);
1033                         if (bloody == 2)
1034                             swordmodel.drawdifftex(bloodswordtextureptr);
1035                     }
1036                     break;
1037                 case staff:
1038                     staffmodel.drawdifftex(stafftextureptr);
1039                     break;
1040                 }
1041
1042                 glPopMatrix();
1043             }
1044
1045             lastdrawnposition = position;
1046             lastdrawntippoint = tippoint;
1047             lastdrawnrotation1 = rotation1;
1048             lastdrawnrotation2 = rotation2;
1049             lastdrawnrotation3 = rotation3;
1050             lastdrawnbigrotation = bigrotation;
1051             lastdrawnbigtilt = bigtilt;
1052             lastdrawnbigtilt2 = bigtilt2;
1053             lastdrawnsmallrotation = smallrotation;
1054             lastdrawnsmallrotation2 = smallrotation2;
1055             if (owner != -1)
1056                 lastdrawnanim = Person::players[owner]->animCurrent;
1057         }
1058         if (owner != -1) {
1059             glMatrixMode(GL_MODELVIEW);
1060             glPushMatrix();
1061             glLoadIdentity();
1062             glTranslatef(position.x, position.y - .02, position.z);
1063             glRotatef(bigrotation, 0, 1, 0);
1064             glRotatef(bigtilt2, 1, 0, 0);
1065             glRotatef(bigtilt, 0, 0, 1);
1066             glRotatef(-rotation1 + 90, 0, 1, 0);
1067             glRotatef(-rotation2 + 90, 0, 0, 1);
1068             glRotatef(-rotation3, 0, 1, 0);
1069             glRotatef(smallrotation, 1, 0, 0);
1070             glRotatef(smallrotation2, 0, 1, 0);
1071             glTranslatef(0, 0, length);
1072             glGetFloatv(GL_MODELVIEW_MATRIX, M);
1073             tippoint.x = M[12];
1074             tippoint.y = M[13];
1075             tippoint.z = M[14];
1076             glPopMatrix();
1077         }
1078     }
1079 }
1080
1081 int Weapons::Draw()
1082 {
1083     glAlphaFunc(GL_GREATER, 0.9);
1084     glEnable(GL_TEXTURE_2D);
1085     glEnable(GL_BLEND);
1086     glEnable(GL_CULL_FACE);
1087     glCullFace(GL_FRONT);
1088     glDepthMask(1);
1089
1090     for (std::vector<Weapon>::iterator weapon = begin(); weapon != end(); ++weapon) {
1091         weapon->Draw();
1092     }
1093     return 0;
1094 }
1095
1096 Weapons::Weapons()
1097 {
1098 }
1099
1100 Weapons::~Weapons()
1101 {
1102     Weapon::stafftextureptr.destroy();
1103     Weapon::knifetextureptr.destroy();
1104     Weapon::lightbloodknifetextureptr.destroy();
1105     Weapon::bloodknifetextureptr.destroy();
1106     Weapon::swordtextureptr.destroy();
1107     Weapon::lightbloodswordtextureptr.destroy();
1108     Weapon::bloodswordtextureptr.destroy();
1109 }
1110