1 /* KJL 14:50:53 10/13/97 -
2 *
3 * Experimental particle system
4 *
5 */
6
7 #include "3dc.h"
8 #include "inline.h"
9 #include "module.h"
10 #include "stratdef.h"
11 #include "gamedef.h"
12 #include "bh_types.h"
13 #include "dynblock.h"
14 #include "dynamics.h"
15 #include "particle.h"
16 #include "kshape.h"
17 #include "sfx.h"
18 #include "d3d_render.h"
19 #include "psndproj.h"
20 #include "lighting.h"
21 #include "bh_light.h"
22 #include "bh_xeno.h"
23 #include "pvisible.h"
24 #include "sphere.h"
25 #include "bh_rubberduck.h"
26 #include "bh_weap.h"
27 #include "weapons.h"
28 #include "decal.h"
29 #include "avpview.h"
30 #include "pldghost.h"
31 #include "detaillevels.h"
32 #include "psnd.h"
33 #include "kzsort.h"
34 #include "avp_userprofile.h"
35 #define UseLocalAssert Yes
36 #include "ourasert.h"
37 #include "savegame.h"
38 #include "los.h"
39 #include "chnkload.h"
40 #include "maths.h"
41
42 #include <math.h>
43
44 #define RGBALIGHT_MAKE(r,g,b,a) RGBA_MAKE(r,g,b,a)
45
46 #define MAX_NO_OF_PHEROMONE_TRAILS 500
47 #define MAX_NO_OF_PARTICLES 5000
48 #define MAX_NO_OF_EXPLOSIONS 10
49
50 #define TRAIL_DECAY_SPEED (51*65536*5)
51
52 static PHEROMONE_TRAIL TrailStorage[MAX_NO_OF_PHEROMONE_TRAILS];
53 static PARTICLE ParticleStorage[MAX_NO_OF_PARTICLES];
54 static VOLUMETRIC_EXPLOSION ExplosionStorage[MAX_NO_OF_EXPLOSIONS];
55
56 static int NumActiveTrails;
57 static int NumActiveParticles;
58 static int CurrentExplosionIndex;
59
60 extern int NormalFrameTime;
61 extern int PrevNormalFrameTime;
62 extern int CloakingPhase;
63
64 int NumberOfBloodParticles;
65 int NumberOfFlaresActive;
66
67 extern SOUND3DDATA PredPistolExplosion_SoundData;
68 extern MODULE *playerPherModule;
69
70 static void InitialiseVolumetricExplosions(void);
71 void DoFlareCorona(DISPLAYBLOCK *objectPtr);
72 void InitialiseRainDrops(void);
73 void HandleRipples(void);
74 void AddRipple(int x,int z,int amplitude);
75 void MakeMolotovExplosionAt(VECTORCH *positionPtr,int seed);
76 static void HandleVolumetricExplosion(VOLUMETRIC_EXPLOSION *expPtr);
77 void DrawXenoborgMainLaserbeam(LASER_BEAM_DESC *laserPtr);
78 void HandlePheromoneTrails(void);
79 void RenderTrailSegment(PHEROMONE_TRAIL *trailPtr);
80
81 PARTICLE_DESC ParticleDescription[MAX_NO_OF_PARTICLE_IDS] =
82 {
83 /* PARTICLE_PREDATOR_BLOOD */
84 {
85 //int StartU;
86 0<<16,
87 //int StartV;
88 64<<16,
89 //int EndU;
90 63<<16,
91 //int EndV;
92 127<<16,
93 //unsigned int Size;
94 200,
95
96 //enum TRANSLUCENCY_TYPE TranslucencyType;
97 TRANSLUCENCY_GLOWING,
98
99 //unsigned char Alpha;
100 128,
101 //unsigned char RedScale;
102 {0, 0, 255, 255, 255},
103 //unsigned char GreenScale;
104 {255, 255, 255, 255, 0},
105 //unsigned char BlueScale;
106 {0, 0, 255, 255, 0},
107
108 //unsigned char IsLit:1;
109 0,
110 //IsDrawnInFront:1;
111 0,
112 //IsDrawnAtBack:1;
113 0,
114
115 },
116 /* PARTICLE_ALIEN_BLOOD */
117 {
118 #if 0
119 //int StartU;
120 1<<16,
121 //int StartV;
122 248<<16,
123 //int EndU;
124 8<<16,
125 //int EndV;
126 256<<16,
127 #else
128 //int StartU;
129 0<<16,
130 //int StartV;
131 64<<16,
132 //int EndU;
133 63<<16,
134 //int EndV;
135 127<<16,
136 #endif
137 //unsigned int Size;
138 50,
139
140 //enum TRANSLUCENCY_TYPE TranslucencyType;
141 TRANSLUCENCY_GLOWING,
142
143 //unsigned char Alpha;
144 128,
145 //unsigned char RedScale;
146 {255, 255, 0, 16, 255},
147 //unsigned char GreenScale;
148 {255, 255, 255, 0, 255},
149 //unsigned char BlueScale;
150 {0, 0, 0, 255, 255},
151
152 //unsigned char IsLit:1;
153 1,
154 //IsDrawnInFront:1;
155 0,
156 //IsDrawnAtBack:1;
157 0,
158
159 },
160 /* PARTICLE_HUMAN_BLOOD */
161 {
162 //int StartU;
163 0<<16,
164 //int StartV;
165 63<<16,
166 //int EndU;
167 63<<16,
168 //int EndV;
169 127<<16,
170 //unsigned int Size;
171 50,
172
173 //enum TRANSLUCENCY_TYPE TranslucencyType;
174 TRANSLUCENCY_INVCOLOUR,
175
176 //unsigned char Alpha;
177 255,
178 //unsigned char RedScale;
179 {0, 0, 0, 0 , 0},
180 //unsigned char GreenScale;
181 {255, 255, 64, 64, 255},
182 //unsigned char BlueScale;
183 {255, 255, 0, 64, 255},
184
185 //unsigned char IsLit:1;
186 0,
187 //IsDrawnInFront:1;
188 0,
189 //IsDrawnAtBack:1;
190 0,
191 },
192 /* PARTICLE_ANDROID_BLOOD */
193 {
194 //int StartU;
195 0<<16,
196 //int StartV;
197 63<<16,
198 //int EndU;
199 63<<16,
200 //int EndV;
201 127<<16,
202 //unsigned int Size;
203 50,
204
205 //enum TRANSLUCENCY_TYPE TranslucencyType;
206 TRANSLUCENCY_GLOWING,
207
208 //unsigned char Alpha;
209 255,
210 //unsigned char RedScale;
211 {255, 255, 255, 255, 255},
212 //unsigned char GreenScale;
213 {255, 255, 255, 255, 255},
214 //unsigned char BlueScale;
215 {255, 255, 255, 255, 255},
216
217 //unsigned char IsLit:1;
218 1,
219 //IsDrawnInFront:1;
220 0,
221 //IsDrawnAtBack:1;
222 0,
223 },
224 /* PARTICLE_MUZZLEFLASH */
225 {
226 //int StartU;
227 64<<16,
228 //int StartV;
229 64<<16,
230 //int EndU;
231 127<<16,
232 //int EndV;
233 127<<16,
234 //unsigned int Size;
235 200,
236
237 //enum TRANSLUCENCY_TYPE TranslucencyType;
238 TRANSLUCENCY_GLOWING,
239
240 //unsigned char Alpha;
241 255,
242 //unsigned char RedScale;
243 {255, 255, 255, 255, 255},
244 //unsigned char GreenScale;
245 {192, 255, 255, 0 , 255},
246 //unsigned char BlueScale;
247 {128, 255, 255, 0 , 0},
248
249 //unsigned char IsLit:1;
250 0,
251 //IsDrawnInFront:1;
252 0,
253 //IsDrawnAtBack:1;
254 0,
255 },
256 /* PARTICLE_SMARTGUNMUZZLEFLASH */
257 {
258 //int StartU;
259 64<<16,
260 //int StartV;
261 0<<16,
262 //int EndU;
263 127<<16,
264 //int EndV;
265 63<<16,
266 //unsigned int Size;
267 800,
268
269 //enum TRANSLUCENCY_TYPE TranslucencyType;
270 TRANSLUCENCY_GLOWING,
271
272 //unsigned char Alpha;
273 255,
274 //unsigned char RedScale;
275 {255, 255, 255, 255, 255},
276 //unsigned char GreenScale;
277 {255, 255, 255, 0, 255},
278 //unsigned char BlueScale;
279 {255, 255, 255, 0, 0},
280
281 //unsigned char IsLit:1;
282 0,
283 //IsDrawnInFront:1;
284 0,
285 //IsDrawnAtBack:1;
286 0,
287 },
288 /* PARTICLE_WATERSPRAY */
289 {
290 //int StartU;
291 0<<16,
292 //int StartV;
293 64<<16,
294 //int EndU;
295 63<<16,
296 //int EndV;
297 127<<16,
298 //unsigned int Size;
299 80,
300
301 //enum TRANSLUCENCY_TYPE TranslucencyType;
302 TRANSLUCENCY_GLOWING,
303
304 //unsigned char Alpha;
305 64,
306 //unsigned char RedScale;
307 {200, 200, 0, 0},
308 //unsigned char GreenScale;
309 {230, 230, 240, 0},
310 //unsigned char BlueScale;
311 {255, 255, 0, 120},
312
313 //unsigned char IsLit:1;
314 1,
315 //IsDrawnInFront:1;
316 0,
317 //IsDrawnAtBack:1;
318 0,
319 },
320 /* PARTICLE_WATERFALLSPRAY */
321 {
322 //int StartU;
323 0<<16,
324 //int StartV;
325 64<<16,
326 //int EndU;
327 63<<16,
328 //int EndV;
329 127<<16,
330 //unsigned int Size;
331 1600,//200,
332
333 //enum TRANSLUCENCY_TYPE TranslucencyType;
334 TRANSLUCENCY_GLOWING,
335
336 //unsigned char Alpha;
337 32,
338 //unsigned char RedScale;
339 {100, 200, 240, 120, 120, 120},
340 //unsigned char GreenScale;
341 {130, 230, 240, 120, 120, 120},
342 //unsigned char BlueScale;
343 {255, 255, 240, 120, 120, 120},
344
345 //unsigned char IsLit:1;
346 0,
347 //IsDrawnInFront:1;
348 0,
349 //IsDrawnAtBack:1;
350 0,
351 },
352 /* PARTICLE_BLACKSMOKE */
353 {
354 //int StartU;
355 0<<16,
356 //int StartV;
357 130<<16,
358 //int EndU;
359 28<<16,
360 //int EndV;
361 157<<16,
362 //unsigned int Size;
363 200,
364
365 //enum TRANSLUCENCY_TYPE TranslucencyType;
366 TRANSLUCENCY_INVCOLOUR,
367
368 //unsigned char Alpha;
369 255,
370 //unsigned char RedScale;
371 {64, 64, 64, 64, 64},
372 //unsigned char GreenScale;
373 {64, 64, 64, 64, 64},
374 //unsigned char BlueScale;
375 {64, 64, 64, 64, 64},
376
377 //unsigned char IsLit:1;
378 0,
379 //IsDrawnInFront:1;
380 0,
381 //IsDrawnAtBack:1;
382 0,
383 },
384 /* PARTICLE_FLARESMOKE */
385 {
386 #if 0
387 //int StartU;
388 0<<16,
389 //int StartV;
390 130<<16,
391 //int EndU;
392 28<<16,
393 //int EndV;
394 157<<16,
395 #else
396 //int StartU;
397 128<<16,
398 //int StartV;
399 0<<16,
400 //int EndU;
401 195<<16,
402 //int EndV;
403 63<<16,
404 #endif
405 //unsigned int Size;
406 200,
407
408 //enum TRANSLUCENCY_TYPE TranslucencyType;
409 TRANSLUCENCY_GLOWING,
410
411 //unsigned char Alpha;
412 64,
413 //unsigned char RedScale;
414 {255, 255, 255, 255, 64},
415 //unsigned char GreenScale;
416 {255, 255, 255, 0, 64},
417 //unsigned char BlueScale;
418 {255, 255, 255, 64, 0},
419
420 //unsigned char IsLit:1;
421 0,
422 //IsDrawnInFront:1;
423 0,
424 //IsDrawnAtBack:1;
425 0,
426 },
427 /* PARTICLE_STEAM */
428 {
429 //int StartU;
430 0<<16,
431 //int StartV;
432 130<<16,
433 //int EndU;
434 28<<16,
435 //int EndV;
436 157<<16,
437 //unsigned int Size;
438 100,
439
440 //enum TRANSLUCENCY_TYPE TranslucencyType;
441 TRANSLUCENCY_GLOWING,
442
443 //unsigned char Alpha;
444 64,
445 //unsigned char RedScale;
446 {128, 128, 128, 128, 64},
447 //unsigned char GreenScale;
448 {128, 128, 128, 128, 64},
449 //unsigned char BlueScale;
450 {128, 128, 128, 128, 0},
451
452 //unsigned char IsLit:1;
453 0,
454 //IsDrawnInFront:1;
455 0,
456 //IsDrawnAtBack:1;
457 0,
458 },
459 /* PARTICLE_IMPACTSMOKE */
460 {
461 //int StartU;
462 0<<16,
463 //int StartV;
464 130<<16,
465 //int EndU;
466 28<<16,
467 //int EndV;
468 157<<16,
469 //unsigned int Size;
470 100,
471
472 //enum TRANSLUCENCY_TYPE TranslucencyType;
473 TRANSLUCENCY_INVCOLOUR,
474
475 //unsigned char Alpha;
476 255,
477 //unsigned char RedScale;
478 {64, 64, 64, 64, 64},
479 //unsigned char GreenScale;
480 {64, 64, 64, 64, 64},
481 //unsigned char BlueScale;
482 {64, 64, 64, 64, 64},
483
484 //unsigned char IsLit:1;
485 0,
486 //IsDrawnInFront:1;
487 0,
488 //IsDrawnAtBack:1;
489 0,
490 },
491 /* PARTICLE_GUNMUZZLE_SMOKE */
492 {
493 //int StartU;
494 128<<16,
495 //int StartV;
496 0<<16,
497 //int EndU;
498 195<<16,
499 //int EndV;
500 63<<16,
501 //unsigned int Size;
502 32,
503
504 //enum TRANSLUCENCY_TYPE TranslucencyType;
505 TRANSLUCENCY_GLOWING,
506
507 //unsigned char Alpha;
508 64,
509 //unsigned char RedScale;
510 {255, 255, 255, 255, 64},
511 //unsigned char GreenScale;
512 {255, 255, 255, 0, 64},
513 //unsigned char BlueScale;
514 {255, 255, 255, 64, 0},
515
516 //unsigned char IsLit:1;
517 1,
518 //IsDrawnInFront:1;
519 0,
520 //IsDrawnAtBack:1;
521 0,
522 },
523 /* PARTICLE_FLAME */
524 {
525 #if 0
526 //int StartU;
527 0<<16,
528 //int StartV;
529 0<<16,
530 //int EndU;
531 63<<16,
532 //int EndV;
533 63<<16,
534 #else
535 //int StartU;
536 64<<16,
537 //int StartV;
538 0<<16,
539 //int EndU;
540 (64+127)<<16,
541 //int EndV;
542 63<<16,
543 #endif
544 //unsigned int Size;
545 0,
546
547 //enum TRANSLUCENCY_TYPE TranslucencyType;
548 TRANSLUCENCY_GLOWING,
549
550 //unsigned char Alpha;
551 64,
552 //unsigned char RedScale;
553 {255, 255, 255, 128, 128, 0},
554 //unsigned char GreenScale;
555 {128, 128, 255, 64, 64, 128},
556 //unsigned char BlueScale;
557 {64, 64, 255, 255, 0, 0},
558
559 //unsigned char IsLit:1;
560 0,
561 //IsDrawnInFront:1;
562 0,
563 //IsDrawnAtBack:1;
564 0,
565 },
566 /* PARTICLE_NONCOLLIDINGFLAME */
567 {
568 #if 0
569 //int StartU;
570 0<<16,
571 //int StartV;
572 0<<16,
573 //int EndU;
574 63<<16,
575 //int EndV;
576 63<<16,
577 #else
578 //int StartU;
579 64<<16,
580 //int StartV;
581 0<<16,
582 //int EndU;
583 (64+127)<<16,
584 //int EndV;
585 63<<16,
586 #endif
587 //unsigned int Size;
588 0,
589
590 //enum TRANSLUCENCY_TYPE TranslucencyType;
591 TRANSLUCENCY_GLOWING,
592
593 //unsigned char Alpha;
594 64,
595 //unsigned char RedScale;
596 {255, 255, 255, 128, 128, 0},
597 //unsigned char GreenScale;
598 {128, 128, 255, 64, 64, 128},
599 //unsigned char BlueScale;
600 {64, 64, 255, 255, 0, 0},
601
602 //unsigned char IsLit:1;
603 0,
604 //IsDrawnInFront:1;
605 0,
606 //IsDrawnAtBack:1;
607 0,
608 },
609 /* PARTICLE_NONDAMAGINGFLAME */
610 {
611 #if 0
612 //int StartU;
613 0<<16,
614 //int StartV;
615 0<<16,
616 //int EndU;
617 63<<16,
618 //int EndV;
619 63<<16,
620 #else
621 //int StartU;
622 64<<16,
623 //int StartV;
624 0<<16,
625 //int EndU;
626 (64+127)<<16,
627 //int EndV;
628 63<<16,
629 #endif
630 //unsigned int Size;
631 0,
632
633 //enum TRANSLUCENCY_TYPE TranslucencyType;
634 TRANSLUCENCY_GLOWING,
635
636 //unsigned char Alpha;
637 64,
638 //unsigned char RedScale;
639 {255, 255, 255, 128, 128, 0},
640 //unsigned char GreenScale;
641 {128, 128, 255, 64, 64, 128},
642 //unsigned char BlueScale;
643 {64, 64, 255, 255, 0, 0},
644
645 //unsigned char IsLit:1;
646 0,
647 //IsDrawnInFront:1;
648 0,
649 //IsDrawnAtBack:1;
650 0,
651 },
652 /* PARTICLE_FIRE */
653 {
654 #if 1
655 //int StartU;
656 0<<16,
657 //int StartV;
658 0<<16,
659 //int EndU;
660 63<<16,
661 //int EndV;
662 63<<16,
663 #else
664 //int StartU;
665 64<<16,
666 //int StartV;
667 0<<16,
668 //int EndU;
669 (64+127)<<16,
670 //int EndV;
671 63<<16,
672 #endif
673
674 //unsigned int Size;
675 0,
676
677 //enum TRANSLUCENCY_TYPE TranslucencyType;
678 TRANSLUCENCY_GLOWING,
679
680 //unsigned char Alpha;
681 64,
682 //unsigned char RedScale;
683 {255, 255, 255, 128, 128, 0},
684 //unsigned char GreenScale;
685 {128, 128, 255, 64, 64, 128},
686 //unsigned char BlueScale;
687 {64, 64, 255, 255, 0, 0},
688
689 //unsigned char IsLit:1;
690 0,
691 //IsDrawnInFront:1;
692 0,
693 //IsDrawnAtBack:1;
694 0,
695 },
696 /* PARTICLE_EXPLOSIONFIRE */
697 {
698 #if 0
699 //int StartU;
700 128<<16,
701 //int StartV;
702 0<<16,
703 //int EndU;
704 192<<16,
705 //int EndV;
706 63<<16,
707 #else
708 //int StartU;
709 0<<16,
710 //int StartV;
711 0<<16,
712 //int EndU;
713 48<<16,
714 //int EndV;
715 63<<16,
716 #endif
717 //unsigned int Size;
718 800,
719
720 //enum TRANSLUCENCY_TYPE TranslucencyType;
721 TRANSLUCENCY_GLOWING,
722
723 //unsigned char Alpha;
724 255,
725 //unsigned char RedScale;
726 {255, 255, 255, 128, 128, 0},
727 //unsigned char GreenScale;
728 {128, 128, 255, 64, 64, 128},
729 //unsigned char BlueScale;
730 {64, 64, 255, 255, 0, 0},
731
732 //unsigned char IsLit:1;
733 0,
734 //IsDrawnInFront:1;
735 0,
736 //IsDrawnAtBack:1;
737 0,
738 },
739 /* PARTICLE_MOLOTOVFLAME */
740 {
741 //int StartU;
742 64<<16,
743 //int StartV;
744 0<<16,
745 //int EndU;
746 (64+127)<<16,
747 //int EndV;
748 63<<16,
749 //unsigned int Size;
750 800,
751
752 //enum TRANSLUCENCY_TYPE TranslucencyType;
753 TRANSLUCENCY_GLOWING,
754
755 //unsigned char Alpha;
756 255,
757 //unsigned char RedScale;
758 {255, 255, 255, 128, 128, 0},
759 //unsigned char GreenScale;
760 {128, 128, 255, 64, 64, 128},
761 //unsigned char BlueScale;
762 {64, 64, 255, 255, 0, 0},
763
764 //unsigned char IsLit:1;
765 0,
766 //IsDrawnInFront:1;
767 0,
768 //IsDrawnAtBack:1;
769 0,
770 },
771 /* PARTICLE_MOLOTOVFLAME_NONDAMAGING */
772 {
773 //int StartU;
774 64<<16,
775 //int StartV;
776 0<<16,
777 //int EndU;
778 (64+127)<<16,
779 //int EndV;
780 63<<16,
781 //unsigned int Size;
782 800,
783
784 //enum TRANSLUCENCY_TYPE TranslucencyType;
785 TRANSLUCENCY_GLOWING,
786
787 //unsigned char Alpha;
788 255,
789 //unsigned char RedScale;
790 {255, 255, 255, 128, 128, 0},
791 //unsigned char GreenScale;
792 {128, 128, 255, 64, 64, 128},
793 //unsigned char BlueScale;
794 {64, 64, 255, 255, 0, 0},
795
796 //unsigned char IsLit:1;
797 0,
798 //IsDrawnInFront:1;
799 0,
800 //IsDrawnAtBack:1;
801 0,
802 },
803 /* PARTICLE_SPARK */
804 {
805 //int StartU;
806 1<<16,
807 //int StartV;
808 1<<16,
809 //int EndU;
810 64<<16,
811 //int EndV;
812 64<<16,
813 //unsigned int Size;
814 200/8,
815
816 //enum TRANSLUCENCY_TYPE TranslucencyType;
817 TRANSLUCENCY_GLOWING,
818
819 //unsigned char Alpha;
820 64,
821 //unsigned char RedScale;
822 {255, 255, 255, 255, 255},
823 //unsigned char GreenScale;
824 {128, 128, 255, 0, 255},
825 //unsigned char BlueScale;
826 {64, 64, 255, 0, 0},
827
828 //unsigned char IsLit:1;
829 0,
830 //IsDrawnInFront:1;
831 0,
832 //IsDrawnAtBack:1;
833 0,
834 },
835 /* PARTICLE_RICOCHET_SPARK */
836 {
837 //int StartU;
838 1<<16,
839 //int StartV;
840 1<<16,
841 //int EndU;
842 64<<16,
843 //int EndV;
844 64<<16,
845 //unsigned int Size;
846 200/8,
847
848 //enum TRANSLUCENCY_TYPE TranslucencyType;
849 TRANSLUCENCY_GLOWING,
850
851 //unsigned char Alpha;
852 64,
853 //unsigned char RedScale;
854 {255, 255, 255, 255, 255},
855 //unsigned char GreenScale;
856 {128, 128, 255, 0, 255},
857 //unsigned char BlueScale;
858 {64, 64, 255, 0, 255},
859
860 //unsigned char IsLit:1;
861 0,
862 //IsDrawnInFront:1;
863 0,
864 //IsDrawnAtBack:1;
865 0,
866 },
867 /* PARTICLE_ORANGE_SPARK */
868 {
869 //int StartU;
870 224<<16,
871 //int StartV;
872 192<<16,
873 //int EndU;
874 255<<16,
875 //int EndV;
876 223<<16,
877 //unsigned int Size;
878 50,
879
880 //enum TRANSLUCENCY_TYPE TranslucencyType;
881 TRANSLUCENCY_GLOWING,
882
883 //unsigned char Alpha;
884 255,
885 //unsigned char RedScale;
886 {255, 64, 64, 64, 64},
887 //unsigned char GreenScale;
888 {255, 64, 64, 64, 64},
889 //unsigned char BlueScale;
890 {255, 64, 64, 64, 64},
891
892 //unsigned char IsLit:1;
893 0,
894 //IsDrawnInFront:1;
895 0,
896 //IsDrawnAtBack:1;
897 0,
898 },
899 /* PARTICLE_ORANGE_PLASMA */
900 {
901 //int StartU;
902 224<<16,
903 //int StartV;
904 192<<16,
905 //int EndU;
906 255<<16,
907 //int EndV;
908 223<<16,
909 //unsigned int Size;
910 50,
911
912 //enum TRANSLUCENCY_TYPE TranslucencyType;
913 TRANSLUCENCY_GLOWING,
914
915 //unsigned char Alpha;
916 255,
917 //unsigned char RedScale;
918 {255, 64, 64, 64, 64, 0},
919 //unsigned char GreenScale;
920 {255, 64, 64, 64, 64, 64},
921 //unsigned char BlueScale;
922 {255, 64, 64, 64, 64, 0},
923
924 //unsigned char IsLit:1;
925 0,
926 //IsDrawnInFront:1;
927 0,
928 //IsDrawnAtBack:1;
929 0,
930 },
931
932 /* PARTICLE_PLASMATRAIL */
933 {
934 //int StartU;
935 64<<16,
936 //int StartV;
937 64<<16,
938 //int EndU;
939 127<<16,
940 //int EndV;
941 127<<16,
942 //unsigned int Size;
943 200/4,
944
945 //enum TRANSLUCENCY_TYPE TranslucencyType;
946 TRANSLUCENCY_GLOWING,
947
948 //unsigned char Alpha;
949 64,
950 //unsigned char RedScale;
951 {255, 255, 255, 255, 255, 0},
952 //unsigned char GreenScale;
953 {128, 128, 255, 0, 255, 255},
954 //unsigned char BlueScale;
955 {64, 64, 255, 0, 0, 0},
956
957 //unsigned char IsLit:1;
958 0,
959 //IsDrawnInFront:1;
960 0,
961 //IsDrawnAtBack:1;
962 0,
963 },
964 /* PARTICLE_LASERBEAM */
965 {
966 //int StartU;
967 32<<16,
968 //int StartV;
969 0<<16,
970 //int EndU;
971 32<<16,
972 //int EndV;
973 63<<16,
974 //unsigned int Size;
975 50,
976
977 //enum TRANSLUCENCY_TYPE TranslucencyType;
978 TRANSLUCENCY_GLOWING,
979
980 //unsigned char Alpha;
981 64,
982 //unsigned char RedScale;
983 {255, 255, 255, 255, 255, 0},
984 //unsigned char GreenScale;
985 {128, 128, 255, 0, 255, 255},
986 //unsigned char BlueScale;
987 {64, 64, 255, 0, 0, 0},
988
989 //unsigned char IsLit:1;
990 0,
991 //IsDrawnInFront:1;
992 0,
993 //IsDrawnAtBack:1;
994 0,
995 },
996 /* PARTICLE_PLASMABEAM */
997 {
998 //int StartU;
999 192<<16,
1000 //int StartV;
1001 224<<16,
1002 //int EndU;
1003 223<<16,
1004 //int EndV;
1005 255<<16,
1006 //unsigned int Size;
1007 50,
1008
1009 //enum TRANSLUCENCY_TYPE TranslucencyType;
1010 TRANSLUCENCY_GLOWING,
1011
1012 //unsigned char Alpha;
1013 64,
1014 //unsigned char RedScale;
1015 {255, 255, 255, 255, 255, 0},
1016 //unsigned char GreenScale;
1017 {128, 128, 255, 0, 255, 255},
1018 //unsigned char BlueScale;
1019 {64, 64, 255, 0, 0, 0},
1020
1021 //unsigned char IsLit:1;
1022 0,
1023 //IsDrawnInFront:1;
1024 0,
1025 //IsDrawnAtBack:1;
1026 0,
1027 },
1028 /* PARTICLE_TRACER */
1029 {
1030 //int StartU;
1031 32<<16,
1032 //int StartV;
1033 0<<16,
1034 //int EndU;
1035 32<<16,
1036 //int EndV;
1037 63<<16,
1038 //unsigned int Size;
1039 16,
1040
1041 //enum TRANSLUCENCY_TYPE TranslucencyType;
1042 TRANSLUCENCY_GLOWING,
1043
1044 //unsigned char Alpha;
1045 64,
1046 //unsigned char RedScale;
1047 {255, 255, 255, 255, 255},
1048 //unsigned char GreenScale;
1049 {255, 128, 255, 0, 255},
1050 //unsigned char BlueScale;
1051 {64, 64, 255, 0, 0},
1052
1053 //unsigned char IsLit:1;
1054 0,
1055 //IsDrawnInFront:1;
1056 0,
1057 //IsDrawnAtBack:1;
1058 0,
1059 },
1060
1061
1062
1063 /* PARTICLE_LIGHTFLARE */
1064 {
1065 //int StartU;
1066 64<<16,
1067 //int StartV;
1068 64<<16,
1069 //int EndU;
1070 127<<16,
1071 //int EndV;
1072 127<<16,
1073 //unsigned int Size;
1074 200,
1075
1076 //enum TRANSLUCENCY_TYPE TranslucencyType;
1077 TRANSLUCENCY_GLOWING,
1078
1079 //unsigned char Alpha;
1080 255,
1081 //unsigned char RedScale;
1082 {255, 255, 255, 255, 255, 0},
1083 //unsigned char GreenScale;
1084 {255, 255, 255, 0, 255, 255},
1085 //unsigned char BlueScale;
1086 {255, 255, 255, 0, 0, 0},
1087
1088 //unsigned char IsLit:1;
1089 0,
1090 //IsDrawnInFront:1;
1091 1,
1092 //IsDrawnAtBack:1;
1093 0,
1094 },
1095 /* PARTICLE_STAR */
1096 {
1097 //int StartU;
1098 64<<16,
1099 //int StartV;
1100 64<<16,
1101 //int EndU;
1102 127<<16,
1103 //int EndV;
1104 127<<16,
1105 //unsigned int Size;
1106 200,
1107
1108 //enum TRANSLUCENCY_TYPE TranslucencyType;
1109 TRANSLUCENCY_GLOWING,
1110
1111 //unsigned char Alpha;
1112 255,
1113 //unsigned char RedScale;
1114 {255, 255, 255, 255, 255, 0},
1115 //unsigned char GreenScale;
1116 {255, 255, 255, 0, 255, 255},
1117 //unsigned char BlueScale;
1118 {255, 255, 255, 0, 0, 0},
1119
1120 //unsigned char IsLit:1;
1121 0,
1122 //IsDrawnInFront:1;
1123 0,
1124 //IsDrawnAtBack:1;
1125 1,
1126 },
1127 /* PARTICLE_FLECHETTE */
1128 {
1129 //int StartU;
1130 64<<16,
1131 //int StartV;
1132 64<<16,
1133 //int EndU;
1134 127<<16,
1135 //int EndV;
1136 127<<16,
1137 //unsigned int Size;
1138 100,
1139
1140 //enum TRANSLUCENCY_TYPE TranslucencyType;
1141 TRANSLUCENCY_NORMAL,
1142
1143 //unsigned char Alpha;
1144 255,
1145 //unsigned char RedScale;
1146 {255, 255, 255, 255, 255, 0},
1147 //unsigned char GreenScale;
1148 {255, 255, 255, 0, 255, 255},
1149 //unsigned char BlueScale;
1150 {255, 255, 255, 0, 0, 0},
1151
1152 //unsigned char IsLit:1;
1153 0,
1154 //IsDrawnInFront:1;
1155 0,
1156 //IsDrawnAtBack:1;
1157 0,
1158 },
1159 /* PARTICLE_SMOKECLOUD */
1160 {
1161 //int StartU;
1162 128<<16,
1163 //int StartV;
1164 64<<16,
1165 //int EndU;
1166 191<<16,
1167 //int EndV;
1168 127<<16,
1169 //unsigned int Size;
1170 1000,
1171
1172 //enum TRANSLUCENCY_TYPE TranslucencyType;
1173 TRANSLUCENCY_GLOWING,
1174
1175 //unsigned char Alpha;
1176 255,
1177 //unsigned char RedScale;
1178 {128, 64, 64, 64, 0},
1179 //unsigned char GreenScale;
1180 {128, 64, 64, 64, 64},
1181 //unsigned char BlueScale;
1182 {128, 64, 64, 64, 0},
1183
1184 //unsigned char IsLit:1;
1185 1,
1186 //IsDrawnInFront:1;
1187 0,
1188 //IsDrawnAtBack:1;
1189 0,
1190 },
1191 /* PARTICLE_BLUEPLASMASPHERE */
1192 {
1193 //int StartU;
1194 224<<16,
1195 //int StartV;
1196 160<<16,
1197 //int EndU;
1198 255<<16,
1199 //int EndV;
1200 191<<16,
1201 //unsigned int Size;
1202 500,
1203
1204 //enum TRANSLUCENCY_TYPE TranslucencyType;
1205 TRANSLUCENCY_GLOWING,
1206
1207 //unsigned char Alpha;
1208 255,
1209 //unsigned char RedScale;
1210 {255, 64, 64, 64, 64, 0},
1211 //unsigned char GreenScale;
1212 {255, 64, 64, 64, 64, 255},
1213 //unsigned char BlueScale;
1214 {255, 64, 64, 64, 0, 0},
1215
1216 //unsigned char IsLit:1;
1217 0,
1218 //IsDrawnInFront:1;
1219 0,
1220 //IsDrawnAtBack:1;
1221 0,
1222 },
1223 /* PARTICLE_ELECTRICALPLASMASPHERE */
1224 {
1225 //int StartU;
1226 64<<16,
1227 //int StartV;
1228 128<<16,
1229 //int EndU;
1230 127<<16,
1231 //int EndV;
1232 191<<16,
1233 //unsigned int Size;
1234 2000,
1235
1236 //enum TRANSLUCENCY_TYPE TranslucencyType;
1237 TRANSLUCENCY_GLOWING,
1238
1239 //unsigned char Alpha;
1240 255,
1241 //unsigned char RedScale;
1242 {255, 64, 64, 64, 64, 0},
1243 //unsigned char GreenScale;
1244 {255, 64, 64, 64, 64, 255},
1245 //unsigned char BlueScale;
1246 {255, 64, 64, 64, 0, 0},
1247
1248 //unsigned char IsLit:1;
1249 0,
1250 //IsDrawnInFront:1;
1251 0,
1252 //IsDrawnAtBack:1;
1253 0,
1254 },
1255 /* PARTICLE_PREDPISTOL_FLECHETTE */
1256 {
1257 //int StartU;
1258 1<<16,
1259 //int StartV;
1260 1<<16,
1261 //int EndU;
1262 64<<16,
1263 //int EndV;
1264 64<<16,
1265 //unsigned int Size;
1266 200/8,
1267
1268 //enum TRANSLUCENCY_TYPE TranslucencyType;
1269 TRANSLUCENCY_GLOWING,
1270
1271 //unsigned char Alpha;
1272 64,
1273 //unsigned char RedScale;
1274 {255, 255, 255, 255, 255, 0},
1275 //unsigned char GreenScale;
1276 {128, 128, 255, 0, 255, 255},
1277 //unsigned char BlueScale;
1278 {64, 64, 255, 0, 0, 0},
1279
1280 //unsigned char IsLit:1;
1281 0,
1282 //IsDrawnInFront:1;
1283 0,
1284 //IsDrawnAtBack:1;
1285 0,
1286 },
1287 /* PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING */
1288 {
1289 //int StartU;
1290 1<<16,
1291 //int StartV;
1292 1<<16,
1293 //int EndU;
1294 64<<16,
1295 //int EndV;
1296 64<<16,
1297 //unsigned int Size;
1298 200/8,
1299
1300 //enum TRANSLUCENCY_TYPE TranslucencyType;
1301 TRANSLUCENCY_GLOWING,
1302
1303 //unsigned char Alpha;
1304 64,
1305 //unsigned char RedScale;
1306 {255, 255, 255, 255, 255, 0},
1307 //unsigned char GreenScale;
1308 {128, 128, 255, 0, 255, 255},
1309 //unsigned char BlueScale;
1310 {64, 64, 255, 0, 0, 0},
1311
1312 //unsigned char IsLit:1;
1313 0,
1314 //IsDrawnInFront:1;
1315 0,
1316 //IsDrawnAtBack:1;
1317 0,
1318 },
1319 /* PARTICLE_FLECHETTE_NONDAMAGING */
1320 {
1321 //int StartU;
1322 64<<16,
1323 //int StartV;
1324 64<<16,
1325 //int EndU;
1326 127<<16,
1327 //int EndV;
1328 127<<16,
1329 //unsigned int Size;
1330 100,
1331
1332 //enum TRANSLUCENCY_TYPE TranslucencyType;
1333 TRANSLUCENCY_NORMAL,
1334
1335 //unsigned char Alpha;
1336 255,
1337 //unsigned char RedScale;
1338 {255, 255, 255, 255, 255, 0},
1339 //unsigned char GreenScale;
1340 {255, 255, 255, 0, 255, 255},
1341 //unsigned char BlueScale;
1342 {255, 255, 255, 0, 0, 0},
1343
1344 //unsigned char IsLit:1;
1345 0,
1346 //IsDrawnInFront:1;
1347 0,
1348 //IsDrawnAtBack:1;
1349 0,
1350 },
1351 /* PARTICLE_DEWLINE */
1352 {
1353 //int StartU;
1354 64<<16,
1355 //int StartV;
1356 64<<16,
1357 //int EndU;
1358 127<<16,
1359 //int EndV;
1360 127<<16,
1361 //unsigned int Size;
1362 200/4,
1363
1364 //enum TRANSLUCENCY_TYPE TranslucencyType;
1365 TRANSLUCENCY_GLOWING,
1366
1367 //unsigned char Alpha;
1368 64,
1369 //unsigned char RedScale;
1370 {255, 255, 255, 255, 255, 0},
1371 //unsigned char GreenScale;
1372 {128, 128, 255, 0, 255, 255},
1373 //unsigned char BlueScale;
1374 {64, 64, 255, 0, 0, 0},
1375
1376 //unsigned char IsLit:1;
1377 0,
1378 //IsDrawnInFront:1;
1379 0,
1380 //IsDrawnAtBack:1;
1381 0,
1382 },
1383 /* PARTICLE_PARGEN_FLAME */
1384 {
1385 //int StartU;
1386 64<<16,
1387 //int StartV;
1388 0<<16,
1389 //int EndU;
1390 (64+127)<<16,
1391 //int EndV;
1392 63<<16,
1393 //unsigned int Size;
1394 0,
1395
1396 //enum TRANSLUCENCY_TYPE TranslucencyType;
1397 TRANSLUCENCY_GLOWING,
1398
1399 //unsigned char Alpha;
1400 64,
1401 //unsigned char RedScale;
1402 {255, 255, 255, 128, 128, 0},
1403 //unsigned char GreenScale;
1404 {128, 128, 255, 64, 64, 128},
1405 //unsigned char BlueScale;
1406 {64, 64, 255, 255, 0, 0},
1407
1408 //unsigned char IsLit:1;
1409 0,
1410 //IsDrawnInFront:1;
1411 0,
1412 //IsDrawnAtBack:1;
1413 0,
1414 },
1415
1416 };
1417
1418
1419 static PARTICLE* AllocateParticle(void);
1420 static void DeallocateParticle(PARTICLE *particlePtr);
1421 static PHEROMONE_TRAIL* AllocatePheromoneTrail(void);
1422 static void DeallocatePheromoneTrail(PHEROMONE_TRAIL *trailPtr);
1423
1424
1425
1426
InitialiseParticleSystem(void)1427 void InitialiseParticleSystem(void)
1428 {
1429 NumActiveParticles = 0;
1430 NumberOfBloodParticles = 0;
1431
1432 NumActiveTrails = 0;
1433
1434 InitialiseVolumetricExplosions();
1435 InitialiseRainDrops();
1436 InitialiseDecalSystem();
1437 InitForceField();
1438 Generate_Sphere();
1439
1440 {
1441 NumberOfFlaresActive=0;
1442 }
1443 }
1444
AllocateParticle(void)1445 static PARTICLE* AllocateParticle(void)
1446 {
1447 PARTICLE *particlePtr = 0; /* Default to null ptr */
1448
1449 if (NumActiveParticles != MAX_NO_OF_PARTICLES)
1450 {
1451 particlePtr = &ParticleStorage[NumActiveParticles];
1452 NumActiveParticles++;
1453 }
1454 else
1455 {
1456 /* unable to allocate a particle */
1457 }
1458
1459 return particlePtr;
1460 }
DeallocateParticle(PARTICLE * particlePtr)1461 static void DeallocateParticle(PARTICLE *particlePtr)
1462 {
1463 /* is pointer within array? */
1464 LOCALASSERT(particlePtr>=ParticleStorage);
1465 LOCALASSERT(particlePtr<=&ParticleStorage[MAX_NO_OF_PARTICLES-1]);
1466
1467 NumActiveParticles--;
1468 *particlePtr = ParticleStorage[NumActiveParticles];
1469 }
1470
AllocatePheromoneTrail(void)1471 static PHEROMONE_TRAIL* AllocatePheromoneTrail(void)
1472 {
1473 PHEROMONE_TRAIL *trailPtr = 0; /* Default to null ptr */
1474
1475 if (NumActiveTrails != MAX_NO_OF_PHEROMONE_TRAILS)
1476 {
1477 trailPtr = &TrailStorage[NumActiveTrails];
1478 NumActiveTrails++;
1479 }
1480 else
1481 {
1482 /* unable to allocate a trail */
1483 }
1484
1485 return trailPtr;
1486 }
DeallocatePheromoneTrail(PHEROMONE_TRAIL * trailPtr)1487 static void DeallocatePheromoneTrail(PHEROMONE_TRAIL *trailPtr)
1488 {
1489 /* is pointer within array? */
1490 LOCALASSERT(trailPtr>=TrailStorage);
1491 LOCALASSERT(trailPtr<=&TrailStorage[MAX_NO_OF_PHEROMONE_TRAILS-1]);
1492
1493 NumActiveTrails--;
1494 *trailPtr = TrailStorage[NumActiveTrails];
1495 }
1496
InitialiseVolumetricExplosions(void)1497 static void InitialiseVolumetricExplosions(void)
1498 {
1499 int i;
1500 for(i=0; i<MAX_NO_OF_EXPLOSIONS; i++)
1501 {
1502 ExplosionStorage[i].LifeTime = 0;
1503 }
1504 CurrentExplosionIndex = 0;
1505 }
AllocateVolumetricExplosion(void)1506 static VOLUMETRIC_EXPLOSION* AllocateVolumetricExplosion(void)
1507 {
1508 VOLUMETRIC_EXPLOSION *explosionPtr = 0; /* Default to null ptr */
1509
1510 explosionPtr = &ExplosionStorage[CurrentExplosionIndex];
1511
1512 CurrentExplosionIndex++;
1513 if (CurrentExplosionIndex>=MAX_NO_OF_EXPLOSIONS)
1514 {
1515 CurrentExplosionIndex=0;
1516 }
1517
1518 LOCALASSERT(explosionPtr);
1519 return explosionPtr;
1520 }
1521
1522
MakeParticle(VECTORCH * positionPtr,VECTORCH * velocityPtr,enum PARTICLE_ID particleID)1523 void MakeParticle(VECTORCH *positionPtr, VECTORCH *velocityPtr, enum PARTICLE_ID particleID)
1524 {
1525 PARTICLE *particlePtr;
1526
1527 if( (particleID == PARTICLE_ALIEN_BLOOD) || (particleID == PARTICLE_PREDATOR_BLOOD) || (particleID == PARTICLE_HUMAN_BLOOD)|| (particleID == PARTICLE_ANDROID_BLOOD))
1528 if (NumberOfBloodParticles>MAX_NO_OF_BLOOD_PARTICLES)
1529 return;
1530
1531 particlePtr = AllocateParticle();
1532 /* were we able to allocate a particle? */
1533 if (particlePtr)
1534 {
1535 PARTICLE_DESC *particleDescPtr = &ParticleDescription[particleID];
1536 particlePtr->Position = *positionPtr;
1537 particlePtr->Velocity = *velocityPtr;
1538
1539 particlePtr->ParticleID = particleID;
1540
1541 particlePtr->Colour = RGBALIGHT_MAKE
1542 (
1543 particleDescPtr->RedScale[CurrentVisionMode],
1544 particleDescPtr->GreenScale[CurrentVisionMode],
1545 particleDescPtr->BlueScale[CurrentVisionMode],
1546 particleDescPtr->Alpha
1547 );
1548 particlePtr->Size = particleDescPtr->Size;
1549
1550 switch(particlePtr->ParticleID)
1551 {
1552 case PARTICLE_PREDATOR_BLOOD:
1553 case PARTICLE_ALIEN_BLOOD:
1554 case PARTICLE_HUMAN_BLOOD:
1555 case PARTICLE_ANDROID_BLOOD:
1556 {
1557 particlePtr->Offset = particlePtr->Position;
1558 particlePtr->LifeTime = ONE_FIXED;
1559 NumberOfBloodParticles++;
1560 break;
1561 }
1562 case PARTICLE_BLACKSMOKE:
1563 {
1564 particlePtr->LifeTime = ONE_FIXED+(FastRandom()&32767);
1565 particlePtr->Offset.vx = ((FastRandom()&1023) - 512)*2;
1566 particlePtr->Offset.vz = ((FastRandom()&1023) - 512)*2;
1567 break;
1568 }
1569 case PARTICLE_WATERSPRAY:
1570 {
1571 particlePtr->LifeTime = ONE_FIXED/2;
1572 break;
1573 }
1574 case PARTICLE_WATERFALLSPRAY:
1575 {
1576 particlePtr->LifeTime = ONE_FIXED*10;
1577 break;
1578 }
1579
1580 case PARTICLE_FLARESMOKE:
1581 case PARTICLE_STEAM:
1582 {
1583 particlePtr->LifeTime = (ONE_FIXED*1)/2+(FastRandom()&32767);
1584 particlePtr->Offset.vx = ((FastRandom()&8191) - 4096);
1585 particlePtr->Offset.vz = ((FastRandom()&8191) - 4096);
1586 break;
1587 }
1588 case PARTICLE_IMPACTSMOKE:
1589 {
1590 particlePtr->LifeTime = ONE_FIXED+(FastRandom()&32767);
1591 particlePtr->Offset.vx = ((FastRandom()&1023) - 512)*2;
1592 particlePtr->Offset.vz = ((FastRandom()&1023) - 512)*2;
1593 break;
1594 }
1595 case PARTICLE_GUNMUZZLE_SMOKE:
1596 {
1597 particlePtr->LifeTime = ONE_FIXED/2+(FastRandom()&32767);
1598 particlePtr->Offset.vx = ((FastRandom()&1023) - 512);
1599 particlePtr->Offset.vz = ((FastRandom()&1023) - 512);
1600 break;
1601 }
1602
1603 case PARTICLE_SPARK:
1604 {
1605 particlePtr->LifeTime = ONE_FIXED;
1606 break;
1607 }
1608 case PARTICLE_RICOCHET_SPARK:
1609 case PARTICLE_ORANGE_SPARK:
1610 {
1611 particlePtr->LifeTime = ONE_FIXED/4;
1612 break;
1613 }
1614
1615 case PARTICLE_ORANGE_PLASMA:
1616 {
1617 particlePtr->LifeTime = ONE_FIXED/8;
1618 break;
1619 }
1620
1621 case PARTICLE_PLASMATRAIL:
1622 {
1623 particlePtr->LifeTime = ONE_FIXED/2;
1624 particlePtr->Offset=particlePtr->Position;
1625 break;
1626 }
1627 case PARTICLE_DEWLINE:
1628 {
1629 particlePtr->LifeTime = ONE_FIXED; // /2
1630 particlePtr->Offset=particlePtr->Position;
1631 break;
1632 }
1633
1634 case PARTICLE_FLAME:
1635 case PARTICLE_NONCOLLIDINGFLAME:
1636 case PARTICLE_NONDAMAGINGFLAME:
1637 case PARTICLE_PARGEN_FLAME:
1638 {
1639 particlePtr->Offset.vx = (FastRandom()&4095);
1640 particlePtr->Offset.vy = ((FastRandom()&32767) - 16384);
1641
1642 particlePtr->LifeTime = ONE_FIXED/2;
1643 break;
1644 }
1645 case PARTICLE_FIRE:
1646 {
1647 particlePtr->LifeTime = ONE_FIXED/2+(FastRandom()&16383);
1648 break;
1649 }
1650 case PARTICLE_EXPLOSIONFIRE:
1651 {
1652 particlePtr->LifeTime = ONE_FIXED/4;
1653 particlePtr->Offset = particlePtr->Position;
1654 // particlePtr->Position.vx += particlePtr->Velocity.vx;
1655 // particlePtr->Position.vy += particlePtr->Velocity.vy;
1656 // particlePtr->Position.vz += particlePtr->Velocity.vz;
1657 break;
1658 }
1659 case PARTICLE_MOLOTOVFLAME:
1660 {
1661 particlePtr->LifeTime = ONE_FIXED*2-(FastRandom()&32767);
1662 break;
1663 }
1664
1665 case PARTICLE_FLECHETTE:
1666 case PARTICLE_FLECHETTE_NONDAMAGING:
1667 {
1668 particlePtr->LifeTime = ONE_FIXED*8;
1669 {
1670 particlePtr->Offset.vy = 1;
1671 }
1672 break;
1673 }
1674
1675 case PARTICLE_SMOKECLOUD:
1676 {
1677 particlePtr->LifeTime = ONE_FIXED*16-1;
1678 particlePtr->Offset.vx = (FastRandom()&4095);
1679 particlePtr->Offset.vy = ((FastRandom()&16383) - 8192);
1680 break;
1681 }
1682 case PARTICLE_BLUEPLASMASPHERE:
1683 {
1684 particlePtr->LifeTime = 0;
1685 break;
1686 }
1687 case PARTICLE_ELECTRICALPLASMASPHERE:
1688 {
1689 particlePtr->LifeTime = 32767;
1690 break;
1691 }
1692 case PARTICLE_PREDPISTOL_FLECHETTE:
1693 case PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING:
1694 {
1695 particlePtr->LifeTime = ONE_FIXED;
1696 break;
1697 }
1698 case PARTICLE_TRACER:
1699 {
1700 particlePtr->Position = *positionPtr;
1701 particlePtr->Offset = *velocityPtr;
1702 particlePtr->LifeTime = 0;
1703 break;
1704 }
1705
1706 default:
1707 {
1708 /* particle initialised wrongly */
1709 DeallocateParticle(particlePtr);
1710 LOCALASSERT(0);
1711 break;
1712 }
1713 }
1714
1715 }
1716 }
1717
HandleParticleSystem(void)1718 void HandleParticleSystem(void)
1719 {
1720 int i;
1721 PARTICLE *particlePtr;
1722 HandleRipples();
1723 // D3D_DrawWaterTest();
1724
1725 HandleDecalSystem();
1726 D3D_DecalSystem_End();
1727
1728
1729
1730 // textprint("Particles Active: %d\n",i);
1731 // D3D_DecalSystem_Setup();
1732 i = NumActiveParticles;
1733 particlePtr = ParticleStorage;
1734
1735 while(i--)
1736 {
1737 PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
1738
1739 particlePtr->NotYetRendered = 1;
1740 switch(particlePtr->ParticleID)
1741 {
1742 case PARTICLE_ALIEN_BLOOD:
1743 case PARTICLE_PREDATOR_BLOOD:
1744 case PARTICLE_HUMAN_BLOOD:
1745 case PARTICLE_ANDROID_BLOOD:
1746 {
1747 particlePtr->Size = 64-(FastRandom()&31);
1748 particlePtr->Offset = particlePtr->Position;
1749 particlePtr->Offset.vx += particlePtr->Velocity.vx>>4;
1750 particlePtr->Offset.vy += particlePtr->Velocity.vy>>4;
1751 particlePtr->Offset.vz += particlePtr->Velocity.vz>>4;
1752 break;
1753 }
1754 case PARTICLE_FLARESMOKE:
1755 {
1756 // particlePtr->Position.vy -= MUL_FIXED(1000+(FastRandom()&511),NormalFrameTime);
1757 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
1758
1759 if (particlePtr->Velocity.vy > -1300)
1760 particlePtr->Velocity.vy -= MUL_FIXED(4000,NormalFrameTime);
1761
1762 if (particlePtr->Velocity.vx > 0)
1763 {
1764 particlePtr->Velocity.vx -= MUL_FIXED(2000,NormalFrameTime);
1765 if (particlePtr->Velocity.vx < 0) particlePtr->Velocity.vx = 0;
1766 }
1767 else if (particlePtr->Velocity.vx < 0)
1768 {
1769 particlePtr->Velocity.vx += MUL_FIXED(2000,NormalFrameTime);
1770 if (particlePtr->Velocity.vx > 0) particlePtr->Velocity.vx = 0;
1771 }
1772
1773 if (particlePtr->Velocity.vz > 0)
1774 {
1775 particlePtr->Velocity.vz -= MUL_FIXED(2000,NormalFrameTime);
1776 if (particlePtr->Velocity.vz < 0) particlePtr->Velocity.vz = 0;
1777 }
1778 else if (particlePtr->Velocity.vz < 0)
1779 {
1780 particlePtr->Velocity.vz += MUL_FIXED(2000,NormalFrameTime);
1781 if (particlePtr->Velocity.vz > 0) particlePtr->Velocity.vz = 0;
1782 }
1783
1784
1785 particlePtr->Position.vx += MUL_FIXED
1786 (
1787 particlePtr->Velocity.vx+
1788 MUL_FIXED
1789 (
1790 -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4,
1791 particlePtr->Offset.vx
1792 ),
1793 NormalFrameTime
1794
1795 );
1796
1797 particlePtr->Position.vz += MUL_FIXED
1798 (
1799 particlePtr->Velocity.vz+
1800 MUL_FIXED
1801 (
1802 GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4,
1803 particlePtr->Offset.vz
1804 ),
1805 NormalFrameTime
1806
1807 );
1808
1809 particlePtr->Colour = RGBALIGHT_MAKE
1810 (
1811 particleDescPtr->RedScale[CurrentVisionMode],
1812 particleDescPtr->GreenScale[CurrentVisionMode],
1813 particleDescPtr->BlueScale[CurrentVisionMode],
1814 (particlePtr->LifeTime>>10)
1815 );
1816 particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime,200)+50;
1817
1818 break;
1819 }
1820 case PARTICLE_STEAM:
1821 {
1822 // particlePtr->Position.vy -= MUL_FIXED(1000+(FastRandom()&511),NormalFrameTime);
1823 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
1824
1825 if (particlePtr->Velocity.vy > -1300)
1826 particlePtr->Velocity.vy -= MUL_FIXED(4000,NormalFrameTime);
1827
1828 if (particlePtr->Velocity.vx > 0)
1829 {
1830 particlePtr->Velocity.vx -= MUL_FIXED(2000,NormalFrameTime);
1831 if (particlePtr->Velocity.vx < 0) particlePtr->Velocity.vx = 0;
1832 }
1833 else if (particlePtr->Velocity.vx < 0)
1834 {
1835 particlePtr->Velocity.vx += MUL_FIXED(2000,NormalFrameTime);
1836 if (particlePtr->Velocity.vx > 0) particlePtr->Velocity.vx = 0;
1837 }
1838
1839 if (particlePtr->Velocity.vz > 0)
1840 {
1841 particlePtr->Velocity.vz -= MUL_FIXED(2000,NormalFrameTime);
1842 if (particlePtr->Velocity.vz < 0) particlePtr->Velocity.vz = 0;
1843 }
1844 else if (particlePtr->Velocity.vz < 0)
1845 {
1846 particlePtr->Velocity.vz += MUL_FIXED(2000,NormalFrameTime);
1847 if (particlePtr->Velocity.vz > 0) particlePtr->Velocity.vz = 0;
1848 }
1849
1850
1851 particlePtr->Position.vx += MUL_FIXED
1852 (
1853 particlePtr->Velocity.vx+
1854 MUL_FIXED
1855 (
1856 -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4,
1857 particlePtr->Offset.vx
1858 ),
1859 NormalFrameTime
1860
1861 );
1862
1863 particlePtr->Position.vz += MUL_FIXED
1864 (
1865 particlePtr->Velocity.vz+
1866 MUL_FIXED
1867 (
1868 GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4,
1869 particlePtr->Offset.vz
1870 ),
1871 NormalFrameTime
1872
1873 );
1874 particlePtr->Colour = RGBALIGHT_MAKE
1875 (
1876 particleDescPtr->RedScale[CurrentVisionMode],
1877 particleDescPtr->GreenScale[CurrentVisionMode],
1878 particleDescPtr->BlueScale[CurrentVisionMode],
1879 (particlePtr->LifeTime>>14)+17
1880 );
1881 break;
1882 }
1883
1884 case PARTICLE_BLACKSMOKE:
1885 case PARTICLE_IMPACTSMOKE:
1886 {
1887 // particlePtr->Position.vy -= MUL_FIXED(1000+(FastRandom()&511),NormalFrameTime);
1888 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
1889
1890 if (particlePtr->Velocity.vy > -1300)
1891 particlePtr->Velocity.vy -= MUL_FIXED(3000,NormalFrameTime);
1892
1893 if (particlePtr->Velocity.vx > 0)
1894 {
1895 particlePtr->Velocity.vx -= MUL_FIXED(2000,NormalFrameTime);
1896 if (particlePtr->Velocity.vx < 0) particlePtr->Velocity.vx = 0;
1897 }
1898 else if (particlePtr->Velocity.vx < 0)
1899 {
1900 particlePtr->Velocity.vx += MUL_FIXED(2000,NormalFrameTime);
1901 if (particlePtr->Velocity.vx > 0) particlePtr->Velocity.vx = 0;
1902 }
1903
1904 if (particlePtr->Velocity.vz > 0)
1905 {
1906 particlePtr->Velocity.vz -= MUL_FIXED(2000,NormalFrameTime);
1907 if (particlePtr->Velocity.vz < 0) particlePtr->Velocity.vz = 0;
1908 }
1909 else if (particlePtr->Velocity.vz < 0)
1910 {
1911 particlePtr->Velocity.vz += MUL_FIXED(2000,NormalFrameTime);
1912 if (particlePtr->Velocity.vz > 0) particlePtr->Velocity.vz = 0;
1913 }
1914
1915
1916 particlePtr->Position.vx += MUL_FIXED
1917 (
1918 particlePtr->Velocity.vx+
1919 MUL_FIXED
1920 (
1921 -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4,
1922 particlePtr->Offset.vx
1923 ),
1924 NormalFrameTime
1925
1926 );
1927
1928 particlePtr->Position.vz += MUL_FIXED
1929 (
1930 particlePtr->Velocity.vz+
1931 MUL_FIXED
1932 (
1933 GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4,
1934 particlePtr->Offset.vz
1935 ),
1936 NormalFrameTime
1937
1938 );
1939
1940 {
1941 int colour = particlePtr->LifeTime>>11;
1942 particlePtr->Colour = RGBALIGHT_MAKE(colour,colour,colour,255);
1943 }
1944
1945 break;
1946 }
1947 case PARTICLE_GUNMUZZLE_SMOKE:
1948 {
1949 // particlePtr->Position.vy -= MUL_FIXED(1000+(FastRandom()&511),NormalFrameTime);
1950 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
1951 #if 1
1952 if (particlePtr->Velocity.vy > -1300)
1953 particlePtr->Velocity.vy -= MUL_FIXED(1024,NormalFrameTime);
1954
1955 if (particlePtr->Velocity.vx > 0)
1956 {
1957 particlePtr->Velocity.vx -= MUL_FIXED(1024,NormalFrameTime);
1958 if (particlePtr->Velocity.vx < 0) particlePtr->Velocity.vx = 0;
1959 }
1960 else if (particlePtr->Velocity.vx < 0)
1961 {
1962 particlePtr->Velocity.vx += MUL_FIXED(1024,NormalFrameTime);
1963 if (particlePtr->Velocity.vx > 0) particlePtr->Velocity.vx = 0;
1964 }
1965
1966 if (particlePtr->Velocity.vz > 0)
1967 {
1968 particlePtr->Velocity.vz -= MUL_FIXED(1024,NormalFrameTime);
1969 if (particlePtr->Velocity.vz < 0) particlePtr->Velocity.vz = 0;
1970 }
1971 else if (particlePtr->Velocity.vz < 0)
1972 {
1973 particlePtr->Velocity.vz += MUL_FIXED(1024,NormalFrameTime);
1974 if (particlePtr->Velocity.vz > 0) particlePtr->Velocity.vz = 0;
1975 }
1976 #endif
1977
1978 particlePtr->Position.vx += MUL_FIXED
1979 (
1980 particlePtr->Velocity.vx+
1981 MUL_FIXED
1982 (
1983 -GetSin(((particlePtr->Position.vz+particlePtr->Position.vy)*16)&4095)/4,
1984 particlePtr->Offset.vx
1985 ),
1986 NormalFrameTime
1987
1988 );
1989
1990 particlePtr->Position.vz += MUL_FIXED
1991 (
1992 particlePtr->Velocity.vz+
1993 MUL_FIXED
1994 (
1995 GetCos(((particlePtr->Position.vx+particlePtr->Position.vy)*16)&4095)/4,
1996 particlePtr->Offset.vz
1997 ),
1998 NormalFrameTime
1999
2000 );
2001
2002 particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime,48);
2003 {
2004 int colour = particlePtr->LifeTime>>11;
2005 particlePtr->Colour = RGBALIGHT_MAKE(32,32,32,colour);
2006 }
2007
2008 break;
2009 }
2010 case PARTICLE_FLAME:
2011 case PARTICLE_NONDAMAGINGFLAME:
2012 case PARTICLE_PARGEN_FLAME:
2013 {
2014 particlePtr->Size = 20+(ONE_FIXED/2-particlePtr->LifeTime)/64;
2015 if (particlePtr->LifeTime==ONE_FIXED/2)
2016 {
2017 switch (CurrentVisionMode)
2018 {
2019 default:
2020 case VISION_MODE_NORMAL:
2021 {
2022 particlePtr->Colour = RGBALIGHT_MAKE(16,16,128,(particlePtr->LifeTime>>8)|9);
2023 break;
2024 }
2025 case VISION_MODE_IMAGEINTENSIFIER:
2026 {
2027 particlePtr->Colour = RGBALIGHT_MAKE(0,32,0,(particlePtr->LifeTime>>8)|9);
2028 break;
2029 }
2030 case VISION_MODE_PRED_THERMAL:
2031 {
2032 particlePtr->Colour = RGBALIGHT_MAKE(0,0,128,(particlePtr->LifeTime>>8)|9);
2033 break;
2034 }
2035 case VISION_MODE_PRED_SEEALIENS:
2036 case VISION_MODE_PRED_SEEPREDTECH:
2037 {
2038 particlePtr->Colour = RGBALIGHT_MAKE(192,128,32,(particlePtr->LifeTime>>8)|9);
2039 break;
2040 }
2041 }
2042 }
2043 else
2044 {
2045 particlePtr->Colour = RGBALIGHT_MAKE
2046 (
2047 particleDescPtr->RedScale[CurrentVisionMode],
2048 particleDescPtr->GreenScale[CurrentVisionMode],
2049 particleDescPtr->BlueScale[CurrentVisionMode],
2050 (particlePtr->LifeTime>>8)|9
2051 );
2052 }
2053
2054
2055 break;
2056 }
2057 case PARTICLE_FIRE:
2058 {
2059 particlePtr->Size = 300-(FastRandom()&127);
2060 break;
2061 }
2062 case PARTICLE_EXPLOSIONFIRE:
2063 {
2064 VECTORCH obstacleNormal;
2065 int moduleIndex;
2066
2067 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex) && !(FastRandom()&15))
2068 {
2069 MakeDecal(DECAL_SCORCHED,&obstacleNormal,&(particlePtr->Position),moduleIndex);
2070 particlePtr->LifeTime=0;
2071 }
2072 break;
2073 }
2074 case PARTICLE_MOLOTOVFLAME:
2075 {
2076 VECTORCH obstacleNormal;
2077 int moduleIndex;
2078
2079 particlePtr->Colour = RGBALIGHT_MAKE
2080 (
2081 particleDescPtr->RedScale[CurrentVisionMode],
2082 particleDescPtr->GreenScale[CurrentVisionMode],
2083 particleDescPtr->BlueScale[CurrentVisionMode],
2084 (particlePtr->LifeTime>>10)|9
2085 );
2086
2087 particlePtr->Velocity.vy += MUL_FIXED(8000,NormalFrameTime);
2088 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))
2089 {
2090 #if 0
2091 int magOfPerpImp = DotProduct(&obstacleNormal,&(particlePtr->Velocity));
2092 particlePtr->Velocity.vx -= MUL_FIXED(obstacleNormal.vx, magOfPerpImp);
2093 particlePtr->Velocity.vy -= MUL_FIXED(obstacleNormal.vy, magOfPerpImp);
2094 particlePtr->Velocity.vz -= MUL_FIXED(obstacleNormal.vz, magOfPerpImp);
2095 #endif
2096 }
2097 particlePtr->Size = 800-(FastRandom()&255);
2098 break;
2099 }
2100
2101
2102 case PARTICLE_NONCOLLIDINGFLAME:
2103 {
2104 particlePtr->Size = 20+(ONE_FIXED/2-particlePtr->LifeTime)/64;
2105 break;
2106 }
2107 case PARTICLE_ORANGE_SPARK:
2108 {
2109 particlePtr->Offset = particlePtr->Position;
2110
2111 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2112 particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2113 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2114 particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2115 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2116 particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2117
2118 {
2119 int l = particlePtr->LifeTime*8;
2120 l = MUL_FIXED(255,l);
2121
2122 if (l>255)
2123 {
2124 switch (CurrentVisionMode)
2125 {
2126 default:
2127 case VISION_MODE_NORMAL:
2128 {
2129 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2130 break;
2131 }
2132 case VISION_MODE_IMAGEINTENSIFIER:
2133 {
2134 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2135 break;
2136 }
2137 case VISION_MODE_PRED_THERMAL:
2138 case VISION_MODE_PRED_SEEALIENS:
2139 case VISION_MODE_PRED_SEEPREDTECH:
2140 {
2141 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2142 break;
2143 }
2144 }
2145 }
2146 else
2147 {
2148 switch (CurrentVisionMode)
2149 {
2150 default:
2151 case VISION_MODE_NORMAL:
2152 {
2153 particlePtr->Colour = RGBALIGHT_MAKE(255,l,0,l);
2154 break;
2155 }
2156 case VISION_MODE_IMAGEINTENSIFIER:
2157 {
2158 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,128,l);
2159 break;
2160 }
2161 case VISION_MODE_PRED_THERMAL:
2162 case VISION_MODE_PRED_SEEALIENS:
2163 case VISION_MODE_PRED_SEEPREDTECH:
2164 {
2165 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2166 break;
2167 }
2168 }
2169 }
2170 }
2171
2172 break;
2173 }
2174 case PARTICLE_ORANGE_PLASMA:
2175 {
2176 particlePtr->Offset = particlePtr->Position;
2177
2178 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2179 particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2180 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2181 particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2182 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2183 particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2184
2185 {
2186 int l = particlePtr->LifeTime*16;
2187 l = MUL_FIXED(255,l);
2188
2189 if (l>255)
2190 {
2191 switch (CurrentVisionMode)
2192 {
2193 default:
2194 case VISION_MODE_NORMAL:
2195 {
2196 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2197 break;
2198 }
2199 case VISION_MODE_IMAGEINTENSIFIER:
2200 {
2201 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2202 break;
2203 }
2204 case VISION_MODE_PRED_THERMAL:
2205 case VISION_MODE_PRED_SEEALIENS:
2206 case VISION_MODE_PRED_SEEPREDTECH:
2207 {
2208 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2209 break;
2210 }
2211 }
2212 }
2213 else
2214 {
2215 switch (CurrentVisionMode)
2216 {
2217 default:
2218 case VISION_MODE_NORMAL:
2219 {
2220 particlePtr->Colour = RGBALIGHT_MAKE(255,l,0,l);
2221 break;
2222 }
2223 case VISION_MODE_IMAGEINTENSIFIER:
2224 {
2225 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,128,l);
2226 break;
2227 }
2228 case VISION_MODE_PRED_THERMAL:
2229 case VISION_MODE_PRED_SEEALIENS:
2230 case VISION_MODE_PRED_SEEPREDTECH:
2231 {
2232 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2233 break;
2234 }
2235 }
2236 }
2237 }
2238
2239 break;
2240 }
2241 case PARTICLE_RICOCHET_SPARK:
2242 {
2243 particlePtr->Offset = particlePtr->Position;
2244
2245 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2246 particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2247 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2248 particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2249 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2250 particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2251
2252 {
2253 int l = particlePtr->LifeTime*8;
2254 l = MUL_FIXED(255,l);
2255
2256 if (l>255)
2257 {
2258 switch (CurrentVisionMode)
2259 {
2260 default:
2261 case VISION_MODE_NORMAL:
2262 {
2263 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2264 break;
2265 }
2266 case VISION_MODE_IMAGEINTENSIFIER:
2267 {
2268 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2269 break;
2270 }
2271 case VISION_MODE_PRED_THERMAL:
2272 {
2273 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2274 break;
2275 }
2276 case VISION_MODE_PRED_SEEALIENS:
2277 case VISION_MODE_PRED_SEEPREDTECH:
2278 {
2279 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2280 break;
2281 }
2282 }
2283 }
2284 else
2285 {
2286 switch (CurrentVisionMode)
2287 {
2288 default:
2289 case VISION_MODE_NORMAL:
2290 {
2291 particlePtr->Colour = RGBALIGHT_MAKE(255,l,0,l);
2292 break;
2293 }
2294 case VISION_MODE_IMAGEINTENSIFIER:
2295 {
2296 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,128,l);
2297 break;
2298 }
2299 case VISION_MODE_PRED_THERMAL:
2300 {
2301 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2302 break;
2303 }
2304 case VISION_MODE_PRED_SEEALIENS:
2305 case VISION_MODE_PRED_SEEPREDTECH:
2306 {
2307 particlePtr->Colour = RGBALIGHT_MAKE(l,l,0,l);
2308 break;
2309 }
2310
2311 }
2312 }
2313 }
2314
2315 break;
2316 }
2317
2318 case PARTICLE_SPARK:
2319 {
2320 particlePtr->Offset = particlePtr->Position;
2321
2322 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2323 particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2324 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2325 particlePtr->Velocity.vy += MUL_FIXED(5000,NormalFrameTime);
2326 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2327 particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2328
2329 {
2330 int l = particlePtr->LifeTime*2;
2331 l = MUL_FIXED(255,l);
2332
2333 if (l>255)
2334 {
2335 switch (CurrentVisionMode)
2336 {
2337 default:
2338 case VISION_MODE_NORMAL:
2339 {
2340 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,255,255);
2341 break;
2342 }
2343 case VISION_MODE_IMAGEINTENSIFIER:
2344 {
2345 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2346 break;
2347 }
2348 case VISION_MODE_PRED_THERMAL:
2349 {
2350 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2351 break;
2352 }
2353 case VISION_MODE_PRED_SEEALIENS:
2354 case VISION_MODE_PRED_SEEPREDTECH:
2355 {
2356 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2357 break;
2358 }
2359 }
2360 }
2361 else
2362 {
2363 switch (CurrentVisionMode)
2364 {
2365 default:
2366 case VISION_MODE_NORMAL:
2367 {
2368 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l,l);
2369 break;
2370 }
2371 case VISION_MODE_IMAGEINTENSIFIER:
2372 {
2373 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,128,l);
2374 break;
2375 }
2376 case VISION_MODE_PRED_THERMAL:
2377 {
2378 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2379 break;
2380 }
2381 case VISION_MODE_PRED_SEEALIENS:
2382 case VISION_MODE_PRED_SEEPREDTECH:
2383 {
2384 particlePtr->Colour = RGBALIGHT_MAKE(l,l,0,l);
2385 break;
2386 }
2387 }
2388 }
2389 }
2390 break;
2391 }
2392
2393 case PARTICLE_DEWLINE:
2394 {
2395 int l = (particlePtr->LifeTime)/64/4;
2396 if (l>255)
2397 {
2398 switch (CurrentVisionMode)
2399 {
2400 default:
2401 case VISION_MODE_NORMAL:
2402 {
2403 particlePtr->Colour = RGBALIGHT_MAKE(255,255,255,255);
2404 break;
2405 }
2406 case VISION_MODE_IMAGEINTENSIFIER:
2407 {
2408 particlePtr->Colour = RGBALIGHT_MAKE(0,255,0,255);
2409 break;
2410 }
2411 case VISION_MODE_PRED_THERMAL:
2412 {
2413 particlePtr->Colour = RGBALIGHT_MAKE(255,0,0,255);
2414 break;
2415 }
2416 case VISION_MODE_PRED_SEEALIENS:
2417 case VISION_MODE_PRED_SEEPREDTECH:
2418 {
2419 particlePtr->Colour = RGBALIGHT_MAKE(255,128,64,255);
2420 break;
2421 }
2422 }
2423 }
2424 else
2425 {
2426 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2427 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2428 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2429 switch (CurrentVisionMode)
2430 {
2431 default:
2432 case VISION_MODE_NORMAL:
2433 {
2434 particlePtr->Colour = RGBALIGHT_MAKE(255,128+(l/2),64+((3*l)/4),l);
2435 break;
2436 }
2437 case VISION_MODE_IMAGEINTENSIFIER:
2438 {
2439 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,l);
2440 break;
2441 }
2442 case VISION_MODE_PRED_THERMAL:
2443 {
2444 particlePtr->Colour = RGBALIGHT_MAKE(255,l/2,l/2,l);
2445 break;
2446 }
2447 case VISION_MODE_PRED_SEEALIENS:
2448 case VISION_MODE_PRED_SEEPREDTECH:
2449 {
2450 particlePtr->Colour = RGBALIGHT_MAKE(255,l/2,l/4,l);
2451 break;
2452 }
2453 }
2454 particlePtr->Size = 32+(FastRandom()&31);
2455 }
2456
2457 break;
2458 }
2459 case PARTICLE_PLASMATRAIL:
2460 {
2461 int l = (particlePtr->LifeTime)/64/4;
2462 if (l>255)
2463 {
2464 switch (CurrentVisionMode)
2465 {
2466 default:
2467 case VISION_MODE_NORMAL:
2468 {
2469 particlePtr->Colour = RGBALIGHT_MAKE(0,0,255,255);
2470 break;
2471 }
2472 case VISION_MODE_IMAGEINTENSIFIER:
2473 {
2474 particlePtr->Colour = RGBALIGHT_MAKE(0,255,0,255);
2475 break;
2476 }
2477 case VISION_MODE_PRED_THERMAL:
2478 {
2479 particlePtr->Colour = RGBALIGHT_MAKE(0,0,255,255);
2480 break;
2481 }
2482 case VISION_MODE_PRED_SEEALIENS:
2483 case VISION_MODE_PRED_SEEPREDTECH:
2484 {
2485 particlePtr->Colour = RGBALIGHT_MAKE(255,128,64,255);
2486 break;
2487 }
2488 }
2489 }
2490 else
2491 {
2492 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2493 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2494 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2495 switch (CurrentVisionMode)
2496 {
2497 default:
2498 case VISION_MODE_NORMAL:
2499 {
2500 particlePtr->Colour = RGBALIGHT_MAKE(l/4,l/2,255,l);
2501 break;
2502 }
2503 case VISION_MODE_IMAGEINTENSIFIER:
2504 {
2505 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,l);
2506 break;
2507 }
2508 case VISION_MODE_PRED_THERMAL:
2509 {
2510 particlePtr->Colour = RGBALIGHT_MAKE(l/4,l/2,255,l);
2511 break;
2512 }
2513 case VISION_MODE_PRED_SEEALIENS:
2514 case VISION_MODE_PRED_SEEPREDTECH:
2515 {
2516 particlePtr->Colour = RGBALIGHT_MAKE(255,l/2,l/4,l);
2517 break;
2518 }
2519 }
2520 particlePtr->Size = 32+(FastRandom()&31);
2521 }
2522
2523 break;
2524 }
2525
2526 case PARTICLE_WATERSPRAY:
2527 {
2528 particlePtr->Colour = RGBALIGHT_MAKE
2529 (
2530 particleDescPtr->RedScale[CurrentVisionMode],
2531 particleDescPtr->GreenScale[CurrentVisionMode],
2532 particleDescPtr->BlueScale[CurrentVisionMode],
2533 particleDescPtr->Alpha
2534 );
2535 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2536 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2537 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2538 particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
2539
2540 break;
2541 }
2542 case PARTICLE_WATERFALLSPRAY:
2543 {
2544 extern int WaterFallBase;
2545 int y = particlePtr->Position.vy;
2546 particlePtr->Colour = RGBALIGHT_MAKE
2547 (
2548 particleDescPtr->RedScale[CurrentVisionMode],
2549 particleDescPtr->GreenScale[CurrentVisionMode],
2550 particleDescPtr->BlueScale[CurrentVisionMode],
2551 particleDescPtr->Alpha
2552 );
2553
2554 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
2555 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
2556 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
2557
2558 particlePtr->Velocity.vy += MUL_FIXED(10000+(FastRandom()&511),NormalFrameTime);
2559
2560 if(particlePtr->Position.vz < 54885 && particlePtr->Position.vx < 179427)
2561 {
2562 if (y<4742 && particlePtr->Position.vy>4742)
2563 {
2564 particlePtr->Position.vy=4742;
2565 particlePtr->Velocity.vy=-MUL_FIXED(particlePtr->Velocity.vy,ONE_FIXED/2-(FastRandom()&16384));
2566 }
2567 }
2568 else if (particlePtr->Position.vz < 58600)
2569 {
2570 int l = DIV_FIXED(particlePtr->Position.vz - 54885,58600-54885);
2571
2572 if (particlePtr->Position.vx < 179427 - MUL_FIXED(l,179427-175545))
2573 {
2574 int yThreshold = 4742 + MUL_FIXED(l,8635-4742);
2575 if (y<yThreshold && particlePtr->Position.vy>yThreshold)
2576 {
2577 particlePtr->Position.vy=yThreshold;
2578 particlePtr->Velocity.vy=-MUL_FIXED(particlePtr->Velocity.vy,ONE_FIXED/2-(FastRandom()&16384));
2579 }
2580 }
2581 }
2582
2583 particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/4;
2584 particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/4;
2585 particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/4;
2586
2587 if (particlePtr->Position.vy>WaterFallBase)
2588 {
2589 particlePtr->LifeTime = 0;
2590 }
2591
2592 break;
2593 }
2594 case PARTICLE_FLECHETTE:
2595 case PARTICLE_FLECHETTE_NONDAMAGING:
2596 {
2597 {
2598 int l = particlePtr->LifeTime/4;
2599 l = MUL_FIXED(255,l);
2600
2601 if (l>255)
2602 {
2603 switch (CurrentVisionMode)
2604 {
2605 default:
2606 case VISION_MODE_NORMAL:
2607 {
2608 particlePtr->Colour = RGBALIGHT_MAKE((l-255)/2+32,0,0,255);
2609 break;
2610 }
2611 case VISION_MODE_IMAGEINTENSIFIER:
2612 {
2613 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2614 break;
2615 }
2616 case VISION_MODE_PRED_THERMAL:
2617 case VISION_MODE_PRED_SEEALIENS:
2618 case VISION_MODE_PRED_SEEPREDTECH:
2619 {
2620 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2621 break;
2622 }
2623 }
2624 }
2625 else
2626 {
2627 switch (CurrentVisionMode)
2628 {
2629 default:
2630 case VISION_MODE_NORMAL:
2631 {
2632 particlePtr->Colour = RGBALIGHT_MAKE(32,0,0,l);
2633 break;
2634 }
2635 case VISION_MODE_IMAGEINTENSIFIER:
2636 {
2637 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,l);
2638 break;
2639 }
2640 case VISION_MODE_PRED_THERMAL:
2641 case VISION_MODE_PRED_SEEALIENS:
2642 case VISION_MODE_PRED_SEEPREDTECH:
2643 {
2644 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2645 break;
2646 }
2647 }
2648 }
2649 }
2650
2651 if (particlePtr->Offset.vy)//particlePtr->Velocity.vx || particlePtr->Velocity.vy || particlePtr->Velocity.vz)
2652 {
2653 VECTORCH obstacleNormal;
2654 int moduleIndex;
2655 VECTORCH velocityBackup = particlePtr->Velocity;
2656
2657 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))
2658 {
2659 if(moduleIndex==-1)
2660 {
2661 particlePtr->LifeTime=0;
2662 }
2663 else
2664 {
2665 particlePtr->Offset.vy = 0;
2666 particlePtr->Velocity = velocityBackup;
2667 particlePtr->Position.vx += particlePtr->Velocity.vx>>10;
2668 particlePtr->Position.vy += particlePtr->Velocity.vy>>10;
2669 particlePtr->Position.vz += particlePtr->Velocity.vz>>10;
2670 }
2671 }
2672 }
2673
2674 break;
2675 }
2676 case PARTICLE_SMOKECLOUD:
2677 {
2678 if (particlePtr->LifeTime<ONE_FIXED*8)
2679 {
2680 int colour = (particlePtr->LifeTime/(8*256*4));
2681 particlePtr->Colour = RGBALIGHT_MAKE(255,255,255,colour);
2682 }
2683 else
2684 {
2685 particlePtr->Colour = RGBALIGHT_MAKE(255,255,255,64);
2686 }
2687 particlePtr->Size = 1000+500-(particlePtr->LifeTime>>10);
2688
2689 AddEffectsOfForceGenerators(&particlePtr->Position,&particlePtr->Velocity,32*64);
2690
2691 break;
2692 }
2693 case PARTICLE_BLUEPLASMASPHERE:
2694 {
2695 break;
2696 }
2697 case PARTICLE_ELECTRICALPLASMASPHERE:
2698 {
2699 {
2700 int colour = (particlePtr->LifeTime/128);
2701 particlePtr->Size = 200+(ONE_FIXED-particlePtr->LifeTime)/16;
2702 particlePtr->Colour = RGBALIGHT_MAKE(255,255,255,colour);
2703 }
2704 break;
2705 }
2706 case PARTICLE_PREDPISTOL_FLECHETTE:
2707 case PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING:
2708 {
2709 /* CDF 7/12/98 Placeholder till Kevin gets better. */
2710
2711 /* Based on PARTICLE_SPARK for vision... */
2712 particlePtr->Offset = particlePtr->Position;
2713
2714 {
2715 int l = particlePtr->LifeTime*2;
2716 l = MUL_FIXED(255,l);
2717
2718 if (l>255)
2719 {
2720 switch (CurrentVisionMode)
2721 {
2722 default:
2723 case VISION_MODE_NORMAL:
2724 {
2725 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,255,255);
2726 break;
2727 }
2728 case VISION_MODE_IMAGEINTENSIFIER:
2729 {
2730 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l/2,255);
2731 break;
2732 }
2733 case VISION_MODE_PRED_THERMAL:
2734 {
2735 particlePtr->Colour = RGBALIGHT_MAKE(l-255,255,255,255);
2736 break;
2737 }
2738 case VISION_MODE_PRED_SEEALIENS:
2739 case VISION_MODE_PRED_SEEPREDTECH:
2740 {
2741 particlePtr->Colour = RGBALIGHT_MAKE(255,255,l-255,255);
2742 break;
2743 }
2744 }
2745 }
2746 else
2747 {
2748 switch (CurrentVisionMode)
2749 {
2750 default:
2751 case VISION_MODE_NORMAL:
2752 {
2753 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,l,l);
2754 break;
2755 }
2756 case VISION_MODE_IMAGEINTENSIFIER:
2757 {
2758 particlePtr->Colour = RGBALIGHT_MAKE(l/2,l/2,128,l);
2759 break;
2760 }
2761 case VISION_MODE_PRED_THERMAL:
2762 {
2763 particlePtr->Colour = RGBALIGHT_MAKE(0,l,l,l);
2764 break;
2765 }
2766 case VISION_MODE_PRED_SEEALIENS:
2767 case VISION_MODE_PRED_SEEPREDTECH:
2768 {
2769 particlePtr->Colour = RGBALIGHT_MAKE(l,l,0,l);
2770 break;
2771 }
2772 }
2773 }
2774 }
2775
2776 {
2777 VECTORCH obstacleNormal;
2778 int moduleIndex;
2779
2780 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))
2781 {
2782 if (moduleIndex!=-1)
2783 {
2784 MakeDecal(DECAL_SCORCHED,&obstacleNormal,&(particlePtr->Position),moduleIndex);
2785 }
2786 particlePtr->LifeTime=0;
2787 }
2788 }
2789 break;
2790 }
2791 case PARTICLE_TRACER:
2792 {
2793 break;
2794 }
2795 default:
2796 {
2797 /* particle initialised wrongly */
2798 LOCALASSERT(0);
2799 break;
2800 }
2801 }
2802 particlePtr++;
2803 }
2804
2805 //
2806 PostLandscapeRendering();
2807 D3D_DecalSystem_Setup();
2808 OutputTranslucentPolyList();
2809
2810 i = NumActiveParticles;
2811 particlePtr = ParticleStorage;
2812 while(i--)
2813 {
2814 particlePtr->LifeTime -= NormalFrameTime;
2815
2816 if (particlePtr->LifeTime<=0)
2817 {
2818 enum PARTICLE_ID particleID = particlePtr->ParticleID;
2819 if( (particleID == PARTICLE_ALIEN_BLOOD) || (particleID == PARTICLE_PREDATOR_BLOOD) || (particleID==PARTICLE_HUMAN_BLOOD) || (particleID == PARTICLE_ANDROID_BLOOD))
2820 {
2821 NumberOfBloodParticles--;
2822 LOCALASSERT(NumberOfBloodParticles>=0);
2823 }
2824
2825 if ((particleID == PARTICLE_NONCOLLIDINGFLAME) && (FastRandom()&65535)<4096)
2826 {
2827 VECTORCH zero = {0,0,0};
2828 MakeParticle(&(particlePtr->Position),&zero,PARTICLE_IMPACTSMOKE);
2829 }
2830 else if ((particleID == PARTICLE_MOLOTOVFLAME) && (FastRandom()&65535)<4096)
2831 {
2832 VECTORCH zero = {0,0,0};
2833 MakeParticle(&(particlePtr->Position),&zero,PARTICLE_IMPACTSMOKE);
2834 }
2835
2836
2837 DeallocateParticle(particlePtr);
2838 }
2839 else
2840 {
2841 particlePtr++;
2842 }
2843 }
2844
2845 {
2846 extern int NumOnScreenBlocks;
2847 extern DISPLAYBLOCK *OnScreenBlockList[];
2848 int numOfObjects = NumOnScreenBlocks;
2849 while(numOfObjects)
2850 {
2851 DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
2852 STRATEGYBLOCK *sbPtr = objectPtr->ObStrategyBlock;
2853
2854 if (!objectPtr->ObShape && objectPtr->SfxPtr)
2855 {
2856 DrawSfxObject(objectPtr);
2857 }
2858 if (objectPtr->HModelControlBlock)
2859 {
2860 SECTION_DATA *firstSectionPtr=objectPtr->HModelControlBlock->section_data;
2861 ScanHModelForDecals(objectPtr,firstSectionPtr);
2862 }
2863 if (sbPtr)
2864 {
2865 switch(sbPtr->I_SBtype)
2866 {
2867 case I_BehaviourPlacedLight:
2868 {
2869 PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->SBdataptr;
2870 GLOBALASSERT(pl_bhv);
2871 GLOBALASSERT(sbPtr->containingModule);
2872
2873 if (LocalDetailLevels.DrawLightCoronas
2874 && pl_bhv->has_corona
2875 && pl_bhv->light->LightBright
2876 && (ModuleCurrVisArray[sbPtr->containingModule->m_index]==2)
2877 && (pl_bhv->light->RedScale
2878 || pl_bhv->light->GreenScale
2879 || pl_bhv->light->BlueScale)
2880 )
2881 {
2882 VECTORCH position=pl_bhv->corona_location;
2883 RotateVector(&position,&objectPtr->ObMat);
2884 position.vx += objectPtr->ObWorld.vx;
2885 position.vy += objectPtr->ObWorld.vy;
2886 position.vz += objectPtr->ObWorld.vz;
2887
2888 if (CameraCanSeeThisPosition_WithIgnore(objectPtr,&position))
2889 {
2890 LIGHTBLOCK *lPtr = pl_bhv->light;
2891 int colour;
2892 switch (CurrentVisionMode)
2893 {
2894 default:
2895 case VISION_MODE_NORMAL:
2896 {
2897 int r = MUL_FIXED(lPtr->RedScale,lPtr->LightBright)>>8;
2898 int g = MUL_FIXED(lPtr->GreenScale,lPtr->LightBright)>>8;
2899 int b = MUL_FIXED(lPtr->BlueScale,lPtr->LightBright)>>8;
2900 if (r>255) r=255;
2901 if (g>255) g=255;
2902 if (b>255) b=255;
2903 colour = 0xff000000+(r<<16)+(g<<8)+(b);
2904 break;
2905 }
2906 case VISION_MODE_IMAGEINTENSIFIER:
2907 {
2908 colour = 0xffffffff;
2909 break;
2910 }
2911 case VISION_MODE_PRED_THERMAL:
2912 case VISION_MODE_PRED_SEEALIENS:
2913 case VISION_MODE_PRED_SEEPREDTECH:
2914 {
2915 int b = MUL_FIXED
2916 (
2917 lPtr->RedScale+lPtr->GreenScale+lPtr->BlueScale,
2918 lPtr->LightBright
2919 )>>10;
2920 if (b>255) b=255;
2921
2922 colour = 0xff000000+(b<<16)+((b>>1)<<8);
2923 break;
2924 }
2925 }
2926 RenderLightFlare(&position,colour);
2927 }
2928 }
2929
2930 break;
2931 }
2932 case I_BehaviourFlareGrenade:
2933 {
2934 if (LocalDetailLevels.DrawLightCoronas)
2935 {
2936 DoFlareCorona(objectPtr);
2937 }
2938 break;
2939 }
2940 case I_BehaviourNetGhost:
2941 {
2942 NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->SBdataptr;
2943
2944 if (ghostDataPtr->type==I_BehaviourFlareGrenade && LocalDetailLevels.DrawLightCoronas)
2945 {
2946 DoFlareCorona(objectPtr);
2947 }
2948 else if (ghostDataPtr->type==I_BehaviourFrisbee)
2949 {
2950 if (sbPtr->DynPtr)
2951 {
2952 if (CameraCanSeeThisPosition_WithIgnore(objectPtr,&(sbPtr->DynPtr->Position)))
2953 {
2954 int colour;
2955 switch (CurrentVisionMode)
2956 {
2957 default:
2958 case VISION_MODE_NORMAL:
2959 {
2960 colour = 0x40ffffff;
2961 break;
2962 }
2963 case VISION_MODE_IMAGEINTENSIFIER:
2964 {
2965 colour = 0x40ffffff;
2966 break;
2967 }
2968 case VISION_MODE_PRED_THERMAL:
2969 case VISION_MODE_PRED_SEEALIENS:
2970 case VISION_MODE_PRED_SEEPREDTECH:
2971 {
2972 colour = 0x40ff8000;
2973 break;
2974 }
2975 }
2976 RenderLightFlare(&(sbPtr->DynPtr->Position),colour);
2977 }
2978 }
2979 }
2980 break;
2981 }
2982 /* CDF 21/7/99 Frisbee Laser? */
2983 case I_BehaviourFrisbee:
2984 {
2985 if (sbPtr->DynPtr)
2986 {
2987 if (CameraCanSeeThisPosition_WithIgnore(objectPtr,&(sbPtr->DynPtr->Position)))
2988 {
2989 int colour;
2990 switch (CurrentVisionMode)
2991 {
2992 default:
2993 case VISION_MODE_NORMAL:
2994 {
2995 colour = 0x40ffffff;
2996 break;
2997 }
2998 case VISION_MODE_IMAGEINTENSIFIER:
2999 {
3000 colour = 0x40ffffff;
3001 break;
3002 }
3003 case VISION_MODE_PRED_THERMAL:
3004 case VISION_MODE_PRED_SEEALIENS:
3005 case VISION_MODE_PRED_SEEPREDTECH:
3006 {
3007 colour = 0x40ff8000;
3008 break;
3009 }
3010 }
3011 RenderLightFlare(&(sbPtr->DynPtr->Position),colour);
3012 }
3013 }
3014 break;
3015 }
3016 /* CDF 21/7/99 Frisbee Laser? */
3017 case I_BehaviourXenoborg:
3018 {
3019 XENO_STATUS_BLOCK *statusPtr = (XENO_STATUS_BLOCK *)sbPtr->SBdataptr;
3020 LASER_BEAM_DESC *laserPtr = statusPtr->TargetingLaser;
3021 int i = 2;
3022 do
3023 {
3024 if (laserPtr->BeamIsOn)
3025 {
3026 if (laserPtr->BeamHasHitPlayer)
3027 {
3028 int colour;
3029 switch (CurrentVisionMode)
3030 {
3031 default:
3032 case VISION_MODE_NORMAL:
3033 {
3034 colour = 0xffff0000;
3035 break;
3036 }
3037 case VISION_MODE_IMAGEINTENSIFIER:
3038 {
3039 colour = 0xffffffff;
3040 break;
3041 }
3042 case VISION_MODE_PRED_THERMAL:
3043 case VISION_MODE_PRED_SEEALIENS:
3044 case VISION_MODE_PRED_SEEPREDTECH:
3045 {
3046 colour = 0xffff8000;
3047 break;
3048 }
3049 }
3050 RenderLightFlare(&(laserPtr->SourcePosition),colour);
3051 }
3052 else
3053 {
3054 PARTICLE particle;
3055 switch (CurrentVisionMode)
3056 {
3057 default:
3058 case VISION_MODE_NORMAL:
3059 {
3060 particle.Colour = RGBALIGHT_MAKE(255,0,0,255);
3061 break;
3062 }
3063 case VISION_MODE_IMAGEINTENSIFIER:
3064 {
3065 particle.Colour = RGBALIGHT_MAKE(255,255,255,255);
3066 break;
3067 }
3068 case VISION_MODE_PRED_THERMAL:
3069 case VISION_MODE_PRED_SEEALIENS:
3070 case VISION_MODE_PRED_SEEPREDTECH:
3071 {
3072 particle.Colour = RGBALIGHT_MAKE(255,128,0,255);
3073 break;
3074 }
3075 }
3076 particle.ParticleID = PARTICLE_LASERBEAM;
3077 particle.Position = laserPtr->SourcePosition;
3078 particle.Offset = laserPtr->TargetPosition;
3079 particle.Size = 20;
3080 RenderParticle(&particle);
3081 }
3082 }
3083 laserPtr++;
3084 }
3085 while(i--);
3086
3087 if (statusPtr->LeftMainBeam.BeamIsOn)
3088 {
3089 DrawXenoborgMainLaserbeam(&statusPtr->LeftMainBeam);
3090 }
3091 if (statusPtr->RightMainBeam.BeamIsOn)
3092 {
3093 DrawXenoborgMainLaserbeam(&statusPtr->RightMainBeam);
3094 }
3095 break;
3096 }
3097 case I_BehaviourSpeargunBolt:
3098 {
3099 SPEAR_BEHAV_BLOCK *bbPtr = (SPEAR_BEHAV_BLOCK * ) sbPtr->SBdataptr;
3100
3101 if (bbPtr->SpearThroughFragment)
3102 {
3103 DISPLAYBLOCK displayblock;
3104 displayblock.ObWorld.vx=bbPtr->Position.vx+sbPtr->DynPtr->Position.vx;
3105 displayblock.ObWorld.vy=bbPtr->Position.vy+sbPtr->DynPtr->Position.vy;
3106 displayblock.ObWorld.vz=bbPtr->Position.vz+sbPtr->DynPtr->Position.vz;
3107 displayblock.ObMat=bbPtr->Orient;
3108 displayblock.ObShape=GetLoadedShapeMSL("spear");
3109 displayblock.ObShapeData=GetShapeData(displayblock.ObShape);
3110
3111 displayblock.name=NULL;
3112 displayblock.ObEuler.EulerX=0;
3113 displayblock.ObEuler.EulerY=0;
3114 displayblock.ObEuler.EulerZ=0;
3115 displayblock.ObFlags=0;
3116 displayblock.ObFlags2=0;
3117 displayblock.ObFlags3=0;
3118 displayblock.ObNumLights=0;
3119 displayblock.ObRadius=0;
3120 displayblock.ObMaxX=0;
3121 displayblock.ObMinX=0;
3122 displayblock.ObMaxY=0;
3123 displayblock.ObMinY=0;
3124 displayblock.ObMaxZ=0;
3125 displayblock.ObMinZ=0;
3126 displayblock.ObTxAnimCtrlBlks=NULL;
3127 displayblock.ObEIDPtr=NULL;
3128 displayblock.ObMorphCtrl=NULL;
3129 displayblock.ObStrategyBlock=NULL;
3130 displayblock.ShapeAnimControlBlock=NULL;
3131 displayblock.HModelControlBlock=NULL;
3132 displayblock.ObMyModule=NULL;
3133 displayblock.SpecialFXFlags = 0;
3134 displayblock.SfxPtr=0;
3135
3136 MakeVector(&displayblock.ObWorld, &Global_VDB_Ptr->VDB_World, &displayblock.ObView);
3137 RotateVector(&displayblock.ObView, &Global_VDB_Ptr->VDB_Mat);
3138 RenderThisDisplayblock(&displayblock);
3139
3140 }
3141 break;
3142 }
3143 default:
3144 {
3145 /* KJL 19:17:48 31/07/98 - check for hmodels */
3146 break;
3147 }
3148 }
3149 }
3150 }
3151 }
3152 HandlePheromoneTrails();
3153 {
3154 int i;
3155 for(i=0; i<MAX_NO_OF_EXPLOSIONS; i++)
3156 {
3157 if (ExplosionStorage[i].LifeTime)
3158 HandleVolumetricExplosion(&ExplosionStorage[i]);
3159 }
3160 }
3161 //RenderBoom();
3162 //RenderFog();
3163 D3D_DecalSystem_End();
3164
3165 }
3166
RenderAllParticlesFurtherAwayThan(int zThreshold)3167 void RenderAllParticlesFurtherAwayThan(int zThreshold)
3168 {
3169 /* now render particles */
3170 int i = NumActiveParticles;
3171 PARTICLE *particlePtr = ParticleStorage;
3172 while(i--)
3173 {
3174 if (particlePtr->NotYetRendered)
3175 {
3176 VECTORCH position = particlePtr->Position;
3177 TranslatePointIntoViewspace(&position);
3178
3179 if (position.vz>zThreshold)
3180 {
3181 particlePtr->NotYetRendered = 0;
3182 switch(particlePtr->ParticleID)
3183 {
3184 case PARTICLE_ALIEN_BLOOD:
3185 {
3186 RenderParticle(particlePtr);
3187 {
3188 VECTORCH obstacleNormal;
3189 int moduleIndex;
3190 #if 1
3191 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))
3192 {
3193 if(moduleIndex!=-1)
3194 {
3195 #if 1
3196 int i = 1;
3197 MATRIXCH orientation;
3198 MakeMatrixFromDirection(&obstacleNormal,&orientation);
3199 while(i--)
3200 {
3201 VECTORCH velocity;
3202 velocity.vx = ((FastRandom()&1023) - 512);
3203 velocity.vy = ((FastRandom()&1023) - 512);
3204 velocity.vz = (255+(FastRandom()&255));
3205 RotateVector(&velocity,&orientation);
3206 MakeParticle(&(particlePtr->Position),&(velocity),PARTICLE_IMPACTSMOKE);
3207 }
3208 #endif
3209 MakeDecal(DECAL_SCORCHED,&obstacleNormal,&(particlePtr->Position),moduleIndex);
3210 }
3211 particlePtr->LifeTime = 0;
3212 }
3213 #endif
3214 }
3215
3216 particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
3217 AddEffectsOfForceGenerators(&particlePtr->Position,&particlePtr->Velocity,32*16);
3218
3219 break;
3220 }
3221 case PARTICLE_PREDATOR_BLOOD:
3222 {
3223 RenderParticle(particlePtr);
3224 {
3225 VECTORCH obstacleNormal;
3226 int moduleIndex;
3227
3228 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))//&& !(FastRandom()&15))
3229 {
3230 if(moduleIndex!=-1)
3231 {
3232 MakeDecal(DECAL_PREDATOR_BLOOD,&obstacleNormal,&(particlePtr->Position),moduleIndex);
3233 }
3234 particlePtr->LifeTime = 0;
3235 }
3236 }
3237
3238 particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
3239 AddEffectsOfForceGenerators(&particlePtr->Position,&particlePtr->Velocity,32*16);
3240 break;
3241
3242 }
3243 case PARTICLE_HUMAN_BLOOD:
3244 {
3245 RenderParticle(particlePtr);
3246 {
3247 VECTORCH obstacleNormal;
3248 int moduleIndex;
3249
3250 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))//&& !(FastRandom()&15))
3251 {
3252 if(moduleIndex!=-1)
3253 {
3254 MakeDecal(DECAL_HUMAN_BLOOD,&obstacleNormal,&(particlePtr->Position),moduleIndex);
3255 }
3256 particlePtr->LifeTime = 0;
3257 }
3258 }
3259
3260 particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
3261 AddEffectsOfForceGenerators(&particlePtr->Position,&particlePtr->Velocity,32*16);
3262 break;
3263 }
3264 case PARTICLE_ANDROID_BLOOD:
3265 {
3266 RenderParticle(particlePtr);
3267 {
3268 VECTORCH obstacleNormal;
3269 int moduleIndex;
3270
3271 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex))//&& !(FastRandom()&15))
3272 {
3273 if(moduleIndex!=-1)
3274 {
3275 MakeDecal(DECAL_ANDROID_BLOOD,&obstacleNormal,&(particlePtr->Position),moduleIndex);
3276 }
3277 particlePtr->LifeTime = 0;
3278 }
3279 }
3280
3281 particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
3282 AddEffectsOfForceGenerators(&particlePtr->Position,&particlePtr->Velocity,32*16);
3283 break;
3284 }
3285 case PARTICLE_FLARESMOKE:
3286 {
3287 RenderParticle(particlePtr);
3288 {
3289 VECTORCH impulse={0,0,0};
3290 int t = MUL_FIXED(NormalFrameTime,NormalFrameTime*4);
3291 AddEffectsOfForceGenerators(&particlePtr->Position,&impulse,8);
3292 particlePtr->Position.vx += MUL_FIXED(impulse.vx,t);
3293 particlePtr->Position.vy += MUL_FIXED(impulse.vy,t);
3294 particlePtr->Position.vz += MUL_FIXED(impulse.vz,t);
3295
3296 }
3297 break;
3298 }
3299 case PARTICLE_FLAME:
3300 case PARTICLE_NONDAMAGINGFLAME:
3301 case PARTICLE_PARGEN_FLAME:
3302 {
3303 RenderParticle(particlePtr);
3304 {
3305 VECTORCH obstacleNormal;
3306 int moduleIndex;
3307
3308 if(ParticleDynamics(particlePtr,&obstacleNormal,&moduleIndex) && !(FastRandom()&15))
3309 {
3310 if (particlePtr->ParticleID!=PARTICLE_NONDAMAGINGFLAME) {
3311 if(moduleIndex!=-1)
3312 {
3313 MakeDecal(DECAL_SCORCHED,&obstacleNormal,&(particlePtr->Position),moduleIndex);
3314 }
3315 }
3316 }
3317 }
3318 particlePtr->Velocity.vy -= MUL_FIXED(8000,NormalFrameTime);
3319 break;
3320 }
3321 case PARTICLE_FIRE:
3322 {
3323 RenderParticle(particlePtr);
3324
3325 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3326 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3327 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3328 particlePtr->Velocity.vy -= MUL_FIXED(4000,NormalFrameTime);
3329
3330 break;
3331 }
3332 case PARTICLE_NONCOLLIDINGFLAME:
3333 {
3334 RenderParticle(particlePtr);
3335
3336 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3337 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3338 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3339 particlePtr->Velocity.vy -= MUL_FIXED(8000,NormalFrameTime);
3340 break;
3341 }
3342 case PARTICLE_FLECHETTE:
3343 case PARTICLE_FLECHETTE_NONDAMAGING:
3344 {
3345 RenderFlechetteParticle(particlePtr);
3346 break;
3347 }
3348 case PARTICLE_STEAM:
3349 case PARTICLE_BLACKSMOKE:
3350 case PARTICLE_IMPACTSMOKE:
3351 case PARTICLE_GUNMUZZLE_SMOKE:
3352 case PARTICLE_EXPLOSIONFIRE:
3353 case PARTICLE_MOLOTOVFLAME:
3354 case PARTICLE_ORANGE_SPARK:
3355 case PARTICLE_ORANGE_PLASMA:
3356 case PARTICLE_RICOCHET_SPARK:
3357 case PARTICLE_SPARK:
3358 case PARTICLE_PLASMATRAIL:
3359 case PARTICLE_DEWLINE:
3360 case PARTICLE_WATERSPRAY:
3361 case PARTICLE_WATERFALLSPRAY:
3362 case PARTICLE_SMOKECLOUD:
3363 case PARTICLE_BLUEPLASMASPHERE:
3364 case PARTICLE_ELECTRICALPLASMASPHERE:
3365 case PARTICLE_PREDPISTOL_FLECHETTE:
3366 case PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING:
3367 case PARTICLE_TRACER:
3368 {
3369 RenderParticle(particlePtr);
3370 break;
3371 }
3372 default:
3373 {
3374 /* particle initialised wrongly */
3375 LOCALASSERT(0);
3376 break;
3377 }
3378 }
3379 }
3380 }
3381 particlePtr++;
3382 }
3383 }
DoFlareCorona(DISPLAYBLOCK * objectPtr)3384 void DoFlareCorona(DISPLAYBLOCK *objectPtr)
3385 {
3386 VECTORCH position=objectPtr->ObWorld;
3387
3388 if (CameraCanSeeThisPosition_WithIgnore(objectPtr,&position))
3389 {
3390 LIGHTBLOCK *lPtr = objectPtr->ObLights[0];
3391 int a = lPtr->LightBright>>8;
3392 int colour;
3393
3394 if (a>255) a=255;
3395
3396 switch (CurrentVisionMode)
3397 {
3398 default:
3399 case VISION_MODE_NORMAL:
3400 {
3401 colour = 0xffc8ff + (a<<24);
3402 break;
3403 }
3404 case VISION_MODE_IMAGEINTENSIFIER:
3405 {
3406 colour = 0xffffffff;
3407 break;
3408 }
3409 case VISION_MODE_PRED_THERMAL:
3410 case VISION_MODE_PRED_SEEALIENS:
3411 case VISION_MODE_PRED_SEEPREDTECH:
3412 {
3413 int b = MUL_FIXED
3414 (
3415 lPtr->RedScale+lPtr->GreenScale+lPtr->BlueScale,
3416 lPtr->LightBright
3417 )>>10;
3418 if (b>255) b=255;
3419
3420 colour = 0xff000000+(b<<16)+((b>>1)<<8);
3421 break;
3422 }
3423 }
3424 RenderLightFlare(&position,colour);
3425 }
3426 }
3427 #define MAX_RAINDROPS 1000
3428 static PARTICLE RainDropStorage[MAX_RAINDROPS];
3429 #define MAX_NO_OF_RIPPLES 100
3430 RIPPLE RippleStorage[MAX_NO_OF_RIPPLES];
3431 int ActiveRippleNumber;
InitialiseRainDrops(void)3432 void InitialiseRainDrops(void)
3433 {
3434 {
3435 int i = MAX_RAINDROPS;
3436 PARTICLE *particlePtr = RainDropStorage;
3437 do
3438 {
3439 particlePtr->Position.vy = 0x7fffffff;
3440 particlePtr->LifeTime = 0;
3441 particlePtr++;
3442 }
3443 while(--i);
3444 }
3445 {
3446 int i = MAX_NO_OF_RIPPLES;
3447 RIPPLE *ripplePtr = RippleStorage;
3448 do
3449 {
3450 ripplePtr->Active = 0;
3451 ripplePtr++;
3452 }
3453 while(--i);
3454 ActiveRippleNumber=0;
3455 }
3456 }
3457
HandleRainDrops(MODULE * modulePtr,int numberOfRaindrops)3458 void HandleRainDrops(MODULE *modulePtr,int numberOfRaindrops)
3459 {
3460 int i = numberOfRaindrops;
3461
3462 PARTICLE *particlePtr = RainDropStorage;
3463 LOCALASSERT(i<MAX_RAINDROPS);
3464 do
3465 {
3466 if((particlePtr->Position.vy > modulePtr->m_world.vy+modulePtr->m_maxy-500)
3467 ||(particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx)
3468 ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx)
3469 ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz)
3470 ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz))
3471 {
3472 AddRipple(particlePtr->Position.vx,particlePtr->Position.vz,400);
3473 particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_miny;
3474 particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx));
3475 particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz));
3476 // particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3477 // particlePtr->Velocity.vx = (FastRandom()&255)+5000;
3478 // particlePtr->Velocity.vz = (FastRandom()&255)-128;
3479 particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3480 particlePtr->Velocity.vx = (FastRandom()&255)-128;
3481 particlePtr->Velocity.vz = (FastRandom()&255)-128;
3482 {
3483 particlePtr->Offset.vx = -particlePtr->Velocity.vz;
3484 particlePtr->Offset.vy = 0;
3485 particlePtr->Offset.vz = particlePtr->Velocity.vx;
3486 Normalise(&(particlePtr->Offset));
3487 // particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
3488 // particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
3489 particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,50);
3490 particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,50);
3491 }
3492 }
3493 {
3494 VECTORCH prevPosition = particlePtr->Position;
3495
3496 #if 0
3497 ParticleDynamics(particlePtr);
3498 #else
3499 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3500 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3501 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3502 #endif
3503 if (particlePtr->Position.vy>modulePtr->m_world.vy+modulePtr->m_maxy-500)
3504 particlePtr->Position.vy=modulePtr->m_world.vy+modulePtr->m_maxy-495;
3505 D3D_DrawParticle_Rain(particlePtr,&prevPosition);
3506 }
3507 particlePtr++;
3508 }
3509 while(--i);
3510
3511 }
3512 #if 0
3513 void HandleRain(MODULE *modulePtr,int numberOfRaindrops)
3514 {
3515 int i = numberOfRaindrops;
3516 /* KJL 15:23:37 12/8/97 - this is written to work with the yard in genshd1 */
3517
3518 PARTICLE *particlePtr = RainDropStorage;
3519 LOCALASSERT(i<MAX_RAINDROPS);
3520 do
3521 {
3522 int killDrop=0;
3523
3524 if((particlePtr->Position.vx > -10418)
3525 &&(particlePtr->Position.vy > -4030)
3526 &&(particlePtr->Position.vz < 35070)
3527 &&(particlePtr->Position.vz > -11600))
3528 {
3529 killDrop=1;
3530 }
3531
3532 if((particlePtr->Position.vy > 3000)
3533 ||(particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx)
3534 ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx)
3535 ||(particlePtr->Position.vz < -50655)//modulePtr->m_world.vz+modulePtr->m_minz)
3536 ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz))
3537 {
3538 killDrop=1;
3539 }
3540
3541 if (killDrop)
3542 {
3543 particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_miny;
3544 particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx));
3545 particlePtr->Position.vz = -50655/*+modulePtr->m_minz*/+(FastRandom()%(modulePtr->m_maxz+50655));//-modulePtr->m_minz));
3546 particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3547 particlePtr->Velocity.vx = (FastRandom()&255)+5000;
3548 particlePtr->Velocity.vz = (FastRandom()&255)-128;
3549 {
3550 particlePtr->Offset.vx = -particlePtr->Velocity.vz;
3551 particlePtr->Offset.vy = 0;
3552 particlePtr->Offset.vz = particlePtr->Velocity.vx;
3553 Normalise(&(particlePtr->Offset));
3554 particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
3555 particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
3556 }
3557 }
3558 {
3559 VECTORCH prevPosition = particlePtr->Position;
3560
3561 #if 0
3562 ParticleDynamics(particlePtr);
3563 #else
3564 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3565 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3566 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3567 #endif
3568 D3D_DrawParticle_Rain(particlePtr,&prevPosition);
3569 }
3570 particlePtr++;
3571 }
3572 while(--i);
3573
3574 }
3575 #endif
HandleRain(int numberOfRaindrops)3576 void HandleRain(int numberOfRaindrops)
3577 {
3578 int i = numberOfRaindrops;
3579 /* KJL 15:23:37 12/8/97 - this is written to work with the yard in genshd1 */
3580
3581 PARTICLE *particlePtr = RainDropStorage;
3582 LOCALASSERT(i<MAX_RAINDROPS);
3583 do
3584 {
3585 int killDrop=0;
3586
3587 if((particlePtr->Position.vx > -10418)
3588 &&(particlePtr->Position.vy > -4030)
3589 &&(particlePtr->Position.vz < 35070)
3590 &&(particlePtr->Position.vz > -11600))
3591 {
3592 killDrop=1;
3593 }
3594 if((particlePtr->Position.vx > -45486)
3595 &&(particlePtr->Position.vx < -29901)
3596 &&(particlePtr->Position.vy > -6000)
3597 &&(particlePtr->Position.vz < -50656)
3598 &&(particlePtr->Position.vz > -70130))
3599 {
3600 killDrop=1;
3601 }
3602
3603 if((particlePtr->Position.vy > 3000)
3604 ||(particlePtr->Position.vx < -77000)
3605 ||(particlePtr->Position.vx > 134000)
3606 ||(particlePtr->Position.vz < -145000)//modulePtr->m_world.vz+modulePtr->m_minz)
3607 ||(particlePtr->Position.vz > 48706))
3608 {
3609 killDrop=1;
3610 }
3611
3612 if (killDrop)
3613 {
3614 particlePtr->Position.vy = -10000;
3615 particlePtr->Position.vx = -77000+(FastRandom()%(211000));
3616 particlePtr->Position.vz = -145000+(FastRandom()%(145000+49000));
3617 particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3618 particlePtr->Velocity.vx = (FastRandom()&255)+5000;
3619 particlePtr->Velocity.vz = (FastRandom()&255)-128;
3620 {
3621 particlePtr->Offset.vx = -particlePtr->Velocity.vz;
3622 particlePtr->Offset.vy = 0;
3623 particlePtr->Offset.vz = particlePtr->Velocity.vx;
3624 Normalise(&(particlePtr->Offset));
3625 particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
3626 particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
3627 }
3628 }
3629 {
3630 VECTORCH prevPosition = particlePtr->Position;
3631
3632 #if 0
3633 ParticleDynamics(particlePtr);
3634 #else
3635 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3636 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3637 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3638 #endif
3639 D3D_DrawParticle_Rain(particlePtr,&prevPosition);
3640 }
3641 particlePtr++;
3642 }
3643 while(--i);
3644
3645 }
HandleRainInTrench(int numberOfRaindrops)3646 void HandleRainInTrench(int numberOfRaindrops)
3647 {
3648 int i = numberOfRaindrops;
3649 /* KJL 15:23:37 12/8/97 - this is written to work with the yard in genshd1 */
3650
3651 PARTICLE *particlePtr = RainDropStorage;
3652 LOCALASSERT(i<MAX_RAINDROPS);
3653 do
3654 {
3655 int killDrop=0;
3656 /*
3657 if((particlePtr->Position.vx > -10418)
3658 &&(particlePtr->Position.vy > -4030)
3659 &&(particlePtr->Position.vz < 35070)
3660 &&(particlePtr->Position.vz > -11600))
3661 {
3662 killDrop=1;
3663 }
3664 */
3665 if((particlePtr->Position.vy > 3000)
3666 ||(particlePtr->Position.vx < 13500)
3667 ||(particlePtr->Position.vx > -50000)
3668 ||(particlePtr->Position.vz < -150655)
3669 ||(particlePtr->Position.vz > -50655))
3670 {
3671 killDrop=1;
3672 }
3673
3674 if (killDrop)
3675 {
3676 particlePtr->Position.vy = -16000;
3677 particlePtr->Position.vx = -50000+(FastRandom()%(63500));
3678 particlePtr->Position.vz = -150655+(FastRandom()%(100000));
3679 particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3680 particlePtr->Velocity.vx = (FastRandom()&255)+5000;
3681 particlePtr->Velocity.vz = (FastRandom()&255)-128;
3682 {
3683 particlePtr->Offset.vx = -particlePtr->Velocity.vz;
3684 particlePtr->Offset.vy = 0;
3685 particlePtr->Offset.vz = particlePtr->Velocity.vx;
3686 Normalise(&(particlePtr->Offset));
3687 particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
3688 particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
3689 }
3690 }
3691 {
3692 VECTORCH prevPosition = particlePtr->Position;
3693
3694 #if 0
3695 ParticleDynamics(particlePtr);
3696 #else
3697 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3698 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3699 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3700 #endif
3701 D3D_DrawParticle_Rain(particlePtr,&prevPosition);
3702 }
3703 particlePtr++;
3704 }
3705 while(--i);
3706
3707 }
3708
HandleRainShaft(MODULE * modulePtr,int bottomY,int topY,int numberOfRaindrops)3709 void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops)
3710 {
3711 int i = numberOfRaindrops;
3712 PARTICLE_DESC *particleDescPtr = &ParticleDescription[PARTICLE_WATERFALLSPRAY];
3713
3714 PARTICLE *particlePtr = RainDropStorage;
3715 LOCALASSERT(i<MAX_RAINDROPS);
3716 do
3717 {
3718 if((particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx)
3719 ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx)
3720 ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz)
3721 ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz))
3722 {
3723 particlePtr->LifeTime=0;
3724 }
3725 else if(particlePtr->Position.vy > bottomY)
3726 {
3727 particlePtr->Position.vy = bottomY;
3728 particlePtr->Velocity.vy = -particlePtr->Velocity.vy;
3729 particlePtr->Velocity.vx = particlePtr->Velocity.vx;
3730 particlePtr->Velocity.vz = particlePtr->Velocity.vz;
3731 particlePtr->LifeTime = 1;
3732 particlePtr->Size = 100;
3733 AddRipple(particlePtr->Position.vx,particlePtr->Position.vz,100);
3734 }
3735
3736 if (particlePtr->LifeTime<=0)
3737 {
3738 particlePtr->Position.vy = topY;
3739 particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx));
3740 particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz));
3741 particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
3742 particlePtr->Velocity.vx = (FastRandom()&1023)-512;
3743 particlePtr->Velocity.vz = (FastRandom()&1023)-512;
3744 particlePtr->LifeTime = 100*ONE_FIXED;
3745 particlePtr->ParticleID = PARTICLE_WATERFALLSPRAY;
3746 particlePtr->Colour = RGBALIGHT_MAKE
3747 (
3748 particleDescPtr->RedScale[CurrentVisionMode],
3749 particleDescPtr->GreenScale[CurrentVisionMode],
3750 particleDescPtr->BlueScale[CurrentVisionMode],
3751 particleDescPtr->Alpha
3752 );
3753 particlePtr->Size = 20;
3754 }
3755 else
3756 {
3757 particlePtr->LifeTime -= NormalFrameTime;
3758 }
3759
3760 {
3761 particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
3762 particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
3763 particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
3764 #if 0
3765 D3D_DrawParticle_Rain(particlePtr,&prevPosition);
3766 #else
3767 particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/16;
3768 particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/16;
3769 particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/16;
3770
3771 RenderParticle(particlePtr);
3772 #endif
3773 }
3774 particlePtr++;
3775 }
3776 while(--i);
3777
3778 }
3779
HandleRipples(void)3780 void HandleRipples(void)
3781 {
3782 int i;
3783
3784 for(i=0; i<MAX_NO_OF_RIPPLES; i++)
3785 {
3786 if (RippleStorage[i].Active)
3787 {
3788 RippleStorage[i].Radius += MUL_FIXED(2400,NormalFrameTime);
3789 RippleStorage[i].InvRadius = DIV_FIXED(4090,RippleStorage[i].Radius);
3790 RippleStorage[i].Amplitude -= MUL_FIXED(50,NormalFrameTime);
3791
3792 if (RippleStorage[i].Amplitude<0)
3793 {
3794 RippleStorage[i].Active = 0;
3795 }
3796 }
3797 }
3798 }
3799
EffectOfRipples(VECTORCH * point)3800 int EffectOfRipples(VECTORCH *point)
3801 {
3802 int offset;
3803 int i;
3804 offset = GetSin((point->vx+point->vz+CloakingPhase)&4095)>>11;
3805 offset += GetSin((point->vx-point->vz*2+CloakingPhase/2)&4095)>>12;
3806
3807 for(i=0; i<MAX_NO_OF_RIPPLES; i++)
3808 {
3809 if (RippleStorage[i].Active)
3810 {
3811 int dx=point->vx-RippleStorage[i].X;
3812 int dz=point->vz-RippleStorage[i].Z;
3813
3814 if (dx<0) dx = -dx;
3815 if (dz<0) dz = -dz;
3816 {
3817 int a;
3818
3819 if (dx>dz)
3820 {
3821 a = dx+(dz>>1);
3822 }
3823 else
3824 {
3825 a = dz+(dx>>1);
3826 }
3827
3828 if (a<RippleStorage[i].Radius)
3829 {
3830 a = MUL_FIXED(a,RippleStorage[i].InvRadius);
3831
3832 offset+= MUL_FIXED
3833 (
3834 RippleStorage[i].Amplitude,
3835 GetSin(a)
3836 );
3837 }
3838 }
3839 }
3840 }
3841
3842 if (offset>256) offset = 256;
3843 else if (offset<-256) offset = -256;
3844 return offset;
3845 }
3846
3847
AddRipple(int x,int z,int amplitude)3848 void AddRipple(int x,int z,int amplitude)
3849 {
3850 RippleStorage[ActiveRippleNumber].Active=1;
3851 RippleStorage[ActiveRippleNumber].X = x;
3852 RippleStorage[ActiveRippleNumber].Z = z;
3853 RippleStorage[ActiveRippleNumber].Radius = 200;
3854 RippleStorage[ActiveRippleNumber].Amplitude = amplitude;
3855
3856 ActiveRippleNumber++;
3857 if (ActiveRippleNumber == MAX_NO_OF_RIPPLES) ActiveRippleNumber=0;
3858
3859 }
3860
3861
CheckForObjectsInWater(int minX,int maxX,int minZ,int maxZ,int averageY)3862 void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY)
3863 {
3864 extern int NumActiveBlocks;
3865 extern DISPLAYBLOCK* ActiveBlockList[];
3866 int numberOfObjects = NumActiveBlocks;
3867
3868 while (numberOfObjects--)
3869 {
3870 DISPLAYBLOCK* objectPtr = ActiveBlockList[numberOfObjects];
3871
3872 if(objectPtr->ObStrategyBlock)
3873 {
3874 DYNAMICSBLOCK *dynPtr = objectPtr->ObStrategyBlock->DynPtr;
3875
3876
3877 if (dynPtr)
3878 {
3879 int overlapInY=0;
3880 int overlapInX=0;
3881 int overlapInZ=0;
3882
3883 /* floating objects are ignored to avoid positive feedback */
3884 if(dynPtr->IsFloating) continue;
3885 #if 1
3886 if ( (dynPtr->Position.vx==dynPtr->PrevPosition.vx)
3887 &&(dynPtr->Position.vy==dynPtr->PrevPosition.vy)
3888 &&(dynPtr->Position.vz==dynPtr->PrevPosition.vz) )
3889 continue;
3890 #endif
3891
3892 if (dynPtr->Position.vy>dynPtr->PrevPosition.vy)
3893 {
3894 if ((dynPtr->Position.vy+objectPtr->ObRadius > averageY)
3895 &&(dynPtr->PrevPosition.vy-objectPtr->ObRadius < averageY))
3896 {
3897 overlapInY=1;
3898 }
3899 }
3900 else
3901 {
3902 if ((dynPtr->PrevPosition.vy+objectPtr->ObRadius > averageY)
3903 &&(dynPtr->Position.vy-objectPtr->ObRadius < averageY))
3904 {
3905 overlapInY=1;
3906 }
3907 }
3908
3909 if (!overlapInY) continue;
3910
3911 if (dynPtr->Position.vx>dynPtr->PrevPosition.vx)
3912 {
3913 if ((dynPtr->Position.vx+objectPtr->ObRadius > minX)
3914 &&(dynPtr->PrevPosition.vx-objectPtr->ObRadius < maxX))
3915 {
3916 overlapInX=1;
3917 }
3918 }
3919 else
3920 {
3921 if ((dynPtr->PrevPosition.vx+objectPtr->ObRadius > minX)
3922 &&(dynPtr->Position.vx-objectPtr->ObRadius < maxX))
3923 {
3924 overlapInX=1;
3925 }
3926 }
3927
3928 if (!overlapInX) continue;
3929
3930 if (dynPtr->Position.vz>dynPtr->PrevPosition.vz)
3931 {
3932 if ((dynPtr->Position.vz+objectPtr->ObRadius > minZ)
3933 &&(dynPtr->PrevPosition.vz-objectPtr->ObRadius < maxZ))
3934 {
3935 overlapInZ=1;
3936 }
3937 }
3938 else
3939 {
3940 if ((dynPtr->PrevPosition.vz+objectPtr->ObRadius > minZ)
3941 &&(dynPtr->Position.vz-objectPtr->ObRadius < maxZ))
3942 {
3943 overlapInZ=1;
3944 }
3945 }
3946
3947 if (!overlapInZ) continue;
3948
3949 /* we have an overlap */
3950
3951 /* KJL 16:37:29 27/08/98 - if object is on fire its now put out */
3952 objectPtr->ObStrategyBlock->SBDamageBlock.IsOnFire=0;
3953
3954 if (objectPtr->ObStrategyBlock->I_SBtype == I_BehaviourFlareGrenade)
3955 {
3956 VECTORCH upwards = {0,-65536,0};
3957 dynPtr->IsFloating = 1;
3958 dynPtr->GravityOn = 0;
3959 dynPtr->Elasticity = 0;
3960 MakeMatrixFromDirection(&upwards,&(dynPtr->OrientMat));
3961 }
3962 else if (objectPtr == Player)
3963 {
3964 PLAYER_STATUS *playerStatusPtr = (PLAYER_STATUS *)(objectPtr->ObStrategyBlock->SBdataptr);
3965 LOCALASSERT(playerStatusPtr);
3966
3967 playerStatusPtr->IsMovingInWater = 1;
3968 }
3969 {
3970
3971 AddRipple(dynPtr->Position.vx,dynPtr->Position.vz,100);
3972 #if 0
3973 {
3974 int i;
3975 for (i=0; i<10; i++)
3976 {
3977 VECTORCH velocity;
3978 velocity.vy = (-(FastRandom()%(magnitude)))*8;
3979 velocity.vx = ((FastRandom()&1023)-512)*8;
3980 velocity.vz = ((FastRandom()&1023)-512)*8;
3981 MakeParticle(&(dynPtr->Position), &velocity, PARTICLE_WATERSPRAY);
3982 }
3983 }
3984 #endif
3985 }
3986 }
3987 }
3988 }
3989 }
3990
DrawMuzzleFlash(VECTORCH * positionPtr,VECTORCH * directionPtr,enum MUZZLE_FLASH_ID muzzleFlashID)3991 void DrawMuzzleFlash(VECTORCH *positionPtr,VECTORCH *directionPtr, enum MUZZLE_FLASH_ID muzzleFlashID)
3992 {
3993 PARTICLE particle;
3994 particle.Position = *positionPtr;
3995
3996 D3D_DecalSystem_Setup();
3997
3998 switch (muzzleFlashID)
3999 {
4000 case MUZZLE_FLASH_SMARTGUN:
4001 {
4002 #if 0
4003 PARTICLE_DESC *particleDescPtr;
4004 particle.ParticleID=PARTICLE_SMARTGUNMUZZLEFLASH;
4005 particleDescPtr = &ParticleDescription[particle.ParticleID];
4006
4007 particle.Colour = RGBALIGHT_MAKE(particleDescPtr->RedScale[CurrentVisionMode],particleDescPtr->GreenScale[CurrentVisionMode],particleDescPtr->BlueScale[CurrentVisionMode],particleDescPtr->Alpha);
4008 particle.Size = particleDescPtr->Size;
4009
4010 particle.Position.vx += MUL_FIXED(100,directionPtr->vx);
4011 particle.Position.vy += MUL_FIXED(100,directionPtr->vy);
4012 particle.Position.vz += MUL_FIXED(100,directionPtr->vz);
4013 RenderParticle(&particle);
4014 #else
4015 PARTICLE_DESC *particleDescPtr=&ParticleDescription[PARTICLE_MUZZLEFLASH];
4016 MATRIXCH muzzleMatrix;
4017 MATRIXCH rotmat;
4018 MakeMatrixFromDirection(directionPtr,&muzzleMatrix);
4019 {
4020 int angle = 4096/12;
4021 int cos = GetCos(angle);
4022 int sin = GetSin(angle);
4023 rotmat.mat11 = cos;
4024 rotmat.mat12 = sin;
4025 rotmat.mat13 = 0;
4026 rotmat.mat21 = -sin;
4027 rotmat.mat22 = cos;
4028 rotmat.mat23 = 0;
4029 rotmat.mat31 = 0;
4030 rotmat.mat32 = 0;
4031 rotmat.mat33 = 65536;
4032 }
4033 #if 1
4034 {
4035 int i = 16;
4036 PARTICLE particle;
4037
4038 particle.Position = *positionPtr;
4039 particle.Position.vx += MUL_FIXED(100 - (FastRandom()&15),directionPtr->vx);
4040 particle.Position.vy += MUL_FIXED(100 - (FastRandom()&15),directionPtr->vy);
4041 particle.Position.vz += MUL_FIXED(100 - (FastRandom()&15),directionPtr->vz);
4042
4043 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4044
4045 particle.Colour = RGBALIGHT_MAKE(particleDescPtr->RedScale[CurrentVisionMode],particleDescPtr->GreenScale[CurrentVisionMode],particleDescPtr->BlueScale[CurrentVisionMode],particleDescPtr->Alpha);
4046 particle.Size = 200;
4047
4048 while(i--)
4049 {
4050 RenderParticle(&particle);
4051 particle.Position.vx += MUL_FIXED(50 - (FastRandom()&15),directionPtr->vx);
4052 particle.Position.vy += MUL_FIXED(50 - (FastRandom()&15),directionPtr->vy);
4053 particle.Position.vz += MUL_FIXED(50 - (FastRandom()&15),directionPtr->vz);
4054 particle.Size -= (FastRandom()&3)+3;
4055 }
4056
4057 }
4058 #endif
4059 {
4060 int a;
4061 for (a=0; a<12;a++)
4062 {
4063 int i=8;
4064 PARTICLE particle;
4065
4066 particle.Position = *positionPtr;
4067 particle.Position.vx += -MUL_FIXED(200,directionPtr->vx) + MUL_FIXED(50,muzzleMatrix.mat21);
4068 particle.Position.vy += -MUL_FIXED(200,directionPtr->vy) + MUL_FIXED(50,muzzleMatrix.mat22);
4069 particle.Position.vz += -MUL_FIXED(200,directionPtr->vz) + MUL_FIXED(50,muzzleMatrix.mat23);
4070
4071 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4072
4073 particle.Colour = RGBALIGHT_MAKE(particleDescPtr->RedScale[CurrentVisionMode],particleDescPtr->GreenScale[CurrentVisionMode],particleDescPtr->BlueScale[CurrentVisionMode],particleDescPtr->Alpha);
4074 particle.Size = 50;
4075
4076 if (!(a&1)) i+=8;
4077
4078 while(i--)
4079 {
4080 RenderParticle(&particle);
4081 particle.Position.vx += MUL_FIXED((FastRandom()&31)+16,muzzleMatrix.mat21);
4082 particle.Position.vy += MUL_FIXED((FastRandom()&31)+16,muzzleMatrix.mat22);
4083 particle.Position.vz += MUL_FIXED((FastRandom()&31)+16,muzzleMatrix.mat23);
4084 particle.Size += (FastRandom()&15);
4085 }
4086
4087 MatrixMultiply(&muzzleMatrix,&rotmat,&muzzleMatrix);
4088 }
4089
4090 }
4091 #endif
4092 break;
4093 }
4094 case MUZZLE_FLASH_AMORPHOUS:
4095 {
4096 PARTICLE_DESC *particleDescPtr;
4097 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4098 particleDescPtr = &ParticleDescription[particle.ParticleID];
4099
4100 particle.Colour = RGBALIGHT_MAKE(particleDescPtr->RedScale[CurrentVisionMode],particleDescPtr->GreenScale[CurrentVisionMode],particleDescPtr->BlueScale[CurrentVisionMode],particleDescPtr->Alpha);
4101 particle.Size = particleDescPtr->Size;
4102
4103 RenderParticle(&particle);
4104 particle.Position.vx += MUL_FIXED(100,directionPtr->vx);
4105 particle.Position.vy += MUL_FIXED(100,directionPtr->vy);
4106 particle.Position.vz += MUL_FIXED(100,directionPtr->vz);
4107 RenderParticle(&particle);
4108 particle.Position.vx += MUL_FIXED(100,directionPtr->vx);
4109 particle.Position.vy += MUL_FIXED(100,directionPtr->vy);
4110 particle.Position.vz += MUL_FIXED(100,directionPtr->vz);
4111 RenderParticle(&particle);
4112 {
4113 int i = 16;
4114 particle.Size = 20;
4115
4116 while(i--)
4117 {
4118 RenderParticle(&particle);
4119 particle.Position.vx = positionPtr->vx + MUL_FIXED(100,directionPtr->vx) + (FastRandom()&127)-64;
4120 particle.Position.vy = positionPtr->vy + MUL_FIXED(100,directionPtr->vy) + (FastRandom()&127)-64;
4121 particle.Position.vz = positionPtr->vz + MUL_FIXED(100,directionPtr->vz) + (FastRandom()&127)-64;
4122 }
4123
4124 }
4125 break;
4126 }
4127 case MUZZLE_FLASH_SKEETER:
4128 {
4129 PARTICLE_DESC *particleDescPtr;
4130 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4131 particleDescPtr = &ParticleDescription[particle.ParticleID];
4132
4133 particle.Colour = RGBALIGHT_MAKE(particleDescPtr->RedScale[CurrentVisionMode],particleDescPtr->GreenScale[CurrentVisionMode],particleDescPtr->BlueScale[CurrentVisionMode],particleDescPtr->Alpha);
4134 particle.Size = particleDescPtr->Size;
4135
4136 RenderParticle(&particle);
4137 particle.Position.vx += MUL_FIXED(20,directionPtr->vx);
4138 particle.Position.vy += MUL_FIXED(20,directionPtr->vy);
4139 particle.Position.vz += MUL_FIXED(20,directionPtr->vz);
4140 RenderParticle(&particle);
4141 particle.Position.vx += MUL_FIXED(20,directionPtr->vx);
4142 particle.Position.vy += MUL_FIXED(20,directionPtr->vy);
4143 particle.Position.vz += MUL_FIXED(20,directionPtr->vz);
4144 RenderParticle(&particle);
4145 {
4146 int i = 16;
4147 particle.Size = 20;
4148
4149 while(i--)
4150 {
4151 RenderParticle(&particle);
4152 particle.Position.vx = positionPtr->vx + MUL_FIXED(100,directionPtr->vx) + (FastRandom()&127)-64;
4153 particle.Position.vy = positionPtr->vy + MUL_FIXED(100,directionPtr->vy) + (FastRandom()&127)-64;
4154 particle.Position.vz = positionPtr->vz + MUL_FIXED(100,directionPtr->vz) + (FastRandom()&127)-64;
4155 }
4156
4157 }
4158 break;
4159 }
4160 default:
4161 {
4162 LOCALASSERT(0);
4163 return;
4164 }
4165 }
4166 D3D_DecalSystem_End();
4167
4168 }
4169
DrawFrisbeePlasmaBolt(VECTORCH * positionPtr,VECTORCH * directionPtr)4170 void DrawFrisbeePlasmaBolt(VECTORCH *positionPtr,VECTORCH *directionPtr)
4171 {
4172 int i = 16;
4173 PARTICLE particle;
4174
4175 particle.Position = *positionPtr;
4176
4177 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4178
4179 particle.Colour = RGBALIGHT_MAKE(255,255,255,255);
4180 particle.Size = 200;
4181
4182 while(i--)
4183 {
4184 RenderParticle(&particle);
4185 particle.Position.vx -= MUL_FIXED(50,directionPtr->vx);
4186 particle.Position.vy -= MUL_FIXED(50,directionPtr->vy);
4187 particle.Position.vz -= MUL_FIXED(50,directionPtr->vz);
4188 particle.Size -= 10;
4189 }
4190
4191 }
4192
DrawPredatorPlasmaBolt(VECTORCH * positionPtr,VECTORCH * directionPtr)4193 void DrawPredatorPlasmaBolt(VECTORCH *positionPtr,VECTORCH *directionPtr)
4194 {
4195 int i = 16;
4196 PARTICLE particle;
4197
4198 particle.Position = *positionPtr;
4199
4200 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4201
4202 particle.Colour = RGBALIGHT_MAKE(50,255,255,255);
4203 particle.Size = 200;
4204
4205 while(i--)
4206 {
4207 RenderParticle(&particle);
4208 particle.Position.vx -= MUL_FIXED(50,directionPtr->vx);
4209 particle.Position.vy -= MUL_FIXED(50,directionPtr->vy);
4210 particle.Position.vz -= MUL_FIXED(50,directionPtr->vz);
4211 particle.Size -= 10;
4212 }
4213
4214 }
4215
DrawSmallPredatorPlasmaBolt(VECTORCH * positionPtr,VECTORCH * directionPtr)4216 void DrawSmallPredatorPlasmaBolt(VECTORCH *positionPtr,VECTORCH *directionPtr)
4217 {
4218 #if 0
4219 int i = 16;
4220 PARTICLE particle;
4221
4222 particle.Position = *positionPtr;
4223
4224 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4225
4226 particle.Colour = RGBALIGHT_MAKE(50,255,255,255);
4227 particle.Size = 100;
4228
4229 while(i--)
4230 {
4231 RenderParticle(&particle);
4232 particle.Position.vx -= MUL_FIXED(25,directionPtr->vx);
4233 particle.Position.vy -= MUL_FIXED(25,directionPtr->vy);
4234 particle.Position.vz -= MUL_FIXED(25,directionPtr->vz);
4235 particle.Size -= 5;
4236 }
4237 #else
4238 PARTICLE particle;
4239
4240 particle.Position = *positionPtr;
4241
4242 particle.ParticleID=PARTICLE_ELECTRICALPLASMASPHERE;
4243
4244 particle.Colour = RGBALIGHT_MAKE(255,255,255,128);
4245 particle.Size = 200;
4246
4247 RenderParticle(&particle);
4248 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4249 particle.Colour = RGBALIGHT_MAKE(255,255,255,64);
4250 particle.Size = 1000;
4251 RenderParticle(&particle);
4252 RenderParticle(&particle);
4253
4254 #endif
4255
4256 }
4257
4258
4259
MakeFlareParticle(DYNAMICSBLOCK * dynPtr)4260 void MakeFlareParticle(DYNAMICSBLOCK *dynPtr)
4261 {
4262 // int i = MUL_FIXED(4,density);
4263 // while(i--)
4264 {
4265 VECTORCH velocity;
4266 velocity.vx = ((FastRandom()&2047) - 1024);
4267 velocity.vy = ((FastRandom()&2047) - 1024);
4268 velocity.vz = (1000+(FastRandom()&255))*2;
4269 RotateVector(&velocity,&(dynPtr->OrientMat));
4270 MakeParticle(&(dynPtr->Position),&(velocity),PARTICLE_FLARESMOKE);
4271 }
4272 }
MakeRocketTrailParticles(VECTORCH * prevPositionPtr,VECTORCH * positionPtr)4273 void MakeRocketTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr)
4274 {
4275 VECTORCH disp;
4276
4277 disp.vx = positionPtr->vx - prevPositionPtr->vx;
4278 disp.vy = positionPtr->vy - prevPositionPtr->vy;
4279 disp.vz = positionPtr->vz - prevPositionPtr->vz;
4280
4281 if (disp.vx!=0 || disp.vy!=0 || disp.vz!=0)
4282 {
4283 int i=16;
4284 do
4285 {
4286 {
4287 VECTORCH position;
4288 VECTORCH velocity;
4289 velocity.vx = (FastRandom()&1023) - 512;
4290 velocity.vy = (FastRandom()&1023) - 512;
4291 velocity.vz = (FastRandom()&1023) - 512;
4292
4293 position.vx = prevPositionPtr->vx + (disp.vx*i)/16;
4294 position.vy = prevPositionPtr->vy + (disp.vy*i)/16;
4295 position.vz = prevPositionPtr->vz + (disp.vz*i)/16;
4296
4297 MakeParticle(&position,&(velocity),PARTICLE_BLACKSMOKE);
4298 }
4299 }
4300 while(i--);
4301 }
4302 }
MakeGrenadeTrailParticles(VECTORCH * prevPositionPtr,VECTORCH * positionPtr)4303 void MakeGrenadeTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr)
4304 {
4305 VECTORCH disp;
4306
4307 disp.vx = positionPtr->vx - prevPositionPtr->vx;
4308 disp.vy = positionPtr->vy - prevPositionPtr->vy;
4309 disp.vz = positionPtr->vz - prevPositionPtr->vz;
4310
4311 if (!(disp.vx==0 && disp.vy==0 && disp.vz==0))
4312 {
4313 int i=8;
4314 do
4315 {
4316 {
4317 VECTORCH position;
4318 VECTORCH velocity;
4319 velocity.vx = (FastRandom()&1023) - 512;
4320 velocity.vy = (FastRandom()&1023) - 512;
4321 velocity.vz = (FastRandom()&1023) - 512;
4322
4323 position.vx = prevPositionPtr->vx + (disp.vx*i)/16;
4324 position.vy = prevPositionPtr->vy + (disp.vy*i)/16;
4325 position.vz = prevPositionPtr->vz + (disp.vz*i)/16;
4326
4327 MakeParticle(&position,&(velocity),PARTICLE_FLARESMOKE);
4328 }
4329 }
4330 while(i--);
4331 }
4332 }
4333
MakeImpactSmoke(MATRIXCH * orientationPtr,VECTORCH * positionPtr)4334 void MakeImpactSmoke(MATRIXCH *orientationPtr, VECTORCH *positionPtr)
4335 {
4336 int i = 5;
4337 while(i--)
4338 {
4339 VECTORCH velocity;
4340 velocity.vx = ((FastRandom()&1023) - 512);
4341 velocity.vy = ((FastRandom()&1023) - 512);
4342 velocity.vz = (255+(FastRandom()&255));
4343 RotateVector(&velocity,orientationPtr);
4344 MakeParticle(positionPtr,&(velocity),PARTICLE_IMPACTSMOKE);
4345 }
4346 }
4347
MakeImpactSparks(VECTORCH * incidentPtr,VECTORCH * normalPtr,VECTORCH * positionPtr)4348 void MakeImpactSparks(VECTORCH *incidentPtr, VECTORCH *normalPtr, VECTORCH *positionPtr)
4349 {
4350 int noOfSparks = 5;
4351 VECTORCH velocity;
4352 int d = -2*DotProduct(incidentPtr,normalPtr);
4353 velocity.vx = (incidentPtr->vx + MUL_FIXED(d,normalPtr->vx))>>3;
4354 velocity.vy = (incidentPtr->vy + MUL_FIXED(d,normalPtr->vy))>>3;
4355 velocity.vz = (incidentPtr->vz + MUL_FIXED(d,normalPtr->vz))>>3;
4356
4357 do
4358 {
4359
4360 // VECTORCH velocity;
4361 velocity.vx = velocity.vx + (FastRandom()&2047)-1024;
4362 velocity.vy = velocity.vy + (FastRandom()&2047)-1024;
4363 velocity.vz = velocity.vz + (FastRandom()&2047)-1024;
4364 MakeParticle(positionPtr,&velocity,PARTICLE_RICOCHET_SPARK);
4365 }
4366 while(--noOfSparks);
4367 MakeRicochetSound(positionPtr);
4368 }
4369
MakeSprayOfSparks(MATRIXCH * orientationPtr,VECTORCH * positionPtr)4370 void MakeSprayOfSparks(MATRIXCH *orientationPtr, VECTORCH *positionPtr)
4371 {
4372 int noOfSparks = 15;
4373 do
4374 {
4375
4376 VECTORCH velocity;
4377 velocity.vx = (FastRandom()&2047)-1024;
4378 velocity.vy = (FastRandom()&2047);
4379 velocity.vz = -(FastRandom()&2047)-1024;
4380 RotateVector(&velocity,orientationPtr);
4381 MakeParticle(positionPtr,&velocity,PARTICLE_SPARK);
4382 }
4383 while(--noOfSparks);
4384
4385 MakeLightElement(positionPtr,LIGHTELEMENT_ELECTRICAL_SPARKS);
4386 }
4387
MakeVolumetricExplosionAt(VECTORCH * positionPtr,enum EXPLOSION_ID explosionID)4388 void MakeVolumetricExplosionAt(VECTORCH *positionPtr, enum EXPLOSION_ID explosionID)
4389 {
4390 switch (explosionID)
4391 {
4392 case EXPLOSION_HUGE:
4393 case EXPLOSION_HUGE_NOCOLLISIONS:
4394 {
4395 VOLUMETRIC_EXPLOSION *expPtr;
4396 int i;
4397 int r;
4398
4399 /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
4400 {
4401 MODULE *module = ModuleFromPosition(positionPtr, (MODULE*)NULL);
4402 if (!module) return;
4403 }
4404
4405 expPtr = AllocateVolumetricExplosion();
4406 r = (FastRandom()&7)+1;
4407
4408 if (explosionID == EXPLOSION_HUGE_NOCOLLISIONS)
4409 {
4410 expPtr->UseCollisions = 0;
4411 }
4412 else
4413 {
4414 expPtr->UseCollisions = 1;
4415 }
4416
4417 for(i=0; i<SPHERE_VERTICES; i++)
4418 {
4419 expPtr->Position[i] = *positionPtr;
4420 expPtr->Velocity[i].vx = SphereVertex[i].vx;
4421 expPtr->Velocity[i].vy = SphereVertex[i].vy;
4422 expPtr->Velocity[i].vz = SphereVertex[i].vz;
4423 expPtr->BeenStopped[i] = 0;
4424 expPtr->RipplePhase[i] = FastRandom()&4095;
4425 expPtr->NumberVerticesMoving=SPHERE_VERTICES;
4426 }
4427 expPtr->LifeTime = ONE_FIXED-1;
4428 expPtr->ExplosionPhase = 1;
4429
4430 for(i=0; i<r; i++)
4431 {
4432 CreateFlamingDebris(positionPtr,&SphereVertex[FastRandom()%SPHERE_VERTICES]);
4433 }
4434 if ((positionPtr->vx!=Player->ObWorld.vx)
4435 ||(positionPtr->vy!=Player->ObWorld.vy)
4436 ||(positionPtr->vz!=Player->ObWorld.vz))
4437 {
4438 MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
4439 }
4440
4441 #if 1
4442 for (i=0; i<LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion; i++)
4443 {
4444 VECTORCH position = *positionPtr;
4445 position.vx += (FastRandom()&2047)-1024;
4446 position.vy += (FastRandom()&2047)-1024;
4447 position.vz += (FastRandom()&2047)-1024;
4448 MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD);
4449 }
4450 #endif
4451 break;
4452 }
4453 case EXPLOSION_MOLOTOV:
4454 {
4455 MakeMolotovExplosionAt(positionPtr,0);
4456 break;
4457 }
4458 case EXPLOSION_PULSEGRENADE:
4459 case EXPLOSION_SMALL_NOCOLLISIONS:
4460 {
4461 VOLUMETRIC_EXPLOSION *expPtr;
4462 int i;
4463 int r;
4464
4465 /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
4466 {
4467 MODULE *module = ModuleFromPosition(positionPtr, (MODULE*)NULL);
4468 if (!module) return;
4469 }
4470 #if 1
4471 expPtr = AllocateVolumetricExplosion();
4472
4473 if (explosionID == EXPLOSION_SMALL_NOCOLLISIONS)
4474 {
4475 expPtr->UseCollisions = 0;
4476 }
4477 else
4478 {
4479 expPtr->UseCollisions = 1;
4480 }
4481 r = (FastRandom()&7)+1;
4482
4483 for(i=0; i<SPHERE_VERTICES; i++)
4484 {
4485 expPtr->Position[i] = *positionPtr;
4486 expPtr->Velocity[i].vx = SphereVertex[i].vx;
4487 expPtr->Velocity[i].vy = SphereVertex[i].vy;
4488 expPtr->Velocity[i].vz = SphereVertex[i].vz;
4489 expPtr->BeenStopped[i] = 0;
4490 expPtr->RipplePhase[i] = FastRandom()&4095;
4491 expPtr->NumberVerticesMoving=SPHERE_VERTICES;
4492 }
4493 expPtr->LifeTime = ONE_FIXED/2;
4494 expPtr->ExplosionPhase = 1;
4495 #endif
4496 #if 0
4497 for(i=0; i<r; i++)
4498 {
4499 CreateFlamingDebris(positionPtr,&SphereVertex[FastRandom()%SPHERE_VERTICES]);
4500 }
4501 #endif
4502 if ((positionPtr->vx!=Player->ObWorld.vx)
4503 ||(positionPtr->vy!=Player->ObWorld.vy)
4504 ||(positionPtr->vz!=Player->ObWorld.vz))
4505 {
4506 MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
4507 // MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_EXPLOSION);
4508 }
4509
4510 #if 1
4511 for (i=0; i<LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion; i++)
4512 {
4513 VECTORCH position = *positionPtr;
4514 position.vx += (FastRandom()&1023)-512;
4515 position.vy += (FastRandom()&1023)-512;
4516 position.vz += (FastRandom()&1023)-512;
4517 MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD);
4518 }
4519 #endif
4520 break;
4521 }
4522 case EXPLOSION_PREDATORPISTOL:
4523 {
4524 MakeElectricalExplosion(positionPtr);
4525 break;
4526 }
4527 default:
4528 break;
4529 }
4530 }
4531
4532
MakeFlechetteExplosionAt(VECTORCH * positionPtr,int seed)4533 void MakeFlechetteExplosionAt(VECTORCH *positionPtr,int seed)
4534 {
4535 extern SOUND3DDATA Explosion_SoundData;
4536 int i;
4537 enum PARTICLE_ID particle_to_use;
4538
4539 Explosion_SoundData.position=*positionPtr;
4540 Sound_Play(SID_FRAG_RICOCHETS,"n",&Explosion_SoundData);
4541
4542 if(!seed)
4543 {
4544 //need to get a random number seed for this explosion
4545 while(!seed) seed=FastRandom();
4546
4547 //explosion originated on this computer , so use damaging type
4548 particle_to_use=PARTICLE_FLECHETTE;
4549
4550 //if in a network game , send explosion to other players
4551 if(AvP.Network!=I_No_Network)
4552 {
4553 AddNetMsg_MakeFlechetteExplosion(positionPtr,seed);
4554 }
4555 }
4556 else
4557 {
4558 //explosion passed across the network
4559 //use the nondamaging flechette
4560 particle_to_use=PARTICLE_FLECHETTE_NONDAMAGING;
4561 }
4562 SetSeededFastRandom(seed);
4563
4564 /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
4565 {
4566 MODULE *module = ModuleFromPosition(positionPtr, (MODULE*)NULL);
4567 if (!module) return;
4568 }
4569 #if 0
4570 for(i=0; i<SPHERE_VERTICES; i++)
4571 {
4572 if (SphereVertex[i].vy<0) MakeParticle(positionPtr,&SphereVertex[i],PARTICLE_FLECHETTE);
4573 }
4574 #else
4575 for (i=0; i<100; i++)
4576 {
4577 VECTORCH velocity;
4578 int phi = SeededFastRandom()&4095;
4579
4580 velocity.vy = -(SeededFastRandom()&65535);
4581 {
4582 float y = ((float)velocity.vy)/65536.0;
4583 y = sqrt(1-y*y);
4584
4585 f2i(velocity.vx,(float)GetCos(phi)*y);
4586 f2i(velocity.vz,(float)GetSin(phi)*y);
4587 }
4588
4589 MakeParticle(positionPtr, &velocity, particle_to_use);
4590 }
4591 #endif
4592 MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
4593 }
MakeMolotovExplosionAt(VECTORCH * positionPtr,int seed)4594 void MakeMolotovExplosionAt(VECTORCH *positionPtr,int seed)
4595 {
4596 int i;
4597 enum PARTICLE_ID particle_to_use;
4598
4599 if(!seed)
4600 {
4601 //need to get a random number seed for this explosion
4602 while(!seed) seed=FastRandom();
4603
4604 //explosion originated on this computer , so use damaging type
4605 particle_to_use=PARTICLE_MOLOTOVFLAME;
4606
4607 //if in a network game , send explosion to other players
4608 if(AvP.Network!=I_No_Network)
4609 {
4610 // AddNetMsg_MakeFlechetteExplosion(positionPtr,seed);
4611 }
4612 }
4613 else
4614 {
4615 //explosion passed across the network
4616 //use the nondamaging flechette
4617 // particle_to_use=PARTICLE_FLECHETTE_NONDAMAGING;
4618 }
4619 SetSeededFastRandom(seed);
4620
4621 /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
4622 {
4623 MODULE *module = ModuleFromPosition(positionPtr, (MODULE*)NULL);
4624 if (!module) return;
4625 }
4626 for (i=0; i<100; i++)
4627 {
4628 VECTORCH velocity;
4629 int phi = SeededFastRandom()&4095;
4630
4631 velocity.vy = -(SeededFastRandom()&65535);
4632 {
4633 float y = ((float)velocity.vy)/65536.0;
4634 y = sqrt(1-y*y);
4635
4636 f2i(velocity.vx,(float)GetCos(phi)*y);
4637 f2i(velocity.vz,(float)GetSin(phi)*y);
4638 }
4639 velocity.vx /= 8;
4640 velocity.vy /= 16;
4641 velocity.vz /= 8;
4642
4643 MakeParticle(positionPtr, &velocity, particle_to_use);
4644 }
4645 // MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
4646 }
4647
4648
HandleVolumetricExplosion(VOLUMETRIC_EXPLOSION * expPtr)4649 static void HandleVolumetricExplosion(VOLUMETRIC_EXPLOSION *expPtr)
4650 {
4651 int i;
4652 PARTICLE particle;
4653 int velocityModifier;
4654 particle.ParticleID = PARTICLE_EXPLOSIONFIRE;
4655
4656 if (!expPtr->LifeTime) return;
4657 RenderExplosionSurface(expPtr);
4658
4659 if (expPtr->ExplosionPhase)
4660 {
4661 {
4662 int v = (DIV_FIXED(SPHERE_VERTICES,expPtr->NumberVerticesMoving+1)+ONE_FIXED);
4663 velocityModifier = MUL_FIXED(GetSin(expPtr->LifeTime/64)/16,v);
4664 }
4665
4666 for(i=0; i<SPHERE_VERTICES; i++)
4667 {
4668 int v;
4669 VECTORCH obstacleNormal = {0,0,0};
4670 int moduleIndex;
4671 if ((expPtr->Velocity[i].vx==0)
4672 &&(expPtr->Velocity[i].vy==0)
4673 &&(expPtr->Velocity[i].vz==0))
4674 continue;
4675 particle.Velocity = expPtr->Velocity[i];
4676 #if 1
4677 {
4678 v = GetSin((CloakingPhase*4+expPtr->RipplePhase[i])&4095)/4;
4679 v = velocityModifier+MUL_FIXED(v,velocityModifier);
4680 }
4681 #endif
4682 particle.Velocity.vx = MUL_FIXED(particle.Velocity.vx,v);
4683 particle.Velocity.vy = MUL_FIXED(particle.Velocity.vy,v);
4684 particle.Velocity.vz = MUL_FIXED(particle.Velocity.vz,v);
4685
4686
4687 particle.Position = expPtr->Position[i];
4688
4689 if(LocalDetailLevels.ExplosionsDeformToEnvironment && expPtr->UseCollisions)
4690 {
4691 if(ParticleDynamics(&particle,&obstacleNormal,&moduleIndex))
4692 {
4693 int magOfPerpImp = DotProduct(&obstacleNormal,&(expPtr->Velocity[i]));
4694 expPtr->Velocity[i].vx -= MUL_FIXED(obstacleNormal.vx, magOfPerpImp);
4695 expPtr->Velocity[i].vy -= MUL_FIXED(obstacleNormal.vy, magOfPerpImp);
4696 expPtr->Velocity[i].vz -= MUL_FIXED(obstacleNormal.vz, magOfPerpImp);
4697
4698 if(!expPtr->BeenStopped[i])
4699 {
4700 expPtr->BeenStopped[i] = 1;
4701 expPtr->NumberVerticesMoving--;
4702 }
4703 }
4704 }
4705 else
4706 {
4707 particle.Position.vx += MUL_FIXED(particle.Velocity.vx,NormalFrameTime);
4708 particle.Position.vy += MUL_FIXED(particle.Velocity.vy,NormalFrameTime);
4709 particle.Position.vz += MUL_FIXED(particle.Velocity.vz,NormalFrameTime);
4710 }
4711 expPtr->Position[i] = particle.Position;
4712 }
4713
4714
4715 expPtr->LifeTime -= NormalFrameTime;
4716
4717 if (expPtr->LifeTime<=0)
4718 {
4719 expPtr->LifeTime=0;
4720 }
4721 }
4722 }
4723
MakeOldVolumetricExplosionAt(VECTORCH * positionPtr)4724 void MakeOldVolumetricExplosionAt(VECTORCH *positionPtr)
4725 {
4726 int noRequired = 32;//MUL_FIXED(2500,NormalFrameTime);
4727 int i;
4728 // VECTORCH zero={0,0,0};
4729 for (i=0; i<noRequired; i++)
4730 {
4731 VECTORCH velocity;
4732 int phi = FastRandom()&4095;
4733 int speed = 6000*4+(FastRandom()&4095);
4734
4735 velocity.vz = (FastRandom()&131071) - ONE_FIXED;
4736 {
4737 float z = ((float)velocity.vz)/65536.0;
4738 z = sqrt(1-z*z);
4739
4740 f2i(velocity.vx,(float)GetCos(phi)*z);
4741 f2i(velocity.vy,(float)GetSin(phi)*z);
4742 }
4743
4744 velocity.vx = MUL_FIXED(velocity.vx,speed);
4745 velocity.vy = MUL_FIXED(velocity.vy,speed);
4746 velocity.vz = MUL_FIXED(velocity.vz,speed);
4747
4748 MakeParticle(positionPtr, &velocity, PARTICLE_EXPLOSIONFIRE);
4749 }
4750
4751 MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
4752 }
4753
MakePlasmaExplosion(VECTORCH * positionPtr,VECTORCH * fromPositionPtr,enum EXPLOSION_ID explosionID)4754 extern void MakePlasmaExplosion(VECTORCH *positionPtr, VECTORCH *fromPositionPtr, enum EXPLOSION_ID explosionID)
4755 {
4756 switch (explosionID)
4757 {
4758 case EXPLOSION_DISSIPATINGPLASMA:
4759 {
4760 MakeParticle(positionPtr,positionPtr,PARTICLE_BLUEPLASMASPHERE);
4761 MakeLightElement(positionPtr,LIGHTELEMENT_PLASMACASTERHIT);
4762 MakeBloodExplosion(fromPositionPtr, 127, positionPtr, 200, PARTICLE_ORANGE_SPARK);
4763 Sound_Play(SID_PLASMABOLT_DISSIPATE,"d",positionPtr);
4764 break;
4765 }
4766 case EXPLOSION_FOCUSEDPLASMA:
4767 {
4768 MakeParticle(positionPtr,positionPtr,PARTICLE_BLUEPLASMASPHERE);
4769 MakeLightElement(positionPtr,LIGHTELEMENT_PLASMACASTERHIT);
4770 MakeFocusedExplosion(fromPositionPtr, positionPtr, 100, PARTICLE_ORANGE_PLASMA);
4771 Sound_Play(SID_PLASMABOLT_HIT,"d",positionPtr);
4772 break;
4773 }
4774 default:
4775 break;
4776 }
4777 }
MakeElectricalExplosion(VECTORCH * positionPtr)4778 extern void MakeElectricalExplosion(VECTORCH *positionPtr)
4779 {
4780 {
4781 PredPistolExplosion_SoundData.position=*positionPtr;
4782 Sound_Play(SID_WIL_PRED_PISTOL_EXPLOSION,"n",&PredPistolExplosion_SoundData);
4783 }
4784 //Sound_Play(SID_WIL_PRED_PISTOL_EXPLOSION,"d",positionPtr);
4785 MakeParticle(positionPtr,positionPtr,PARTICLE_ELECTRICALPLASMASPHERE);
4786 MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_EXPLOSION);
4787 }
4788
MakeBloodExplosion(VECTORCH * originPtr,int creationRadius,VECTORCH * blastPositionPtr,int noOfParticles,enum PARTICLE_ID particleID)4789 void MakeBloodExplosion(VECTORCH *originPtr, int creationRadius, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID)
4790 {
4791 VECTORCH blastDir;
4792 int i;
4793
4794 /* Dividing by zero can be bad for your health */
4795 LOCALASSERT(creationRadius!=0);
4796
4797 blastDir.vx = originPtr->vx - blastPositionPtr->vx;
4798 blastDir.vy = originPtr->vy - blastPositionPtr->vy;
4799 blastDir.vz = originPtr->vz - blastPositionPtr->vz;
4800
4801 for (i=0; i<noOfParticles; i++)
4802 {
4803 VECTORCH velocity;
4804 VECTORCH position;
4805 int phi = FastRandom()&4095;
4806 int speed = 6000+(FastRandom()&4095);
4807 int r;
4808 //speed = FastRandom()&2047;
4809
4810 velocity.vz = (FastRandom()&131071) - ONE_FIXED;
4811 {
4812 float z = ((float)velocity.vz)/65536.0;
4813 z = sqrt(1-z*z);
4814
4815 f2i(velocity.vx,(float)GetCos(phi)*z);
4816 f2i(velocity.vy,(float)GetSin(phi)*z);
4817 }
4818
4819 if (DotProduct(&velocity,&blastDir)<0)
4820 {
4821 velocity.vx = -velocity.vx;
4822 velocity.vy = -velocity.vy;
4823 velocity.vz = -velocity.vz;
4824 }
4825
4826 r = FastRandom()%creationRadius;
4827 position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r);
4828 position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r);
4829 position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r);
4830
4831 velocity.vx = MUL_FIXED(velocity.vx,speed);
4832 velocity.vy = MUL_FIXED(velocity.vy,speed);
4833 velocity.vz = MUL_FIXED(velocity.vz,speed);
4834
4835
4836 MakeParticle(&position, &velocity, particleID);
4837 }
4838 }
4839
4840
MakeFocusedExplosion(VECTORCH * originPtr,VECTORCH * blastPositionPtr,int noOfParticles,enum PARTICLE_ID particleID)4841 void MakeFocusedExplosion(VECTORCH *originPtr, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID)
4842 {
4843 VECTORCH blastDir;
4844 int i;
4845
4846 blastDir.vx = originPtr->vx - blastPositionPtr->vx;
4847 blastDir.vy = originPtr->vy - blastPositionPtr->vy;
4848 blastDir.vz = originPtr->vz - blastPositionPtr->vz;
4849
4850 for (i=0; i<noOfParticles; i++)
4851 {
4852 VECTORCH velocity,position;
4853 int phi = FastRandom()&4095;
4854 int speed = 6000+(FastRandom()&4095);
4855 int r;
4856 speed = FastRandom()&2047;
4857
4858 velocity.vz = (FastRandom()&131071) - ONE_FIXED;
4859 {
4860 float z = ((float)velocity.vz)/65536.0;
4861 z = sqrt(1-z*z);
4862
4863 f2i(velocity.vx,(float)GetCos(phi)*z);
4864 f2i(velocity.vy,(float)GetSin(phi)*z);
4865 }
4866
4867 if (DotProduct(&velocity,&blastDir)<0)
4868 {
4869 velocity.vx = -velocity.vx;
4870 velocity.vy = -velocity.vy;
4871 velocity.vz = -velocity.vz;
4872 }
4873 r = FastRandom()%127;
4874 position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r);
4875 position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r);
4876 position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r);
4877
4878 velocity.vx = MUL_FIXED(velocity.vx,speed);
4879 velocity.vy = MUL_FIXED(velocity.vy,speed);
4880 velocity.vz = MUL_FIXED(velocity.vz,speed);
4881
4882
4883 MakeParticle(&position, &velocity, particleID);
4884 }
4885 }
4886
4887
4888
4889
MakePlasmaTrailParticles(DYNAMICSBLOCK * dynPtr,int number)4890 void MakePlasmaTrailParticles(DYNAMICSBLOCK *dynPtr, int number)
4891 {
4892
4893 VECTORCH disp;
4894
4895 disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
4896 disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
4897 disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
4898
4899 // if (disp.vx!=0 || disp.vy!=0 || disp.vz!=0)
4900 {
4901 int i=number;
4902 do
4903 {
4904 VECTORCH velocity;
4905 VECTORCH position;
4906 #if 1
4907
4908 int phi = FastRandom()&4095;
4909 int speed = 512;
4910
4911 velocity.vz = (FastRandom()&131071) - ONE_FIXED;
4912 {
4913 float z = ((float)velocity.vz)/65536.0;
4914 z = sqrt(1-z*z);
4915
4916 f2i(velocity.vx,(float)GetCos(phi)*z);
4917 f2i(velocity.vy,(float)GetSin(phi)*z);
4918 }
4919
4920 velocity.vx = MUL_FIXED(velocity.vx,speed);//+dynPtr->LinVelocity.vx/32;
4921 velocity.vy = MUL_FIXED(velocity.vy,speed);//+dynPtr->LinVelocity.vy/32;
4922 velocity.vz = MUL_FIXED(velocity.vz,speed);//+dynPtr->LinVelocity.vz/32;
4923 #else
4924 velocity.vx = dynPtr->LinVelocity.vx;
4925 velocity.vy = dynPtr->LinVelocity.vy;
4926 velocity.vz = dynPtr->LinVelocity.vz;
4927 #endif
4928 position.vx = dynPtr->PrevPosition.vx + (disp.vx*i)/number;
4929 position.vy = dynPtr->PrevPosition.vy + (disp.vy*i)/number;
4930 position.vz = dynPtr->PrevPosition.vz + (disp.vz*i)/number;
4931
4932 MakeParticle(&position, &velocity, PARTICLE_PLASMATRAIL);
4933 }
4934 while(i--);
4935 }
4936 }
4937
MakeDewlineTrailParticles(DYNAMICSBLOCK * dynPtr,int number)4938 void MakeDewlineTrailParticles(DYNAMICSBLOCK *dynPtr, int number)
4939 {
4940
4941 VECTORCH disp;
4942
4943 disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
4944 disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
4945 disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
4946
4947 // if (disp.vx!=0 || disp.vy!=0 || disp.vz!=0)
4948 {
4949 int i=number;
4950 do
4951 {
4952 VECTORCH velocity;
4953 VECTORCH position;
4954 #if 1
4955
4956 int phi = FastRandom()&4095;
4957 int speed = 256; //512
4958
4959 velocity.vz = (FastRandom()&131071) - ONE_FIXED;
4960 {
4961 float z = ((float)velocity.vz)/65536.0;
4962 z = sqrt(1-z*z);
4963
4964 f2i(velocity.vx,(float)GetCos(phi)*z);
4965 f2i(velocity.vy,(float)GetSin(phi)*z);
4966 }
4967
4968 velocity.vx = MUL_FIXED(velocity.vx,speed);//+dynPtr->LinVelocity.vx/32;
4969 velocity.vy = MUL_FIXED(velocity.vy,speed);//+dynPtr->LinVelocity.vy/32;
4970 velocity.vz = MUL_FIXED(velocity.vz,speed);//+dynPtr->LinVelocity.vz/32;
4971 #else
4972 velocity.vx = dynPtr->LinVelocity.vx;
4973 velocity.vy = dynPtr->LinVelocity.vy;
4974 velocity.vz = dynPtr->LinVelocity.vz;
4975 #endif
4976 position.vx = dynPtr->PrevPosition.vx + (disp.vx*i)/number;
4977 position.vy = dynPtr->PrevPosition.vy + (disp.vy*i)/number;
4978 position.vz = dynPtr->PrevPosition.vz + (disp.vz*i)/number;
4979
4980 MakeParticle(&position, &velocity, PARTICLE_DEWLINE);
4981 }
4982 while(i--);
4983 }
4984 }
4985
DrawXenoborgMainLaserbeam(LASER_BEAM_DESC * laserPtr)4986 void DrawXenoborgMainLaserbeam(LASER_BEAM_DESC *laserPtr)
4987 {
4988 if (laserPtr->BeamHasHitPlayer)
4989 {
4990 int colour;
4991 switch (CurrentVisionMode)
4992 {
4993 default:
4994 case VISION_MODE_NORMAL:
4995 {
4996 colour = 0xff0000ff;
4997 break;
4998 }
4999 case VISION_MODE_IMAGEINTENSIFIER:
5000 {
5001 colour = 0xffffffff;
5002 break;
5003 }
5004 case VISION_MODE_PRED_THERMAL:
5005 case VISION_MODE_PRED_SEEALIENS:
5006 case VISION_MODE_PRED_SEEPREDTECH:
5007 {
5008 colour = 0xffff8000;
5009 break;
5010 }
5011 }
5012 RenderLightFlare(&(laserPtr->SourcePosition),colour);
5013 RenderLightFlare(&(laserPtr->SourcePosition),0xffffffff);
5014 }
5015 else
5016 {
5017 PARTICLE particle;
5018 switch (CurrentVisionMode)
5019 {
5020 default:
5021 case VISION_MODE_NORMAL:
5022 {
5023 particle.Colour = RGBALIGHT_MAKE(0,0,255,255);
5024 break;
5025 }
5026 case VISION_MODE_IMAGEINTENSIFIER:
5027 {
5028 particle.Colour = RGBALIGHT_MAKE(255,255,255,255);
5029 break;
5030 }
5031 case VISION_MODE_PRED_THERMAL:
5032 case VISION_MODE_PRED_SEEALIENS:
5033 case VISION_MODE_PRED_SEEPREDTECH:
5034 {
5035 particle.Colour = RGBALIGHT_MAKE(255,128,0,255);
5036 break;
5037 }
5038 }
5039 particle.Colour = RGBALIGHT_MAKE(255,255,255,255);
5040 particle.ParticleID = PARTICLE_PLASMABEAM;
5041 particle.Position = laserPtr->SourcePosition;
5042 particle.Offset = laserPtr->TargetPosition;
5043 particle.Size = 32;
5044 RenderParticle(&particle);
5045 // particle.Colour = RGBALIGHT_MAKE(255,255,255,255);
5046 // particle.Size = 20;
5047 // RenderParticle(&particle);
5048
5049 }
5050 }
5051 /* KJL 16:37:03 20/06/98 - stupid but quick implementation */
5052 #define NO_OF_VERTICES_IN_TRAIL 300
5053 PHEROMONE_TRAIL Trail[NO_OF_VERTICES_IN_TRAIL];
5054
NewTrailPoint(DYNAMICSBLOCK * dynPtr)5055 void NewTrailPoint(DYNAMICSBLOCK *dynPtr)
5056 {
5057 PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail();
5058 if (!trailPtr) return;
5059
5060 GLOBALASSERT(dynPtr);
5061 trailPtr->Vertex[0] = dynPtr->Position;
5062 // trailPtr->Vertex[0].vy -=1000;
5063
5064 trailPtr->Perp[0] = *((VECTORCH*)&(dynPtr->OrientMat.mat11));
5065 trailPtr->Size[0] = 127*65536;
5066
5067 trailPtr->Vertex[1] = dynPtr->PrevPosition;
5068 // trailPtr->Vertex[1].vy -=1000;
5069 trailPtr->Perp[1] = *((VECTORCH*)&(dynPtr->PrevOrientMat.mat11));
5070 trailPtr->Size[1] = 127*65536-MUL_FIXED(TRAIL_DECAY_SPEED,PrevNormalFrameTime);
5071 }
5072
5073 VECTORCH PlayerPheromoneTrailPerp = {0,0,0};
PlayerPheromoneTrail(DYNAMICSBLOCK * dynPtr)5074 void PlayerPheromoneTrail(DYNAMICSBLOCK *dynPtr)
5075 {
5076 PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail();
5077 VECTORCH disp;
5078 if (!trailPtr) return;
5079
5080 disp.vx = dynPtr->Position.vx-dynPtr->PrevPosition.vx;
5081 disp.vy = dynPtr->Position.vy-dynPtr->PrevPosition.vy;
5082 disp.vz = dynPtr->Position.vz-dynPtr->PrevPosition.vz;
5083
5084 trailPtr->Vertex[0] = dynPtr->Position;
5085 #if 1
5086 trailPtr->Vertex[0].vx -= dynPtr->OrientMat.mat21>>6;
5087 trailPtr->Vertex[0].vy -= dynPtr->OrientMat.mat22>>6;
5088 trailPtr->Vertex[0].vz -= dynPtr->OrientMat.mat23>>6;
5089 #endif
5090 // trailPtr->Vertex[0].vy -= 500;
5091
5092 trailPtr->Perp[0] = *((VECTORCH*)&(dynPtr->OrientMat.mat11));
5093 #if 0
5094 trailPtr->Perp[0].vx = disp.vz - disp.vy;
5095 trailPtr->Perp[0].vy = disp.vx - disp.vz;
5096 trailPtr->Perp[0].vz = disp.vy - disp.vx;
5097 if (trailPtr->Perp[0].vx!=0 || trailPtr->Perp[0].vy !=0 || trailPtr->Perp[0].vz!=0)
5098 {
5099 Normalise(&trailPtr->Perp[0]);
5100 }
5101 else
5102 {
5103 trailPtr->Perp[0] = PlayerPheromoneTrailPerp;
5104 }
5105 #endif
5106 trailPtr->Size[0] = 127*65536*4;
5107
5108 trailPtr->Vertex[1] = dynPtr->PrevPosition;
5109 #if 1
5110 trailPtr->Vertex[1].vx -= dynPtr->PrevOrientMat.mat21>>6;
5111 trailPtr->Vertex[1].vy -= dynPtr->PrevOrientMat.mat22>>6;
5112 trailPtr->Vertex[1].vz -= dynPtr->PrevOrientMat.mat23>>6;
5113 #endif
5114 // trailPtr->Vertex[1].vy -= 500;
5115
5116
5117 trailPtr->Perp[1] = *((VECTORCH*)&(dynPtr->PrevOrientMat.mat11));
5118 // trailPtr->Perp[1] = PlayerPheromoneTrailPerp;
5119 // PlayerPheromoneTrailPerp = trailPtr->Perp[0];
5120
5121 trailPtr->Size[1] = 127*65536*4-MUL_FIXED(TRAIL_DECAY_SPEED,PrevNormalFrameTime);
5122 }
5123
HandlePheromoneTrails(void)5124 void HandlePheromoneTrails(void)
5125 {
5126 int i;
5127 PHEROMONE_TRAIL *trailPtr;
5128 int decayDelta;
5129
5130 i = NumActiveTrails;
5131 trailPtr = TrailStorage;
5132 //textprint("Pheromone Segments active:%d\n",NumActiveTrails);
5133
5134 decayDelta = MUL_FIXED(TRAIL_DECAY_SPEED,NormalFrameTime);
5135
5136 #if 0
5137 if (TICKERTAPE_CHEATMODE)
5138 {
5139 decayDelta/=4;
5140 }
5141 #endif
5142 while(i--)
5143 {
5144
5145 trailPtr->Size[0] -= decayDelta;
5146 trailPtr->Size[1] -= decayDelta;
5147 if (trailPtr->Size[1]<0) trailPtr->Size[1]=0;
5148 if (trailPtr->Size[0]<0)
5149 {
5150 DeallocatePheromoneTrail(trailPtr);
5151 }
5152 else
5153 {
5154 RenderTrailSegment(trailPtr);
5155 trailPtr++;
5156 }
5157
5158 }
5159 }
5160 #include "frustum.h"
RenderTrailSegment(PHEROMONE_TRAIL * trailPtr)5161 void RenderTrailSegment(PHEROMONE_TRAIL *trailPtr)
5162 {
5163 POLYHEADER fakeHeader;
5164 VECTORCH temp;
5165 int Uoffset = GetCos(CloakingPhase&4095)*128;
5166 int Voffset = GetSin(CloakingPhase&4095)*128;
5167
5168 temp.vx = trailPtr->Vertex[0].vx - MUL_FIXED(trailPtr->Perp[0].vx,trailPtr->Size[0]/65536);
5169 temp.vy = trailPtr->Vertex[0].vy - MUL_FIXED(trailPtr->Perp[0].vy,trailPtr->Size[0]/65536);
5170 temp.vz = trailPtr->Vertex[0].vz - MUL_FIXED(trailPtr->Perp[0].vz,trailPtr->Size[0]/65536);
5171 VerticesBuffer[0].U = (temp.vx+temp.vz)*8192+Uoffset;
5172 VerticesBuffer[0].V = (temp.vy+temp.vz)*8192+Voffset;
5173 TranslatePointIntoViewspace(&temp);
5174 VerticesBuffer[0].X = temp.vx;
5175 VerticesBuffer[0].Y = temp.vy;
5176 VerticesBuffer[0].Z = temp.vz;
5177 // VerticesBuffer[0].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2;
5178 // VerticesBuffer[0].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2;
5179
5180 temp.vx = trailPtr->Vertex[0].vx + MUL_FIXED(trailPtr->Perp[0].vx,trailPtr->Size[0]/65536);
5181 temp.vy = trailPtr->Vertex[0].vy + MUL_FIXED(trailPtr->Perp[0].vy,trailPtr->Size[0]/65536);
5182 temp.vz = trailPtr->Vertex[0].vz + MUL_FIXED(trailPtr->Perp[0].vz,trailPtr->Size[0]/65536);
5183 VerticesBuffer[1].U = (temp.vx+temp.vz)*8192+Uoffset;
5184 VerticesBuffer[1].V = (temp.vy+temp.vz)*8192+Voffset;
5185 TranslatePointIntoViewspace(&temp);
5186 VerticesBuffer[1].X = temp.vx;
5187 VerticesBuffer[1].Y = temp.vy;
5188 VerticesBuffer[1].Z = temp.vz;
5189 // VerticesBuffer[1].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2;
5190 // VerticesBuffer[1].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2;
5191
5192
5193 temp.vx = trailPtr->Vertex[1].vx + MUL_FIXED(trailPtr->Perp[1].vx,trailPtr->Size[1]/65536);
5194 temp.vy = trailPtr->Vertex[1].vy + MUL_FIXED(trailPtr->Perp[1].vy,trailPtr->Size[1]/65536);
5195 temp.vz = trailPtr->Vertex[1].vz + MUL_FIXED(trailPtr->Perp[1].vz,trailPtr->Size[1]/65536);
5196 VerticesBuffer[2].U = (temp.vx+temp.vz)*8192+Uoffset;
5197 VerticesBuffer[2].V = (temp.vy+temp.vz)*8192+Voffset;
5198 TranslatePointIntoViewspace(&temp);
5199 VerticesBuffer[2].X = temp.vx;
5200 VerticesBuffer[2].Y = temp.vy;
5201 VerticesBuffer[2].Z = temp.vz;
5202 // VerticesBuffer[2].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2;
5203 // VerticesBuffer[2].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2;
5204
5205 temp.vx = trailPtr->Vertex[1].vx - MUL_FIXED(trailPtr->Perp[1].vx,trailPtr->Size[1]/65536);
5206 temp.vy = trailPtr->Vertex[1].vy - MUL_FIXED(trailPtr->Perp[1].vy,trailPtr->Size[1]/65536);
5207 temp.vz = trailPtr->Vertex[1].vz - MUL_FIXED(trailPtr->Perp[1].vz,trailPtr->Size[1]/65536);
5208 VerticesBuffer[3].U = (temp.vx+temp.vz)*8192+Uoffset;
5209 VerticesBuffer[3].V = (temp.vy+temp.vz)*8192+Voffset;
5210 TranslatePointIntoViewspace(&temp);
5211 VerticesBuffer[3].X = temp.vx;
5212 VerticesBuffer[3].Y = temp.vy;
5213 VerticesBuffer[3].Z = temp.vz;
5214 // VerticesBuffer[3].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2;
5215 // VerticesBuffer[3].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2;
5216
5217 {
5218 extern int SpecialFXImageNumber;
5219 extern int CloudyImageNumber;
5220 fakeHeader.PolyFlags = iflag_transparent;
5221 fakeHeader.PolyColour = SpecialFXImageNumber;
5222 fakeHeader.PolyColour = CloudyImageNumber;
5223 }
5224 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
5225
5226
5227 {
5228 int i;
5229 for (i=0; i<4; i++)
5230 {
5231 VerticesBuffer[i].A = trailPtr->Size[i/2]/65536;
5232
5233
5234 VerticesBuffer[i].R = 255;
5235 VerticesBuffer[i].G = 255;
5236 VerticesBuffer[i].B = 255;
5237 VerticesBuffer[i].SpecularR = 0;
5238 VerticesBuffer[i].SpecularG = 0;
5239 VerticesBuffer[i].SpecularB = 0;
5240
5241 }
5242 RenderPolygon.NumberOfVertices=4;
5243 }
5244
5245 GouraudTexturedPolygon_ClipWithZ();
5246 if(RenderPolygon.NumberOfVertices<3) return;
5247 GouraudTexturedPolygon_ClipWithNegativeX();
5248 if(RenderPolygon.NumberOfVertices<3) return;
5249 GouraudTexturedPolygon_ClipWithPositiveY();
5250 if(RenderPolygon.NumberOfVertices<3) return;
5251 GouraudTexturedPolygon_ClipWithNegativeY();
5252 if(RenderPolygon.NumberOfVertices<3) return;
5253 GouraudTexturedPolygon_ClipWithPositiveX();
5254 if(RenderPolygon.NumberOfVertices<3) return;
5255 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5256 }
5257
RenderParticlesInMirror(void)5258 extern void RenderParticlesInMirror(void)
5259 {
5260 /* now render particles */
5261 int i = NumActiveParticles;
5262 PARTICLE *particlePtr = ParticleStorage;
5263
5264 // RenderPlayersImageInMirror();
5265
5266 D3D_DecalSystem_Setup();
5267 while(i--)
5268 {
5269 switch(particlePtr->ParticleID)
5270 {
5271 case PARTICLE_FLARESMOKE:
5272 case PARTICLE_STEAM:
5273 case PARTICLE_BLACKSMOKE:
5274 case PARTICLE_IMPACTSMOKE:
5275 case PARTICLE_SMOKECLOUD:
5276 {
5277 particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx;
5278 RenderParticle(particlePtr);
5279 particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx;
5280 break;
5281 }
5282 default:
5283 break;
5284 }
5285 particlePtr++;
5286 }
5287 // DrawingAReflection=1;
5288 // DrawingAReflection=0;
5289
5290 {
5291 extern int NumOnScreenBlocks;
5292 extern DISPLAYBLOCK *OnScreenBlockList[];
5293 int numOfObjects = NumOnScreenBlocks;
5294 while(numOfObjects)
5295 {
5296 DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
5297
5298 if (!objectPtr->ObShape && objectPtr->SfxPtr)
5299 {
5300 DrawSfxObject(objectPtr);
5301 }
5302 }
5303 }
5304 D3D_DecalSystem_End();
5305
5306 }
5307
5308
5309
5310 #if 0
5311
5312 int FogNotSetupYet=1;
5313 int Fog_Phi[256];
5314 int Fog_Theta[256];
5315 int Fog_Radius[256];
5316 int Fog_PhiDelta[256];
5317 int Fog_ThetaDelta[256];
5318 int Fog_RadiusDelta[256];
5319
5320 void RenderFog(void)
5321 {
5322 int i;
5323 if (FogNotSetupYet)
5324 {
5325 FogNotSetupYet=0;
5326 for (i=0; i<256; i++)
5327 {
5328 Fog_Phi[i] = FastRandom()&2047;
5329 Fog_Theta[i] = FastRandom()&4095;
5330 Fog_Radius[i] = (FastRandom()&8191)-4096;
5331 Fog_PhiDelta[i] = (FastRandom()&1023)-512;
5332 Fog_ThetaDelta[i] = (FastRandom()&1023)-512;
5333 Fog_RadiusDelta[i] = (FastRandom()&255)+255;
5334 }
5335
5336 }
5337 for (i=0; i<255; i++)
5338 {
5339 int phi = Fog_Phi[i];
5340 int theta = Fog_Theta[i];
5341 int radius = Fog_Radius[i];
5342
5343 {
5344 PARTICLE particle;
5345 particle.ParticleID = PARTICLE_NONCOLLIDINGFLAME;
5346 particle.Position.vx = MUL_FIXED(MUL_FIXED(GetCos(phi),GetSin(theta)),radius);
5347 particle.Position.vy = MUL_FIXED(MUL_FIXED(GetSin(phi),GetSin(theta)),radius);
5348 if (particle.Position.vy<0)particle.Position.vy=-particle.Position.vy;
5349 particle.Position.vz = MUL_FIXED(GetCos(theta),radius);
5350 particle.Colour = RGBA_MAKE(255,255,255,255);
5351 particle.Size = 100;
5352 RenderParticle(&particle);
5353 }
5354 Fog_Phi[i]+= MUL_FIXED(Fog_PhiDelta[i],NormalFrameTime);
5355 Fog_Theta[i]+= MUL_FIXED(Fog_ThetaDelta[i],NormalFrameTime);
5356 Fog_Phi[i]&=2047;
5357 Fog_Theta[i]&=4095;
5358 if (Fog_Radius[i]>4096)
5359 {
5360 Fog_Radius[i]-= MUL_FIXED(Fog_RadiusDelta[i],NormalFrameTime);
5361 }
5362 else
5363 {
5364 Fog_Radius[i]+= MUL_FIXED(Fog_RadiusDelta[i],NormalFrameTime);
5365 }
5366
5367 }
5368
5369 }
5370 #endif
5371
5372
5373
5374
5375
5376
5377
5378
5379 #if 1
TimeScaleThingy()5380 void TimeScaleThingy()
5381 {
5382 extern int NumActiveBlocks;
5383 extern DISPLAYBLOCK *ActiveBlockList[];
5384 extern int TimeScale;
5385 int DesiredTimeScale=ONE_FIXED;
5386 extern int RealFrameTime;
5387
5388 int i;
5389
5390 for(i=0;i<NumActiveBlocks;i++)
5391 {
5392 STRATEGYBLOCK* sbPtr = ActiveBlockList[i]->ObStrategyBlock;
5393 if(sbPtr)
5394 {
5395 switch(sbPtr->I_SBtype)
5396 {
5397 case I_BehaviourAlien:
5398 case I_BehaviourQueenAlien :
5399 case I_BehaviourFaceHugger :
5400 case I_BehaviourPredator :
5401 case I_BehaviourXenoborg :
5402 case I_BehaviourMarine :
5403 case I_BehaviourSeal :
5404 case I_BehaviourPredatorAlien :
5405 case I_BehaviourAutoGun :
5406 DesiredTimeScale=MUL_FIXED(DesiredTimeScale,ONE_FIXED*.8);
5407 break;
5408
5409 case I_BehaviourGrenade :
5410 case I_BehaviourRocket :
5411 case I_BehaviourFrisbee:
5412 case I_BehaviourPulseGrenade :
5413 case I_BehaviourMolotov :
5414 DesiredTimeScale=MUL_FIXED(DesiredTimeScale,ONE_FIXED*.7);
5415 break;
5416
5417 default: ;
5418 }
5419 }
5420 }
5421
5422 for(i=0; i<MAX_NO_OF_EXPLOSIONS; i++)
5423 {
5424 if (ExplosionStorage[i].LifeTime)
5425 {
5426 DesiredTimeScale=MUL_FIXED(DesiredTimeScale,ONE_FIXED*.5);
5427 }
5428 }
5429
5430 if(DesiredTimeScale<ONE_FIXED) DesiredTimeScale=MUL_FIXED(DesiredTimeScale,ONE_FIXED*.8);
5431
5432 if(DesiredTimeScale<ONE_FIXED/10) DesiredTimeScale=ONE_FIXED/10;
5433
5434
5435 if(TimeScale<DesiredTimeScale)
5436 {
5437 TimeScale+=RealFrameTime/8;
5438 if(TimeScale>DesiredTimeScale) TimeScale=DesiredTimeScale;
5439 }
5440 else if (TimeScale>DesiredTimeScale)
5441 {
5442 TimeScale-=RealFrameTime;
5443 if(TimeScale<DesiredTimeScale) TimeScale=DesiredTimeScale;
5444 }
5445 }
5446 #else
TimeScaleThingy()5447 void TimeScaleThingy()
5448 {
5449 static int time=0;
5450 extern int TimeScale;
5451 extern int RealFrameTime;
5452 int ts;
5453
5454 time += RealFrameTime;
5455
5456 ts = GetSin((time/64)&4095);
5457 ts = MUL_FIXED(ts,ts)/2;
5458
5459 TimeScale = 32678 + ts;
5460 }
5461 #endif
5462
5463
5464
5465
5466 /*----------------------**
5467 ** Load/Save particles **
5468 **----------------------*/
5469
5470 typedef struct particle_save_block_header
5471 {
5472 SAVE_BLOCK_HEADER header;
5473
5474 int NumActiveParticles;
5475 int NumberOfBloodParticles;
5476
5477 //followed by paricle array after this block
5478
5479 }PARTICLE_SAVE_BLOCK_HEADER;
5480
Load_Particles(SAVE_BLOCK_HEADER * header)5481 void Load_Particles(SAVE_BLOCK_HEADER* header)
5482 {
5483 PARTICLE_SAVE_BLOCK_HEADER* block = (PARTICLE_SAVE_BLOCK_HEADER*) header;
5484 PARTICLE* saved_particle = (PARTICLE*)(block+1);
5485 int expected_size;
5486 int i;
5487
5488 //make sure the block is the correct size
5489 expected_size = sizeof(*block);
5490 expected_size += sizeof(PARTICLE) * block->NumActiveParticles;
5491 if(header->size != expected_size) return;
5492
5493 //right copy the stuff then
5494 NumActiveParticles = block->NumActiveParticles;
5495 NumberOfBloodParticles = block->NumberOfBloodParticles;
5496
5497 for(i=0;i<NumActiveParticles;i++)
5498 {
5499 ParticleStorage[i] = *saved_particle++;
5500 }
5501 }
5502
Save_Particles()5503 void Save_Particles()
5504 {
5505 PARTICLE_SAVE_BLOCK_HEADER* block;
5506 int i;
5507
5508 if(!NumActiveParticles) return;
5509
5510 //get memory for header
5511 GET_SAVE_BLOCK_POINTER(block);
5512
5513 //fill in header
5514 block->header.type = SaveBlock_Particles;
5515 block->header.size = sizeof(*block) + NumActiveParticles * sizeof(PARTICLE);
5516
5517 block->NumActiveParticles = NumActiveParticles;
5518 block->NumberOfBloodParticles = NumberOfBloodParticles;
5519
5520
5521 //now save the particles
5522 for(i=0;i<NumActiveParticles;i++)
5523 {
5524 PARTICLE* particle = GetPointerForSaveBlock(sizeof(PARTICLE));
5525 *particle = ParticleStorage[i];
5526 }
5527 }
5528
5529 /*----------------------**
5530 ** Load/Save Explosions **
5531 **----------------------*/
5532
5533 typedef struct explosion_save_block_header
5534 {
5535 SAVE_BLOCK_HEADER header;
5536
5537 int NumActiveExplosions;
5538 //followed by explosion array after this block
5539
5540 }EXPLOSION_SAVE_BLOCK_HEADER;
5541
5542
5543
Load_VolumetricExplosions(SAVE_BLOCK_HEADER * header)5544 void Load_VolumetricExplosions(SAVE_BLOCK_HEADER* header)
5545 {
5546 int i;
5547 EXPLOSION_SAVE_BLOCK_HEADER* block = (EXPLOSION_SAVE_BLOCK_HEADER*) header;
5548 VOLUMETRIC_EXPLOSION* saved_explosion = (VOLUMETRIC_EXPLOSION*) (block+1);
5549 int expected_size;
5550
5551 //make sure the block is the correct size
5552 expected_size = sizeof(*block);
5553 expected_size += sizeof(VOLUMETRIC_EXPLOSION) * block->NumActiveExplosions;
5554 if(header->size != expected_size) return;
5555
5556 for(i=0;i<block->NumActiveExplosions;i++)
5557 {
5558 VOLUMETRIC_EXPLOSION* explosion = AllocateVolumetricExplosion();
5559 if(explosion)
5560 {
5561 *explosion = *saved_explosion++;
5562 }
5563 }
5564
5565 }
5566
Save_VolumetricExplosions()5567 void Save_VolumetricExplosions()
5568 {
5569 int i;
5570 EXPLOSION_SAVE_BLOCK_HEADER* block;
5571 int NumActiveExplosions = 0;
5572
5573 //first find the number of explosions currently active
5574 for(i=0;i<MAX_NO_OF_EXPLOSIONS;i++)
5575 {
5576 if(ExplosionStorage[i].LifeTime) NumActiveExplosions++;
5577 }
5578
5579 //don's save if there aren't any
5580 if(!NumActiveExplosions) return;
5581
5582 //get memory for header
5583 GET_SAVE_BLOCK_POINTER(block);
5584
5585 //fill in header
5586 block->header.type = SaveBlock_VolumetricExplosions;
5587 block->header.size = sizeof(*block) + NumActiveExplosions * sizeof(VOLUMETRIC_EXPLOSION);
5588
5589 block->NumActiveExplosions = NumActiveExplosions;
5590
5591 //now save the explosions
5592 for(i=0;i<MAX_NO_OF_EXPLOSIONS;i++)
5593 {
5594 if(ExplosionStorage[i].LifeTime)
5595 {
5596 VOLUMETRIC_EXPLOSION* explosion = GetPointerForSaveBlock(sizeof(VOLUMETRIC_EXPLOSION));
5597 *explosion = ExplosionStorage[i];
5598 }
5599 }
5600 }
5601
5602
5603 /*----------------------------**
5604 ** Load/Save pheromone trails **
5605 **----------------------------*/
5606
5607 typedef struct pheromone_save_block_header
5608 {
5609 SAVE_BLOCK_HEADER header;
5610
5611 int NumActiveTrails;
5612 //followed by pheromone array after this block
5613
5614 }PHEROMONE_SAVE_BLOCK_HEADER;
5615
5616
5617
Load_PheromoneTrails(SAVE_BLOCK_HEADER * header)5618 void Load_PheromoneTrails(SAVE_BLOCK_HEADER* header)
5619 {
5620 int i;
5621 PHEROMONE_SAVE_BLOCK_HEADER* block = (PHEROMONE_SAVE_BLOCK_HEADER*) header;
5622 PHEROMONE_TRAIL* saved_trail = (PHEROMONE_TRAIL*) (block+1);
5623 int expected_size;
5624
5625 //make sure the block is the correct size
5626 expected_size = sizeof(*block);
5627 expected_size += sizeof(PHEROMONE_TRAIL) * block->NumActiveTrails;
5628 if(header->size != expected_size) return;
5629
5630 for(i=0;i<block->NumActiveTrails;i++)
5631 {
5632 PHEROMONE_TRAIL* trail = AllocatePheromoneTrail();
5633 if(trail)
5634 {
5635 *trail = *saved_trail++;
5636 }
5637 }
5638
5639 }
5640
Save_PheromoneTrails()5641 void Save_PheromoneTrails()
5642 {
5643 PHEROMONE_SAVE_BLOCK_HEADER* block;
5644 int i;
5645
5646 if(!NumActiveTrails) return;
5647
5648 //get memory for header
5649 GET_SAVE_BLOCK_POINTER(block);
5650
5651 //fill in header
5652 block->header.type = SaveBlock_PheromoneTrail;
5653 block->header.size = sizeof(*block) + NumActiveTrails * sizeof(PHEROMONE_TRAIL);
5654
5655 block->NumActiveTrails = NumActiveTrails;
5656
5657
5658 //now save the trails
5659 for(i=0;i<NumActiveTrails;i++)
5660 {
5661 PHEROMONE_TRAIL* trail = GET_SAVE_BLOCK_POINTER(trail);
5662 *trail = TrailStorage[i];
5663 }
5664
5665 }
5666