1 /*
2  * GameTick.cpp
3  * Copyright (C) 2007 by Bryan Duff <duff0097@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20 
21 #include "Weapon.h"
22 #include "Game.h"
23 
24 extern double multiplier;
25 
26 extern Sprites sprites;
27 
28 extern unsigned int gSourceID[100];
29 extern unsigned int gSampleSet[100];
30 
31 extern Camera camera;
32 extern Fog fog;
33 extern Config config;
34 extern Environment environment;
35 extern Decals decals;
36 
37 extern float soundscalefactor;
38 
39 extern int slomo;
40 
41 extern int forwardskey;
42 extern int backwardskey;
43 extern int leftkey;
44 extern int rightkey;
45 extern int aimkey;
46 extern int psychicaimkey;
47 extern int psychickey;
48 
49 #define maxfallvel 40
50 
Splat(int k)51 void Game::Splat(int k)
52 {
53   if(k != 0 || config.visions == 0) {
54     person[k].health = 0;
55     person[k].DoAnimations(k);
56     person[k].skeleton.offset = 0;
57     person[k].skeleton.free = 1;
58     person[k].longdead = 1;
59 
60     person[k].bleeding = 1;
61     person[k].bleeddelay = 1;
62     person[k].bjoint1 =
63         &person[k].skeleton.joints[person[k].skeleton.jointlabels[head]];
64     person[k].bjoint2 =
65         &person[k].skeleton.joints[person[k].skeleton.jointlabels[neck]];
66 
67     for(int j = 0; j < person[k].skeleton.num_joints; j++) {
68       person[k].skeleton.joints[j].position +=
69           person[k].skeleton.joints[j].offset;
70       person[k].skeleton.joints[j].position =
71           DoRotation(person[k].skeleton.joints[j].position, 0,
72                      person[k].playerrotation, 0);
73       person[k].skeleton.joints[j].position += person[k].playercoords;
74       person[k].skeleton.joints[j].realoldposition =
75           person[k].skeleton.joints[j].position;
76       person[k].skeleton.joints[j].velocity = 0;
77       person[k].skeleton.joints[j].velocity.y += person[k].velocity.y;
78     }
79 
80     float gLoc[3];
81 
82     gLoc[0] =
83         person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].
84         position.x / soundscalefactor;
85     gLoc[1] =
86         person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].
87         position.y / soundscalefactor;
88     gLoc[2] =
89         person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].
90         position.z / soundscalefactor;
91 
92     alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
93     alSourcePlay(gSourceID[headwhacksound]);
94   }
95 }
96 
MainMenuTick()97 void Game::MainMenuTick()
98 {
99     float mousex;
100     float mousey;
101     bool clicked = ButtonClick(1);
102 
103     //resume from pause
104     if(IsKeyDown(theKeyMap, MAC_SPACE_KEY)) {
105       state = GAME;
106     }
107 
108     GetMouse(&mouseloc);
109     mousex = mouseloc.h;
110     mousey = mouseloc.v;
111 
112     mousex = (float)mouseloc.h / screenwidth;
113     mousey = (screenheight - (float)mouseloc.v) / screenheight;
114 
115     //printf("mousex: %f, mousey: %f\n", mousex, mousey);
116 
117     oldmouseoverbutton = mouseoverbutton;
118 
119     mouseoverbutton = 0;
120 
121     Button *button1 =
122       (Button*) WindowMgr::getInstance().getRoot()->getWindow("mainmenu")->
123       getWindow("button1");
124     Button *button2 =
125       (Button*) WindowMgr::getInstance().getRoot()->getWindow("mainmenu")->
126       getWindow("button2");
127     //FIXME: change these coords (put in new button widget)
128     if(button1->isMouseOver(1, mousex, mousey)) {
129       mouseoverbutton = 1;
130     }
131 
132     if(button2->isMouseOver(1, mousex, mousey)) {
133       mouseoverbutton = 2;
134     }
135 
136     if(!mouseoverbutton) {
137       return;
138     }
139 
140     if(!oldbutton) {
141     //start new game
142     if(clicked && mouseoverbutton == 1 && !gameinprogress) {
143       if(environment.type == rainy_environment)
144         alSourcePlay(gSourceID[rainsound]);
145 
146       if(environment.type != rainy_environment)
147         alSourcePause(gSourceID[rainsound]);
148 
149       alSourceStop(gSourceID[whichsong]);
150 
151       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
152       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
153 
154       if(person[0].weapon.type == knife)
155         whichsong = knifesong;
156       else
157         whichsong = shootsong;
158 
159       if(type == zombie_type)
160         whichsong = zombiesong;
161 
162       alSourcef(gSourceID[whichsong], AL_PITCH, 1);
163       alSourcePlay(gSourceID[whichsong]);
164       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
165       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
166 
167       flashamount = 1;
168 
169       flashr = 1;
170       flashg = 1;
171       flashb = 1;
172 
173       state = GAME;
174 
175       alSourcePlay(gSourceID[soulinsound]);
176 
177       mission = 0;
178 
179       InitGame();
180 
181       gameinprogress = 1;
182     }
183 
184     //resume
185     if(clicked && mouseoverbutton == 1 && gameinprogress) {
186 
187       flashamount = 1;
188 
189       flashr = 1;
190       flashg = 1;
191       flashb = 1;
192 
193       state = GAME;
194 
195       MoveMouse(oldmouseloc.h, oldmouseloc.v, &mouseloc);
196 
197       if(environment.type == rainy_environment)
198         alSourcePlay(gSourceID[rainsound]);
199 
200       if(environment.type != rainy_environment)
201         alSourcePause(gSourceID[rainsound]);
202 
203       alSourceStop(gSourceID[whichsong]);
204 
205       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
206       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
207 
208       if(person[0].weapon.type == knife)
209         whichsong = knifesong;
210       else
211         whichsong = shootsong;
212 
213       if(type == zombie_type)
214         whichsong = zombiesong;
215 
216       alSourcePlay(gSourceID[whichsong]);
217 
218       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
219       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
220 
221       alSourcePlay(gSourceID[soulinsound]);
222 
223       if(config.visions)
224         alSourcePlay(gSourceID[visionsound]);
225     }
226 
227     //quit
228     if(clicked && mouseoverbutton == 2 && !gameinprogress) {
229       flashamount = 1;
230       flashr = 1;
231       flashg = 0;
232       flashb = 0;
233 
234       alSourcePlay(gSourceID[losesound]);
235 
236       gQuit = true;
237 
238       config.WriteHighScore(score);
239     }
240 
241     //end game
242     if(clicked && mouseoverbutton == 2 && gameinprogress) {
243       flashamount = 1;
244       flashr = 1;
245       flashg = 1;
246       flashb = 1;
247 
248       alSourcePlay(gSourceID[losesound]);
249 
250       gameinprogress = 0;
251 
252       config.WriteHighScore(score);
253     }
254     }
255 
256     if(clicked)
257       oldbutton = 1;
258 
259     if(!clicked)
260       oldbutton = 0;
261 }
262 
263 //Check collision with buildings, the ground
checkCollisions()264 void Game::checkCollisions()
265 {
266     XYZ collpoint;
267     int pointnum;
268     float depth;
269     bool inblock;
270 
271     person[0].playerrotation = 180 - camera.rotation;
272 
273     //Check people collisions
274     for(int k = 0; k < numpeople; k++) {
275       // SBF - backing up the old coordinates makes
276       // the most sense here.
277       person[k].oldplayercoords = person[k].playercoords;
278       person[k].DoStuff(k);
279 
280       if(person[k].skeleton.free < 1) {
281 
282         if(1 == 1) {
283 
284           person[k].onground = 0;
285 
286           overpoint = person[k].playercoords;
287           overpoint.y += 3000;
288 
289           underpoint = person[k].playercoords;
290           underpoint.y -= 3000;
291 
292           beginx =
293               (int)((person[k].playercoords.x +
294                      block_spacing / 2) / block_spacing);
295 
296           if(beginx < 0)
297             beginx = 0;
298 
299           beginz =
300               (int)((person[k].playercoords.z +
301                      block_spacing / 2) / block_spacing);
302 
303           if(beginz < 0)
304             beginz = 0;
305 
306           endx =
307               (int)((person[k].playercoords.x +
308                      block_spacing / 2) / block_spacing + 1);
309 
310           if(endx > num_blocks - 1)
311             endx = num_blocks - 1;
312 
313           endz =
314               (int)((person[k].playercoords.z +
315                      block_spacing / 2) / block_spacing + 1);
316 
317           if(endz > num_blocks - 1)
318             endz = num_blocks - 1;
319 #if 0
320           if(k != 0) {
321             /* TODO: huh? */
322             beginx == person[k].whichblockx;
323 
324             beginz == person[k].whichblocky;
325 
326             endx == person[k].whichblockx;
327 
328             endz == person[k].whichblocky;
329           }
330 #endif
331           if(beginx <= endx && beginz <= endz)
332 
333             for(int i = beginx; i <= endx; i++)
334               for(int j = beginz; j <= endz; j++) {
335                 inblock = 0;
336 
337                 //Ground collision
338                 move = 0;
339                 move.x = i * block_spacing;
340                 move.z = j * block_spacing;
341 
342                 whichtri =
343                     sidewalkcollide.LineCheck2(overpoint, underpoint,
344                                                &collpoint, move,
345                                                cityrotation[i][j] * 90);
346 
347                 if(whichtri != -1 && person[k].playercoords.y <= collpoint.y
348                    && person[k].velocity.y <= 0) {
349 
350                   person[k].playercoords.y = collpoint.y;
351                   person[k].onground = 1;
352 
353                   if(person[k].velocity.y < -maxfallvel)
354                     Splat(k);
355                   else
356                     person[k].velocity.y = 0;
357                 }
358 
359                 if(whichtri != -1) {
360                   inblock = 1;
361 
362                   if(k == 0) {
363                     onblockx = i;
364                     onblocky = j;
365                   }
366                 }
367                 //Wall collision
368                 if(k == 0) {
369                   if(inblock) {
370                     for(int l = 0; l < 8; l++) {
371                       move = 0;
372                       move.x = i * block_spacing;
373                       move.z = j * block_spacing;
374 
375                       whichtri =
376                           blockwalls[citytype[i][j]].LineCheck3(person[k].
377                                                                 oldplayercoords
378                                                                 +
379                                                                 boundingpoints
380                                                                 [l],
381                                                                 person[k].
382                                                                 playercoords +
383                                                                 boundingpoints
384                                                                 [l], &collpoint,
385                                                                 move,
386                                                                 cityrotation[i]
387                                                                 [j] * 90,
388                                                                 &depth);
389 
390                       if(whichtri != -1) {
391 
392                         normalrotated =
393                             DoRotation(blockwalls[citytype[i][j]].
394                                        normals[whichtri], 0,
395                                        cityrotation[i][j] * 90, 0);
396 
397                         person[k].playercoords +=
398                             normalrotated *
399                             (-
400                              (dotproduct
401                               (normalrotated,
402                                person[k].playercoords -
403                                person[k].oldplayercoords)) - depth);
404                       }
405                     }
406 
407                     for(int l = 0; l < 8; l++) {
408                       pointnum = k + 1;
409 
410                       if(pointnum > 3)
411                         pointnum = 0;
412 
413                       move = 0;
414                       move.x = i * block_spacing;
415                       move.z = j * block_spacing;
416 
417                       whichtri =
418                           blockwalls[citytype[i][j]].LineCheck3(person[k].
419                                                                 playercoords +
420                                                                 boundingpoints
421                                                                 [l],
422                                                                 person[k].
423                                                                 playercoords +
424                                                                 boundingpoints
425                                                                 [pointnum],
426                                                                 &collpoint,
427                                                                 move,
428                                                                 cityrotation[i]
429                                                                 [j] * 90,
430                                                                 &depth);
431 
432                       if(whichtri != -1) {
433 
434                         normalrotated =
435                             DoRotation(blockwalls[citytype[i][j]].
436                                        normals[whichtri], 0,
437                                        cityrotation[i][j] * 90, 0);
438 
439                         person[k].playercoords += normalrotated;
440                       }
441                     }
442                   }
443                   //Roof collision
444                   if(inblock && person[k].playercoords.y > 30) {
445 
446                     if(!person[k].onground) {
447 
448                       move = 0;
449                       move.x = i * block_spacing;
450                       move.z = j * block_spacing;
451 
452                       whichtri =
453                           blockroofs[citytype[i][j]].LineCheck2(overpoint,
454                                                                 underpoint,
455                                                                 &collpoint,
456                                                                 move,
457                                                                 cityrotation[i]
458                                                                 [j] * 90);
459 
460                       if(whichtri != -1
461                          && person[k].playercoords.y <= collpoint.y
462                          && person[k].velocity.y <= 0) {
463 
464                         person[k].playercoords.y = collpoint.y;
465                         person[k].onground = 1;
466 
467                         if(person[k].velocity.y < -maxfallvel)
468                           Splat(k);
469                         else
470                           person[k].velocity.y = 0;
471                       }
472 
473                       if(whichtri != -1)
474                         inblock = 1;
475                     }
476                   }
477                 }
478               }
479 
480           if(person[k].playercoords.y <= 0) {
481 
482             person[k].onground = 1;
483             person[k].playercoords.y = 0;
484 
485             if(person[k].velocity.y < -maxfallvel)
486               Splat(k);
487             else
488               person[k].velocity.y = 0;
489 
490             if(k == 0)
491               onblockx = -1;
492             onblocky = -1;
493           }
494           // SBF - this is definately in the wrong spot!
495           //person[k].oldplayercoords=person[k].playercoords;
496         }
497       }
498     }
499 }
500 
Fire()501 void Game::Fire()
502 {
503 //Fire/wing
504     XYZ wallhit;
505     XYZ start;
506     XYZ finalwallhit;
507 
508     bool firing;
509     float inaccuracy = 0.0;
510     int numshots;
511 
512     XYZ hitnorm;
513     XYZ hitmove;
514 
515     int hitpoly = 0;
516     float hitrotation = 0.0f;
517 
518     Model *model = NULL;
519     bool thirdperson = config.thirdperson;
520 
521     for(int j = 0; j < numpeople; j++) {
522 
523       if(person[j].type == playertype || person[j].type == eviltype) {
524 
525         firing = 0;
526 
527         if(person[j].weapon.ammo > 0 && person[j].weapon.reloading <= 0
528            && person[j].targetanimation != joganim) {
529 
530           if(ButtonClick(1) && !oldbutton && j == 0)
531             firing = 1;
532 
533           if(j != 0)
534             firing = 0;
535 
536           if(j != 0 && person[j].weapon.type != nogun
537              && person[j].weapon.type != knife && person[j].killtargetvisible
538              && person[j].weapon.shotdelay < 0)
539             firing = 1;
540 
541           if(j != 0 && person[j].weapon.type != nogun
542              && person[j].weapon.type != knife && person[j].killtargetvisible
543              && person[j].weapon.shotdelay > 0)
544             person[j].weapon.shotdelay -= multiplier * .9;
545 
546           if(person[j].skeleton.free == 1
547              || person[j].targetanimation == getupfrontanim
548              || person[j].targetanimation == getupbackanim)
549             person[j].weapon.shotdelay = shotdelayamount / difficulty;
550 
551           if(j != 0 && person[j].weapon.type != nogun
552              && person[j].weapon.type != knife && person[j].killtargetvisible)
553             person[j].aiming = 1;
554 
555           if(person[0].weapon.type != assaultrifle)
556             oldbutton = 1;
557 
558         }
559 
560         if(person[j].weapon.ammo == 0 && person[j].reloads[person[j].weapon.type] > 0) {
561           person[j].weapon.ammo = -1;
562           person[j].aiming = 0;
563           firing = 0;
564         }
565 
566         if(person[0].weapon.ammo <= 0 && ButtonClick(1) && !oldbutton
567            && person[0].targetanimation != joganim
568            && person[0].weapon.type != nogun && person[0].weapon.type != knife
569            && person[0].weapon.type != grenade && person[0].aiming) {
570 
571           oldbutton = 1;
572 
573           float gLoc[3];
574           gLoc[0] = person[0].playercoords.x / soundscalefactor;
575           gLoc[1] = person[0].playercoords.y / soundscalefactor;
576           gLoc[2] = person[0].playercoords.z / soundscalefactor;
577 
578           alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc);
579           alSourcePlay(gSourceID[clicksound]);
580         }
581 
582         if(j == 0 && config.visions == 1 && firing) {
583           firing = 0;
584           alSourcePlay(gSourceID[soulinsound]);
585         }
586 
587         if(person[j].aimamount < 1)
588           firing = 0;
589 
590         if(firing) {
591           switch(person[j].weapon.type) {
592             case handgun1:
593             case handgun2:
594               inaccuracy = 8;
595               break;
596 
597             case assaultrifle:
598               inaccuracy = 6;
599               break;
600 
601             case sniperrifle:
602               inaccuracy = 2;
603               break;
604 
605             case shotgun:
606               inaccuracy = 6;
607               break;
608           }
609 
610           if(person[person[j].killtarget].skeleton.free == 1)
611             inaccuracy *= 3;
612 
613           person[j].weapon.shotdelay = shotdelayamount / difficulty;
614 
615           if(person[j].aiming >= 1 && person[j].weapon.recoil <= 0) {
616 
617             //Firing
618             person[j].litup = 1;
619             person[j].weapon.recoil = 1;
620 
621             XYZ end, aim, oldend;
622 
623             HitStruct hitstruct, temphitstruct;
624             hitstruct.hitlocation = 0.0f;
625 
626             float olddistance = 0.0f;
627             float distance = 0.0f;
628             float totalarea = 0.0f;
629 
630             int whichhit = -1;
631 
632             if(person[j].weapon.type == shotgun)
633               numshots = 7;
634 
635             if(person[j].weapon.type != shotgun)
636               numshots = 1;
637 
638             if(person[j].weapon.type != grenade)
639               person[j].weapon.ammo--;
640 
641             for(int p = 0; p < numshots; p++) {
642 
643               if(!zoom || j != 0) {
644 
645                 if(person[j].weapon.type == assaultrifle)
646                   aim =
647                       DoRotation(person[j].skeleton.
648                                  joints[(person[j].skeleton.
649                                          jointlabels[lefthand])].position -
650                                  person[j].skeleton.
651                                  joints[(person[j].skeleton.
652                                          jointlabels[righthand])].position, 0,
653                                  person[j].playerrotation - 2.5, 0);
654 
655                 if(person[j].weapon.type == sniperrifle)
656                   aim =
657                       DoRotation(person[j].skeleton.
658                                  joints[(person[j].skeleton.
659                                          jointlabels[lefthand])].position -
660                                  person[j].skeleton.
661                                  joints[(person[j].skeleton.
662                                          jointlabels[righthand])].position, 0,
663                                  person[j].playerrotation + 4, 0);
664 
665                 if(person[j].weapon.type == shotgun)
666                   aim =
667                       DoRotation(person[j].skeleton.
668                                  joints[(person[j].skeleton.
669                                          jointlabels[lefthand])].position -
670                                  person[j].skeleton.
671                                  joints[(person[j].skeleton.
672                                          jointlabels[righthand])].position,
673                                  2 + (float)(Random() % 1000) / 500, 0, 0);
674 
675                 if(person[j].weapon.type == shotgun)
676                   aim =
677                       DoRotation(aim, 0,
678                                  person[j].playerrotation - 1 +
679                                  (float)(Random() % 1000) / 500, 0);
680 
681                 if(person[j].weapon.type == handgun1 && !thirdperson && j == 0)
682                   aim =
683                       DoRotation(person[j].skeleton.
684                                  joints[(person[j].skeleton.
685                                          jointlabels[righthand])].position -
686                                  (person[j].skeleton.
687                                   joints[person[j].skeleton.jointlabels[head]].
688                                   position * .65 +
689                                   person[j].skeleton.joints[person[j].skeleton.
690                                                             jointlabels[neck]].
691                                   position * .35), 0,
692                                  person[j].playerrotation - .9, 0);
693 
694                 if(person[j].weapon.type == handgun1 && (thirdperson || j != 0))
695                   aim =
696                       DoRotation(person[j].skeleton.
697                                  joints[(person[j].skeleton.
698                                          jointlabels[righthand])].position -
699                                  (person[j].skeleton.
700                                   joints[person[j].skeleton.jointlabels[head]].
701                                   position * .35 +
702                                   person[j].skeleton.joints[person[j].skeleton.
703                                                             jointlabels[neck]].
704                                   position * .65), 0,
705                                  person[j].playerrotation - .9, 0);
706 
707                 if(person[j].weapon.type == handgun2 && !thirdperson && j == 0)
708                   aim =
709                       DoRotation(person[j].skeleton.
710                                  joints[(person[j].skeleton.
711                                          jointlabels[righthand])].position -
712                                  (person[j].skeleton.
713                                   joints[person[j].skeleton.jointlabels[head]].
714                                   position * .65 +
715                                   person[j].skeleton.joints[person[j].skeleton.
716                                                             jointlabels[neck]].
717                                   position * .35), 0,
718                                  person[j].playerrotation - .9, 0);
719 
720                 if(person[j].weapon.type == handgun2 && (thirdperson || j != 0))
721                   aim =
722                       DoRotation(person[j].skeleton.
723                                  joints[(person[j].skeleton.
724                                          jointlabels[righthand])].position -
725                                  (person[j].skeleton.
726                                   joints[person[j].skeleton.jointlabels[head]].
727                                   position * .35 +
728                                   person[j].skeleton.joints[person[j].skeleton.
729                                                             jointlabels[neck]].
730                                   position * .65), 0,
731                                  person[j].playerrotation - .9, 0);
732 
733                 if(j != 0 && person[person[j].killtarget].skeleton.free == 0)
734                   aim =
735                       (DoRotation
736                        (person[person[j].killtarget].skeleton.
737                         joints[person[person[j].killtarget].skeleton.
738                                jointlabels[abdomen]].position, 0,
739                         person[person[j].killtarget].playerrotation,
740                         0) + person[person[j].killtarget].playercoords) -
741                       (DoRotation
742                        (person[j].skeleton.
743                         joints[person[j].skeleton.jointlabels[lefthand]].
744                         position, 0, person[j].playerrotation,
745                         0) + person[j].playercoords);
746 
747                 if(j != 0 && person[person[j].killtarget].skeleton.free != 0)
748                   aim =
749                       person[person[j].killtarget].skeleton.
750                       joints[person[person[j].killtarget].skeleton.
751                              jointlabels[abdomen]].position -
752                       (DoRotation
753                        (person[j].skeleton.
754                         joints[person[j].skeleton.jointlabels[lefthand]].
755                         position, 0, person[j].playerrotation,
756                         0) + person[j].playercoords);
757 
758                 if(j != 0)
759                   aim =
760                       DoRotation(DoRotation
761                                  (DoRotation
762                                   (aim, 0, -person[j].playerrotation, 0),
763                                   (float)(abs(Random() % 2000)) / 2000 *
764                                   inaccuracy - inaccuracy / 2,
765                                   (float)(abs(Random() % 2000)) / 2000 *
766                                   inaccuracy - inaccuracy / 2, 0), 0,
767                                  person[j].playerrotation, 0);
768 
769               }
770 
771               if(zoom && j == 0) {
772                 start = camera.position;
773                 aim = facing;
774               }
775 
776               Normalise(&aim);
777 
778               if(person[j].weapon.type == sniperrifle) {
779 
780                 start =
781                     person[j].playercoords +
782                     DoRotation(person[j].skeleton.
783                                joints[(person[j].skeleton.
784                                        jointlabels[lefthand])].position, 0,
785                                person[j].playerrotation, 0);
786 
787                 float gLoc[3];
788 
789                 start -=
790                     DoRotation(DoRotation
791                                (DoRotation
792                                 (aim, 0, -person[j].playerrotation, 0), 90, 0,
793                                 0), 0, person[j].playerrotation, 0) * .35;
794 
795                 gLoc[0] =
796                     (camera.position.x +
797                      (start.x - camera.position.x) / 4) / soundscalefactor;
798 
799                 gLoc[1] =
800                     (camera.position.y +
801                      (start.y - camera.position.y) / 4) / soundscalefactor;
802 
803                 gLoc[2] =
804                     (camera.position.z +
805                      (start.z - camera.position.z) / 4) / soundscalefactor;
806 
807                 alSourcefv(gSourceID[riflesound], AL_POSITION, gLoc);
808 
809                 alSourcePlay(gSourceID[riflesound]);
810 
811                 if(j == 0) {
812 
813                   if(person[j].currentanimation != crouchanim)
814                     camera.rotation2 -= 7;
815 
816                   if(person[j].currentanimation == crouchanim)
817                     camera.rotation2 -= 3;
818                 }
819               }
820 
821               if(person[j].weapon.type == shotgun) {
822 
823                 start =
824                     person[j].playercoords +
825                     DoRotation(person[j].skeleton.
826                                joints[(person[j].skeleton.
827                                        jointlabels[lefthand])].position, 0,
828                                person[j].playerrotation, 0);
829 
830                 float gLoc[3];
831 
832                 start -=
833                     DoRotation(DoRotation
834                                (DoRotation
835                                 (aim, 0, -person[j].playerrotation, 0), 90, 0,
836                                 0), 0, person[j].playerrotation, 0) * .35;
837 
838                 if(p == numshots - 1) {
839 
840                   gLoc[0] =
841                       (camera.position.x +
842                        (start.x - camera.position.x) / 4) / soundscalefactor;
843 
844                   gLoc[1] =
845                       (camera.position.y +
846                        (start.y - camera.position.y) / 4) / soundscalefactor;
847 
848                   gLoc[2] =
849                       (camera.position.z +
850                        (start.z - camera.position.z) / 4) / soundscalefactor;
851 
852                   alSourcefv(gSourceID[shotgunsound], AL_POSITION, gLoc);
853 
854                   alSourcePlay(gSourceID[shotgunsound]);
855 
856                   if(j == 0) {
857 
858                     if(person[j].currentanimation != crouchanim)
859                       camera.rotation2 -= 7;
860 
861                     if(person[j].currentanimation == crouchanim)
862                       camera.rotation2 -= 3;
863                   }
864                 }
865               }
866 
867               if(person[j].weapon.type == handgun1) {
868 
869                 start =
870                     person[j].playercoords +
871                     DoRotation(person[j].skeleton.
872                                joints[(person[j].skeleton.
873                                        jointlabels[rightwrist])].position, 0,
874                                person[j].playerrotation, 0);
875 
876                 start -=
877                     DoRotation(DoRotation
878                                (DoRotation
879                                 (aim, 0, -person[j].playerrotation, 0), 90, 0,
880                                 0), 0, person[j].playerrotation, 0) * .55;
881 
882                 float gLoc[3];
883 
884                 gLoc[0] =
885                     (camera.position.x +
886                      (start.x - camera.position.x) / 4) / soundscalefactor;
887 
888                 gLoc[1] =
889                     (camera.position.y +
890                      (start.y - camera.position.y) / 4) / soundscalefactor;
891 
892                 gLoc[2] =
893                     (camera.position.z +
894                      (start.z - camera.position.z) / 4) / soundscalefactor;
895 
896                 alSourcefv(gSourceID[pistol1sound], AL_POSITION, gLoc);
897 
898                 alSourcePlay(gSourceID[pistol1sound]);
899 
900                 if(j == 0) {
901 
902                   if(person[j].currentanimation != crouchanim)
903                     camera.rotation2 -= 6;
904 
905                   if(person[j].currentanimation == crouchanim)
906                     camera.rotation2 -= 4;
907                 }
908               }
909 
910               if(person[j].weapon.type == handgun2) {
911 
912                 start =
913                     person[j].playercoords +
914                     DoRotation(person[j].skeleton.
915                                joints[(person[j].skeleton.
916                                        jointlabels[rightwrist])].position, 0,
917                                person[j].playerrotation, 0);
918 
919                 start -=
920                     DoRotation(DoRotation
921                                (DoRotation
922                                 (aim, 0, -person[j].playerrotation, 0), 90, 0,
923                                 0), 0, person[j].playerrotation, 0) * .55;
924 
925 
926 
927                 float gLoc[3];
928 
929                 gLoc[0] =
930                     (camera.position.x +
931                      (start.x - camera.position.x) / 4) / soundscalefactor;
932 
933                 gLoc[1] =
934                     (camera.position.y +
935                      (start.y - camera.position.y) / 4) / soundscalefactor;
936 
937                 gLoc[2] =
938                     (camera.position.z +
939                      (start.z - camera.position.z) / 4) / soundscalefactor;
940 
941                 alSourcefv(gSourceID[pistol2sound], AL_POSITION, gLoc);
942                 alSourcePlay(gSourceID[pistol2sound]);
943 
944                 if(j == 0) {
945                   if(person[j].currentanimation != crouchanim)
946                     camera.rotation2 -= 5;
947 
948                   if(person[j].currentanimation == crouchanim)
949                     camera.rotation2 -= 3;
950                 }
951               }
952 
953               if(person[j].weapon.type == assaultrifle) {
954 
955                 start =
956                     person[j].playercoords +
957                     DoRotation(person[j].skeleton.
958                                joints[(person[j].skeleton.
959                                        jointlabels[lefthand])].position, 0,
960                                person[j].playerrotation, 0);
961 
962                 start -=
963                     DoRotation(DoRotation
964                                (DoRotation
965                                 (aim, 0, -person[j].playerrotation, 0), 90, 0,
966                                 0), 0, person[j].playerrotation, 0) * .25;
967 
968                 float gLoc[3];
969 
970                 gLoc[0] =
971                     (camera.position.x +
972                      (start.x - camera.position.x) / 4) / soundscalefactor;
973 
974                 gLoc[1] =
975                     (camera.position.y +
976                      (start.y - camera.position.y) / 4) / soundscalefactor;
977 
978                 gLoc[2] =
979                     (camera.position.z +
980                      (start.z - camera.position.z) / 4) / soundscalefactor;
981 
982                 alSourcefv(gSourceID[machinegunsound], AL_POSITION, gLoc);
983                 alSourcePlay(gSourceID[machinegunsound]);
984 
985                 if(j == 0) {
986 
987                   if(person[j].currentanimation != crouchanim) {
988                     camera.rotation2 -= 2.3;
989                     camera.rotation += (float)(Random() % 100) / 50;
990                   }
991 
992                   if(person[j].currentanimation == crouchanim) {
993                     camera.rotation2 -= 1.5;
994                     camera.rotation += (float)(Random() % 100) / 60;
995                   }
996                 }
997               }
998 
999               end = start + aim * 1000;
1000 
1001               if(config.debug) {
1002                 if(IsKeyDown(theKeyMap, MAC_G_KEY) && j == 0) {
1003                   sprites.MakeSprite(grenadesprite, 1, 1, 1, 1, start,
1004                                      aim * 200, 1.01);
1005                 }
1006               }
1007 
1008               if(!IsKeyDown(theKeyMap, MAC_G_KEY) || j != 0 || !config.debug) {
1009                 int bulletstrength = 1;
1010                 int firstpass = -1;
1011                 bool penetrate;
1012 
1013                 for(int m = 0; m < bulletstrength; m++) {
1014                   //People
1015                   whichhit = -1;
1016 
1017                   for(int i = 0; i < numpeople; i++) {
1018                     if(i != j && i != firstpass && person[i].existing) {
1019 
1020                       temphitstruct =
1021                           person[i].BulletCollideWithPlayer(i, start, end);
1022 
1023                       if(temphitstruct.collision) {
1024 
1025                         distance =
1026                             findDistancefast(start, temphitstruct.hitlocation);
1027 
1028                         if(distance < olddistance || whichhit == -1) {
1029 
1030                           end = temphitstruct.hitlocation;
1031 
1032                           olddistance = distance;
1033 
1034                           hitstruct = temphitstruct;
1035 
1036                           whichhit = i;
1037                         }
1038                       }
1039                     }
1040                   }
1041 
1042                   //Blocks
1043                   wallhit = 0;
1044 
1045                   beginx =
1046                       (int)(person[j].playercoords.x +
1047                             block_spacing / 2) / block_spacing - 3;
1048 
1049                   if(beginx < 0)
1050                     beginx = 0;
1051 
1052                   beginz =
1053                       (int)(person[j].playercoords.z +
1054                             block_spacing / 2) / block_spacing - 3;
1055 
1056                   if(beginz < 0)
1057                     beginz = 0;
1058 
1059                   endx =
1060                       (int)(person[j].playercoords.x +
1061                             block_spacing / 2) / block_spacing + 3;
1062 
1063                   if(endx > num_blocks - 1)
1064                     endx = num_blocks - 1;
1065 
1066                   endz =
1067                       (int)(person[j].playercoords.z +
1068                             block_spacing / 2) / block_spacing + 3;
1069 
1070                   if(endz > num_blocks - 1)
1071                     endz = num_blocks - 1;
1072 
1073                   if(beginx < endx && beginz < endz)
1074 
1075                     finalwallhit = 0;
1076 
1077                   for(int i = beginx; i <= endx; i++)
1078 
1079                     for(int j = beginz; j <= endz; j++) {
1080 
1081                       move = 0;
1082                       move.x = i * block_spacing;
1083                       move.z = j * block_spacing;
1084 
1085                       whichtri =
1086                           blocks[citytype[i][j]].LineCheck2(start, end,
1087                                                             &wallhit, move,
1088                                                             cityrotation[i][j] *
1089                                                             90);
1090 
1091                       if(whichtri != -1) {
1092                         whichhit = -1;
1093                         end = wallhit;
1094                         finalwallhit = wallhit;
1095 
1096                         hitnorm =
1097                             DoRotation(blocks[citytype[i][j]].normals[whichtri],
1098                                        0, cityrotation[i][j] * 90, 0);
1099 
1100                         hitmove = move;
1101                         hitrotation = cityrotation[i][j] * 90;
1102                         hitpoly = whichtri;
1103                         model = &blocks[citytype[i][j]];
1104 
1105                         if(j == 0
1106                            && blocks[citytype[i][j]].normals[whichtri].y > .9)
1107                           bulletstrength = 2;
1108                       }
1109                     }
1110 
1111                   wallhit = 0;
1112                   wallhit.x = camera.position.x;
1113                   wallhit.z = camera.position.z;
1114 
1115                   whichtri =
1116                       Bigstreet.LineCheck2(start, end, &wallhit, wallhit, 0);
1117 
1118                   if(whichtri != -1) {
1119 
1120                     end.y -= .5;
1121                     end = wallhit;
1122                     finalwallhit = wallhit;
1123 
1124                     bulletstrength = 2;
1125 
1126                     hitnorm = 0;
1127                     hitnorm.y = 1;
1128                     hitmove = 0;
1129                     hitrotation = 0;
1130                   }
1131 
1132                   if(m == 0) {
1133                     if(j == 0 && slomo == 2) {
1134                       soundscalefactor = soundscalefactordefault;
1135 
1136                       alSourceStop(gSourceID[whichsong]);
1137 
1138                       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
1139                       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
1140 
1141                       if(person[0].weapon.type == knife)
1142                         whichsong = knifesong;
1143 
1144                       if(person[0].weapon.type != knife)
1145                         whichsong = shootsong;
1146 
1147                       if(type == zombie_type)
1148                         whichsong = zombiesong;
1149 
1150                       alSourcef(gSourceID[whichsong], AL_PITCH, 1);
1151                       alSourcePlay(gSourceID[whichsong]);
1152                       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
1153                       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
1154 
1155                       slomo = 0;
1156 
1157                       if(whichhit == -1)
1158                         alSourcePlay(gSourceID[disguisekillsound]);
1159 
1160                       flashamount = .5;
1161 
1162                       flashr = 1;
1163                       flashg = 1;
1164                       flashb = 1;
1165                     }
1166                   }
1167                   //Impact
1168 
1169                   oldend = end;
1170 
1171                   //with person
1172                   if(whichhit != -1 && whichhit != firstpass) {
1173                     if(j == 0) {
1174                       person[whichhit].dead = 1;
1175                     }
1176 
1177                     if(whichhit == 1) {
1178                       murderer = j;
1179                     }
1180 
1181                     if(person[whichhit].health == 100 && j == 0) {
1182 
1183                       if(person[whichhit].type == civiliantype)
1184                         civkills++;
1185 
1186                       if(person[whichhit].type == eviltype)
1187                         goodkills++;
1188                     }
1189 
1190                     if(person[whichhit].health == 100 && j != 0) {
1191                       badkills++;
1192                     }
1193                     //penetrate
1194                     penetrate = abs(Random() % 2) == 1;
1195 
1196                     if(numshots > 1)
1197                       penetrate = 0;
1198 
1199                     if(penetrate) {
1200                       bulletstrength = 2;
1201                       firstpass = whichhit;
1202                       end = start + aim * 1000;
1203                     }
1204 
1205                     if(person[j].weapon.type == assaultrifle)
1206                       person[whichhit].health -= 20;
1207 
1208                     if(person[j].weapon.type == assaultrifle
1209                        && person[whichhit].type == zombietype)
1210                       person[whichhit].health -= 60;
1211 
1212                     if(person[j].weapon.type == handgun1) {
1213 
1214                       if(person[whichhit].type != zombietype)
1215                         person[whichhit].health -= 100;
1216 
1217                       if(person[whichhit].type == zombietype)
1218                         person[whichhit].health -= 100;
1219 
1220                       person[whichhit].DoAnimations(whichhit);
1221                     }
1222 
1223                     if(person[j].weapon.type == handgun2)
1224                       person[whichhit].health -= 20;
1225 
1226                     if(person[j].weapon.type == handgun2
1227                        && person[whichhit].type == zombietype)
1228                       person[whichhit].health -= 60;
1229 
1230                     if(person[j].weapon.type == sniperrifle && m != 0)
1231                       person[whichhit].health -= 30;
1232 
1233                     if(person[j].weapon.type == shotgun)
1234                       person[whichhit].health -= 60;
1235 
1236                     if(person[j].weapon.type == sniperrifle && m == 0) {
1237 
1238                       if(person[whichhit].type != zombietype)
1239                         person[whichhit].health -= 100;
1240 
1241                       if(person[whichhit].type == zombietype)
1242                         person[whichhit].health -= 120;
1243 
1244                       person[whichhit].DoAnimations(whichhit);
1245                     }
1246 
1247                     if(hitstruct.joint1->modelnum == headmodel
1248                        && person[whichhit].type != zombietype) {
1249 
1250                       person[whichhit].health -= 60;
1251                     }
1252 
1253                     if(person[whichhit].type == zombietype)
1254                       person[whichhit].speedmult -= .05;
1255 
1256                     if(person[whichhit].type == zombietype)
1257                       person[whichhit].maxhealth -= 10;
1258 
1259                     if(whichhit == 0) {
1260                       bulletstrength = 1;
1261 
1262                       person[0].health = 100;
1263 
1264                       flashr = 0;
1265                       flashg = 0;
1266                       flashb = 0;
1267 
1268                       flashamount = 1;
1269 
1270                       float gLoc[3];
1271                       gLoc[0] = hitstruct.hitlocation.x / soundscalefactor;
1272                       gLoc[1] = hitstruct.hitlocation.y / soundscalefactor;
1273                       gLoc[2] = hitstruct.hitlocation.z / soundscalefactor;
1274 
1275                       alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
1276 
1277                       alSourcePlay(gSourceID[bodywhacksound]);
1278                     }
1279 
1280                     person[whichhit].longdead = 1;
1281 
1282                     if(person[whichhit].health <= 0) {
1283 
1284                       person[whichhit].skeleton.offset = 0;
1285 
1286                       if(person[whichhit].skeleton.free != 1) {
1287 
1288                         person[whichhit].skeleton.free = 1;
1289 
1290                         totalarea = 0;
1291 
1292                         for(int j = 0; j < person[whichhit].skeleton.num_joints;
1293                             j++) {
1294 
1295                           person[whichhit].skeleton.joints[j].position =
1296                               DoRotation(person[whichhit].skeleton.joints[j].
1297                                          position, 0,
1298                                          person[whichhit].playerrotation, 0);
1299 
1300                           person[whichhit].skeleton.joints[j].position +=
1301                               person[whichhit].playercoords;
1302 
1303                           person[whichhit].skeleton.joints[j].realoldposition =
1304                               person[whichhit].skeleton.joints[j].position;
1305 
1306                           person[whichhit].skeleton.joints[j].velocity =
1307                               person[whichhit].velocity;
1308 
1309                           person[whichhit].skeleton.joints[j].velocity.x +=
1310                               (float)(abs(Random() % 20) - 10) / 2;
1311 
1312                           person[whichhit].skeleton.joints[j].velocity.y +=
1313                               (float)(abs(Random() % 20) - 10) / 2;
1314 
1315                           person[whichhit].skeleton.joints[j].velocity.z +=
1316                               (float)(abs(Random() % 20) - 10) / 2;
1317                         }
1318                       }
1319 
1320                       for(int j = 0; j < person[whichhit].skeleton.num_joints;
1321                           j++) {
1322 
1323                         if(findDistancefast
1324                            (person[whichhit].skeleton.joints[j].position,
1325                             hitstruct.hitlocation) < 200) {
1326 
1327                           totalarea +=
1328                               (200 /
1329                                findDistancefast(person[whichhit].skeleton.
1330                                                 joints[j].position,
1331                                                 hitstruct.hitlocation));
1332                         }
1333                       }
1334 
1335                       for(int j = 0; j < person[whichhit].skeleton.num_joints;
1336                           j++) {
1337 
1338                         if(findDistancefast
1339                            (person[whichhit].skeleton.joints[j].position,
1340                             hitstruct.hitlocation) < 200) {
1341 
1342                           person[whichhit].skeleton.joints[j].velocity +=
1343                               aim *
1344                               ((200 /
1345                                 findDistancefast(person[whichhit].skeleton.
1346                                                  joints[j].position,
1347                                                  hitstruct.hitlocation)) /
1348                                totalarea * 200);
1349 
1350                         }
1351                       }
1352                     }
1353 
1354                     if(person[whichhit].health > 0) {
1355 
1356                       if(person[whichhit].killtargetvisible == 0
1357                          && person[whichhit].type != zombietype
1358                          && person[whichhit].currentanimation !=
1359                          getupfrontanim & person[whichhit].currentanimation !=
1360                          getupbackanim) {
1361 
1362                         if(hitstruct.joint1->modelnum == headmodel)
1363                           person[whichhit].targetanimation = headpainanim;
1364 
1365                         if(hitstruct.joint1->modelnum == chestmodel)
1366                           person[whichhit].targetanimation = chestpainanim;
1367 
1368                         if(hitstruct.joint1->modelnum == abdomenmodel)
1369                           person[whichhit].targetanimation = stomachpainanim;
1370 
1371                         if(hitstruct.joint1->label == rightelbow
1372                            || hitstruct.joint1->label == rightshoulder
1373                            || hitstruct.joint1->label == rightwrist
1374                            || hitstruct.joint1->label == righthand)
1375                           person[whichhit].targetanimation = rightarmpainanim;
1376 
1377                         if(hitstruct.joint1->label == leftelbow
1378                            || hitstruct.joint1->label == leftshoulder
1379                            || hitstruct.joint1->label == leftwrist
1380                            || hitstruct.joint1->label == lefthand)
1381                           person[whichhit].targetanimation = leftarmpainanim;
1382 
1383                         if(hitstruct.joint1->label == rightknee
1384                            || hitstruct.joint1->label == righthip
1385                            || hitstruct.joint1->label == rightankle
1386                            || hitstruct.joint1->label == rightfoot)
1387                           person[whichhit].targetanimation = rightlegpainanim;
1388 
1389                         if(hitstruct.joint1->label == leftknee
1390                            || hitstruct.joint1->label == lefthip
1391                            || hitstruct.joint1->label == leftankle
1392                            || hitstruct.joint1->label == leftfoot)
1393                           person[whichhit].targetanimation = leftlegpainanim;
1394 
1395                         person[whichhit].targetframe = 0;
1396                         person[whichhit].target = 0;
1397                       }
1398 
1399                       person[whichhit].skeleton.offset = 1;
1400 
1401                       for(int j = 0; j < person[whichhit].skeleton.num_joints;
1402                           j++) {
1403 
1404                         if(findDistancefast
1405                            (DoRotation
1406                             (person[whichhit].skeleton.joints[j].position, 0,
1407                              person[whichhit].playerrotation,
1408                              0) + person[whichhit].playercoords,
1409                             hitstruct.hitlocation) < 200) {
1410 
1411                           totalarea +=
1412                               (200 /
1413                                findDistancefast(DoRotation
1414                                                 (person[whichhit].skeleton.
1415                                                  joints[j].position, 0,
1416                                                  person[whichhit].
1417                                                  playerrotation,
1418                                                  0) +
1419                                                 person[whichhit].playercoords,
1420                                                 hitstruct.hitlocation));
1421                         }
1422                       }
1423 
1424                       float offsetlength;
1425 
1426                       for(int j = 0; j < person[whichhit].skeleton.num_joints;
1427                           j++) {
1428 
1429                         if(findDistancefast
1430                            (DoRotation
1431                             (person[whichhit].skeleton.joints[j].position, 0,
1432                              person[whichhit].playerrotation,
1433                              0) + person[whichhit].playercoords,
1434                             hitstruct.hitlocation) < 200) {
1435 
1436                           person[whichhit].skeleton.joints[j].offset +=
1437                               DoRotation(aim *
1438                                          ((200 /
1439                                            findDistancefast(DoRotation
1440                                                             (person[whichhit].
1441                                                              skeleton.joints[j].
1442                                                              position, 0,
1443                                                              person[whichhit].
1444                                                              playerrotation,
1445                                                              0) +
1446                                                             person[whichhit].
1447                                                             playercoords,
1448                                                             hitstruct.
1449                                                             hitlocation)) /
1450                                           totalarea * 10), 0,
1451                                          -person[whichhit].playerrotation, 0);
1452 
1453                         }
1454 
1455                         offsetlength =
1456                             findLengthfast(person[whichhit].skeleton.joints[j].
1457                                            offset);
1458 
1459                         if(offsetlength > 36) {
1460 
1461                           Normalise(&person[whichhit].skeleton.joints[j].
1462                                     offset);
1463 
1464                           person[whichhit].skeleton.joints[j].offset *= 6;
1465 
1466                         }
1467                       }
1468                     }
1469 
1470                     if(hitstruct.joint1->modelnum == headmodel
1471                        && person[whichhit].health <= 0) {
1472 
1473                       for(int j = 0; j < person[whichhit].skeleton.num_joints;
1474                           j++) {
1475 
1476                         if(&person[whichhit].skeleton.joints[j] ==
1477                            hitstruct.joint1
1478                            || &person[whichhit].skeleton.joints[j] ==
1479                            hitstruct.joint2) {
1480 
1481                           if(j != person[whichhit].skeleton.jointlabels[abdomen]
1482                              && j !=
1483                              person[whichhit].skeleton.jointlabels[groin]
1484                              && j !=
1485                              person[whichhit].skeleton.jointlabels[neck]) {
1486 
1487                             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
1488                                                person[whichhit].skeleton.
1489                                                joints[j].position,
1490                                                person[whichhit].skeleton.
1491                                                joints[j].velocity / 3, 9);
1492 
1493                             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
1494                                                person[whichhit].skeleton.
1495                                                joints[j].position,
1496                                                DoRotation(person[whichhit].
1497                                                           skeleton.joints[j].
1498                                                           velocity / 3,
1499                                                           Random() % 360,
1500                                                           Random() % 360,
1501                                                           0) / 5, 5);
1502 
1503                             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
1504                                                person[whichhit].skeleton.
1505                                                joints[j].position,
1506                                                DoRotation(person[whichhit].
1507                                                           skeleton.joints[j].
1508                                                           velocity / 3,
1509                                                           Random() % 360,
1510                                                           Random() % 360,
1511                                                           0) / 5, 5);
1512 
1513                             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
1514                                                person[whichhit].skeleton.
1515                                                joints[j].position,
1516                                                DoRotation(person[whichhit].
1517                                                           skeleton.joints[j].
1518                                                           velocity / 3,
1519                                                           Random() % 360,
1520                                                           Random() % 360,
1521                                                           0) / 5, 5);
1522 
1523                             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
1524                                                person[whichhit].skeleton.
1525                                                joints[j].position,
1526                                                DoRotation(person[whichhit].
1527                                                           skeleton.joints[j].
1528                                                           velocity / 3,
1529                                                           Random() % 360,
1530                                                           Random() % 360,
1531                                                           0) / 5, 5);
1532 
1533                             person[whichhit].skeleton.DeleteJoint(j);
1534                             person[whichhit].skeleton.broken = 1;
1535                             person[whichhit].health = -10000;
1536                             person[whichhit].skeleton.joints[j].existing = 0;
1537 
1538                             if(person[whichhit].type == zombietype)
1539                               score += 300;
1540                           }
1541                         }
1542                       }
1543                     }
1544 
1545                     XYZ velocity;
1546                     velocity = aim * -8;
1547                     float size = 0;
1548 
1549                     //blood
1550                     if(!hitstruct.joint1->modelnum == headmodel) {
1551 
1552                       switch(person[j].weapon.type) {
1553                         case sniperrifle:
1554                         case shotgun:
1555                           if(penetrate)
1556                             size = 7;
1557                           else
1558                             size = 5;
1559                           break;
1560 
1561                         case assaultrifle:
1562                           if(penetrate)
1563                             size = 7;
1564                           else
1565                             size = 3;
1566                           break;
1567 
1568                         case handgun1:
1569                         case handgun2:
1570                           if(penetrate)
1571                             size = 4;
1572                           else
1573                             size = 3;
1574                           break;
1575 
1576                         default:
1577                           size = 0;
1578                           break;
1579                       }
1580 
1581                       if(size) {
1582                         sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0,
1583                                            hitstruct.hitlocation, velocity * 0,
1584                                            size);
1585 
1586                         if(penetrate) {
1587                           sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0,
1588                                              hitstruct.hitlocation, velocity * -3,
1589                                              size);
1590                         }
1591                       }
1592                     } else {
1593 
1594                       sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2,
1595                                          hitstruct.hitlocation, velocity * 0,
1596                                          6);
1597 
1598                       sprites.MakeSprite(bloodspritenoup, 1, 1, .5, .5,
1599                                          hitstruct.hitlocation, velocity * -2,
1600                                          7);
1601 
1602                       sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2,
1603                                          hitstruct.hitlocation, velocity * -3,
1604                                          10);
1605                     }
1606 
1607                     person[whichhit].bjoint1 = hitstruct.joint1;
1608                     person[whichhit].bjoint2 = hitstruct.joint2;
1609                     person[whichhit].bleeding = 1;
1610                     person[whichhit].bleeddelay = 1;
1611 
1612                     float gLoc[3];
1613 
1614                     gLoc[0] =
1615                         (camera.position.x +
1616                          (hitstruct.hitlocation.x -
1617                           camera.position.x) / 4) / soundscalefactor;
1618 
1619                     gLoc[1] =
1620                         (camera.position.y +
1621                          (hitstruct.hitlocation.y -
1622                           camera.position.y) / 4) / soundscalefactor;
1623 
1624                     gLoc[2] =
1625                         (camera.position.z +
1626                          (hitstruct.hitlocation.z -
1627                           camera.position.z) / 4) / soundscalefactor;
1628 
1629                     if(!hitstruct.joint1->modelnum == headmodel) {
1630 
1631                       if(!thirdperson)
1632                         alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, 1);
1633 
1634                       if(thirdperson)
1635                         alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, .1);
1636 
1637                       alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc);
1638                       alSourcePlay(gSourceID[bodyhitsound]);
1639                     }
1640 
1641                     if(hitstruct.joint1->modelnum == headmodel) {
1642 
1643                       if(!thirdperson)
1644                         alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 1);
1645 
1646                       if(thirdperson)
1647                         alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, .1);
1648 
1649                       alSourcefv(gSourceID[headshotsound], AL_POSITION, gLoc);
1650                       alSourcePlay(gSourceID[headshotsound]);
1651                     }
1652                   }             //with wall
1653 
1654                   if(oldend == finalwallhit) {
1655 
1656                     decals.MakeDecal(bullethole, finalwallhit, .7, hitnorm,
1657                                      hitpoly, model, hitmove, hitrotation);
1658 
1659                     XYZ velocity;
1660                     //velocity = aim * -4;
1661                     velocity = hitnorm * 3;
1662                     float smokesize, muzzleflashsize;
1663 
1664                     switch(person[j].weapon.type) {
1665                       case sniperrifle:
1666                         smokesize = 10;
1667                         muzzleflashsize = 2;
1668                         break;
1669 
1670                       case shotgun:
1671                         smokesize = 5;
1672                         muzzleflashsize = 0.8;
1673                         break;
1674 
1675                       case assaultrifle:
1676                         smokesize = 6;
1677                         muzzleflashsize = 1;
1678                         break;
1679 
1680                       case handgun1:
1681                       case handgun2:
1682                         smokesize = 6;
1683                         muzzleflashsize = 1;
1684                         break;
1685 
1686                       default:
1687                         smokesize = muzzleflashsize = 0;
1688                         break;
1689                     }
1690 
1691                     if(smokesize && muzzleflashsize) {
1692                       sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit,
1693                                          velocity, smokesize);
1694 
1695                       sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1,
1696                                          finalwallhit, velocity, muzzleflashsize);
1697                     }
1698 
1699                     float gLoc[3];
1700 
1701                     gLoc[0] = finalwallhit.x / soundscalefactor;
1702                     gLoc[1] = finalwallhit.y / soundscalefactor;
1703                     gLoc[2] = finalwallhit.z / soundscalefactor;
1704 
1705                     alSourcefv(gSourceID[wallhitsound], AL_POSITION, gLoc);
1706 
1707                     alSourcePlay(gSourceID[wallhitsound]);
1708                   }
1709 
1710                   lastshot[0] = start;
1711                   lastshot[1] = oldend;
1712 
1713                   XYZ velocity = aim * 8;
1714 
1715                   if(person[j].weapon.type != sniperrifle
1716                      && person[j].weapon.type != shotgun && p == numshots - 1)
1717                     sprites.MakeSprite(smokesprite, .3, 1, 1, 1,
1718                                        start + aim * 1.5, velocity, 3);
1719 
1720                   if(person[j].weapon.type == shotgun && p == numshots - 1)
1721                     sprites.MakeSprite(smokesprite, .4, 1, 1, 1,
1722                                        start + aim * 1.5, velocity, 5);
1723 
1724                   if(person[j].weapon.type == sniperrifle && !zoom)
1725                     sprites.MakeSprite(smokesprite, .3, 1, 1, 1,
1726                                        start + aim * 2.2, velocity, 4);
1727 
1728                   if(j != 0 || zoom == 0)
1729                     sprites.MakeSprite(bullet, .07, 1, 1, .7,
1730                                        lastshot[0] + aim * 1, lastshot[1], .2);
1731 
1732                   //Nearby bullet whoosh
1733                   long dot_ta, dot_tb;
1734                   XYZ *a, *b, *c, nearest;
1735 
1736                   a = &lastshot[0];
1737                   *a += aim * 1;
1738 
1739                   b = &lastshot[1];
1740 
1741                   c = &camera.position;
1742 
1743                   nearest = 0;
1744 
1745                   dot_ta = (long)
1746                       ((c->x - a->x) * (b->x - a->x) + (c->y - a->y) * (b->y -
1747                                                                        a->y) +
1748                       (c->z - a->z) * (b->z - a->z));
1749 
1750                   dot_tb = (long)
1751                       ((c->x - b->x) * (a->x - b->x) + (c->y - b->y) * (a->y -
1752                                                                        b->y) +
1753                       (c->z - b->z) * (a->z - b->z));
1754 
1755                   if(!dot_ta <= 0 && !dot_tb <= 0) {
1756                     nearest.x =
1757                         a->x + ((b->x - a->x) * dot_ta) / (dot_ta + dot_tb);
1758 
1759                     nearest.y =
1760                         a->y + ((b->y - a->y) * dot_ta) / (dot_ta + dot_tb);
1761 
1762                     nearest.z =
1763                         a->z + ((b->z - a->z) * dot_ta) / (dot_ta + dot_tb);
1764                   }
1765 
1766                   if(nearest.x) {
1767 
1768                     if(findDistancefast(nearest, camera.position) < 10
1769                        && (thirdperson == 2 || j != 0)) {
1770 
1771                       float gLoc[3];
1772 
1773                       gLoc[0] =
1774                           (camera.position.x +
1775                            (nearest.x - camera.position.x)) / soundscalefactor;
1776 
1777                       gLoc[1] =
1778                           (camera.position.y +
1779                            (nearest.y - camera.position.y)) / soundscalefactor;
1780 
1781                       gLoc[2] =
1782                           (camera.position.z +
1783                            (nearest.z - camera.position.z)) / soundscalefactor;
1784 
1785                       alSourcefv(gSourceID[nearbulletsound], AL_POSITION, gLoc);
1786                       alSourcePlay(gSourceID[nearbulletsound]);
1787                     }
1788                   }
1789                 }
1790               }
1791             }
1792           }
1793         }
1794       }
1795     }
1796 }
1797 
SpawnPeople()1798 void Game::SpawnPeople()
1799 {
1800     //Spawn people
1801     spawndelay -= multiplier;
1802 
1803     int blockspawnx = 0, blockspawny = 0;
1804     int cyclenum = 0;
1805 
1806     while((citypeoplenum[blockspawnx][blockspawny] >= max_people_block
1807            && cyclenum < 10) || blockspawnx == 0) {
1808 
1809       blockspawnx =
1810           (int)(((person[0].playercoords.x +
1811                   block_spacing / 2) / block_spacing) + Random() % 2);
1812 
1813       blockspawny =
1814           (int)(((person[0].playercoords.z +
1815                   block_spacing / 2) / block_spacing) + Random() % 2);
1816 
1817       cyclenum++;
1818     }
1819 
1820     if(cyclenum < 10) {
1821 
1822       if(spawndelay < 0 && numpeople < max_people) {
1823         if(type == randomshoot_type) {
1824           if(abs(Random() % evilprobability) == 0)
1825             person[numpeople].type = eviltype;
1826           else
1827             person[numpeople].type = civiliantype;
1828         }
1829 
1830         if(type == zombie_type) {
1831           person[numpeople].type = zombietype;
1832         }
1833 
1834         if(person[numpeople].type != civiliantype
1835            && blockspawnx == person[1].whichblockx
1836            && blockspawny == person[1].whichblocky) {
1837 
1838           while((citypeoplenum[blockspawnx][blockspawny] >= max_people_block
1839                  && cyclenum < 10) || blockspawnx == 0
1840                 || (blockspawnx == person[1].whichblockx
1841                     && blockspawny == person[1].whichblocky)) {
1842 
1843             blockspawnx =
1844                 (int)((person[0].playercoords.x +
1845                        block_spacing / 2) / block_spacing) + Random() % 2;
1846 
1847             blockspawny =
1848                 (int)((person[0].playercoords.z +
1849                        block_spacing / 2) / block_spacing) + Random() % 2;
1850 
1851             cyclenum++;
1852           }
1853         }
1854 
1855         person[numpeople].playerrotation = 0;
1856         person[numpeople].whichcostume =
1857             casualcostumes + abs(Random()) % numcasual;
1858 
1859         person[numpeople].whichblockx = blockspawnx;
1860         person[numpeople].whichblocky = blockspawny;
1861 
1862         person[numpeople].pathnum = -1;
1863         person[numpeople].oldpathnum = -1;
1864         person[numpeople].oldoldpathnum = -1;
1865         person[numpeople].oldoldoldpathnum = -1;
1866 
1867         while(person[numpeople].pathnum < 0
1868               || person[numpeople].pathnum >= path.vertexNum
1869               || person[numpeople].pathnum == 1) {
1870 
1871           person[numpeople].pathnum = Random() % path.vertexNum;
1872         }
1873 
1874         person[numpeople].pathtarget.x =
1875             path.vertex[person[numpeople].pathnum].x;
1876         person[numpeople].pathtarget.z =
1877             path.vertex[person[numpeople].pathnum].z;
1878         person[numpeople].pathsize = .98 + float (abs(Random() % 20)) / 400;
1879         person[numpeople].pathtarget *= person[numpeople].pathsize;
1880         person[numpeople].pathtarget.x +=
1881             person[numpeople].whichblockx * block_spacing;
1882         person[numpeople].pathtarget.z +=
1883             person[numpeople].whichblocky * block_spacing;
1884 
1885         person[numpeople].playercoords = person[numpeople].pathtarget;
1886         person[numpeople].oldplayercoords = person[numpeople].playercoords;
1887         person[numpeople].skeleton.free = 0;
1888 
1889         person[numpeople].targetanimation = walkanim;
1890 
1891         if(person[numpeople].type == zombietype)
1892           person[numpeople].targetanimation = zombiewalkanim;
1893 
1894         person[numpeople].speed = 1;
1895         person[numpeople].existing = 0;
1896         person[numpeople].speedmult = .8 + float (abs(Random() % 20)) / 50;
1897 
1898         person[numpeople].health = 100;
1899         person[numpeople].maxhealth = 100;
1900         person[numpeople].playerrotation2 = 0;
1901 
1902         person[numpeople].lastdistancevictim = 200000;
1903 
1904         if(person[numpeople].skeleton.broken)
1905           person[numpeople].skeleton.
1906               Load((char *)":Data:Skeleton:Basic Figure");
1907 
1908         if(numpeople == 1)
1909           person[numpeople].type = viptype;
1910 
1911         ///killtarget appears to be the target for the AI to attack
1912         // 1 - target
1913         // -1 - not target
1914         person[numpeople].killtarget = -1;
1915 
1916         if(person[numpeople].type == eviltype) {
1917           person[numpeople].existing = 1;
1918           person[numpeople].pathsize = 1.04;
1919           person[numpeople].weapon.type = nogun;
1920           person[numpeople].aiming = 1;
1921           person[numpeople].killtarget = -1;
1922           person[numpeople].speedmult = 1 + .3 * difficulty;
1923         }
1924 
1925         if(person[numpeople].type == zombietype) {
1926           person[numpeople].existing = 1;
1927           person[numpeople].pathsize = 1.04;
1928           person[numpeople].weapon.type = nogun;
1929           person[numpeople].aiming = 0;
1930           person[numpeople].killtarget = -1;
1931           person[numpeople].speedmult = 0.7 + .2 * difficulty;
1932         } else {
1933           person[numpeople].weapon.type = nogun;
1934           person[numpeople].aiming = 0;
1935           person[numpeople].killtarget = -1;
1936         }
1937 
1938         if(person[numpeople].type == viptype) {
1939           person[numpeople].existing = 1;
1940         }
1941 
1942         if(enemystate == 2)
1943           person[numpeople].killtarget = 1;
1944 
1945         numpeople++;
1946         citypeoplenum[blockspawnx][blockspawny]++;
1947         spawndelay = .1;
1948       }
1949 
1950       if(spawndelay < 0 && numpeople >= max_people) {
1951 
1952         if(cycle >= max_people)
1953           cycle = 0;
1954 
1955         cyclenum = 0;
1956 
1957         while(cyclenum < max_people
1958               && (person[cycle].type == playertype
1959                   || person[cycle].type == viptype
1960                   ||
1961                   (abs
1962                    (person[cycle].whichblockx -
1963                     ((person[0].playercoords.x +
1964                       block_spacing / 2) / block_spacing)) < 2
1965                    && abs(person[cycle].whichblocky -
1966                           ((person[0].playercoords.z +
1967                             block_spacing / 2) / block_spacing)) < 2))) {
1968 
1969           cycle++;
1970           cyclenum++;
1971 
1972           if(cycle >= max_people)
1973             cycle = 0;
1974         }
1975 
1976         if(cycle < max_people && cyclenum < max_people) {
1977           if(type == randomshoot_type) {
1978             if(abs(Random() % evilprobability) == 0)
1979               person[cycle].type = eviltype;
1980             else
1981               person[cycle].type = civiliantype;
1982           }
1983 
1984           if(type == zombie_type) {
1985             person[cycle].type = zombietype;
1986           }
1987 
1988           if(person[cycle].type != civiliantype
1989              && blockspawnx == person[1].whichblockx
1990              && blockspawny == person[1].whichblocky) {
1991 
1992             while((citypeoplenum[blockspawnx][blockspawny] >= max_people_block
1993                    && cyclenum < 10) || blockspawnx == 0
1994                   || (blockspawnx == person[1].whichblockx
1995                       && blockspawny == person[1].whichblocky)) {
1996 
1997               blockspawnx =
1998                   (int)((person[0].playercoords.x +
1999                          block_spacing / 2) / block_spacing) + Random() % 2;
2000 
2001               blockspawny =
2002                   (int)((person[0].playercoords.z +
2003                          block_spacing / 2) / block_spacing) + Random() % 2;
2004 
2005               cyclenum++;
2006             }
2007           }
2008 
2009           person[cycle].playerrotation = 0;
2010 
2011           person[cycle].whichcostume =
2012               casualcostumes + abs(Random()) % numcasual;
2013 
2014           citypeoplenum[person[cycle].whichblockx][person[cycle].whichblocky]--;
2015 
2016           person[cycle].whichblockx = blockspawnx;
2017           person[cycle].whichblocky = blockspawny;
2018 
2019           person[cycle].pathnum =
2020             person[cycle].oldpathnum =
2021             person[cycle].oldoldpathnum =
2022             person[cycle].oldoldoldpathnum = -1;
2023 
2024           while(person[cycle].pathnum < 0
2025                 || person[cycle].pathnum >= path.vertexNum
2026                 || person[cycle].pathnum == 1) {
2027 
2028             person[cycle].pathnum = Random() % path.vertexNum;
2029 
2030           }
2031 
2032           person[cycle].pathtarget.x = path.vertex[person[cycle].pathnum].x;
2033           person[cycle].pathtarget.z = path.vertex[person[cycle].pathnum].z;
2034           person[cycle].pathsize = .98 + float (abs(Random() % 20)) / 400;
2035           person[cycle].pathtarget *= person[cycle].pathsize;
2036           person[cycle].pathtarget.x +=
2037               person[cycle].whichblockx * block_spacing;
2038           person[cycle].pathtarget.z +=
2039               person[cycle].whichblocky * block_spacing;
2040 
2041 
2042           person[cycle].playercoords = person[cycle].pathtarget;
2043           person[cycle].oldplayercoords = person[cycle].playercoords;
2044           person[cycle].skeleton.free = 0;
2045 
2046 
2047           person[cycle].targetanimation = walkanim;
2048 
2049           if(person[cycle].type == zombietype)
2050             person[cycle].targetanimation = zombiewalkanim;
2051 
2052           person[cycle].speed = 1;
2053           person[cycle].existing = 0;
2054           person[cycle].speedmult = .8 + float (abs(Random() % 20)) / 50;
2055 
2056           person[cycle].health = 100;
2057           person[cycle].maxhealth = 100;
2058           person[cycle].playerrotation2 = 0;
2059 
2060           if(person[cycle].skeleton.broken)
2061             person[cycle].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
2062 
2063           if(enemystate == 1)
2064             person[cycle].killtarget = -1;
2065 
2066           if(person[cycle].type == eviltype) {
2067             person[cycle].existing = 1;
2068             person[cycle].pathsize = 1.04;
2069             person[cycle].weapon.type = nogun;
2070             person[cycle].aiming = 1;
2071             person[cycle].killtarget = -1;
2072             person[cycle].speedmult = 1 + .3 * difficulty;
2073           }
2074 
2075           if(person[cycle].type == zombietype) {
2076             person[cycle].existing = 1;
2077             person[cycle].pathsize = 1.04;
2078             person[cycle].weapon.type = nogun;
2079             person[cycle].aiming = 0;
2080             person[cycle].killtarget = -1;
2081             person[cycle].speedmult = .7 + .2 * difficulty;
2082           } else {
2083             person[cycle].weapon.type = nogun;
2084             person[cycle].aiming = 0;
2085             person[cycle].killtarget = -1;
2086           }
2087 
2088           person[cycle].lastdistancevictim = 200000;
2089 
2090           if(enemystate == 2)
2091             person[cycle].killtarget = 1;
2092 
2093           if(numpeople < max_people)
2094             numpeople++;
2095 
2096           citypeoplenum[blockspawnx][blockspawny]++;
2097 
2098           cycle++;
2099 
2100           spawndelay = .1;
2101         }
2102       }
2103     }
2104 }
2105 
GameTick()2106 void Game::GameTick()
2107 {
2108     int visions = config.visions;
2109     bool killedinnocent = 0;           //Haven't shot any civilians yet...
2110 
2111     XYZ flatfacing;
2112     murderer = 0;
2113 
2114     if(person[1].health <= 0 || person[0].health <= 0 || killedinnocent) {
2115       losedelay -= multiplier / 6;
2116     }
2117 
2118     if(person[1].health > 0 && person[0].health > 0 && !killedinnocent)
2119       timeremaining -= multiplier * 25 / 40;
2120 
2121     if(timeremaining <= 0) {
2122       flashamount = 1;
2123       flashr = 0;
2124       flashg = 1;
2125       flashb = 0;
2126 
2127       mission++;
2128 
2129       alSourcePlay(gSourceID[souloutsound]);
2130 
2131       score += 100 + (mission * 50);
2132 
2133       if(mission >= nummissions) {
2134         config.beatgame = 1;
2135         state = MAINMENU;
2136         gameinprogress = 0;
2137 
2138         alSourcePause(gSourceID[rainsound]);
2139 
2140         alSourceStop(gSourceID[visionsound]);
2141         alSourceStop(gSourceID[whichsong]);
2142 
2143         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
2144         alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
2145 
2146         whichsong = mainmenusong;
2147 
2148         alSourceStop(gSourceID[whichsong]);
2149 
2150         alSourcef(gSourceID[whichsong], AL_PITCH, 1);
2151 
2152         alSourcePlay(gSourceID[whichsong]);
2153 
2154         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
2155         alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
2156 
2157         config.WriteHighScore(score);
2158       }
2159 
2160       if(state != MAINMENU) {
2161         InitGame();
2162 
2163         if(environment.type == rainy_environment)
2164           alSourcePlay(gSourceID[rainsound]);
2165 
2166         if(environment.type != rainy_environment)
2167           alSourcePause(gSourceID[rainsound]);
2168 
2169         alSourceStop(gSourceID[visionsound]);
2170         alSourceStop(gSourceID[whichsong]);
2171 
2172         if(person[0].weapon.type == knife)
2173           whichsong = knifesong;
2174         else
2175           whichsong = shootsong;
2176 
2177         if(type == zombie_type)
2178           whichsong = zombiesong;
2179 
2180         alSourcef(gSourceID[whichsong], AL_PITCH, 1);
2181         alSourcePlay(gSourceID[whichsong]);
2182         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
2183         alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
2184       }
2185     }
2186 
2187     // when you die or kill an innocent
2188     if(losedelay <= 0) {
2189       flashamount = 1;
2190       flashr = 0;
2191       flashg = 0;
2192       flashb = 0;
2193 
2194       if(person[murderer].health > 0)
2195         score = oldscore - 200; //kill innocent
2196       else
2197         score = oldscore - 100; //die
2198 
2199       InitGame();
2200 
2201       alSourceStop(gSourceID[whichsong]);
2202 
2203       if(person[0].weapon.type == knife)
2204         whichsong = knifesong;
2205       else
2206         whichsong = shootsong;
2207 
2208       if(type == zombie_type)
2209         whichsong = zombiesong;
2210 
2211       alSourcef(gSourceID[whichsong], AL_PITCH, 1);
2212 
2213       alSourcePlay(gSourceID[whichsong]);
2214 
2215       alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
2216       alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
2217 
2218       alSourcePlay(gSourceID[soulinsound]);
2219     }
2220 
2221     //unsigned char theKeyMap[16];
2222     //GetKeys((unsigned long *)theKeyMap);
2223 
2224     //Sprites
2225     sprites.DoStuff();
2226 
2227     //Decals
2228     decals.DoStuff();
2229 
2230     //Facing
2231     facing = 0;
2232     facing.z = -1;
2233 
2234     facing = DoRotation(facing, -camera.rotation2, 0, 0);
2235     facing = DoRotation(facing, 0, 0 - camera.rotation, 0);
2236 
2237     flatfacing = facing;
2238     flatfacing.y = 0;
2239     Normalise(&flatfacing);
2240 
2241     if(IsKeyDown(theKeyMap, psychickey) && !oldvisionkey) {
2242       oldvisionkey = 1;
2243       visions = 1 - visions;
2244 
2245       if(visions == 0) {
2246         flashamount = 1;
2247         flashr = 1;
2248         flashg = 1;
2249         flashb = 1;
2250 
2251         //if the player hasn't moved?
2252         if(person[0].playercoords.x != bodycoords.x
2253            || person[0].playercoords.z != bodycoords.z) {
2254 
2255           XYZ towards;
2256 
2257           towards = person[0].playercoords - bodycoords;
2258 
2259           Normalise(&towards);
2260 
2261           camera.rotation = -asin(0 - towards.x);
2262           camera.rotation *= 360 / 6.28;
2263 
2264           if(towards.z > 0)
2265             camera.rotation = 180 - camera.rotation;
2266 
2267           camera.visrotation = camera.rotation;
2268           camera.oldrotation = camera.rotation;
2269           camera.oldoldrotation = camera.rotation;
2270         }
2271 
2272         person[0].playercoords = bodycoords;
2273         person[0].oldplayercoords = bodycoords;
2274         person[0].velocity = 0;
2275 
2276         alSourcePlay(gSourceID[soulinsound]);
2277         alSourceStop(gSourceID[visionsound]);
2278         alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat) (1));
2279         alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat) (1));
2280         alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat) (1));
2281       }
2282 
2283       if(visions == 1) {
2284         alSourceStop(gSourceID[visionsound]);
2285         flashamount = 1;
2286         flashr = 1;
2287         flashg = 0;
2288         flashb = 0;
2289 
2290         bodycoords = person[0].oldplayercoords;
2291 
2292         alSourcePlay(gSourceID[souloutsound]);
2293 
2294         alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat) (.5));
2295         alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat) (.5));
2296         alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat) (.5));
2297 
2298         alSourcePlay(gSourceID[visionsound]);
2299       }
2300     }
2301 
2302     if(!IsKeyDown(theKeyMap, psychickey)) {
2303       oldvisionkey = 0;
2304     }
2305 
2306     int thirdperson = config.thirdperson;
2307 
2308     if(IsKeyDown(theKeyMap, MAC_TAB_KEY) && !tabkeydown) {
2309       thirdperson = 1 - thirdperson;
2310       config.thirdperson = thirdperson;
2311       if(thirdperson) {
2312         lasersight = 1;
2313       } else {
2314         lasersight = 0;
2315       }
2316 
2317       tabkeydown = 1;
2318     }
2319 
2320     if(!IsKeyDown(theKeyMap, MAC_TAB_KEY))
2321       tabkeydown = 0;
2322 
2323     if(IsKeyDown(theKeyMap, aimkey) && !aimtoggle) {
2324       person[0].aiming = 1 - person[0].aiming;
2325       aimtoggle = 1;
2326     }
2327 
2328     if(!IsKeyDown(theKeyMap, aimkey))
2329       aimtoggle = 0;
2330 
2331     if(IsKeyDown(theKeyMap, MAC_R_KEY) && !reloadtoggle) {
2332 
2333       if(person[0].reloads[person[0].weapon.type] > 0 && person[0].weapon.reloading <= 0)
2334         person[0].weapon.ammo = -1;
2335 
2336       reloadtoggle = 1;
2337     }
2338 
2339     if(!IsKeyDown(theKeyMap, MAC_R_KEY))
2340       reloadtoggle = 0;
2341 
2342     if(IsKeyDown(theKeyMap, psychicaimkey) && !slomokeydown && slomo == 0) {
2343       alSourcePlay(gSourceID[souloutsound]);
2344 
2345       slomo = 2;
2346       slomokeydown = 1;
2347 
2348       flashamount = .5;
2349       flashr = 1;
2350       flashg = 0;
2351       flashb = 0;
2352 
2353       score -= 20;
2354 
2355       alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat) (.5));
2356       alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat) (.5));
2357       alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat) (.5));
2358     }
2359 
2360     if(!IsKeyDown(theKeyMap, psychicaimkey))
2361       slomokeydown = 0;
2362 
2363     //Mouse look
2364     if((person[0].aimamount <= 0 && person[0].targetanimation != crouchanim)) {
2365       camera.rotation = camera.visrotation;
2366       camera.rotation2 = camera.visrotation2;
2367 
2368       mousesensitivity = config.usermousesensitivity;
2369     }
2370 
2371     if(person[0].aimamount >= 1 && zoom == 0) {
2372       mousesensitivity = config.usermousesensitivity * .8;
2373     }
2374 
2375     if(slomo == 2) {
2376       mousesensitivity *= .6;
2377     }
2378 
2379     camera.MouseRotate(mousesensitivity);
2380     camera.Smooth();
2381 
2382     if(zoom || person[0].aimamount <= 0 || person[0].weapon.type == nogun
2383        || visions || person[0].weapon.type == grenade
2384        || person[0].weapon.type == knife) {
2385 
2386       camera.visrotation = camera.rotation;
2387       camera.visrotation2 = camera.rotation2;
2388     }
2389 
2390     oldzoom = zoom;
2391 
2392     checkCollisions();
2393 
2394     // Tackle (run + space)
2395     if(IsKeyDown(theKeyMap, MAC_SPACE_KEY)) {
2396       if(visions == 0 && person[0].targetanimation == joganim
2397          && person[0].currentanimation == joganim
2398          && person[0].backwardsanim == 0
2399          && person[0].playerrotation == person[0].playerlowrotation) {
2400 
2401         person[0].targetanimation = diveanim;
2402         person[0].targetframe = 0;
2403         person[0].target = 0;
2404         person[0].aimamount = 0;
2405       }
2406     }
2407 
2408     camera.Update();
2409 
2410     SpawnPeople();
2411 
2412     XYZ towards;
2413     XYZ finaltarget;
2414     finaltarget = 0.0f;
2415     XYZ blah;
2416 
2417     int closesttarget = 0;
2418 
2419     float leastdistance = 0.0f;
2420 
2421     XYZ bleedloc;
2422     XYZ vel;
2423 
2424     float tooclose;
2425     float toofar;
2426 
2427     //People
2428     for(int i = 0; i < numpeople; i++) {
2429       if(person[i].type != zombietype &&
2430           person[i].health < 0 && person[i].longdead < 0
2431          && person[i].firstlongdead == 0) {
2432 
2433           overpoint =
2434               person[i].skeleton.joints[person[i].skeleton.
2435                                         jointlabels[abdomen]].position;
2436 
2437           overpoint.y += 3000;
2438 
2439           underpoint =
2440               person[i].skeleton.joints[person[i].skeleton.
2441                                         jointlabels[abdomen]].position;
2442 
2443           underpoint.y -= 3000;
2444 
2445           move = 0;
2446           move.x = person[i].whichblockx * block_spacing;
2447           move.z = person[i].whichblocky * block_spacing;
2448 
2449           XYZ temp;
2450 
2451           whichtri =
2452               sidewalkcollide.LineCheck2(overpoint, underpoint, &temp, move,
2453                                          cityrotation[person[i].
2454                                                       whichblockx][person[i].
2455                                                                    whichblocky]
2456                                          * 90);
2457 
2458           XYZ normish;
2459 
2460           normish = 0;
2461           normish.y = 1;
2462           // blood pool near where they were hit
2463           if(whichtri >= 0) {
2464             decals.MakeDecal(bloodpool, temp, 12, normish, whichtri,
2465                              &sidewalkcollide, move,
2466                              cityrotation[person[i].whichblockx][person[i].
2467                                                                  whichblocky] *
2468                              90);
2469           }
2470 
2471           if(whichtri == -1) {
2472             temp =
2473                 person[i].skeleton.joints[person[i].skeleton.
2474                                           jointlabels[abdomen]].position;
2475 
2476             temp.y = -.5;
2477             move = 0;
2478 
2479             decals.MakeDecal(bloodpool, temp, 12, normish, 0, &sidewalkcollide,
2480                              move, 0);
2481           }
2482 
2483           person[i].firstlongdead = 1;
2484       }
2485 
2486       if(person[i].health < 100 && person[i].type != zombietype) {
2487         person[i].health -= multiplier * 120;
2488       }
2489 
2490       if(person[i].health < 100 && person[i].type == zombietype) {
2491         person[i].health += multiplier * 10;
2492 
2493         if(person[i].health > person[i].maxhealth)
2494           person[i].health = person[i].maxhealth;
2495 
2496       }
2497       ///alter zombie properties bases on health
2498       if(person[i].health < 100 && person[i].type == zombietype
2499          && person[i].skeleton.free == 1) {
2500         /// multiplier ~0.01 * 10 = 0.1 health per tick
2501         person[i].health += multiplier * 10;
2502 
2503         if(person[i].health > person[i].maxhealth)
2504           person[i].health = person[i].maxhealth;
2505 
2506       }
2507 
2508       if(person[i].health < 40 && person[i].type == zombietype) {
2509 
2510         person[i].speedmult -= multiplier / 20;
2511 
2512         if(person[i].speedmult < .6) {
2513           person[i].speedmult = .6;
2514           person[i].killtarget = -1;
2515         }
2516       }
2517 
2518       if(person[i].health >= 40 && person[i].type == zombietype) {
2519 
2520         person[i].speedmult += multiplier / 40;
2521 
2522         if(person[i].speedmult > .7 + difficulty * .2) {
2523           person[i].speedmult = .7 + difficulty * .2;
2524           person[i].killtarget = 1;
2525         }
2526       }
2527 
2528       if(person[i].maxhealth < 100 && person[i].type == zombietype) {
2529         person[i].maxhealth += multiplier * 2;
2530 
2531         if(person[i].maxhealth > 100)
2532           person[i].maxhealth = 100;
2533       }
2534 
2535       if(person[i].bleeding > 0) {
2536         person[i].bleeding -= multiplier;
2537         person[i].bleeddelay -= multiplier * 10;
2538 
2539         if(person[i].bleeddelay <= 0) {
2540           person[i].bleeddelay = 1;
2541 
2542           if(person[i].skeleton.free == 0) {
2543 
2544             bleedloc =
2545                 DoRotation((person[i].bjoint1->position +
2546                             person[i].bjoint2->position) / 2, 0,
2547                            person[i].playerrotation,
2548                            0) + person[i].playercoords;
2549 
2550           }
2551 
2552           if(person[i].skeleton.free > 0) {
2553             bleedloc =
2554                 (person[i].bjoint1->position + person[i].bjoint2->position) / 2;
2555           }
2556 
2557           vel = 0;
2558 
2559           sprites.MakeSprite(bloodspritedown, .6, 1, .2, .2, bleedloc, vel,
2560                              3 * person[i].bleeding);
2561         }
2562       }
2563 
2564       if(person[i].skeleton.free == 0) {
2565 
2566         //Gun
2567         if(person[i].type == playertype || person[i].type == eviltype) {
2568 
2569           if(i == 0) { //bodyguard
2570             switch(person[i].weapon.type) {
2571               case shotgun:
2572                 person[i].weapon.recoil -= multiplier * 4;
2573                 break;
2574               case sniperrifle:
2575                 person[i].weapon.recoil -= multiplier * 2;
2576                 break;
2577               case handgun1:
2578               case handgun2:
2579                 person[i].weapon.recoil -= multiplier * 5;
2580                 break;
2581               case assaultrifle:
2582                 person[i].weapon.recoil -= multiplier * 10;
2583                 break;
2584             }
2585           } else {
2586             switch(person[i].weapon.type) {
2587               case shotgun:
2588               case sniperrifle:
2589                 person[i].weapon.recoil -= multiplier * 1;
2590                 break;
2591               case handgun1:
2592               case handgun2:
2593                 person[i].weapon.recoil -= multiplier * 2;
2594                 break;
2595               case assaultrifle:
2596                 person[i].weapon.recoil -= multiplier * 10;
2597                 break;
2598             }
2599           }
2600 
2601           if(person[i].weapon.recoil < 0)
2602             person[i].weapon.recoil = 0;
2603 
2604           if(i == 0) {
2605             if(zoom) {
2606               mousesensitivity = .05 * config.usermousesensitivity;
2607 
2608               if(person[i].targetanimation != crouchanim
2609                  || person[i].currentanimation != crouchanim
2610                  || person[i].aiming < 1) {
2611 
2612                 zoom = 0;
2613               }
2614 
2615               if(visions == 1)
2616                 zoom = 0;
2617             }
2618 
2619             if(person[i].currentanimation == crouchanim
2620                && person[i].targetanimation == crouchanim
2621                && person[i].aiming >= 1 && person[i].weapon.type == sniperrifle) {
2622 
2623               zoom = 1;
2624 
2625               if(zoom && !oldzoom)
2626                 camera.rotation2 -= 6;
2627 
2628             }
2629 
2630             if(!zoom)
2631               mousesensitivity = 1 * config.usermousesensitivity;
2632 
2633             if(person[i].weapon.type != sniperrifle)
2634               zoom = 0;
2635 
2636           }
2637         }
2638         //Zombie eat
2639         if(i > 0 && person[person[i].killtarget].eaten == i
2640            && person[i].targetanimation == zombieeatanim) {
2641 
2642           person[person[i].killtarget].skeleton.
2643               joints[person[person[i].killtarget].skeleton.jointlabels[head]].
2644               locked = 1;
2645 
2646           person[person[i].killtarget].skeleton.
2647               joints[person[person[i].killtarget].skeleton.
2648                      jointlabels[rightshoulder]].locked = 1;
2649 
2650           for(int k = 0; k < 2; k++) {
2651 
2652             person[person[i].killtarget].skeleton.
2653                 joints[person[person[i].killtarget].skeleton.jointlabels[head]].
2654                 position =
2655                 DoRotation(person[i].skeleton.
2656                            joints[person[i].skeleton.jointlabels[righthand]].
2657                            position, 0, person[i].playerrotation,
2658                            0) + person[i].playercoords;
2659 
2660             person[person[i].killtarget].skeleton.
2661                 joints[person[person[i].killtarget].skeleton.jointlabels[head]].
2662                 velocity = 0;
2663 
2664             person[person[i].killtarget].skeleton.
2665                 joints[person[person[i].killtarget].skeleton.
2666                        jointlabels[rightshoulder]].position =
2667                 DoRotation(person[i].skeleton.
2668                            joints[person[i].skeleton.jointlabels[lefthand]].
2669                            position, 0, person[i].playerrotation,
2670                            0) + person[i].playercoords;
2671 
2672             person[person[i].killtarget].skeleton.
2673                 joints[person[person[i].killtarget].skeleton.
2674                        jointlabels[rightshoulder]].velocity = 0;
2675 
2676             person[person[i].killtarget].skeleton.DoConstraints();
2677 
2678             person[person[i].killtarget].skeleton.
2679                 DoConstraints(&blocksimplecollide
2680                               [citytype[person[i].whichblockx]
2681                                [person[i].whichblocky]], &move,
2682                               cityrotation[person[i].whichblockx][person[i].
2683                                                                   whichblocky] *
2684                               90);
2685           }
2686 
2687           person[person[i].killtarget].skeleton.
2688               joints[person[person[i].killtarget].skeleton.jointlabels[head]].
2689               locked = 0;
2690 
2691           person[person[i].killtarget].skeleton.
2692               joints[person[person[i].killtarget].skeleton.
2693                      jointlabels[rightshoulder]].locked = 0;
2694 
2695           person[person[i].killtarget].longdead = 1;
2696         }
2697 
2698         if(i > 0 && enemystate != 1 && person[i].type == zombietype
2699            && person[i].speedmult > .7) {
2700 
2701           if(findDistancefast(person[i].playercoords, person[1].playercoords) <
2702              20000)
2703             person[i].killtarget = 1; //vip
2704           else
2705             person[i].killtarget = -1; //none
2706         }
2707 
2708         if(i > 0 && enemystate != 1 && person[i].type == zombietype
2709            && person[i].speedmult < .7) {
2710 
2711           person[i].killtarget = -1;
2712         }
2713 
2714         bool realcheck = false;
2715 
2716         //Pathfinding
2717         if(i > 0 && person[i].targetanimation != getupfrontanim
2718            && person[i].targetanimation != thrownanim
2719            && person[i].targetanimation != getupbackanim
2720            && person[i].currentanimation != getupfrontanim
2721            && person[i].currentanimation != getupbackanim) {
2722 
2723           person[i].pathcheckdelay -= multiplier;
2724 
2725           // Realcheck tells us
2726           // a) we've got close to the end of our path or
2727           // b) we're moving away from our target
2728           realcheck =
2729               (abs(person[i].playercoords.x - person[i].pathtarget.x) < 1
2730                && abs(person[i].playercoords.z - person[i].pathtarget.z) < 1)
2731               || findDistancefast(person[i].playercoords,
2732                                   person[i].pathtarget) >
2733               findDistancefast(person[i].oldplayercoords, person[i].pathtarget);
2734 
2735           if(person[i].targetanimation == idleanim
2736              && person[i].killtargetvisible == 0) {
2737 
2738             person[i].targetanimation = walkanim;
2739 
2740             if(person[i].type == zombietype)
2741               person[i].targetanimation = zombiewalkanim;
2742 
2743             realcheck = 1;
2744           }
2745 
2746           if((realcheck
2747               || ((person[i].killtarget > -1 && person[i].type != civiliantype)
2748                   && person[i].pathcheckdelay <= 0)
2749               || person[i].killtargetvisible)) {
2750 
2751             person[i].pathcheckdelay = 1.2;
2752 
2753             if((person[i].killtarget == -1 || person[i].type == civiliantype)
2754                && !person[i].running) {
2755 
2756               person[i].killtargetvisible = 0;
2757 
2758               leastdistance = 2000000;
2759 
2760               for(int j = 0; j < path.vertexNum; j++) {
2761 
2762                 person[i].pathtarget.x = path.vertex[j].x;
2763                 person[i].pathtarget.z = path.vertex[j].z;
2764                 person[i].pathtarget.y = path.vertex[j].y;
2765 
2766                 person[i].pathtarget *= person[i].pathsize;
2767                 person[i].pathtarget.x += person[i].whichblockx * block_spacing;
2768                 person[i].pathtarget.z += person[i].whichblocky * block_spacing;
2769 
2770                 if(findDistancefast
2771                    (person[i].playercoords,
2772                     person[i].pathtarget) < leastdistance && j != 1
2773                    && j != person[i].oldpathnum && j != person[i].oldoldpathnum
2774                    && j != person[i].oldoldoldpathnum) {
2775 
2776                   leastdistance =
2777                       findDistancefast(person[i].playercoords,
2778                                        person[i].pathtarget);
2779 
2780                   closesttarget = j;
2781                 }
2782               }
2783 
2784               if(closesttarget >= 0 && closesttarget < path.vertexNum) {
2785 
2786                 person[i].oldoldoldpathnum = person[i].oldoldpathnum;
2787                 person[i].oldoldpathnum = person[i].oldpathnum;
2788                 person[i].oldpathnum = person[i].pathnum;
2789                 person[i].pathnum = closesttarget;
2790 
2791                 person[i].pathtarget.x = path.vertex[person[i].pathnum].x;
2792                 person[i].pathtarget.z = path.vertex[person[i].pathnum].z;
2793                 person[i].pathtarget *= person[i].pathsize;
2794                 person[i].pathtarget.x += person[i].whichblockx * block_spacing;
2795                 person[i].pathtarget.z += person[i].whichblocky * block_spacing;
2796               }
2797             }
2798 
2799             if(person[i].running && realcheck) {
2800 
2801               person[i].killtargetvisible = 0;
2802 
2803               person[i].targetanimation = joganim;
2804 
2805               //Dead target?
2806               if(person[person[i].killtarget].health <= 0) {
2807                 person[i].running = 0;
2808               }
2809 
2810               person[i].killtarget = 1;
2811 
2812               //If pathfind
2813               if(realcheck) {
2814 
2815                 leastdistance = 2000000;
2816 
2817                 person[i].lastdistancevictim = 0;
2818 
2819                 closesttarget = -1;
2820 
2821                 //Check best path
2822                 closesttarget = person[i].pathnum;
2823 
2824                 //Check other blocks?
2825                 if((closesttarget == person[i].pathnum)) {
2826 
2827                   beginx = person[i].whichblockx - 2;
2828 
2829                   if(beginx < 0)
2830                     beginx = 0;
2831 
2832                   beginz = person[i].whichblocky - 2;
2833 
2834                   if(beginz < 0)
2835                     beginz = 0;
2836 
2837                   endx = person[i].whichblockx + 2;
2838 
2839                   if(endx > num_blocks - 1)
2840                     endx = num_blocks - 1;
2841 
2842                   endz = person[i].whichblocky + 2;
2843 
2844                   if(endz > num_blocks - 1)
2845                     endz = num_blocks - 1;
2846 
2847                   leastdistance = 2000000;
2848 
2849                   for(int l = beginx; l <= endx; l++) {
2850 
2851                     for(int m = beginx; m <= endx; m++) {
2852 
2853                       for(int j = 0; j < path.vertexNum; j++) {
2854 
2855                         person[i].pathtarget.x = path.vertex[j].x;
2856                         person[i].pathtarget.y = path.vertex[j].y;
2857                         person[i].pathtarget.z = path.vertex[j].z;
2858 
2859                         person[i].pathtarget *= person[i].pathsize;
2860                         person[i].pathtarget.x += l * block_spacing;
2861                         person[i].pathtarget.z += m * block_spacing;
2862 
2863                         if(findDistancefast
2864                            (person[i].playercoords,
2865                             person[i].pathtarget) < leastdistance
2866                            && findDistancefast(person[i].pathtarget,
2867                                                person[person[i].killtarget].
2868                                                playercoords) >
2869                            findDistancefast(person[i].playercoords,
2870                                             person[person[i].killtarget].
2871                                             playercoords) && j != 1
2872                            && blocksimple.LineCheck2(person[i].playercoords,
2873                                                      person[i].pathtarget,
2874                                                      &blah, move,
2875                                                      cityrotation[person[i].
2876                                                                   whichblockx]
2877                                                      [person[i].whichblocky]) ==
2878                            -1
2879                            && blocksimple.LineCheck2(person[i].playercoords,
2880                                                      person[i].pathtarget,
2881                                                      &blah, move,
2882                                                      cityrotation[l][m]) ==
2883                            -1) {
2884 
2885                           person[i].lastdistancevictim =
2886                               findDistancefast(person[i].pathtarget,
2887                                                person[person[i].killtarget].
2888                                                playercoords);
2889 
2890                           leastdistance =
2891                               findDistancefast(person[i].playercoords,
2892                                                person[i].pathtarget);
2893 
2894                           closesttarget = j;
2895 
2896                           finaltarget = person[i].pathtarget;
2897 
2898                           person[i].whichblockx = l;
2899 
2900                           person[i].whichblocky = m;
2901                         }
2902                       }
2903                     }
2904                   }
2905                 }
2906 
2907                 if(closesttarget != -1) {
2908 
2909                   person[i].pathnum = closesttarget;
2910 
2911                   person[i].pathtarget = finaltarget;
2912                 }
2913               }
2914             }
2915             //Assassin
2916             if((person[i].killtarget > -1 && person[i].type != civiliantype)
2917                && !person[i].running) {
2918 
2919               //Dead target?
2920               if(person[person[i].killtarget].health <= 0
2921                  && person[i].type == eviltype) {
2922 
2923                 person[i].playerrotation2 = 0;
2924                 person[i].weapon.type = nogun;
2925                 person[i].targetanimation = walkanim;
2926                 person[i].lastdistancevictim = 200000;
2927                 person[i].pathnum = -1;
2928 
2929                 enemystate = 1;
2930                 person[i].killtarget = -1;
2931                 realcheck = 1;
2932               }
2933 
2934               if(person[i].type == zombietype
2935                  && person[person[i].killtarget].health <= 0) {
2936 
2937                 if(person[person[i].killtarget].eaten != i) {
2938 
2939                   person[i].playerrotation2 = 0;
2940                   person[i].targetanimation = zombiewalkanim;
2941                   person[i].lastdistancevictim = 200000;
2942                   person[i].pathnum = -1;
2943 
2944                   realcheck = 1;
2945 
2946                   person[i].killtarget = -1;
2947                 }
2948 
2949                 if(person[person[i].killtarget].eaten == i
2950                    && person[i].targetanimation != zombieeatanim) {
2951 
2952                   person[i].targetanimation = zombieeatanim;
2953                   person[i].targetframe = 0;
2954                   person[i].target = 0;
2955                 }
2956 
2957                 enemystate = 1;
2958               }
2959 
2960               if(person[person[i].killtarget].health > 0) {
2961 
2962                 if(person[person[i].killtarget].skeleton.free) {
2963 
2964                   person[person[i].killtarget].playercoords =
2965                       person[person[i].killtarget].averageloc;
2966                 }
2967 
2968                 //If pathfind
2969                 if(realcheck) {
2970 
2971                   leastdistance = 2000000;
2972                   person[i].lastdistancevictim = 2000000;
2973                   closesttarget = -1;
2974 
2975                   //Check best path
2976                   for(int j = 0; j < path.vertexNum; j++) {
2977 
2978                     person[i].pathtarget.x = path.vertex[j].x;
2979                     person[i].pathtarget.z = path.vertex[j].z;
2980                     person[i].pathtarget.y = path.vertex[j].y;
2981 
2982                     person[i].pathtarget *= person[i].pathsize;
2983 
2984                     person[i].pathtarget.x +=
2985                         person[i].whichblockx * block_spacing;
2986 
2987                     person[i].pathtarget.z +=
2988                         person[i].whichblocky * block_spacing;
2989 
2990                     if(findDistancefast
2991                        (person[i].playercoords,
2992                         person[i].pathtarget) < leastdistance
2993                        && findDistancefast(person[i].pathtarget,
2994                                            person[person[i].killtarget].
2995                                            playercoords) <
2996                        person[i].lastdistancevictim && j != 1
2997                        && blocksimple.LineCheck2(person[i].playercoords,
2998                                                  person[i].pathtarget, &blah,
2999                                                  move,
3000                                                  cityrotation[person[i].
3001                                                               whichblockx]
3002                                                  [person[i].whichblocky]) == -1) {
3003 
3004                       leastdistance =
3005                           findDistancefast(person[i].playercoords,
3006                                            person[i].pathtarget);
3007 
3008                       person[i].lastdistancevictim =
3009                           findDistancefast(person[i].pathtarget,
3010                                            person[person[i].killtarget].
3011                                            playercoords);
3012 
3013                       closesttarget = j;
3014 
3015                       finaltarget = person[i].pathtarget;
3016                     }
3017                   }
3018 
3019                   leastdistance = 2000000;
3020 
3021                   for(int j = 0; j < path.vertexNum; j++) {
3022 
3023                     person[i].pathtarget.x = path.vertex[j].x;
3024                     person[i].pathtarget.z = path.vertex[j].z;
3025                     person[i].pathtarget.y = path.vertex[j].y;
3026 
3027                     person[i].pathtarget *= person[i].pathsize;
3028 
3029                     person[i].pathtarget.x +=
3030                         person[i].whichblockx * block_spacing;
3031 
3032                     person[i].pathtarget.z +=
3033                         person[i].whichblocky * block_spacing;
3034 
3035                     if(findDistancefast
3036                        (person[i].playercoords,
3037                         person[i].pathtarget) < leastdistance
3038                        && findDistancefast(person[i].pathtarget,
3039                                            person[person[i].killtarget].
3040                                            playercoords) <
3041                        person[i].lastdistancevictim && j != 1
3042                        && blocksimple.LineCheck2(person[i].playercoords,
3043                                                  person[i].pathtarget, &blah,
3044                                                  move,
3045                                                  cityrotation[person[i].
3046                                                               whichblockx]
3047                                                  [person[i].whichblocky]) == -1) {
3048 
3049                       leastdistance =
3050                           findDistancefast(person[i].playercoords,
3051                                            person[i].pathtarget);
3052 
3053                       person[i].lastdistancevictim =
3054                           findDistancefast(person[i].pathtarget,
3055                                            person[person[i].killtarget].
3056                                            playercoords);
3057 
3058                       closesttarget = j;
3059 
3060                       finaltarget = person[i].pathtarget;
3061                     }
3062                   }
3063 
3064                   //Check other blocks?
3065                   if((closesttarget == person[i].pathnum)
3066                      || closesttarget == -1) {
3067 
3068                     beginx = person[i].whichblockx - 2;
3069 
3070                     if(beginx < 0)
3071                       beginx = 0;
3072 
3073                     beginz = person[i].whichblocky - 2;
3074 
3075                     if(beginz < 0)
3076                       beginz = 0;
3077 
3078                     endx = person[i].whichblockx + 2;
3079 
3080                     if(endx > num_blocks - 1)
3081                       endx = num_blocks - 1;
3082 
3083                     endz = person[i].whichblocky + 2;
3084 
3085                     if(endz > num_blocks - 1)
3086                       endz = num_blocks - 1;
3087 
3088                     leastdistance = 2000000;
3089 
3090                     for(int l = beginx; l <= endx; l++) {
3091 
3092                       for(int m = beginx; m <= endx; m++) {
3093 
3094                         if(l != person[i].whichblockx
3095                            || m != person[i].whichblocky) {
3096 
3097                           for(int j = 0; j < path.vertexNum; j++) {
3098 
3099                             person[i].pathtarget.x = path.vertex[j].x;
3100                             person[i].pathtarget.y = path.vertex[j].y;
3101                             person[i].pathtarget.z = path.vertex[j].z;
3102 
3103                             person[i].pathtarget *= person[i].pathsize;
3104                             person[i].pathtarget.x += l * block_spacing;
3105                             person[i].pathtarget.z += m * block_spacing;
3106 
3107                             if(findDistancefast
3108                                (person[i].playercoords,
3109                                 person[i].pathtarget) < leastdistance
3110                                && findDistancefast(person[i].pathtarget,
3111                                                    person[person[i].killtarget].
3112                                                    playercoords) <
3113                                findDistancefast(person[i].playercoords,
3114                                                 person[person[i].killtarget].
3115                                                 playercoords) && j != 1
3116                                && blocksimple.LineCheck2(person[i].playercoords,
3117                                                          person[i].pathtarget,
3118                                                          &blah, move,
3119                                                          cityrotation[l][m]) ==
3120                                -1
3121                                && blocksimple.LineCheck2(person[i].playercoords,
3122                                                          person[i].pathtarget,
3123                                                          &blah, move,
3124                                                          cityrotation[person[i].
3125                                                                       whichblockx]
3126                                                          [person[i].
3127                                                           whichblocky]) == -1) {
3128 
3129                               leastdistance =
3130                                   findDistancefast(person[i].playercoords,
3131                                                    person[i].pathtarget);
3132 
3133                               closesttarget = j;
3134 
3135                               finaltarget = person[i].pathtarget;
3136 
3137                               person[i].whichblockx = l;
3138                               person[i].whichblocky = m;
3139                             }
3140                           }
3141                         }
3142                       }
3143                     }
3144                   }
3145 
3146                   if(closesttarget != -1) {
3147                     person[i].onpath = 1;
3148                     person[i].pathnum = closesttarget;
3149                     person[i].pathtarget = finaltarget;
3150                   }
3151                 }
3152                 //Check killtargetvisible
3153                 person[i].killtargetvisible = 1;
3154 
3155                 if(person[person[i].killtarget].health <= 0)
3156                   person[i].killtargetvisible = 0;
3157 
3158                 if(closesttarget != -1
3159                    && findDistancefast(person[i].playercoords,
3160                                        person[person[i].killtarget].
3161                                        playercoords) > 30000)
3162                   person[i].killtargetvisible = 0;
3163 
3164                 if(person[i].killtarget == 0 && visions == 1)
3165                   person[i].killtargetvisible = 0;
3166 
3167                 if(person[i].killtargetvisible) {
3168 
3169                   beginx = person[i].whichblockx - 2;
3170 
3171                   if(beginx < 0)
3172                     beginx = 0;
3173 
3174                   beginz = person[i].whichblocky - 2;
3175 
3176                   if(beginz < 0)
3177                     beginz = 0;
3178 
3179                   endx = person[i].whichblockx + 2;
3180 
3181                   if(endx > num_blocks - 1)
3182                     endx = num_blocks - 1;
3183 
3184                   endz = person[i].whichblocky + 2;
3185 
3186                   if(endz > num_blocks - 1)
3187                     endz = num_blocks - 1;
3188 
3189                   for(int l = beginx; l <= endx; l++) {
3190 
3191                     for(int m = beginx; m <= endx; m++) {
3192 
3193                       move.x = l * block_spacing;
3194                       move.z = m * block_spacing;
3195                       move.y = -3;
3196 
3197                       if(person[i].killtargetvisible) {
3198 
3199                         if(blocksimple.
3200                            LineCheck2(person[i].playercoords,
3201                                       person[person[i].killtarget].playercoords,
3202                                       &blah, move, cityrotation[l][m]) != -1) {
3203 
3204                           person[i].killtargetvisible = 0;
3205                         }
3206                       }
3207                     }
3208                   }
3209                 }
3210 
3211                 if(person[i].type == eviltype) {
3212 
3213                   if(!person[i].killtargetvisible
3214                      && person[i].targetanimation == idleanim) {
3215 
3216                     person[i].targetanimation = joganim;
3217                   }
3218 
3219                   if(!person[i].killtargetvisible) {
3220                     person[i].aiming = 0;
3221                   }
3222 
3223                   if(person[i].killtargetvisible) {
3224 
3225                     person[i].onpath = 0;
3226                     person[i].lastdistancevictim = 200000;
3227                     person[i].pathnum = -1;
3228                     //if no weapon, arm them
3229                     if(person[i].weapon.type == nogun) {
3230 
3231                       person[i].weapon.type =
3232                           possiblegun[abs(Random() % numpossibleguns)];
3233 
3234                       person[i].reloads[person[i].weapon.type] = 1;
3235 
3236                       if(person[i].weapon.type == knife)
3237                         person[i].speedmult = .8 + .5 * difficulty;
3238                     }
3239 
3240                     if(person[i].aiming == 0)
3241                       person[i].weapon.shotdelay = shotdelayamount / difficulty;
3242 
3243                     person[i].aiming = 1;
3244 
3245                     if(person[i].weapon.reloading > 0)
3246                       person[i].aiming = 0;
3247 
3248                     if(person[i].weapon.type == handgun1
3249                        || person[i].weapon.type == handgun2)
3250                       person[i].playerrotation2 = -10;
3251 
3252                     if(person[i].weapon.type == assaultrifle
3253                        || person[i].weapon.type == sniperrifle
3254                        || person[i].weapon.type == shotgun)
3255                       person[i].playerrotation2 = 20;
3256 
3257                     tooclose = 1300;
3258                     toofar = 3000;
3259 
3260                     switch(person[i].weapon.type) {
3261                       case shotgun:
3262                         tooclose = 1400;
3263                         toofar = 5000;
3264                         break;
3265 
3266                       case assaultrifle:
3267                         tooclose = 5000;
3268                         toofar = 9000;
3269                         break;
3270 
3271                       case sniperrifle:
3272                         tooclose = 10000;
3273                         toofar = 20000;
3274                         break;
3275 
3276                       case knife:
3277                         tooclose = 20;
3278                         toofar = 20000;
3279                         break;
3280                     }
3281 
3282                     if(findDistancefast
3283                        (person[i].playercoords,
3284                         person[person[i].killtarget].playercoords) > toofar)
3285 
3286                       person[i].targetanimation = joganim;
3287 
3288                     if((findDistancefast
3289                         (person[i].playercoords,
3290                          person[person[i].killtarget].playercoords) <= tooclose
3291                         && person[person[i].killtarget].skeleton.free == 0)
3292                        || (tooclose > 200
3293                            && findDistancefast(person[i].playercoords,
3294                                                person[person[i].killtarget].
3295                                                playercoords) <= 200)
3296                        || (tooclose <= 200
3297                            && findDistancefast(person[i].playercoords,
3298                                                person[person[i].killtarget].
3299                                                playercoords) < tooclose)) {
3300 
3301                       if(person[i].targetanimation != idleanim) {
3302                         person[i].targetanimation = idleanim;
3303                         person[i].targetframe = 0;
3304                         person[i].target = 0;
3305                       }
3306 
3307                       if(person[i].weapon.type == knife
3308                          && person[person[i].killtarget].health == 100) {
3309 
3310                         murderer = i;
3311 
3312                         person[i].attacktarget = 0;
3313                         person[i].attackframe = 0;
3314 
3315                         float gLoc[3];
3316 
3317                         gLoc[0] =
3318                             (camera.position.x +
3319                              ((person[i].playercoords.x + flatfacing.x) -
3320                               camera.position.x) / 2) / soundscalefactor;
3321 
3322                         gLoc[1] =
3323                             (camera.position.y +
3324                              ((person[i].playercoords.y + flatfacing.y) -
3325                               camera.position.y) / 2) / soundscalefactor;
3326 
3327                         gLoc[2] =
3328                             (camera.position.z +
3329                              ((person[i].playercoords.z + flatfacing.z) -
3330                               camera.position.z) / 2) / soundscalefactor;
3331 
3332                         if(person[person[i].killtarget].type != zombietype) {
3333 
3334                           alSourcefv(gSourceID[knifeslashsound], AL_POSITION,
3335                                      gLoc);
3336 
3337                           alSourcePlay(gSourceID[knifeslashsound]);
3338 
3339                           person[person[i].killtarget].bjoint1 =
3340                               &person[person[i].killtarget].skeleton.
3341                               joints[person[person[i].killtarget].skeleton.
3342                                      jointlabels[neck]];
3343 
3344                           person[person[i].killtarget].bjoint2 =
3345                               &person[person[i].killtarget].skeleton.
3346                               joints[person[person[i].killtarget].skeleton.
3347                                      jointlabels[neck]];
3348 
3349                           person[person[i].killtarget].bleeding = 1;
3350                           person[person[i].killtarget].bleeddelay = 1;
3351                           person[person[i].killtarget].health -= 20;
3352 
3353                           person[person[i].killtarget].targetanimation =
3354                               chestpainanim;
3355 
3356                           person[person[i].killtarget].targetframe = 0;
3357                           person[person[i].killtarget].target = 0;
3358                           person[person[i].killtarget].longdead = 1;
3359                         }
3360                       }
3361                     }
3362 
3363                     finaltarget = person[person[i].killtarget].playercoords;
3364                   }
3365                 }
3366 
3367                 if(person[i].type == zombietype
3368                    && person[person[i].killtarget].health > 0) {
3369 
3370                   if(!person[i].killtargetvisible
3371                      && person[i].targetanimation == idleanim) {
3372 
3373                     person[i].targetanimation = zombiejoganim;
3374                   }
3375 
3376                   if(!person[i].killtargetvisible) {
3377                     person[i].aiming = 0;
3378                   }
3379 
3380                   if(person[i].killtargetvisible) {
3381                     person[i].onpath = 0;
3382                     person[i].lastdistancevictim = 200000;
3383                     person[i].pathnum = -1;
3384 
3385                     if(person[i].aiming == 0)
3386                       person[i].weapon.shotdelay = shotdelayamount / difficulty;
3387 
3388                     if(findDistancefast
3389                        (person[i].playercoords,
3390                         person[person[i].killtarget].playercoords) > 20
3391                        || person[i].targetanimation != idleanim)
3392 
3393                       person[i].targetanimation = zombiejoganim;
3394 
3395                     if(findDistancefast
3396                        (person[i].playercoords,
3397                         person[person[i].killtarget].playercoords) <= 20) {
3398 
3399                       murderer = i;
3400 
3401                       person[person[i].killtarget].health = 0;
3402                       person[person[i].killtarget].eaten = i;
3403                     }
3404 
3405                     finaltarget = person[person[i].killtarget].playercoords;
3406                   }
3407                 }
3408 
3409                 if(person[i].killtargetvisible || realcheck)
3410                   person[i].pathtarget = finaltarget;
3411 
3412                 if(realcheck)
3413                   person[i].lastdistancevictim =
3414                       findDistancefast(person[i].pathtarget,
3415                                        person[person[i].killtarget].
3416                                        playercoords);
3417 
3418               }
3419             }
3420 
3421             if(person[i].targetanimation != zombieeatanim
3422                || person[i].type != zombietype) {
3423 
3424               towards = person[i].playercoords - person[i].pathtarget;
3425 
3426               Normalise(&towards);
3427 
3428               person[i].playerrotation = asin(0 - towards.x) * 360 / 6.28;
3429 
3430               if(towards.z > 0)
3431                 person[i].playerrotation = 180 - person[i].playerrotation;
3432 
3433             }
3434           }
3435         }
3436 
3437         person[i].whichblockx =
3438             (int)((person[i].playercoords.x +
3439                    block_spacing / 2) / block_spacing);
3440 
3441         person[i].whichblocky =
3442             (int)((person[i].playercoords.z +
3443                    block_spacing / 2) / block_spacing);
3444 
3445         if(!person[i].onground)
3446           person[i].velocity.y += multiplier * gravity;
3447 
3448         if(!person[i].onground && (i != 0 || visions != 1))
3449           person[i].playercoords += person[i].velocity * multiplier;
3450 
3451         //Death by bleeding/shock
3452         if(person[i].health <= 0) {
3453           person[i].skeleton.offset = 0;
3454           person[i].skeleton.free = 1;
3455           person[i].longdead = 1;
3456 
3457           for(int j = 0; j < person[i].skeleton.num_joints; j++) {
3458 
3459             person[i].skeleton.joints[j].position +=
3460                 person[i].skeleton.joints[j].offset;
3461 
3462             person[i].skeleton.joints[j].position =
3463                 DoRotation(person[i].skeleton.joints[j].position, 0,
3464                            person[i].playerrotation, 0);
3465 
3466             person[i].skeleton.joints[j].position += person[i].playercoords;
3467 
3468             person[i].skeleton.joints[j].realoldposition =
3469                 person[i].skeleton.joints[j].position;
3470 
3471             person[i].skeleton.joints[j].velocity =
3472                 DoRotation(person[i].skeleton.joints[j].velocity, 0,
3473                            person[i].playerrotation, 0);
3474 
3475             person[i].skeleton.joints[j].velocity += person[i].velocity;
3476             person[i].skeleton.joints[j].velocity += person[i].facing * 4;
3477           }
3478         }
3479       }
3480       //Rag doll
3481       if(person[i].skeleton.free == 1 && person[i].longdead > 0) {
3482 
3483         person[i].whichblockx =
3484             (int)((person[i].skeleton.joints[0].position.x +
3485                    block_spacing / 2) / block_spacing);
3486 
3487         person[i].whichblocky =
3488             (int)((person[i].skeleton.joints[0].position.z +
3489                    block_spacing / 2) / block_spacing);
3490 
3491         move = 0;
3492         move.x = person[i].whichblockx * block_spacing;
3493         move.z = person[i].whichblocky * block_spacing;
3494 
3495         person[i].skeleton.DoGravity();
3496 
3497         if(person[i].averageloc.y <= 50)
3498           person[i].skeleton.
3499               DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx]
3500                                                 [person[i].whichblocky]], &move,
3501                             cityrotation[person[i].whichblockx][person[i].
3502                                                                 whichblocky] *
3503                             90);
3504 
3505         if(person[i].averageloc.y > 50)
3506           person[i].skeleton.
3507               DoConstraints(&blockcollide[citytype[person[i].whichblockx]
3508                                           [person[i].whichblocky]], &move,
3509                             cityrotation[person[i].whichblockx][person[i].
3510                                                                 whichblocky] *
3511                             90);
3512 
3513         person[i].oldaverageloc = person[i].averageloc;
3514         person[i].averageloc = 0;
3515 
3516         for(int j = 0; j < person[i].skeleton.num_joints; j++) {
3517           person[i].averageloc += person[i].skeleton.joints[j].position;
3518         }
3519 
3520         person[i].averageloc /= person[i].skeleton.num_joints;
3521         person[i].playercoords = person[i].averageloc;
3522 
3523         if(person[i].longdead < multiplier / 2 && person[i].longdead > 0)
3524           person[i].DrawSkeleton(i);
3525 
3526         if(findDistancefast(person[i].averageloc, person[i].oldaverageloc) <
3527            .2 * multiplier)
3528           person[i].longdead -= multiplier / 2;
3529       }
3530 
3531       if(person[i].skeleton.free == 1 && person[i].longdead <= 0
3532          && person[i].health > 0 && person[i].longdead != -1) {
3533 
3534         person[i].longdead = 1;
3535         person[i].skeleton.free = 0;
3536         person[i].currentanimation = lyinganim;
3537         person[i].target = 0;
3538         person[i].targetframe = 0;
3539 
3540         //Get up from front or back?
3541         if(person[i].skeleton.forward.y > 0)
3542           person[i].targetanimation = getupfrontanim;
3543         else
3544           person[i].targetanimation = getupbackanim;
3545 
3546         //Find playercoords
3547         person[i].playercoords = person[i].averageloc;
3548 
3549         for(int j = 0; j < person[i].skeleton.num_joints; j++) {
3550           if(person[i].skeleton.joints[j].position.y > person[i].playercoords.y)
3551             person[i].playercoords.y = person[i].skeleton.joints[j].position.y;
3552         }
3553 
3554         //Find orientation
3555         XYZ firsttop =
3556             person[i].skeleton.joints[person[i].skeleton.jointlabels[neck]].
3557             position -
3558             person[i].skeleton.joints[person[i].skeleton.jointlabels[groin]].
3559             position;
3560 
3561         Normalise(&firsttop);
3562 
3563         person[i].playerrotation = acos(0 - firsttop.z);
3564         person[i].playerrotation *= 360 / 6.28;
3565 
3566         if(0 > firsttop.x)
3567           person[i].playerrotation = 360 - person[i].playerrotation;
3568 
3569         person[i].playerrotation *= -1;
3570         person[i].playervelocity = 0;
3571 
3572         if(person[i].targetanimation == getupfrontanim)
3573           person[i].playerrotation += 180;
3574 
3575         for(int j = 0; j < person[i].skeleton.num_joints; j++) {
3576 
3577           person[i].tempanimation.position[j][0] =
3578               person[i].skeleton.joints[j].position - person[i].playercoords;
3579 
3580           person[i].tempanimation.position[j][0] =
3581               DoRotation(person[i].tempanimation.position[j][0], 0,
3582                          -person[i].playerrotation, 0);
3583 
3584         }
3585       }
3586     }
3587 
3588     //Grenade
3589     if(ButtonClick(1) && person[0].weapon.type == grenade && person[0].weapon.ammo > 0
3590        && person[0].weapon.reloading <= 0 && person[0].attackframe < 0
3591        && person[0].targetanimation != crouchanim) {
3592 
3593       if(person[0].grenphase == 0) {
3594 
3595         XYZ soundsource =
3596             DoRotation(person[0].skeleton.
3597                        joints[person[0].skeleton.jointlabels[righthand]].
3598                        position, 0, person[0].playerrotation,
3599                        0) + person[0].playercoords;
3600 
3601         float gLoc[3];
3602         gLoc[0] = soundsource.x / soundscalefactor;
3603         gLoc[1] = soundsource.y / soundscalefactor;
3604         gLoc[2] = soundsource.z / soundscalefactor;
3605 
3606         alSourcefv(gSourceID[pinpullsound], AL_POSITION, gLoc);
3607         alSourcePlay(gSourceID[pinpullsound]);
3608 
3609         person[0].grenphase = 1;
3610       }
3611     }
3612 
3613     if((!ButtonClick(1)) && person[0].weapon.type == grenade) {
3614 
3615       if(person[0].grenphase == 1) {
3616         person[0].grenphase = 0;
3617         person[0].attackframe = 0;
3618         person[0].attacktarget = 0;
3619         person[0].killtarget = 0;
3620       }
3621     }
3622 
3623     if(person[0].targetanimation == crouchanim) {
3624 
3625       if(person[0].grenphase == 1) {
3626         person[0].grenphase = 0;
3627 
3628         XYZ soundsource =
3629             DoRotation(person[0].skeleton.
3630                        joints[person[0].skeleton.jointlabels[righthand]].
3631                        position, 0, person[0].playerrotation,
3632                        0) + person[0].playercoords;
3633 
3634         float gLoc[3];
3635         gLoc[0] = soundsource.x / soundscalefactor;
3636         gLoc[1] = soundsource.y / soundscalefactor;
3637         gLoc[2] = soundsource.z / soundscalefactor;
3638 
3639         alSourcefv(gSourceID[pinreplacesound], AL_POSITION, gLoc);
3640 
3641         alSourcePlay(gSourceID[pinreplacesound]);
3642       }
3643     }
3644     //Get gun
3645     int temp;
3646     int temp2;
3647     bool switched = 0;
3648 
3649     if(ButtonClick(1) && !oldbutton
3650        && (person[0].aiming == 0 || person[0].weapon.type == grenade
3651            || person[0].weapon.type == nogun || person[0].weapon.type == knife)
3652        && person[0].currentanimation == crouchanim) {
3653 
3654       for(int i = 0; i < max_people; i++) {
3655 
3656         if(!switched && person[i].skeleton.free == 1
3657            && findDistancefast(person[0].playercoords,
3658                                person[i].averageloc) < 200) {
3659 
3660           float gLoc[3];
3661           gLoc[0] = person[0].playercoords.x / soundscalefactor;
3662           gLoc[1] = person[0].playercoords.y / soundscalefactor;
3663           gLoc[2] = person[0].playercoords.z / soundscalefactor;
3664 
3665           alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc);
3666           alSourcePlay(gSourceID[clicksound]);
3667 
3668           temp = person[0].weapon.type;
3669           temp2 = person[0].weapon.ammo;
3670 
3671           person[0].weapon.type = person[i].weapon.type;
3672           person[0].weapon.ammo = person[i].weapon.ammo;
3673 
3674           person[i].weapon.type = temp;
3675           person[i].weapon.ammo = temp2;
3676 
3677           person[0].aiming = 1;
3678           person[0].aimamount = 0;
3679 
3680           switched = 1;
3681         }
3682       }
3683     }
3684     //Throw
3685     Person *bg = &person[0]; //main player
3686     if(ButtonClick(1) && bg->attackframe < 0
3687        && ((bg->weapon.type == nogun || bg->aiming == 0)
3688            && bg->weapon.type != knife)
3689        && bg->currentanimation != crouchanim
3690        && bg->targetanimation != crouchanim
3691        && bg->targetanimation != throwanim && config.visions == 0) {
3692 
3693       if(bg->targetanimation == idleanim
3694          || bg->targetanimation == walkanim) {
3695 
3696         bool attacking = 0;
3697         float closedistance = -1;
3698         bg->killtarget = -1;
3699         Person *person1;
3700 
3701         for(int i = 1; i < numpeople; i++) {
3702           person1 = &person[i];
3703           if(person1->skeleton.free < 1 && (person1->weapon.type != nogun)
3704              && findDistancefast(person1->playercoords,
3705                                  bg->playercoords + flatfacing) < 12) {
3706 
3707             attacking = 1;
3708 
3709             if(bg->killtarget == -1
3710                || findDistancefast(person1->playercoords,
3711                                    bg->playercoords) < closedistance) {
3712 
3713               bg->killtarget = i;
3714 
3715               closedistance =
3716                   findDistancefast(person1->playercoords,
3717                                    bg->playercoords);
3718 
3719             }
3720           }
3721         }
3722         //bodyguard target
3723         Person *bg_target = &person[bg->killtarget];
3724 
3725         if(attacking) {
3726 
3727           score += 150;
3728 
3729           bg->aiming = 1;
3730           bg->weapon.type = bg_target->weapon.type;
3731           bg->weapon.ammo = bg_target->weapon.ammo;
3732 
3733           bg_target->weapon.type = nogun;
3734           bg_target->killtarget = -1;
3735 
3736           bg->targetframe = 0;
3737           bg->targetanimation = throwanim;
3738           bg->target = 1;
3739           bg->speed = 1;
3740 
3741           bg_target->targetframe = 0;
3742           bg_target->targetanimation = thrownanim;
3743           bg_target->target = 1;
3744           bg_target->playercoords = bg->playercoords;
3745           bg_target->playerrotation =
3746               bg->playerrotation;
3747 
3748           bg_target->speed = bg->speed;
3749           bg_target->speedmult = 1;
3750         }
3751       }
3752     }
3753 
3754     //Gun whacking
3755     bool whacked = 0;
3756     if(ButtonClick(1)
3757        && (person[0].aiming == 0 || person[0].weapon.ammo <= 0
3758            || person[0].weapon.type == nogun || person[0].weapon.type == knife
3759            || person[0].targetanimation == joganim)
3760        && person[0].currentanimation != crouchanim
3761        && person[0].targetanimation != throwanim
3762        && person[0].weapon.type != grenade
3763        && person[0].targetanimation != crouchanim && visions == 0) {
3764 
3765       if(person[0].attackframe == -1
3766          || person[person[0].killtarget].skeleton.free == 1) {
3767 
3768         bool attacking = 0;
3769         float closedistance = -1;
3770         person[0].killtarget = -1;
3771 
3772         for(int i = 1; i < numpeople; i++) {
3773 
3774           if(person[i].existing && person[i].type != viptype
3775              && person[i].skeleton.free < 1
3776              && findDistancefast(person[i].playercoords,
3777                                  person[0].playercoords + flatfacing) <
3778              12 + (person[0].weapon.type == knife) * 10) {
3779 
3780             if(person[0].killtarget == -1
3781                || findDistancefast(person[i].playercoords,
3782                                    person[0].playercoords) < closedistance) {
3783 
3784               attacking = 1;
3785 
3786               person[0].killtarget = i;
3787 
3788               closedistance =
3789                   findDistancefast(person[i].playercoords,
3790                                    person[0].playercoords);
3791             }
3792           }
3793         }
3794 
3795         if(attacking) {
3796           person[0].attacktarget = 0;
3797           person[0].attackframe = 0;
3798         }
3799 
3800         whacked = 0;
3801       }
3802     }
3803 
3804     XYZ velocity;
3805 
3806     if(person[0].attackframe > 1
3807        || (person[0].attackframe >= 0
3808            && person[0].currentanimation == joganim)) {
3809 
3810       if(person[person[0].killtarget].skeleton.free < 1
3811          && person[0].killtarget != 0 && (person[0].aiming < 1
3812                                           || person[0].weapon.type == nogun
3813                                           || person[0].weapon.type == knife
3814                                           || person[0].targetanimation ==
3815                                           joganim)) {
3816 
3817         float gLoc[3];
3818 
3819         gLoc[0] =
3820             (camera.position.x +
3821              ((person[0].playercoords.x + flatfacing.x) -
3822               camera.position.x) / 2) / soundscalefactor;
3823 
3824         gLoc[1] =
3825             (camera.position.y +
3826              ((person[0].playercoords.y + flatfacing.y) -
3827               camera.position.y) / 2) / soundscalefactor;
3828 
3829         gLoc[2] =
3830             (camera.position.z +
3831              ((person[0].playercoords.z + flatfacing.z) -
3832               camera.position.z) / 2) / soundscalefactor;
3833 
3834         if(person[person[0].killtarget].type != zombietype) {
3835 
3836           if(person[0].weapon.type != knife) {
3837 
3838             alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
3839 
3840             alSourcePlay(gSourceID[headwhacksound]);
3841 
3842           }
3843 
3844           if(person[0].weapon.type == knife) {
3845 
3846             alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
3847 
3848             alSourcePlay(gSourceID[knifeslashsound]);
3849 
3850             person[person[0].killtarget].bjoint1 =
3851                 &person[person[0].killtarget].skeleton.
3852                 joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
3853 
3854             person[person[0].killtarget].bjoint2 =
3855                 &person[person[0].killtarget].skeleton.
3856                 joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
3857 
3858             person[person[0].killtarget].bleeding = 1;
3859             person[person[0].killtarget].bleeddelay = 1;
3860 
3861             person[0].bjoint1 =
3862                 &person[0].skeleton.joints[person[0].skeleton.
3863                                            jointlabels[righthand]];
3864 
3865             person[0].bjoint2 =
3866                 &person[0].skeleton.joints[person[0].skeleton.
3867                                            jointlabels[righthand]];
3868 
3869             person[0].bleeding = 1;
3870             person[0].bleeddelay = 1;
3871 
3872             velocity =
3873                 DoRotation(flatfacing, 0, 70, 0) * 50 + person[0].velocity * 2;
3874 
3875             velocity.y += 30;
3876 
3877             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
3878                                DoRotation(person[person[0].killtarget].skeleton.
3879                                           joints[person[person[0].killtarget].
3880                                                  skeleton.jointlabels[neck]].
3881                                           position, 0,
3882                                           person[person[0].killtarget].
3883                                           playerrotation,
3884                                           0) +
3885                                person[person[0].killtarget].playercoords,
3886                                velocity * .3, 2);
3887 
3888             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
3889                                DoRotation(person[person[0].killtarget].skeleton.
3890                                           joints[person[person[0].killtarget].
3891                                                  skeleton.jointlabels[neck]].
3892                                           position, 0,
3893                                           person[person[0].killtarget].
3894                                           playerrotation,
3895                                           0) +
3896                                person[person[0].killtarget].playercoords,
3897                                velocity * .2, 3);
3898 
3899             sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
3900                                DoRotation(person[person[0].killtarget].skeleton.
3901                                           joints[person[person[0].killtarget].
3902                                                  skeleton.jointlabels[neck]].
3903                                           position, 0,
3904                                           person[person[0].killtarget].
3905                                           playerrotation,
3906                                           0) +
3907                                person[person[0].killtarget].playercoords,
3908                                velocity * .1, 4);
3909 
3910           }
3911 
3912           person[person[0].killtarget].health -= 100;
3913           person[person[0].killtarget].skeleton.free = 1;
3914           person[person[0].killtarget].longdead = 1;
3915 
3916           for(int j = 0; j < person[person[0].killtarget].skeleton.num_joints;
3917               j++) {
3918 
3919             person[person[0].killtarget].skeleton.joints[j].position =
3920                 DoRotation(person[person[0].killtarget].skeleton.joints[j].
3921                            position, 0,
3922                            person[person[0].killtarget].playerrotation, 0);
3923 
3924             person[person[0].killtarget].skeleton.joints[j].position +=
3925                 person[person[0].killtarget].playercoords;
3926 
3927             person[person[0].killtarget].skeleton.joints[j].realoldposition =
3928                 person[person[0].killtarget].skeleton.joints[j].position;
3929 
3930             person[person[0].killtarget].skeleton.joints[j].velocity =
3931                 person[person[0].killtarget].velocity;
3932 
3933             person[person[0].killtarget].skeleton.joints[j].velocity.x +=
3934                 abs(Random() % 10) - 5;
3935 
3936             person[person[0].killtarget].skeleton.joints[j].velocity.y +=
3937                 abs(Random() % 10) - 5;
3938 
3939             person[person[0].killtarget].skeleton.joints[j].velocity.z +=
3940                 abs(Random() % 10) - 5;
3941 
3942           }
3943 
3944           if(person[0].weapon.type != knife) {
3945 
3946             person[person[0].killtarget].skeleton.
3947                 joints[person[person[0].killtarget].skeleton.jointlabels[head]].
3948                 velocity += DoRotation(flatfacing, 0, 40, 0) * 50;
3949 
3950             person[person[0].killtarget].skeleton.
3951                 joints[person[person[0].killtarget].skeleton.jointlabels[head]].
3952                 velocity += person[0].velocity * 2;
3953           }
3954         } else {
3955           if(whacked == 0) {
3956             whacked = 1;
3957 
3958             if(person[0].weapon.type != knife) {
3959               alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
3960               alSourcePlay(gSourceID[headwhacksound]);
3961             }
3962 
3963             if(person[0].weapon.type == knife) {
3964 
3965               alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
3966               alSourcePlay(gSourceID[knifeslashsound]);
3967 
3968               person[person[0].killtarget].bjoint1 =
3969                   &person[person[0].killtarget].skeleton.
3970                   joints[person[person[0].killtarget].skeleton.
3971                          jointlabels[neck]];
3972 
3973               person[person[0].killtarget].bjoint2 =
3974                   &person[person[0].killtarget].skeleton.
3975                   joints[person[person[0].killtarget].skeleton.
3976                          jointlabels[neck]];
3977 
3978               person[person[0].killtarget].bleeding = 1;
3979               person[person[0].killtarget].bleeddelay = 1;
3980 
3981               person[0].bjoint1 =
3982                   &person[0].skeleton.joints[person[0].skeleton.
3983                                              jointlabels[righthand]];
3984 
3985               person[0].bjoint2 =
3986                   &person[0].skeleton.joints[person[0].skeleton.
3987                                              jointlabels[righthand]];
3988 
3989               person[0].bleeding = 1;
3990               person[0].bleeddelay = 1;
3991 
3992               velocity =
3993                   DoRotation(flatfacing, 0, 70,
3994                              0) * 50 + person[0].velocity * 2;
3995 
3996               velocity.y += 30;
3997 
3998               sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
3999                                  DoRotation(person[person[0].killtarget].
4000                                             skeleton.
4001                                             joints[person[person[0].killtarget].
4002                                                    skeleton.jointlabels[neck]].
4003                                             position, 0,
4004                                             person[person[0].killtarget].
4005                                             playerrotation,
4006                                             0) +
4007                                  person[person[0].killtarget].playercoords,
4008                                  velocity * .3, 2);
4009 
4010               sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
4011                                  DoRotation(person[person[0].killtarget].
4012                                             skeleton.
4013                                             joints[person[person[0].killtarget].
4014                                                    skeleton.jointlabels[neck]].
4015                                             position, 0,
4016                                             person[person[0].killtarget].
4017                                             playerrotation,
4018                                             0) +
4019                                  person[person[0].killtarget].playercoords,
4020                                  velocity * .2, 3);
4021 
4022               sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
4023                                  DoRotation(person[person[0].killtarget].
4024                                             skeleton.
4025                                             joints[person[person[0].killtarget].
4026                                                    skeleton.jointlabels[neck]].
4027                                             position, 0,
4028                                             person[person[0].killtarget].
4029                                             playerrotation,
4030                                             0) +
4031                                  person[person[0].killtarget].playercoords,
4032                                  velocity * .1, 4);
4033 
4034             }
4035 
4036             person[person[0].killtarget].health -= 200;
4037             person[person[0].killtarget].maxhealth -= 20;
4038             person[person[0].killtarget].skeleton.free = 1;
4039             person[person[0].killtarget].longdead = 1;
4040 
4041             for(int j = 0; j < person[person[0].killtarget].skeleton.num_joints;
4042                 j++) {
4043 
4044               person[person[0].killtarget].skeleton.joints[j].position =
4045                   DoRotation(person[person[0].killtarget].skeleton.joints[j].
4046                              position, 0,
4047                              person[person[0].killtarget].playerrotation, 0);
4048 
4049               person[person[0].killtarget].skeleton.joints[j].position +=
4050                   person[person[0].killtarget].playercoords;
4051 
4052               person[person[0].killtarget].skeleton.joints[j].realoldposition =
4053                   person[person[0].killtarget].skeleton.joints[j].position;
4054 
4055               person[person[0].killtarget].skeleton.joints[j].velocity =
4056                   person[person[0].killtarget].velocity;
4057 
4058               person[person[0].killtarget].skeleton.joints[j].velocity.x +=
4059                   abs(Random() % 10) - 5;
4060 
4061               person[person[0].killtarget].skeleton.joints[j].velocity.y +=
4062                   abs(Random() % 10) - 5;
4063 
4064               person[person[0].killtarget].skeleton.joints[j].velocity.z +=
4065                   abs(Random() % 10) - 5;
4066             }
4067 
4068             if(person[0].weapon.type != knife) {
4069 
4070               person[person[0].killtarget].skeleton.
4071                   joints[person[person[0].killtarget].skeleton.
4072                          jointlabels[head]].velocity +=
4073                   DoRotation(flatfacing, 0, 40, 0) * 50;
4074 
4075               person[person[0].killtarget].skeleton.
4076                   joints[person[person[0].killtarget].skeleton.
4077                          jointlabels[head]].velocity += person[0].velocity * 2;
4078             }
4079           }
4080         }
4081       }
4082     }
4083     //Tackle
4084     if(person[0].currentanimation == diveanim && visions == 0) {
4085 
4086       for(int i = 1; i < numpeople; i++) {
4087 
4088         if(person[i].skeleton.free < 1
4089            && findDistancefast(person[i].playercoords,
4090                                person[0].playercoords + flatfacing) < 22) {
4091 
4092           float gLoc[3];
4093 
4094           gLoc[0] =
4095               (camera.position.x +
4096                ((person[0].playercoords.x + flatfacing.x) -
4097                 camera.position.x) / 2) / soundscalefactor;
4098 
4099           gLoc[1] =
4100               (camera.position.y +
4101                ((person[0].playercoords.y + flatfacing.y) -
4102                 camera.position.y) / 2) / soundscalefactor;
4103 
4104           gLoc[2] =
4105               (camera.position.z +
4106                ((person[0].playercoords.z + flatfacing.z) -
4107                 camera.position.z) / 2) / soundscalefactor;
4108 
4109           alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
4110           alSourcePlay(gSourceID[headwhacksound]);
4111 
4112           person[i].skeleton.free = 1;
4113           person[i].longdead = 1;
4114 
4115           for(int j = 0; j < person[i].skeleton.num_joints; j++) {
4116 
4117             person[i].skeleton.joints[j].position =
4118                 DoRotation(person[i].skeleton.joints[j].position, 0,
4119                            person[i].playerrotation, 0);
4120 
4121             person[i].skeleton.joints[j].position += person[i].playercoords;
4122 
4123             person[i].skeleton.joints[j].realoldposition =
4124                 person[i].skeleton.joints[j].position;
4125 
4126             person[i].skeleton.joints[j].velocity = person[0].velocity;
4127             person[i].skeleton.joints[j].velocity.y = -10;
4128             person[i].skeleton.joints[j].velocity.x += abs(Random() % 10) - 5;
4129             person[i].skeleton.joints[j].velocity.y += abs(Random() % 10) - 5;
4130             person[i].skeleton.joints[j].velocity.z += abs(Random() % 10) - 5;
4131           }
4132         }
4133       }
4134     }
4135 
4136     Fire(); //fire weapon and hit something, hopefully...
4137 
4138     XYZ start;
4139     XYZ wallhit;
4140 
4141     if(!ButtonClick(1))
4142       oldbutton = 0;
4143 
4144     if(lasersight && person[0].weapon.type != grenade) {
4145 
4146       for(int j = 0; j < numpeople; j++) {
4147         if(person[j].type == playertype) {
4148           if(person[j].aiming >= 1) {
4149 
4150             //Firing
4151             XYZ end, aim;
4152             XYZ finalwallhit;
4153             HitStruct hitstruct, temphitstruct;
4154             float olddistance = 0.0;
4155             float distance;
4156             int whichhit = -1;
4157 
4158             if(!zoom || j != 0) {
4159 
4160               if(person[j].weapon.type == assaultrifle)
4161                 aim =
4162                     DoRotation(person[j].skeleton.
4163                                joints[(person[j].skeleton.
4164                                        jointlabels[lefthand])].position -
4165                                person[j].skeleton.
4166                                joints[(person[j].skeleton.
4167                                        jointlabels[righthand])].position, 0,
4168                                person[j].playerrotation - 2.5, 0);
4169 
4170               if(person[j].weapon.type == sniperrifle)
4171                 aim =
4172                     DoRotation(person[j].skeleton.
4173                                joints[(person[j].skeleton.
4174                                        jointlabels[lefthand])].position -
4175                                person[j].skeleton.
4176                                joints[(person[j].skeleton.
4177                                        jointlabels[righthand])].position, 0,
4178                                person[j].playerrotation + 4, 0);
4179 
4180               if(person[j].weapon.type == shotgun)
4181                 aim =
4182                     DoRotation(person[j].skeleton.
4183                                joints[(person[j].skeleton.
4184                                        jointlabels[lefthand])].position -
4185                                person[j].skeleton.
4186                                joints[(person[j].skeleton.
4187                                        jointlabels[righthand])].position, 0,
4188                                person[j].playerrotation + 4, 0);
4189 
4190               if(person[j].weapon.type == handgun1 && !thirdperson && j == 0)
4191                 aim =
4192                     DoRotation(person[j].skeleton.
4193                                joints[(person[j].skeleton.
4194                                        jointlabels[righthand])].position -
4195                                (person[j].skeleton.
4196                                 joints[person[j].skeleton.jointlabels[head]].
4197                                 position * .65 +
4198                                 person[j].skeleton.joints[person[j].skeleton.
4199                                                           jointlabels[neck]].
4200                                 position * .35), 0,
4201                                person[j].playerrotation - .9, 0);
4202 
4203               if(person[j].weapon.type == handgun1 && (thirdperson || j != 0))
4204                 aim =
4205                     DoRotation(person[j].skeleton.
4206                                joints[(person[j].skeleton.
4207                                        jointlabels[righthand])].position -
4208                                (person[j].skeleton.
4209                                 joints[person[j].skeleton.jointlabels[head]].
4210                                 position * .35 +
4211                                 person[j].skeleton.joints[person[j].skeleton.
4212                                                           jointlabels[neck]].
4213                                 position * .65), 0,
4214                                person[j].playerrotation - .9, 0);
4215 
4216               if(person[j].weapon.type == handgun2 && !thirdperson && j == 0)
4217                 aim =
4218                     DoRotation(person[j].skeleton.
4219                                joints[(person[j].skeleton.
4220                                        jointlabels[righthand])].position -
4221                                (person[j].skeleton.
4222                                 joints[person[j].skeleton.jointlabels[head]].
4223                                 position * .65 +
4224                                 person[j].skeleton.joints[person[j].skeleton.
4225                                                           jointlabels[neck]].
4226                                 position * .35), 0,
4227                                person[j].playerrotation - .9, 0);
4228 
4229               if(person[j].weapon.type == handgun2 && (thirdperson || j != 0))
4230                 aim =
4231                     DoRotation(person[j].skeleton.
4232                                joints[(person[j].skeleton.
4233                                        jointlabels[righthand])].position -
4234                                (person[j].skeleton.
4235                                 joints[person[j].skeleton.jointlabels[head]].
4236                                 position * .35 +
4237                                 person[j].skeleton.joints[person[j].skeleton.
4238                                                           jointlabels[neck]].
4239                                 position * .65), 0,
4240                                person[j].playerrotation - .9, 0);
4241 
4242             }
4243 
4244             if(zoom && j == 0) {
4245               start = camera.position;
4246               aim = facing;
4247             }
4248 
4249             Normalise(&aim);
4250 
4251             if(person[j].weapon.type == sniperrifle) {
4252 
4253               start =
4254                   person[j].playercoords +
4255                   DoRotation(person[j].skeleton.
4256                              joints[(person[j].skeleton.jointlabels[lefthand])].
4257                              position, 0, person[j].playerrotation, 0);
4258 
4259               start -=
4260                   DoRotation(DoRotation
4261                              (DoRotation(aim, 0, -person[j].playerrotation, 0),
4262                               90, 0, 0), 0, person[j].playerrotation,
4263                              0) * (0 - .4);
4264 
4265             }
4266 
4267             if(person[j].weapon.type == shotgun) {
4268 
4269               start =
4270                   person[j].playercoords +
4271                   DoRotation(person[j].skeleton.
4272                              joints[(person[j].skeleton.jointlabels[lefthand])].
4273                              position, 0, person[j].playerrotation, 0);
4274 
4275               start -=
4276                   DoRotation(DoRotation
4277                              (DoRotation(aim, 0, -person[j].playerrotation, 0),
4278                               90, 0, 0), 0, person[j].playerrotation,
4279                              0) * (0 - .4);
4280 
4281             }
4282 
4283             if(person[j].weapon.type == handgun1) {
4284 
4285               start =
4286                   person[j].playercoords +
4287                   DoRotation(person[j].skeleton.
4288                              joints[(person[j].skeleton.
4289                                      jointlabels[rightwrist])].position, 0,
4290                              person[j].playerrotation, 0);
4291 
4292               start -=
4293                   DoRotation(DoRotation
4294                              (DoRotation(aim, 0, -person[j].playerrotation, 0),
4295                               90, 0, 0), 0, person[j].playerrotation,
4296                              0) * (.55 - .4);
4297 
4298             }
4299 
4300             if(person[j].weapon.type == handgun2) {
4301 
4302               start =
4303                   person[j].playercoords +
4304                   DoRotation(person[j].skeleton.
4305                              joints[(person[j].skeleton.
4306                                      jointlabels[rightwrist])].position, 0,
4307                              person[j].playerrotation, 0);
4308 
4309               start -=
4310                   DoRotation(DoRotation
4311                              (DoRotation(aim, 0, -person[j].playerrotation, 0),
4312                               90, 0, 0), 0, person[j].playerrotation,
4313                              0) * (.55 - .4);
4314 
4315             }
4316 
4317             if(person[j].weapon.type == assaultrifle) {
4318 
4319               start =
4320                   person[j].playercoords +
4321                   DoRotation(person[j].skeleton.
4322                              joints[(person[j].skeleton.jointlabels[lefthand])].
4323                              position, 0, person[j].playerrotation, 0);
4324 
4325               start -=
4326                   DoRotation(DoRotation
4327                              (DoRotation(aim, 0, -person[j].playerrotation, 0),
4328                               90, 0, 0), 0, person[j].playerrotation,
4329                              0) * (.25 - .4);
4330 
4331             }
4332 
4333             end = start + aim * 1000;
4334 
4335             //Blocks
4336             wallhit = 0;
4337 
4338             beginx =
4339                 (int)(person[j].playercoords.x +
4340                       block_spacing / 2) / block_spacing - 2;
4341 
4342             if(beginx < 0)
4343               beginx = 0;
4344 
4345             beginz =
4346                 (int)(person[j].playercoords.z +
4347                       block_spacing / 2) / block_spacing - 2;
4348 
4349             if(beginz < 0)
4350               beginz = 0;
4351 
4352             endx =
4353                 (int)(person[j].playercoords.x +
4354                       block_spacing / 2) / block_spacing + 2;
4355 
4356             if(endx > num_blocks - 1)
4357               endx = num_blocks - 1;
4358 
4359             endz =
4360                 (int)(person[j].playercoords.z +
4361                       block_spacing / 2) / block_spacing + 2;
4362 
4363             if(endz > num_blocks - 1)
4364               endz = num_blocks - 1;
4365 
4366             if(beginx < endx && beginz < endz)
4367 
4368               finalwallhit = 0;
4369 
4370             for(int i = beginx; i <= endx; i++)
4371               for(int j = beginz; j <= endz; j++) {
4372                 move = 0;
4373                 move.x = i * block_spacing;
4374                 move.z = j * block_spacing;
4375 
4376                 whichtri =
4377                     blocks[citytype[i][j]].LineCheck2(start, end, &wallhit,
4378                                                       move,
4379                                                       cityrotation[i][j] * 90);
4380 
4381                 if(whichtri != -1) {
4382                   end = wallhit;
4383                   finalwallhit = wallhit;
4384                 }
4385               }
4386 
4387             wallhit = 0;
4388             wallhit.x = camera.position.x;
4389             wallhit.z = camera.position.z;
4390 
4391             whichtri = Bigstreet.LineCheck2(start, end, &wallhit, wallhit, 0);
4392 
4393             if(whichtri != -1) {
4394               end = wallhit;
4395               finalwallhit = wallhit;
4396             }
4397             //People
4398             whichhit = -1;
4399 
4400             for(int i = 0; i < numpeople; i++) {
4401 
4402               if(i != j
4403                  && findDistancefast(person[j].playercoords,
4404                                      person[i].playercoords) < 20000) {
4405 
4406                 temphitstruct =
4407                     person[i].BulletCollideWithPlayer(i, start, end);
4408 
4409                 if(temphitstruct.collision) {
4410                   distance = findDistancefast(start, temphitstruct.hitlocation);
4411 
4412                   if(distance < olddistance || whichhit == -1) {
4413                     end = temphitstruct.hitlocation;
4414                     olddistance = distance;
4415                     hitstruct = temphitstruct;
4416                     whichhit = i;
4417                   }
4418                 }
4419               }
4420             }
4421 
4422             aimer[0] = start;
4423             aimer[1] = end;
4424 
4425             sprites.MakeSprite(bulletinstant, .4, 1, 0, 0, aimer[0], aimer[1],
4426                                .2);
4427 
4428           }
4429         }
4430       }
4431     }
4432     //Snow
4433     float snowdelay = environment.snowdelay;
4434     snowdelay -= multiplier;
4435 
4436     float precipitationhorz = environment.precipitationhorz;
4437     float precipitationvert = environment.precipitationvert;
4438     float precipitationdensity = environment.precipitationdensity;
4439 
4440     while(snowdelay < 0 && environment.type == snowy_environment) {
4441       snowdelay += 1 / precipitationdensity * 2;
4442 
4443       velocity = 0;
4444       velocity.y = -5;
4445 
4446       start = camera.position;
4447       start.y += precipitationvert;
4448       start.x += Random() % (int)precipitationhorz;
4449       start.z += Random() % (int)precipitationhorz;
4450 
4451       sprites.MakeSprite(snowsprite, 1, 1, 1, 1, start, velocity, 1.01);
4452 
4453     }
4454 
4455     while(snowdelay < 0 && environment.type == rainy_environment) {
4456       snowdelay += 1 / precipitationdensity / 4;
4457 
4458       velocity = 0;
4459       velocity.y = -100;
4460 
4461       start = camera.position;
4462       start.y += precipitationvert;
4463       start.x += Random() % (int)precipitationhorz *.5;
4464       start.z += Random() % (int)precipitationhorz *.5;
4465 
4466       sprites.MakeSprite(rainsprite, .5, 1, 1, 1, start, velocity, 2.00);
4467 
4468     }
4469 
4470     //Grenade collision
4471     int wherex, wherey, whichsound;
4472     bool impact;
4473 
4474     for(int i = 0; i < sprites.howmanysprites; i++) {
4475 
4476       if(sprites.type[i] == grenadesprite || sprites.type[i] == spoonsprite
4477          || sprites.type[i] == pinsprite) {
4478 
4479         impact = 0;
4480 
4481         if(sprites.type[i] != grenadesprite) {
4482           sprites.brightness[i] -= multiplier * .2;
4483         }
4484 
4485         if(findLengthfast(sprites.velocity[i]) > 0) {
4486 
4487           wherex =
4488               (int)(sprites.location[i].x + block_spacing / 2) / block_spacing;
4489 
4490           wherey =
4491               (int)(sprites.location[i].z + block_spacing / 2) / block_spacing;
4492 
4493           move = 0;
4494           move.x = wherex * block_spacing;
4495           move.z = wherey * block_spacing;
4496 
4497           whichtri =
4498               blocks[citytype[wherex][wherey]].LineCheck2(sprites.
4499                                                           oldlocation[i],
4500                                                           sprites.location[i],
4501                                                           &wallhit, move,
4502                                                           cityrotation[wherex]
4503                                                           [wherey] * 90);
4504 
4505           if(whichtri != -1) {
4506 
4507             impact = 1;
4508 
4509             normalrotated =
4510                 DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri],
4511                            0, cityrotation[wherex][wherey] * 90, 0);
4512 
4513             if(sprites.size[i] > 1)
4514               decals.MakeDecal(crater, wallhit, 9, normalrotated, whichtri,
4515                                &blocks[citytype[wherex][wherey]], move,
4516                                cityrotation[wherex][wherey] * 90);
4517 
4518             sprites.location[i] = wallhit + normalrotated * .02;
4519 
4520             ReflectVector(&sprites.velocity[i], &normalrotated);
4521 
4522             sprites.velocity[i] *= .3;
4523 
4524             if(sprites.type[i] == grenadesprite) {
4525 
4526               float gLoc[3];
4527 
4528               gLoc[0] =
4529                   (((sprites.location[i].x) -
4530                     camera.position.x) / findLengthfast(sprites.velocity[i]) *
4531                    5 + camera.position.x) / soundscalefactor;
4532 
4533               gLoc[1] =
4534                   (((sprites.location[i].y) -
4535                     camera.position.y) / findLengthfast(sprites.velocity[i]) *
4536                    5 + camera.position.y) / soundscalefactor;
4537 
4538               gLoc[2] =
4539                   (((sprites.location[i].z) -
4540                     camera.position.z) / findLengthfast(sprites.velocity[i]) *
4541                    5 + camera.position.z) / soundscalefactor;
4542 
4543               whichsound = abs(Random() % 2);
4544 
4545               alSourcefv(gSourceID[bouncesound + whichsound], AL_POSITION,
4546                          gLoc);
4547 
4548               if(sprites.size[i] <= 1)
4549                 alSourcePlay(gSourceID[bouncesound + whichsound]);
4550 
4551             }
4552 
4553             if(findLengthfast(sprites.velocity[i]) <= 10)
4554               sprites.velocity[i] = 0;
4555 
4556           }
4557 
4558           if(sprites.location[i].y < 0) {
4559             impact = 1;
4560 
4561             sprites.velocity[i].y *= -1;
4562             sprites.velocity[i] *= .3;
4563             sprites.location[i].y = 0;
4564 
4565             if(sprites.type[i] == grenadesprite) {
4566 
4567               if(sprites.size[i] > 1) {
4568                 move = 0;
4569 
4570                 sprites.location[i].y = -.5;
4571 
4572                 XYZ normish;
4573                 normish = 0;
4574                 normish.y = 1;
4575 
4576                 decals.MakeDecal(crater, sprites.location[i], 9, normish, 0,
4577                                  &blocks[citytype[wherex][wherey]], move, 0);
4578 
4579               }
4580 
4581               float gLoc[3];
4582 
4583               gLoc[0] =
4584                   (((sprites.location[i].x) -
4585                     camera.position.x) / findLengthfast(sprites.velocity[i]) *
4586                    5 + camera.position.x) / soundscalefactor;
4587 
4588               gLoc[1] =
4589                   (((sprites.location[i].y) -
4590                     camera.position.y) / findLengthfast(sprites.velocity[i]) *
4591                    5 + camera.position.y) / soundscalefactor;
4592 
4593               gLoc[2] =
4594                   (((sprites.location[i].z) -
4595                     camera.position.z) / findLengthfast(sprites.velocity[i]) *
4596                    5 + camera.position.z) / soundscalefactor;
4597 
4598               whichsound = abs(Random() % 2);
4599 
4600               alSourcefv(gSourceID[bouncesound + whichsound], AL_POSITION,
4601                          gLoc);
4602 
4603               if(sprites.size[i] <= 1)
4604                 alSourcePlay(gSourceID[bouncesound + whichsound]);
4605 
4606             }
4607 
4608             if(findLengthfast(sprites.velocity[i]) <= 10)
4609               sprites.velocity[i] = 0;
4610 
4611           }
4612 
4613           if(sprites.type[i] == grenadesprite
4614              && findLengthfast(sprites.velocity[i]) > 20) {
4615 
4616             HitStruct hitstruct;
4617 
4618             for(int j = 0; j < numpeople; j++) {
4619 
4620               if((j != 0 || sprites.brightness[i] < .9) && person[j].existing) {
4621 
4622                 hitstruct =
4623                     person[j].BulletCollideWithPlayer(j, sprites.oldlocation[i],
4624                                                       sprites.location[i]);
4625 
4626                 if(hitstruct.collision) {
4627 
4628                   impact = 1;
4629 
4630                   sprites.location[i] = hitstruct.hitlocation;
4631 
4632                   float gLoc[3];
4633 
4634                   gLoc[0] =
4635                       (((sprites.location[i].x) -
4636                         camera.position.x) /
4637                        findLengthfast(sprites.velocity[i]) * 5 +
4638                        camera.position.x) / soundscalefactor;
4639 
4640                   gLoc[1] =
4641                       (((sprites.location[i].y) -
4642                         camera.position.y) /
4643                        findLengthfast(sprites.velocity[i]) * 5 +
4644                        camera.position.y) / soundscalefactor;
4645 
4646                   gLoc[2] =
4647                       (((sprites.location[i].z) -
4648                         camera.position.z) /
4649                        findLengthfast(sprites.velocity[i]) * 5 +
4650                        camera.position.z) / soundscalefactor;
4651 
4652                   if(person[j].skeleton.free < 1) {
4653 
4654                     if((hitstruct.joint1->label == head
4655                         || hitstruct.joint2->label == head)
4656                        && person[j].type != zombietype) {
4657 
4658                       alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
4659 
4660                       if(sprites.size[i] <= 1)
4661                         alSourcePlay(gSourceID[headwhacksound]);
4662 
4663                       person[j].skeleton.free = 1;
4664 
4665                       person[j].longdead = 1;
4666 
4667                       for(int k = 0; k < person[j].skeleton.num_joints; k++) {
4668                         person[j].skeleton.joints[k].position =
4669                             DoRotation(person[j].skeleton.joints[k].position, 0,
4670                                        person[j].playerrotation, 0);
4671                         person[j].skeleton.joints[k].position +=
4672                             person[j].playercoords;
4673                         person[j].skeleton.joints[k].realoldposition =
4674                             person[j].skeleton.joints[k].position;
4675 
4676                         person[j].skeleton.joints[k].velocity =
4677                             person[j].velocity;
4678                         person[j].skeleton.joints[k].velocity.x +=
4679                             abs(Random() % 10) - 5;
4680                         person[j].skeleton.joints[k].velocity.y +=
4681                             abs(Random() % 10) - 5;
4682                         person[j].skeleton.joints[k].velocity.z +=
4683                             abs(Random() % 10) - 5;
4684 
4685                       }
4686 
4687                       hitstruct.joint1->velocity += sprites.velocity[i];
4688                       hitstruct.joint2->velocity += sprites.velocity[i];
4689 
4690                       if(person[j].type == civiliantype)
4691                         civkills++;
4692 
4693                       if(person[j].type == eviltype)
4694                         goodkills++;
4695 
4696                     } else {
4697 
4698                       float totalarea = 0.0f;
4699 
4700                       alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
4701 
4702                       if(sprites.size[i] <= 1)
4703                         alSourcePlay(gSourceID[bodywhacksound]);
4704 
4705                       person[j].skeleton.offset = 1;
4706 
4707                       for(int k = 0; k < person[j].skeleton.num_joints; k++) {
4708 
4709                         if(findDistancefast
4710                            (DoRotation
4711                             (person[j].skeleton.joints[k].position, 0,
4712                              person[j].playerrotation,
4713                              0) + person[j].playercoords,
4714                             hitstruct.hitlocation) < 200) {
4715 
4716                           totalarea +=
4717                               (200 /
4718                                findDistancefast(DoRotation
4719                                                 (person[j].skeleton.joints[k].
4720                                                  position, 0,
4721                                                  person[j].playerrotation,
4722                                                  0) + person[j].playercoords,
4723                                                 hitstruct.hitlocation));
4724                         }
4725                       }
4726 
4727                       float offsetlength;
4728 
4729                       for(int k = 0; k < person[j].skeleton.num_joints; k++) {
4730 
4731                         if(findDistancefast
4732                            (DoRotation
4733                             (person[j].skeleton.joints[k].position, 0,
4734                              person[j].playerrotation,
4735                              0) + person[j].playercoords,
4736                             hitstruct.hitlocation) < 200) {
4737 
4738                           person[j].skeleton.joints[k].offset +=
4739                               DoRotation(sprites.velocity[i] * .1 *
4740                                          ((200 /
4741                                            findDistancefast(DoRotation
4742                                                             (person[j].skeleton.
4743                                                              joints[k].position,
4744                                                              0,
4745                                                              person[j].
4746                                                              playerrotation,
4747                                                              0) +
4748                                                             person[j].
4749                                                             playercoords,
4750                                                             hitstruct.
4751                                                             hitlocation)) /
4752                                           totalarea * 10), 0,
4753                                          -person[j].playerrotation, 0);
4754 
4755                         }
4756 
4757                         offsetlength =
4758                             findLengthfast(person[j].skeleton.joints[k].offset);
4759 
4760                         if(offsetlength > 9) {
4761 
4762                           Normalise(&person[j].skeleton.joints[k].offset);
4763 
4764                           person[j].skeleton.joints[k].offset *= 3;
4765 
4766                         }
4767                       }
4768                     }
4769                   }
4770 
4771                   sprites.velocity[i] *= -.3;
4772 
4773                 }
4774               }
4775             }
4776           }
4777 
4778           sprites.oldlocation[i] = sprites.location[i];
4779 
4780         }
4781         //Explode
4782         if(sprites.type[i] == grenadesprite) {
4783 
4784           sprites.brightness[i] -= multiplier * .3;
4785 
4786           if(sprites.brightness[i] <= 0 || (impact && sprites.size[i] > 1)) {
4787 
4788             sprites.brightness[i] = 0;
4789 
4790             sprites.MakeSprite(smokesprite, 1, 1, 1, 1, sprites.location[i],
4791                                facing * 0, 60);
4792 
4793             sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1,
4794                                sprites.location[i], facing * 0, 9);
4795 
4796             float gLoc[3];
4797 
4798             gLoc[0] =
4799                 (((sprites.location[i].x) - camera.position.x) / 3 +
4800                  camera.position.x) / soundscalefactor;
4801 
4802             gLoc[1] =
4803                 (((sprites.location[i].y) - camera.position.y) / 3 +
4804                  camera.position.y) / soundscalefactor;
4805 
4806             gLoc[2] =
4807                 (((sprites.location[i].z) - camera.position.z) / 3 +
4808                  camera.position.z) / soundscalefactor;
4809 
4810             alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc);
4811 
4812             alSourcePlay(gSourceID[explosionsound]);
4813 
4814             XYZ relation;
4815 
4816             camera.camerashake =
4817                 1 - findDistance(person[0].playercoords,
4818                                  sprites.location[i]) / 200;
4819 
4820             //if(!sprites.size[i]>1){
4821 
4822             overpoint = sprites.location[i];
4823             overpoint.y += 3000;
4824 
4825             underpoint = sprites.location[i];
4826             underpoint.y -= 3000;
4827 
4828             move = 0;
4829 
4830             wherex =
4831                 (int)(sprites.location[i].x +
4832                       block_spacing / 2) / block_spacing;
4833 
4834             wherey =
4835                 (int)(sprites.location[i].z +
4836                       block_spacing / 2) / block_spacing;
4837 
4838             move.x = wherex * block_spacing;
4839             move.z = wherey * block_spacing;
4840 
4841             XYZ temp;
4842 
4843             whichtri =
4844                 sidewalkcollide.LineCheck2(overpoint, underpoint, &temp, move,
4845                                            cityrotation[wherex][wherey] * 90);
4846 
4847             XYZ normish;
4848             normish = 0;
4849             normish.y = 1;
4850 
4851             if(whichtri >= 0) {
4852 
4853               decals.MakeDecal(crater, sprites.location[i], 9, normish, 0,
4854                                &sidewalkcollide, move,
4855                                cityrotation[wherex][wherey] * 90);
4856 
4857             }
4858 
4859             if(whichtri == -1) {
4860               temp = sprites.location[i];
4861               temp.y = -.5;
4862 
4863               move = 0;
4864 
4865               decals.MakeDecal(crater, sprites.location[i], 9, normish, 0,
4866                                &sidewalkcollide, move, 0);
4867 
4868             }
4869             //}
4870 
4871             for(int k = 0; k < numpeople; k++) {
4872 
4873               if(person[k].existing
4874                  && (person[k].longdead != -1 || person[k].skeleton.free < 1)) {
4875 
4876                 if((findDistancefast
4877                     (person[k].playercoords, sprites.location[i]) < 700
4878                     && person[k].skeleton.free < 1)
4879                    ||
4880                    (findDistancefast(person[k].averageloc, sprites.location[i])
4881                     < 700 && person[k].skeleton.free >= 1)) {
4882 
4883                   if(person[k].skeleton.free != 1) {
4884 
4885                     if(person[k].type == civiliantype)
4886                       civkills++;
4887 
4888                     if(person[k].type == eviltype)
4889                       goodkills++;
4890 
4891                     person[k].skeleton.free = 1;
4892 
4893                     person[k].killtargetvisible = 0;
4894 
4895                     if((findDistancefast
4896                         (person[k].playercoords, sprites.location[i]) < 600
4897                         && person[k].skeleton.free < 1)
4898                        ||
4899                        (findDistancefast
4900                         (person[k].averageloc, sprites.location[i]) < 600
4901                         && person[k].skeleton.free >= 1)
4902                        || person[k].type == playertype) {
4903 
4904                       person[k].health -= 100;
4905                       person[k].bleeding = 1;
4906                     }
4907 
4908                     person[k].DoAnimations(k);
4909                     person[k].longdead = 1;
4910                     person[k].bleeddelay = 1;
4911 
4912                     person[k].bjoint1 =
4913                         &person[k].skeleton.joints[person[k].skeleton.
4914                                                    jointlabels[head]];
4915 
4916                     person[k].bjoint2 =
4917                         &person[k].skeleton.joints[person[k].skeleton.
4918                                                    jointlabels[neck]];
4919 
4920                     for(int j = 0; j < person[k].skeleton.num_joints; j++) {
4921 
4922                       person[k].skeleton.joints[j].position =
4923                           DoRotation(person[k].skeleton.joints[j].position, 0,
4924                                      person[k].playerrotation, 0);
4925 
4926                       person[k].skeleton.joints[j].position +=
4927                           person[k].playercoords;
4928 
4929                       person[k].skeleton.joints[j].realoldposition =
4930                           person[k].skeleton.joints[j].position;
4931 
4932                       person[k].skeleton.joints[j].velocity =
4933                           DoRotation(person[k].skeleton.joints[j].velocity, 0,
4934                                      person[k].playerrotation, 0);
4935 
4936                       person[k].skeleton.joints[j].velocity +=
4937                           person[k].velocity;
4938 
4939                       person[k].skeleton.joints[j].velocity.x +=
4940                           abs(Random() % 20) - 10;
4941 
4942                       person[k].skeleton.joints[j].velocity.y +=
4943                           abs(Random() % 20) - 10;
4944 
4945                       person[k].skeleton.joints[j].velocity.z +=
4946                           abs(Random() % 20) - 10;
4947 
4948                   }}
4949 
4950                   for(int j = 0; j < person[k].skeleton.num_joints; j++) {
4951 
4952                     relation =
4953                         person[k].skeleton.joints[j].position -
4954                         sprites.location[i];
4955 
4956                     Normalise(&relation);
4957 
4958                     if(findDistance
4959                        (person[k].skeleton.joints[j].position,
4960                         sprites.location[i]) > 1)
4961                       person[k].skeleton.joints[j].velocity +=
4962                           relation /
4963                           findDistance(person[k].skeleton.joints[j].position,
4964                                        sprites.location[i]) * 300;
4965 
4966                     else
4967                       person[k].skeleton.joints[j].velocity += relation * 300;
4968 
4969                   }
4970 
4971                   person[k].longdead = 1;
4972 
4973                   for(int j = 0; j < person[k].skeleton.num_joints; j++) {
4974 
4975                     //Sever stuff
4976                     if(findLengthfast(person[k].skeleton.joints[j].velocity) >
4977                        1500 && person[k].skeleton.joints[j].existing == 1
4978                        && abs(Random() % 3) != 1) {
4979 
4980                       sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,
4981                                          person[k].skeleton.joints[j].position,
4982                                          person[k].skeleton.joints[j].velocity /
4983                                          3, 9);
4984 
4985                       person[k].skeleton.DeleteJoint(j);
4986                       person[k].skeleton.broken = 2;
4987                       person[k].skeleton.joints[j].existing = 0;
4988                       person[k].health = -10000;
4989                     }
4990                   }
4991                 }
4992               }
4993             }
4994           }
4995         }
4996       }
4997     }
4998 
4999     //camera shake
5000     camera.camerashake -= multiplier;
5001 
5002     if(camera.camerashake < 0)
5003       camera.camerashake = 0;
5004 
5005     //camera position
5006     XYZ average;
5007 
5008     if(!zoom)
5009       average =
5010           person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].
5011           position * (person[0].aimamount / 2 + .5) +
5012           person[0].skeleton.joints[(person[0].skeleton.jointlabels[neck])].
5013           position * ((1 - person[0].aimamount) / 2);
5014 
5015     if(zoom)
5016       average =
5017           person[0].skeleton.
5018           joints[(person[0].skeleton.jointlabels[righthand])].position;
5019 
5020     if(person[0].skeleton.free == 0 && thirdperson != 2)
5021       camera.position =
5022           person[0].playercoords + DoRotation(average, 0,
5023                                               person[0].playerrotation, 0);
5024 
5025     if(person[0].skeleton.free == 1 && thirdperson != 2)
5026       camera.position = average;
5027 
5028     //Restraints
5029     if(camera.position.y < .1)
5030       camera.position.y = .1;
5031 
5032     if(thirdperson != 2) {
5033       oldrot = camera.visrotation;
5034       oldrot2 = camera.visrotation2;
5035     }
5036     //Kill count
5037     for(int i = 0; i < numpeople; i++) {
5038 
5039       if(person[i].oldhealth > 0 && person[i].health <= 0) {
5040 
5041         if(i == 1)
5042           alSourcePlay(gSourceID[losesound]);
5043 
5044         if(person[i].type == civiliantype) {
5045 
5046           alSourcePlay(gSourceID[disguisekillsound]);
5047 
5048           score -= 300;
5049         }
5050 
5051         if(person[i].type == eviltype) {
5052 
5053           alSourcePlay(gSourceID[soulinsound]);
5054 
5055           score += 75;
5056 
5057           if(person[i].weapon.type == knife)
5058             score += 50;
5059 
5060         }
5061 
5062         person[i].firstlongdead = 0;
5063       }
5064 
5065       person[i].oldhealth = person[i].health;
5066     }
5067 
5068     if(slomo == 2) {
5069       psychicpower -= multiplier * 15;
5070 
5071       if(psychicpower < 0) {
5072 
5073         soundscalefactor = soundscalefactordefault;
5074 
5075         alSourceStop(gSourceID[whichsong]);
5076 
5077         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
5078         alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
5079 
5080         if(person[0].weapon.type == knife)
5081           whichsong = knifesong;
5082 
5083         if(person[0].weapon.type != knife)
5084           whichsong = shootsong;
5085 
5086         if(type == zombie_type)
5087           whichsong = zombiesong;
5088 
5089         alSourcef(gSourceID[whichsong], AL_PITCH, 1);
5090         alSourcePlay(gSourceID[whichsong]);
5091         alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
5092         alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
5093 
5094         slomo = 0;
5095 
5096         alSourcePlay(gSourceID[soulinsound]);
5097 
5098         psychicpower = 0;
5099 
5100         flashamount = .5;
5101 
5102         flashr = 1;
5103         flashg = 1;
5104         flashb = 1;
5105       }
5106     }
5107 
5108     psychicpower += multiplier * 5;
5109 
5110     if(psychicpower > 10)
5111       psychicpower = 10;
5112 
5113     //3d sound
5114     float gLoc[3];
5115 
5116     gLoc[0] = camera.position.x / soundscalefactor;
5117     gLoc[1] = camera.position.y / soundscalefactor;
5118     gLoc[2] = camera.position.z / soundscalefactor;
5119 
5120     //Set listener position
5121     alListenerfv(AL_POSITION, gLoc);
5122 
5123     //Set orientation with forward and up vectors
5124     XYZ upvector;
5125 
5126     upvector = 0;
5127     upvector.z = -1;
5128 
5129     upvector = DoRotation(upvector, -camera.rotation2 + 90, 0, 0);
5130     upvector = DoRotation(upvector, 0, 0 - camera.rotation, 0);
5131 
5132     float ori[6];
5133 
5134     ori[0] = -facing.x;
5135     ori[1] = facing.y;
5136     ori[2] = facing.z;
5137     ori[3] = -upvector.x;
5138     ori[4] = upvector.y;
5139     ori[5] = upvector.z;
5140 
5141     alListenerfv(AL_ORIENTATION, ori);
5142 
5143     if(person[0].currentanimation == throwanim
5144        || person[0].currentanimation == diveanim || paused) {
5145 
5146       MoveMouse(oldmouseloc.h, oldmouseloc.v, &mouseloc);
5147 
5148       GetMouse(&mouseloc);
5149     }
5150 
5151     oldmouseloc = mouseloc;
5152 
5153     if(score < 0)
5154       score = 0;
5155 }
5156 
Tick()5157 void Game::Tick()
5158 {
5159   GetKeys((unsigned long *)theKeyMap);
5160 
5161   if(state == MAINMENU) {
5162     MainMenuTick();
5163   } else if(state == GAME) {
5164     GameTick();
5165   }
5166 }
5167 
5168