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