4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "system.h"
 
 
2
#include "stratdef.h"
 
 
3
#include "bh_types.h"
 
 
4
#include "dynamics.h"
 
 
5
#include "kshape.h"
 
 
6
#include "sfx.h"
 
 
7
#include "lighting.h"
 
 
8
#include "bh_light.h"
 
 
9
#include "npc_xenoborg.h"
 
 
10
#include "weapons.h"
 
 
11
#include "weaponbehaviour.h"
 
 
12
#include "pldghost.h"
 
 
13
#include "userprofile.h"
 
 
14
#include "savegame.h"
 
 
15
#include "los.h"
 
 
16
#include <math.h>
 
 
17
#include <assert.h>
 
 
18
 
 
 
19
#define MAX_NO_OF_PHEROMONE_TRAILS 500
 
 
20
#define MAX_NO_OF_EXPLOSIONS 10
 
 
21
#define TRAIL_DECAY_SPEED (51*65536*5)
 
 
22
 
 
 
23
static PHEROMONE_TRAIL TrailStorage[MAX_NO_OF_PHEROMONE_TRAILS];
 
 
24
 
 
 
25
static PARTICLE ParticleStorage[MAX_NO_OF_PARTICLES];
 
 
26
static PARTICLE BloodParticleStorage[MAX_NO_OF_BLOOD_PARTICLES];
 
 
27
 
 
 
28
static struct VOLUMETRIC_EXPLOSION ExplosionStorage[MAX_NO_OF_EXPLOSIONS];
 
 
29
static struct VOLUMETRIC_EXPLOSION* active_volumetric_explosion[MAX_NO_OF_EXPLOSIONS];
 
 
30
static int NumActiveTrails;
 
 
31
static int NumActiveParticles;
 
 
32
static int CurrentExplosionIndex;
 
 
33
 
 
 
34
extern int SeededFastRandom();
 
 
35
extern void SetSeededFastRandom(int seed);
 
 
36
 
 
 
37
extern void PostLandscapeRendering();
 
 
38
extern void DrawParticle_Rain(PARTICLE *particlePtr, VECTORCH *prevPositionPtr);
 
 
39
extern void AttachSpearGunArrow(DISPLAYBLOCK *dptr);
 
 
40
extern void TexturedPolygon(int texture, RENDERVERTEX *vertices, enum TRANSLUCENCY_TYPE TranslucencyMode);
 
 
41
 
 
 
42
extern DISPLAYBLOCK *ActiveBlockList[];
 
 
43
extern int NumActiveBlocks;
 
 
44
extern int PrevNormalFrameTime;
 
 
45
extern int CloakingPhase;
 
 
46
extern SOUND3DDATA PredPistolExplosion_SoundData;
 
 
47
 
 
 
48
extern struct KObject VisibleObjects[maxobjects];
 
 
49
extern int numVisObjs;
 
 
50
 
 
 
51
int NumberOfBloodParticles;
 
 
52
 
 
 
53
const PARTICLE_DESC ParticleDescription[MAX_NO_OF_PARTICLE_IDS] =
 
 
54
{
 
 
55
    /* PARTICLE_PREDATOR_BLOOD */
 
 
56
    {
 
 
57
        //int StartU;
 
 
58
        0<<16,
 
 
59
        //int StartV;
 
 
60
        64<<16,
 
 
61
        //int EndU;
 
 
62
        63<<16,
 
 
63
        //int EndV;
 
 
64
        127<<16,
 
 
65
        //unsigned int Size;
 
 
66
        200,
 
 
67
 
 
 
68
        TRANSLUCENCY_GLOWING,
 
 
69
 
 
 
70
        //unsigned char Alpha;
 
 
71
        128,
 
 
72
        //unsigned char RedScale;
 
 
73
        {0, 0, 255, 255, 255},
 
 
74
        //unsigned char GreenScale;
 
 
75
        {255, 255, 255, 255, 0},
 
 
76
        //unsigned char BlueScale;
 
 
77
        {0, 0, 255, 255, 0},
 
 
78
 
 
 
79
        //unsigned char IsLit:1;
 
 
80
        0,
 
 
81
        //IsDrawnInFront:1;
 
 
82
        0,
 
 
83
        //IsDrawnAtBack:1;
 
 
84
        0
 
 
85
    },
 
 
86
    /* PARTICLE_ALIEN_BLOOD */
 
 
87
    {
 
 
88
        //int StartU;
 
 
89
        0<<16,
 
 
90
        //int StartV;
 
 
91
        64<<16,
 
 
92
        //int EndU;
 
 
93
        63<<16,
 
 
94
        //int EndV;
 
 
95
        127<<16,
 
 
96
        //unsigned int Size;
 
 
97
        50,
 
 
98
 
 
 
99
        TRANSLUCENCY_GLOWING,
 
 
100
 
 
 
101
        //unsigned char Alpha;
 
 
102
        128,
 
 
103
        //unsigned char RedScale;
 
 
104
        {255, 255, 0, 16, 255},
 
 
105
        //unsigned char GreenScale;
 
 
106
        {255, 255, 255, 0, 255},
 
 
107
        //unsigned char BlueScale;
 
 
108
        {0, 0, 0, 255, 255},
 
 
109
 
 
 
110
        //unsigned char IsLit:1;
 
 
111
        1,
 
 
112
        //IsDrawnInFront:1;
 
 
113
        0,
 
 
114
        //IsDrawnAtBack:1;
 
 
115
        0
 
 
116
    },
 
 
117
    /* PARTICLE_HUMAN_BLOOD */
 
 
118
    {
 
 
119
        //int StartU;
 
 
120
        0<<16,
 
 
121
        //int StartV;
 
 
122
        63<<16,
 
 
123
        //int EndU;
 
 
124
        63<<16,
 
 
125
        //int EndV;
 
 
126
        127<<16,
 
 
127
        //unsigned int Size;
 
 
128
        50,
 
 
129
 
 
 
130
        TRANSLUCENCY_INVCOLOUR,
 
 
131
 
 
 
132
        //unsigned char Alpha;
 
 
133
        255,
 
 
134
        //unsigned char RedScale;
 
 
135
        {0, 0, 0, 0, 0},
 
 
136
        //unsigned char GreenScale;
 
 
137
        {255, 255, 64, 64, 255},
 
 
138
        //unsigned char BlueScale;
 
 
139
        {255, 255, 0, 64, 255},
 
 
140
 
 
 
141
        //unsigned char IsLit:1;
 
 
142
        0,
 
 
143
        //IsDrawnInFront:1;
 
 
144
        0,
 
 
145
        //IsDrawnAtBack:1;
 
 
146
        0
 
 
147
    },
 
 
148
    /* PARTICLE_ANDROID_BLOOD */
 
 
149
    {
 
 
150
        //int StartU;
 
 
151
        0<<16,
 
 
152
        //int StartV;
 
 
153
        63<<16,
 
 
154
        //int EndU;
 
 
155
        63<<16,
 
 
156
        //int EndV;
 
 
157
        127<<16,
 
 
158
        //unsigned int Size;
 
 
159
        50,
 
 
160
 
 
 
161
        TRANSLUCENCY_GLOWING,
 
 
162
 
 
 
163
        //unsigned char Alpha;
 
 
164
        255,
 
 
165
        //unsigned char RedScale;
 
 
166
        {255, 255, 255, 255, 255},
 
 
167
        //unsigned char GreenScale;
 
 
168
        {255, 255, 255, 255, 255},
 
 
169
        //unsigned char BlueScale;
 
 
170
        {255, 255, 255, 255, 255},
 
 
171
 
 
 
172
        //unsigned char IsLit:1;
 
 
173
        1,
 
 
174
        //IsDrawnInFront:1;
 
 
175
        0,
 
 
176
        //IsDrawnAtBack:1;
 
 
177
        0
 
 
178
    },
 
 
179
    /* PARTICLE_MUZZLEFLASH */
 
 
180
    {
 
 
181
        //int StartU;
 
 
182
        64<<16,
 
 
183
        //int StartV;
 
 
184
        64<<16,
 
 
185
        //int EndU;
 
 
186
        127<<16,
 
 
187
        //int EndV;
 
 
188
        127<<16,
 
 
189
        //unsigned int Size;
 
 
190
        200,
 
 
191
 
 
 
192
        TRANSLUCENCY_GLOWING,
 
 
193
 
 
 
194
        //unsigned char Alpha;
 
 
195
        155,
 
 
196
        //unsigned char RedScale;
 
 
197
        {255, 255, 255, 255, 255},
 
 
198
        //unsigned char GreenScale;
 
 
199
        {192, 255, 255, 0, 255},
 
 
200
        //unsigned char BlueScale;
 
 
201
        {128, 255, 255, 0, 0},
 
 
202
 
 
 
203
        //unsigned char IsLit:1;
 
 
204
        0,
 
 
205
        //IsDrawnInFront:1;
 
 
206
        0,
 
 
207
        //IsDrawnAtBack:1;
 
 
208
        0
 
 
209
    },
 
 
210
    /* PARTICLE_WATERSPRAY */
 
 
211
    {
 
 
212
        //int StartU;
 
 
213
        0<<16,
 
 
214
        //int StartV;
 
 
215
           64<<16,
 
 
216
        //int EndU;
 
 
217
        63<<16,
 
 
218
        //int EndV;
 
 
219
        127<<16,
 
 
220
        //unsigned int Size;
 
 
221
        80,
 
 
222
 
 
 
223
        TRANSLUCENCY_GLOWING,
 
 
224
 
 
 
225
        //unsigned char Alpha;
 
 
226
        64,
 
 
227
        //unsigned char RedScale;
 
 
228
        {200, 200, 0, 0},
 
 
229
        //unsigned char GreenScale;
 
 
230
        {230, 230, 240, 0},
 
 
231
        //unsigned char BlueScale;
 
 
232
        {255, 255, 0, 120},
 
 
233
 
 
 
234
        //unsigned char IsLit:1;
 
 
235
        1,
 
 
236
        //IsDrawnInFront:1;
 
 
237
        0,
 
 
238
        //IsDrawnAtBack:1;
 
 
239
        0
 
 
240
    },
 
 
241
    /* PARTICLE_WATERFALLSPRAY */
 
 
242
    {
 
 
243
        //int StartU;
 
 
244
        0<<16,
 
 
245
        //int StartV;
 
 
246
           64<<16,
 
 
247
        //int EndU;
 
 
248
        63<<16,
 
 
249
        //int EndV;
 
 
250
        127<<16,
 
 
251
        //unsigned int Size;
 
 
252
        1600,//200,
 
 
253
 
 
 
254
        TRANSLUCENCY_GLOWING,
 
 
255
 
 
 
256
        //unsigned char Alpha;
 
 
257
        32,
 
 
258
        //unsigned char RedScale;
 
 
259
        {100, 200, 240, 120, 120, 120},
 
 
260
        //unsigned char GreenScale;
 
 
261
        {130, 230, 240, 120, 120, 120},
 
 
262
        //unsigned char BlueScale;
 
 
263
        {255, 255, 240, 120, 120, 120},
 
 
264
 
 
 
265
        //unsigned char IsLit:1;
 
 
266
        0,
 
 
267
        //IsDrawnInFront:1;
 
 
268
        0,
 
 
269
        //IsDrawnAtBack:1;
 
 
270
        0
 
 
271
    },
 
 
272
    /* PARTICLE_BLACKSMOKE */
 
 
273
    {
 
 
274
        //int StartU;
 
 
275
        0<<16,
 
 
276
        //int StartV;
 
 
277
           130<<16,
 
 
278
        //int EndU;
 
 
279
        28<<16,
 
 
280
        //int EndV;
 
 
281
        157<<16,
 
 
282
        //unsigned int Size;
 
 
283
        200,
 
 
284
 
 
 
285
        TRANSLUCENCY_INVCOLOUR,
 
 
286
 
 
 
287
        //unsigned char Alpha;
 
 
288
        255,
 
 
289
        //unsigned char RedScale;
 
 
290
        {64, 64, 64, 64, 64},
 
 
291
        //unsigned char GreenScale;
 
 
292
        {64, 64, 64, 64, 64},
 
 
293
        //unsigned char BlueScale;
 
 
294
        {64, 64, 64, 64, 64},
 
 
295
 
 
 
296
        //unsigned char IsLit:1;
 
 
297
        0,
 
 
298
        //IsDrawnInFront:1;
 
 
299
        0,
 
 
300
        //IsDrawnAtBack:1;
 
 
301
        0
 
 
302
    },
 
 
303
    /* PARTICLE_FLARESMOKE */
 
 
304
    {
 
 
305
        //int StartU;
 
 
306
        128<<16,
 
 
307
        //int StartV;
 
 
308
           0<<16,
 
 
309
        //int EndU;
 
 
310
        195<<16,
 
 
311
        //int EndV;
 
 
312
        63<<16,
 
 
313
        //unsigned int Size;
 
 
314
        200,
 
 
315
 
 
 
316
        TRANSLUCENCY_GLOWING,
 
 
317
 
 
 
318
        //unsigned char Alpha;
 
 
319
        64,
 
 
320
        //unsigned char RedScale;
 
 
321
        {255, 255, 255, 255, 64},
 
 
322
        //unsigned char GreenScale;
 
 
323
        {255, 255, 255, 0, 64},
 
 
324
        //unsigned char BlueScale;
 
 
325
        {255, 255, 255, 64, 0},
 
 
326
 
 
 
327
        //unsigned char IsLit:1;
 
 
328
        0,
 
 
329
        //IsDrawnInFront:1;
 
 
330
        0,
 
 
331
        //IsDrawnAtBack:1;
 
 
332
        0
 
 
333
    },
 
 
334
    /* PARTICLE_STEAM */
 
 
335
    {
 
 
336
        //int StartU;
 
 
337
        0<<16,
 
 
338
        //int StartV;
 
 
339
           130<<16,
 
 
340
        //int EndU;
 
 
341
        28<<16,
 
 
342
        //int EndV;
 
 
343
        157<<16,
 
 
344
        //unsigned int Size;
 
 
345
        100,
 
 
346
 
 
 
347
        TRANSLUCENCY_GLOWING,
 
 
348
 
 
 
349
        //unsigned char Alpha;
 
 
350
        64,
 
 
351
        //unsigned char RedScale;
 
 
352
        {128, 128, 128, 128, 64},
 
 
353
        //unsigned char GreenScale;
 
 
354
        {128, 128, 128, 128, 64},
 
 
355
        //unsigned char BlueScale;
 
 
356
        {128, 128, 128, 128, 0},
 
 
357
 
 
 
358
        //unsigned char IsLit:1;
 
 
359
        0,
 
 
360
        //IsDrawnInFront:1;
 
 
361
        0,
 
 
362
        //IsDrawnAtBack:1;
 
 
363
        0
 
 
364
    },
 
 
365
    /* PARTICLE_IMPACTSMOKE */
 
 
366
    {
 
 
367
        //int StartU;
 
 
368
        0<<16,
 
 
369
        //int StartV;
 
 
370
           130<<16,
 
 
371
        //int EndU;
 
 
372
        28<<16,
 
 
373
        //int EndV;
 
 
374
        157<<16,
 
 
375
        //unsigned int Size;
 
 
376
        //100,
 
 
377
        50,
 
 
378
 
 
 
379
        TRANSLUCENCY_INVCOLOUR,
 
 
380
 
 
 
381
        //unsigned char Alpha;
 
 
382
        255,
 
 
383
        //unsigned char RedScale;
 
 
384
        {64, 64, 64, 64, 64},
 
 
385
        //unsigned char GreenScale;
 
 
386
        {64, 64, 64, 64, 64},
 
 
387
        //unsigned char BlueScale;
 
 
388
        {64, 64, 64, 64, 64},
 
 
389
 
 
 
390
        //unsigned char IsLit:1;
 
 
391
        0,
 
 
392
        //IsDrawnInFront:1;
 
 
393
        0,
 
 
394
        //IsDrawnAtBack:1;
 
 
395
        0
 
 
396
    },
 
 
397
    /* PARTICLE_GUNMUZZLE_SMOKE */
 
 
398
    {
 
 
399
        //int StartU;
 
 
400
        128<<16,
 
 
401
        //int StartV;
 
 
402
           0<<16,
 
 
403
        //int EndU;
 
 
404
        195<<16,
 
 
405
        //int EndV;
 
 
406
        63<<16,
 
 
407
        //unsigned int Size;
 
 
408
        8,
 
 
409
 
 
 
410
        TRANSLUCENCY_INVCOLOUR,
 
 
411
 
 
 
412
        //unsigned char Alpha;
 
 
413
        64,
 
 
414
        //unsigned char RedScale;
 
 
415
        {64, 64, 64, 64, 64},
 
 
416
        //unsigned char GreenScale;
 
 
417
        {64, 64, 64, 64, 64},
 
 
418
        //unsigned char BlueScale;
 
 
419
        {64, 64, 64, 64, 64},
 
 
420
 
 
 
421
        //unsigned char IsLit:1;
 
 
422
        0,
 
 
423
        //IsDrawnInFront:1;
 
 
424
        0,
 
 
425
        //IsDrawnAtBack:1;
 
 
426
        0
 
 
427
    },
 
 
428
    /* PARTICLE_FLAME */
 
 
429
    {
 
 
430
        //int StartU;
 
 
431
        64<<16,
 
 
432
        //int StartV;
 
 
433
           0<<16,
 
 
434
        //int EndU;
 
 
435
        (64+127)<<16,
 
 
436
        //int EndV;
 
 
437
        63<<16,
 
 
438
        //unsigned int Size;
 
 
439
        0,
 
 
440
 
 
 
441
        TRANSLUCENCY_GLOWING,
 
 
442
 
 
 
443
        //unsigned char Alpha;
 
 
444
        64,
 
 
445
        //unsigned char RedScale;
 
 
446
        {255, 255, 255, 128, 128, 0},
 
 
447
        //unsigned char GreenScale;
 
 
448
        {128, 128, 255, 64, 64, 128},
 
 
449
        //unsigned char BlueScale;
 
 
450
        {64, 64, 255, 255, 0, 0},
 
 
451
 
 
 
452
        //unsigned char IsLit:1;
 
 
453
        0,
 
 
454
        //IsDrawnInFront:1;
 
 
455
        0,
 
 
456
        //IsDrawnAtBack:1;
 
 
457
        0
 
 
458
    },
 
 
459
    /* PARTICLE_NONCOLLIDINGFLAME */
 
 
460
    {
 
 
461
        //int StartU;
 
 
462
        64<<16,
 
 
463
        //int StartV;
 
 
464
           0<<16,
 
 
465
        //int EndU;
 
 
466
        (64+127)<<16,
 
 
467
        //int EndV;
 
 
468
        63<<16,
 
 
469
        //unsigned int Size;
 
 
470
        0,
 
 
471
 
 
 
472
        TRANSLUCENCY_GLOWING,
 
 
473
 
 
 
474
        //unsigned char Alpha;
 
 
475
        64,
 
 
476
        //unsigned char RedScale;
 
 
477
        {255, 255, 255, 128, 128, 0},
 
 
478
        //unsigned char GreenScale;
 
 
479
        {128, 128, 255, 64, 64, 128},
 
 
480
        //unsigned char BlueScale;
 
 
481
        {64, 64, 255, 255, 0, 0},
 
 
482
 
 
 
483
        //unsigned char IsLit:1;
 
 
484
        0,
 
 
485
        //IsDrawnInFront:1;
 
 
486
        0,
 
 
487
        //IsDrawnAtBack:1;
 
 
488
        0
 
 
489
    },
 
 
490
    /* PARTICLE_NONDAMAGINGFLAME */
 
 
491
    {
 
 
492
        //int StartU;
 
 
493
        64<<16,
 
 
494
        //int StartV;
 
 
495
           0<<16,
 
 
496
        //int EndU;
 
 
497
        (64+127)<<16,
 
 
498
        //int EndV;
 
 
499
        63<<16,
 
 
500
        //unsigned int Size;
 
 
501
        0,
 
 
502
 
 
 
503
        TRANSLUCENCY_GLOWING,
 
 
504
 
 
 
505
        //unsigned char Alpha;
 
 
506
        64,
 
 
507
        //unsigned char RedScale;
 
 
508
        {255, 255, 255, 128, 128, 0},
 
 
509
        //unsigned char GreenScale;
 
 
510
        {128, 128, 255, 64, 64, 128},
 
 
511
        //unsigned char BlueScale;
 
 
512
        {64, 64, 255, 255, 0, 0},
 
 
513
 
 
 
514
        //unsigned char IsLit:1;
 
 
515
        0,
 
 
516
        //IsDrawnInFront:1;
 
 
517
        0,
 
 
518
        //IsDrawnAtBack:1;
 
 
519
        0
 
 
520
    },
 
 
521
    /* PARTICLE_FIRE */
 
 
522
    {
 
 
523
           //int StartU;
 
 
524
        0<<16,
 
 
525
        //int StartV;
 
 
526
           0<<16,
 
 
527
        //int EndU;
 
 
528
        63<<16,
 
 
529
        //int EndV;
 
 
530
        63<<16,
 
 
531
        //unsigned int Size;
 
 
532
        0,
 
 
533
 
 
 
534
        TRANSLUCENCY_GLOWING,
 
 
535
 
 
 
536
        //unsigned char Alpha;
 
 
537
        64,
 
 
538
        //unsigned char RedScale;
 
 
539
        {255, 255, 255, 128, 128, 0},
 
 
540
        //unsigned char GreenScale;
 
 
541
        {128, 128, 255, 64, 64, 128},
 
 
542
        //unsigned char BlueScale;
 
 
543
        {64, 64, 255, 255, 0, 0},
 
 
544
 
 
 
545
        //unsigned char IsLit:1;
 
 
546
        0,
 
 
547
        //IsDrawnInFront:1;
 
 
548
        0,
 
 
549
        //IsDrawnAtBack:1;
 
 
550
        0
 
 
551
    },
 
 
552
    /* PARTICLE_EXPLOSIONFIRE */
 
 
553
    {
 
 
554
        //int StartU;
 
 
555
        0<<16,
 
 
556
        //int StartV;
 
 
557
           0<<16,
 
 
558
        //int EndU;
 
 
559
        48<<16,
 
 
560
        //int EndV;
 
 
561
        63<<16,
 
 
562
        //unsigned int Size;
 
 
563
        800,
 
 
564
 
 
 
565
        TRANSLUCENCY_GLOWING,
 
 
566
 
 
 
567
        //unsigned char Alpha;
 
 
568
        255,  
 
 
569
        //unsigned char RedScale;
 
 
570
        {255, 255, 255, 128, 128, 0},
 
 
571
        //unsigned char GreenScale;
 
 
572
        {128, 128, 255, 64, 64, 128},
 
 
573
        //unsigned char BlueScale;
 
 
574
        {64, 64, 255, 255, 0, 0},
 
 
575
 
 
 
576
        //unsigned char IsLit:1;
 
 
577
        0,
 
 
578
        //IsDrawnInFront:1;
 
 
579
        0,
 
 
580
        //IsDrawnAtBack:1;
 
 
581
        0
 
 
582
    },
 
 
583
    /* PARTICLE_MOLOTOVFLAME */
 
 
584
    {
 
 
585
        //int StartU;
 
 
586
        64<<16,
 
 
587
        //int StartV;
 
 
588
           0<<16,
 
 
589
        //int EndU;
 
 
590
        (64+127)<<16,
 
 
591
        //int EndV;
 
 
592
        63<<16,
 
 
593
        //unsigned int Size;
 
 
594
        800,
 
 
595
 
 
 
596
        TRANSLUCENCY_GLOWING,
 
 
597
 
 
 
598
        //unsigned char Alpha;
 
 
599
        255,  
 
 
600
        //unsigned char RedScale;
 
 
601
        {255, 255, 255, 128, 128, 0},
 
 
602
        //unsigned char GreenScale;
 
 
603
        {128, 128, 255, 64, 64, 128},
 
 
604
        //unsigned char BlueScale;
 
 
605
        {64, 64, 255, 255, 0, 0},
 
 
606
 
 
 
607
        //unsigned char IsLit:1;
 
 
608
        0,
 
 
609
        //IsDrawnInFront:1;
 
 
610
        0,
 
 
611
        //IsDrawnAtBack:1;
 
 
612
        0
 
 
613
    },
 
 
614
    /* PARTICLE_SPARK */
 
 
615
    {
 
 
616
        //int StartU;
 
 
617
        1<<16,
 
 
618
        //int StartV;
 
 
619
           1<<16,
 
 
620
        //int EndU;
 
 
621
        64<<16,
 
 
622
        //int EndV;
 
 
623
        64<<16,
 
 
624
        //unsigned int Size;
 
 
625
        200/8,
 
 
626
 
 
 
627
        TRANSLUCENCY_GLOWING,
 
 
628
 
 
 
629
        //unsigned char Alpha;
 
 
630
        64,
 
 
631
        //unsigned char RedScale;
 
 
632
        {255, 255, 255, 255, 255},
 
 
633
        //unsigned char GreenScale;
 
 
634
        {128, 128, 255, 0, 255},
 
 
635
        //unsigned char BlueScale;
 
 
636
        {64, 64, 255, 0, 0},
 
 
637
 
 
 
638
        //unsigned char IsLit:1;
 
 
639
        0,
 
 
640
        //IsDrawnInFront:1;
 
 
641
        0,
 
 
642
        //IsDrawnAtBack:1;
 
 
643
        0
 
 
644
    },
 
 
645
    /* PARTICLE_RICOCHET_SPARK */
 
 
646
    {
 
 
647
        //int StartU;
 
 
648
        1<<16,
 
 
649
        //int StartV;
 
 
650
           1<<16,
 
 
651
        //int EndU;
 
 
652
        64<<16,
 
 
653
        //int EndV;
 
 
654
        64<<16,
 
 
655
        //unsigned int Size;
 
 
656
        200/8,
 
 
657
 
 
 
658
        TRANSLUCENCY_GLOWING,
 
 
659
 
 
 
660
        //unsigned char Alpha;
 
 
661
        64,
 
 
662
        //unsigned char RedScale;
 
 
663
        {255, 255, 255, 255, 255},
 
 
664
        //unsigned char GreenScale;
 
 
665
        {128, 128, 255, 0, 255},
 
 
666
        //unsigned char BlueScale;
 
 
667
        {64, 64, 255, 0, 255},
 
 
668
 
 
 
669
        //unsigned char IsLit:1;
 
 
670
        0,
 
 
671
        //IsDrawnInFront:1;
 
 
672
        0,
 
 
673
        //IsDrawnAtBack:1;
 
 
674
        0
 
 
675
    },
 
 
676
    /* PARTICLE_ORANGE_SPARK */
 
 
677
    {
 
 
678
        //int StartU;
 
 
679
        224<<16,
 
 
680
        //int StartV;
 
 
681
           192<<16,
 
 
682
        //int EndU;
 
 
683
        255<<16,
 
 
684
        //int EndV;
 
 
685
        223<<16,
 
 
686
        //unsigned int Size;
 
 
687
        50,
 
 
688
 
 
 
689
        TRANSLUCENCY_GLOWING,
 
 
690
 
 
 
691
        //unsigned char Alpha;
 
 
692
        255,
 
 
693
        //unsigned char RedScale;
 
 
694
        {255, 64, 64, 64, 64},
 
 
695
        //unsigned char GreenScale;
 
 
696
        {255, 64, 64, 64, 64},
 
 
697
        //unsigned char BlueScale;
 
 
698
        {255, 64, 64, 64, 64},
 
 
699
 
 
 
700
        //unsigned char IsLit:1;
 
 
701
        0,
 
 
702
        //IsDrawnInFront:1;
 
 
703
        0,
 
 
704
        //IsDrawnAtBack:1;
 
 
705
        0
 
 
706
    },
 
 
707
    /* PARTICLE_ORANGE_PLASMA */
 
 
708
    {
 
 
709
        //int StartU;
 
 
710
        224<<16,
 
 
711
        //int StartV;
 
 
712
           192<<16,
 
 
713
        //int EndU;
 
 
714
        255<<16,
 
 
715
        //int EndV;
 
 
716
        223<<16,
 
 
717
        //unsigned int Size;
 
 
718
        50,
 
 
719
 
 
 
720
        TRANSLUCENCY_GLOWING,
 
 
721
 
 
 
722
        //unsigned char Alpha;
 
 
723
        255,
 
 
724
        //unsigned char RedScale;
 
 
725
        {255, 64, 64, 64, 64, 0},
 
 
726
        //unsigned char GreenScale;
 
 
727
        {255, 64, 64, 64, 64, 64},
 
 
728
        //unsigned char BlueScale;
 
 
729
        {255, 64, 64, 64, 64, 0},
 
 
730
 
 
 
731
        //unsigned char IsLit:1;
 
 
732
        0,
 
 
733
        //IsDrawnInFront:1;
 
 
734
        0,
 
 
735
        //IsDrawnAtBack:1;
 
 
736
        0
 
 
737
    },
 
 
738
    /* PARTICLE_PLASMATRAIL */
 
 
739
    {
 
 
740
        //int StartU;
 
 
741
        64<<16,
 
 
742
        //int StartV;
 
 
743
        64<<16,
 
 
744
        //int EndU;
 
 
745
        127<<16,
 
 
746
        //int EndV;
 
 
747
        127<<16,
 
 
748
        //unsigned int Size;
 
 
749
        200/4,
 
 
750
 
 
 
751
        TRANSLUCENCY_GLOWING,
 
 
752
 
 
 
753
        //unsigned char Alpha;
 
 
754
        64,
 
 
755
        //unsigned char RedScale;
 
 
756
        {255, 255, 255, 255, 255, 0},
 
 
757
        //unsigned char GreenScale;
 
 
758
        {128, 128, 255, 0, 255, 255},
 
 
759
        //unsigned char BlueScale;
 
 
760
        {64, 64, 255, 0, 0, 0},
 
 
761
 
 
 
762
        //unsigned char IsLit:1;
 
 
763
        0,
 
 
764
        //IsDrawnInFront:1;
 
 
765
        0,
 
 
766
        //IsDrawnAtBack:1;
 
 
767
        0
 
 
768
    },
 
 
769
    /* PARTICLE_LASERBEAM */
 
 
770
    {
 
 
771
        //int StartU;
 
 
772
        32<<16,
 
 
773
        //int StartV;
 
 
774
           0<<16,
 
 
775
        //int EndU;
 
 
776
        32<<16,
 
 
777
        //int EndV;
 
 
778
        63<<16,
 
 
779
        //unsigned int Size;
 
 
780
        50,
 
 
781
 
 
 
782
        TRANSLUCENCY_GLOWING,
 
 
783
 
 
 
784
        //unsigned char Alpha;
 
 
785
        64,
 
 
786
        //unsigned char RedScale;
 
 
787
        {255, 255, 255, 255, 255, 0},
 
 
788
        //unsigned char GreenScale;
 
 
789
        {128, 128, 255, 0, 255, 255},
 
 
790
        //unsigned char BlueScale;
 
 
791
        {64, 64, 255, 0, 0, 0},
 
 
792
 
 
 
793
        //unsigned char IsLit:1;
 
 
794
        0,
 
 
795
        //IsDrawnInFront:1;
 
 
796
        0,
 
 
797
        //IsDrawnAtBack:1;
 
 
798
        0
 
 
799
    },
 
 
800
    /* PARTICLE_PLASMABEAM */
 
 
801
    {
 
 
802
        //int StartU;
 
 
803
        192<<16,
 
 
804
        //int StartV;
 
 
805
           224<<16,
 
 
806
        //int EndU;
 
 
807
        223<<16,
 
 
808
        //int EndV;
 
 
809
        255<<16,
 
 
810
        //unsigned int Size;
 
 
811
        50,
 
 
812
 
 
 
813
        TRANSLUCENCY_GLOWING,
 
 
814
 
 
 
815
        //unsigned char Alpha;
 
 
816
        64,
 
 
817
        //unsigned char RedScale;
 
 
818
        {255, 255, 255, 255, 255, 0},
 
 
819
        //unsigned char GreenScale;
 
 
820
        {128, 128, 255, 0, 255, 255},
 
 
821
        //unsigned char BlueScale;
 
 
822
        {64, 64, 255, 0, 0, 0},
 
 
823
 
 
 
824
        //unsigned char IsLit:1;
 
 
825
        0,
 
 
826
        //IsDrawnInFront:1;
 
 
827
        0,
 
 
828
        //IsDrawnAtBack:1;
 
 
829
        0
 
 
830
    },
 
 
831
    /* PARTICLE_LIGHTFLARE */
 
 
832
    {
 
 
833
        //int StartU;
 
 
834
        64<<16,
 
 
835
        //int StartV;
 
 
836
        64<<16,
 
 
837
        //int EndU;
 
 
838
        127<<16,
 
 
839
        //int EndV;
 
 
840
        127<<16,
 
 
841
        //unsigned int Size;
 
 
842
        200,
 
 
843
 
 
 
844
        TRANSLUCENCY_GLOWING,
 
 
845
 
 
 
846
        //unsigned char Alpha;
 
 
847
        255,
 
 
848
        //unsigned char RedScale;
 
 
849
        {255, 255, 255, 255, 255, 0},
 
 
850
        //unsigned char GreenScale;
 
 
851
        {255, 255, 255, 0, 255, 255},
 
 
852
        //unsigned char BlueScale;
 
 
853
        {255, 255, 255, 0, 0, 0},
 
 
854
 
 
 
855
        //unsigned char IsLit:1;
 
 
856
        0,
 
 
857
        //IsDrawnInFront:1;
 
 
858
        1,
 
 
859
        //IsDrawnAtBack:1;
 
 
860
        0
 
 
861
    },
 
 
862
    /* PARTICLE_STAR */
 
 
863
    {
 
 
864
        //int StartU;
 
 
865
        64<<16,
 
 
866
        //int StartV;
 
 
867
        64<<16,
 
 
868
        //int EndU;
 
 
869
        127<<16,
 
 
870
        //int EndV;
 
 
871
        127<<16,
 
 
872
        //unsigned int Size;
 
 
873
        200,
 
 
874
 
 
 
875
        TRANSLUCENCY_GLOWING,
 
 
876
 
 
 
877
        //unsigned char Alpha;
 
 
878
        255,
 
 
879
        //unsigned char RedScale;
 
 
880
        {255, 255, 255, 255, 255, 0},
 
 
881
        //unsigned char GreenScale;
 
 
882
        {255, 255, 255, 0, 255, 255},
 
 
883
        //unsigned char BlueScale;
 
 
884
        {255, 255, 255, 0, 0, 0},
 
 
885
 
 
 
886
        //unsigned char IsLit:1;
 
 
887
        0,
 
 
888
        //IsDrawnInFront:1;
 
 
889
        0,
 
 
890
        //IsDrawnAtBack:1;
 
 
891
        1
 
 
892
    },
 
 
893
    /* PARTICLE_FLECHETTE */
 
 
894
    {
 
 
895
        //int StartU;
 
 
896
        64<<16,
 
 
897
        //int StartV;
 
 
898
        64<<16,
 
 
899
        //int EndU;
 
 
900
        127<<16,
 
 
901
        //int EndV;
 
 
902
        127<<16,
 
 
903
        //unsigned int Size;
 
 
904
        100,
 
 
905
 
 
 
906
        TRANSLUCENCY_NORMAL,
 
 
907
 
 
 
908
        //unsigned char Alpha;
 
 
909
        255,
 
 
910
        //unsigned char RedScale;
 
 
911
        {255, 255, 255, 255, 255, 0},
 
 
912
        //unsigned char GreenScale;
 
 
913
        {255, 255, 255, 0, 255, 255},
 
 
914
        //unsigned char BlueScale;
 
 
915
        {255, 255, 255, 0, 0, 0},
 
 
916
 
 
 
917
        //unsigned char IsLit:1;
 
 
918
        0,
 
 
919
        //IsDrawnInFront:1;
 
 
920
        0,
 
 
921
        //IsDrawnAtBack:1;
 
 
922
        0
 
 
923
    },
 
 
924
    /* PARTICLE_SMOKECLOUD */
 
 
925
    {
 
 
926
        //int StartU;
 
 
927
        128<<16,
 
 
928
        //int StartV;
 
 
929
           64<<16,
 
 
930
        //int EndU;
 
 
931
        191<<16,
 
 
932
        //int EndV;
 
 
933
        127<<16,
 
 
934
        //unsigned int Size;
 
 
935
        1000,
 
 
936
 
 
 
937
        TRANSLUCENCY_GLOWING,
 
 
938
 
 
 
939
        //unsigned char Alpha;
 
 
940
        255,
 
 
941
        //unsigned char RedScale;
 
 
942
        {128, 64, 64, 64, 0},
 
 
943
        //unsigned char GreenScale;
 
 
944
        {128, 64, 64, 64, 64},
 
 
945
        //unsigned char BlueScale;
 
 
946
        {128, 64, 64, 64, 0},
 
 
947
 
 
 
948
        //unsigned char IsLit:1;
 
 
949
        0,
 
 
950
        //IsDrawnInFront:1;
 
 
951
        0,
 
 
952
        //IsDrawnAtBack:1;
 
 
953
        0
 
 
954
    },
 
 
955
    /* PARTICLE_ELECTRICALPLASMASPHERE */
 
 
956
    {
 
 
957
        //int StartU;
 
 
958
        64<<16,
 
 
959
        //int StartV;
 
 
960
           128<<16,
 
 
961
        //int EndU;
 
 
962
        127<<16,
 
 
963
        //int EndV;
 
 
964
        191<<16,
 
 
965
        //unsigned int Size;
 
 
966
        2000,
 
 
967
 
 
 
968
        TRANSLUCENCY_GLOWING,
 
 
969
 
 
 
970
        //unsigned char Alpha;
 
 
971
        255,
 
 
972
        //unsigned char RedScale;
 
 
973
        {255, 64, 64, 64, 64, 0},
 
 
974
        //unsigned char GreenScale;
 
 
975
        {255, 64, 64, 64, 64, 255},
 
 
976
        //unsigned char BlueScale;
 
 
977
        {255, 64, 64, 64, 0, 0},
 
 
978
 
 
 
979
        //unsigned char IsLit:1;
 
 
980
        0,
 
 
981
        //IsDrawnInFront:1;
 
 
982
        0,
 
 
983
        //IsDrawnAtBack:1;
 
 
984
        0
 
 
985
    }, 
 
 
986
    /* PARTICLE_FLECHETTE_NONDAMAGING */
 
 
987
    {
 
 
988
        //int StartU;
 
 
989
        64<<16,
 
 
990
        //int StartV;
 
 
991
        64<<16,
 
 
992
        //int EndU;
 
 
993
        127<<16,
 
 
994
        //int EndV;
 
 
995
        127<<16,
 
 
996
        //unsigned int Size;
 
 
997
        100,
 
 
998
 
 
 
999
        TRANSLUCENCY_NORMAL,
 
 
1000
 
 
 
1001
        //unsigned char Alpha;
 
 
1002
        255,
 
 
1003
        //unsigned char RedScale;
 
 
1004
        {255, 255, 255, 255, 255, 0},
 
 
1005
        //unsigned char GreenScale;
 
 
1006
        {255, 255, 255, 0, 255, 255},
 
 
1007
        //unsigned char BlueScale;
 
 
1008
        {255, 255, 255, 0, 0, 0},
 
 
1009
 
 
 
1010
        //unsigned char IsLit:1;
 
 
1011
        0,
 
 
1012
        //IsDrawnInFront:1;
 
 
1013
        0,
 
 
1014
        //IsDrawnAtBack:1;
 
 
1015
        0
 
 
1016
    },
 
 
1017
    /* PARTICLE_DEWLINE */
 
 
1018
    {
 
 
1019
        //int StartU;
 
 
1020
        64<<16,
 
 
1021
        //int StartV;
 
 
1022
        64<<16,
 
 
1023
        //int EndU;
 
 
1024
        127<<16,
 
 
1025
        //int EndV;
 
 
1026
        127<<16,
 
 
1027
        //unsigned int Size;
 
 
1028
        200/4,
 
 
1029
 
 
 
1030
        TRANSLUCENCY_GLOWING,
 
 
1031
 
 
 
1032
        //unsigned char Alpha;
 
 
1033
        64,
 
 
1034
        //unsigned char RedScale;
 
 
1035
        {255, 255, 255, 255, 255, 0},
 
 
1036
        //unsigned char GreenScale;
 
 
1037
        {128, 128, 255, 0, 255, 255},
 
 
1038
        //unsigned char BlueScale;
 
 
1039
        {64, 64, 255, 0, 0, 0},
 
 
1040
 
 
 
1041
        //unsigned char IsLit:1;
 
 
1042
        0,
 
 
1043
        //IsDrawnInFront:1;
 
 
1044
        0,
 
 
1045
        //IsDrawnAtBack:1;
 
 
1046
        0
 
 
1047
    },
 
 
1048
    /* PARTICLE_LIGHT */
 
 
1049
    {
 
 
1050
        //int StartU;
 
 
1051
        64<<16,
 
 
1052
        //int StartV;
 
 
1053
        64<<16,
 
 
1054
        //int EndU;
 
 
1055
        127<<16,
 
 
1056
        //int EndV;
 
 
1057
        127<<16,
 
 
1058
 
 
 
1059
        //unsigned int Size;
 
 
1060
        400,
 
 
1061
 
 
 
1062
        TRANSLUCENCY_GLOWING,
 
 
1063
 
 
 
1064
        //unsigned char Alpha;
 
 
1065
        0,
 
 
1066
        //unsigned char RedScale;
 
 
1067
        {255, 255, 255, 255, 255},
 
 
1068
        //unsigned char GreenScale;
 
 
1069
        {192, 255, 255, 0, 255},
 
 
1070
        //unsigned char BlueScale;
 
 
1071
        {128, 255, 255, 0, 0},
 
 
1072
 
 
 
1073
        //unsigned char IsLit:1;
 
 
1074
        0,
 
 
1075
        //IsDrawnInFront:1;
 
 
1076
        0,
 
 
1077
        //IsDrawnAtBack:1;
 
 
1078
        0
 
 
1079
    }
 
 
1080
};
 
 
1081
 
 
 
1082
#define MAX_NO_OF_RIPPLES 100
 
 
1083
#define MAX_RAINDROPS 1000
 
 
1084
 
 
 
1085
static struct
 
 
1086
{
 
 
1087
    int Active;
 
 
1088
    int X;
 
 
1089
    int Z;
 
 
1090
    int Amplitude;
 
 
1091
    int Radius;
 
 
1092
    int InvRadius;
 
 
1093
 
 
 
1094
} RippleStorage[MAX_NO_OF_RIPPLES];
 
 
1095
 
 
 
1096
static PARTICLE RainDropStorage[MAX_RAINDROPS];
 
 
1097
int ActiveRippleNumber;
 
 
1098
 
 
 
1099
static void InitialiseRainDrops()
 
 
1100
{
 
 
1101
    int i = MAX_RAINDROPS;
 
 
1102
    ActiveRippleNumber = 0;
 
 
1103
 
 
 
1104
    for(i=0; i < MAX_RAINDROPS; ++i)
 
 
1105
    {
 
 
1106
        PARTICLE *particlePtr = &RainDropStorage[i];
 
 
1107
        particlePtr->Position.vy = 0x7fffffff;
 
 
1108
        particlePtr->LifeTime = 0;
 
 
1109
    }
 
 
1110
 
 
 
1111
    i = MAX_NO_OF_RIPPLES;
 
 
1112
 
 
 
1113
    for(i=0; i < MAX_NO_OF_RIPPLES; ++i)
 
 
1114
        RippleStorage[i].Active = 0;
 
 
1115
}
 
 
1116
 
 
 
1117
void InitialiseParticleSystem()
 
 
1118
{
 
 
1119
     NumActiveParticles = NumberOfBloodParticles = NumActiveTrails = CurrentExplosionIndex = 0;
 
 
1120
 
 
 
1121
    InitialiseRainDrops();
 
 
1122
}
 
 
1123
 
 
 
1124
static PHEROMONE_TRAIL* AllocatePheromoneTrail()
 
 
1125
{
 
 
1126
    return (NumActiveTrails < MAX_NO_OF_PHEROMONE_TRAILS) ? &TrailStorage[NumActiveTrails++] : NULL;
 
 
1127
}
 
 
1128
 
 
 
1129
static struct VOLUMETRIC_EXPLOSION* AllocateVolumetricExplosion()
 
 
1130
{
 
 
1131
    if (CurrentExplosionIndex >= MAX_NO_OF_EXPLOSIONS)
 
 
1132
        CurrentExplosionIndex = 0;
 
 
1133
 
 
 
1134
    active_volumetric_explosion[CurrentExplosionIndex] = &ExplosionStorage[CurrentExplosionIndex];
 
 
1135
 
 
 
1136
    return &ExplosionStorage[CurrentExplosionIndex++];
 
 
1137
}
 
 
1138
 
 
 
1139
void MakeBloodParticle(VECTORCH *positionPtr, VECTORCH *velocityPtr, enum PARTICLE_ID particleID)
 
 
1140
{
 
 
1141
    if (NumberOfBloodParticles < UserProfile.GameOptions.BloodParticles)
 
 
1142
    {
 
 
1143
        PARTICLE *particlePtr = &BloodParticleStorage[NumberOfBloodParticles];
 
 
1144
        const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particleID];
 
 
1145
        particlePtr->Position = *positionPtr;
 
 
1146
        particlePtr->Velocity = *velocityPtr;
 
 
1147
        particlePtr->ParticleID = particleID;
 
 
1148
        particlePtr->Colour = RGBA_MAKE (particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
1149
                        particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
1150
                        particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
1151
                        particleDescPtr->Alpha);
 
 
1152
 
 
 
1153
        particlePtr->Size = particleDescPtr->Size;
 
 
1154
 
 
 
1155
        switch(particlePtr->ParticleID)
 
 
1156
        {
 
 
1157
            case PARTICLE_ALIEN_BLOOD:
 
 
1158
            case PARTICLE_HUMAN_BLOOD:
 
 
1159
            case PARTICLE_PREDATOR_BLOOD:
 
 
1160
            case PARTICLE_ANDROID_BLOOD:
 
 
1161
                particlePtr->Offset = particlePtr->Position;
 
 
1162
                particlePtr->LifeTime = ONE_FIXED * 4;
 
 
1163
            break;
 
 
1164
            case PARTICLE_SPARK:      
 
 
1165
                particlePtr->LifeTime = ONE_FIXED;
 
 
1166
            default:
 
 
1167
            return;
 
 
1168
        }
 
 
1169
 
 
 
1170
        NumberOfBloodParticles++;
 
 
1171
    }
 
 
1172
}
 
 
1173
 
 
 
1174
void MakeParticle(const VECTORCH *positionPtr, const VECTORCH *velocityPtr, enum PARTICLE_ID particleID)
 
 
1175
{
 
 
1176
    if (NumActiveParticles < UserProfile.GameOptions.NoneBloodParticles)
 
 
1177
    {
 
 
1178
        PARTICLE *particlePtr = &ParticleStorage[NumActiveParticles];
 
 
1179
 
 
 
1180
        const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particleID];
 
 
1181
        particlePtr->Position = *positionPtr;
 
 
1182
        particlePtr->Velocity = *velocityPtr;
 
 
1183
        particlePtr->ParticleID = particleID;
 
 
1184
        particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
1185
                        particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
1186
                        particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
1187
                        particleDescPtr->Alpha);
 
 
1188
 
 
 
1189
        particlePtr->Size = particleDescPtr->Size;
 
 
1190
 
 
 
1191
        switch(particlePtr->ParticleID)
 
 
1192
        {
 
 
1193
            case PARTICLE_BLACKSMOKE:
 
 
1194
                particlePtr->LifeTime = ONE_FIXED + (FastRandom() & 32767);
 
 
1195
                particlePtr->Offset.vx = ((FastRandom()&1023) - 512) * 2;
 
 
1196
                particlePtr->Offset.vz = ((FastRandom()&1023) - 512) * 2;
 
 
1197
            break;
 
 
1198
            case PARTICLE_FLARESMOKE:
 
 
1199
            case PARTICLE_STEAM:
 
 
1200
                particlePtr->LifeTime = (ONE_FIXED) /2 + (FastRandom() & 32767);
 
 
1201
                particlePtr->Offset.vx = ((FastRandom() & 8191) - 4096);
 
 
1202
                particlePtr->Offset.vz = ((FastRandom() & 8191) - 4096);
 
 
1203
            break;
 
 
1204
            case PARTICLE_IMPACTSMOKE:
 
 
1205
                particlePtr->LifeTime = ONE_FIXED + (FastRandom() & 32767);
 
 
1206
                particlePtr->Offset.vx = ((FastRandom() & 1023) - 512)*2;
 
 
1207
                particlePtr->Offset.vz = ((FastRandom() & 1023) - 512)*2;
 
 
1208
            break;
 
 
1209
            case PARTICLE_GUNMUZZLE_SMOKE:
 
 
1210
                particlePtr->LifeTime = ONE_FIXED + (FastRandom() & 32767);
 
 
1211
                particlePtr->Offset.vx = ((FastRandom() & 1023) - 512) * 0;
 
 
1212
                particlePtr->Offset.vz = ((FastRandom() & 1023) - 512) * 0;
 
 
1213
            break;
 
 
1214
            case PARTICLE_SPARK:
 
 
1215
                particlePtr->LifeTime = ONE_FIXED;
 
 
1216
            break;
 
 
1217
            case PARTICLE_RICOCHET_SPARK:
 
 
1218
            case PARTICLE_ORANGE_SPARK:
 
 
1219
                particlePtr->LifeTime = ONE_FIXED/4;
 
 
1220
            break;
 
 
1221
            case PARTICLE_FLAME:
 
 
1222
            case PARTICLE_NONCOLLIDINGFLAME:
 
 
1223
            case PARTICLE_NONDAMAGINGFLAME:
 
 
1224
                particlePtr->Offset.vx = (FastRandom() & 4095);
 
 
1225
                particlePtr->Offset.vy = ((FastRandom() & 32767) - 16384);
 
 
1226
                particlePtr->LifeTime = ONE_FIXED/2;
 
 
1227
            break;
 
 
1228
            case PARTICLE_FIRE:
 
 
1229
                particlePtr->LifeTime = ONE_FIXED/2 + (FastRandom() & 16383);
 
 
1230
            break;
 
 
1231
            case PARTICLE_MOLOTOVFLAME:
 
 
1232
                particlePtr->LifeTime = ONE_FIXED*2 - (FastRandom() & 32767);
 
 
1233
            break;
 
 
1234
            case PARTICLE_FLECHETTE:
 
 
1235
            case PARTICLE_FLECHETTE_NONDAMAGING:
 
 
1236
                particlePtr->LifeTime = ONE_FIXED * 8;
 
 
1237
                particlePtr->Offset.vy = 1;
 
 
1238
            break;
 
 
1239
            case PARTICLE_SMOKECLOUD:
 
 
1240
                particlePtr->LifeTime = ONE_FIXED*16-1;
 
 
1241
                particlePtr->Offset.vx = (FastRandom() & 4095);
 
 
1242
                particlePtr->Offset.vy = ((FastRandom() & 16383) - 8192);
 
 
1243
            break;
 
 
1244
            case PARTICLE_ELECTRICALPLASMASPHERE:
 
 
1245
                particlePtr->LifeTime = 32767;
 
 
1246
            break;
 
 
1247
            case PARTICLE_ORANGE_PLASMA:
 
 
1248
                particlePtr->LifeTime = ONE_FIXED/8;
 
 
1249
            break;
 
 
1250
            case PARTICLE_PLASMATRAIL:
 
 
1251
            case PARTICLE_DEWLINE:
 
 
1252
                particlePtr->LifeTime = ONE_FIXED;
 
 
1253
                particlePtr->Offset = particlePtr->Position;
 
 
1254
            break;
 
 
1255
            case PARTICLE_WATERSPRAY:
 
 
1256
                particlePtr->LifeTime = ONE_FIXED/2;
 
 
1257
            break;
 
 
1258
            case PARTICLE_WATERFALLSPRAY:
 
 
1259
                particlePtr->LifeTime = ONE_FIXED*10;
 
 
1260
            break;
 
 
1261
            default:
 
 
1262
            {
 
 
1263
                assert(0);
 
 
1264
                return;
 
 
1265
            }
 
 
1266
        }
 
 
1267
 
 
 
1268
        NumActiveParticles++;
 
 
1269
    }
 
 
1270
}
 
 
1271
 
 
 
1272
static void DoFlareCorona(DISPLAYBLOCK *objectPtr)
 
 
1273
{
 
 
1274
    if(IsThisObjectVisibleFromThisPosition_WithIgnore(objectPtr, PlayerStatus.DisplayBlock, &Global_VDB.VDB_World))
 
 
1275
    {
 
 
1276
        LIGHTBLOCK *lPtr = objectPtr->ObLights[0];
 
 
1277
        int a = lPtr->LightBright >> 8;
 
 
1278
        int colour;
 
 
1279
 
 
 
1280
        if (a > 255)
 
 
1281
            a = 255;
 
 
1282
 
 
 
1283
        switch (PlayerStatus.VisionMode)
 
 
1284
        {
 
 
1285
            case VISION_MODE_NORMAL:
 
 
1286
            default:
 
 
1287
                colour = 0xffc8ff + (a<<24);
 
 
1288
            break;
 
 
1289
            case VISION_MODE_IMAGEINTENSIFIER:
 
 
1290
                colour = 0xffffffff;
 
 
1291
            break;
 
 
1292
            case VISION_MODE_PRED_THERMAL:
 
 
1293
            case VISION_MODE_PRED_SEEALIENS:
 
 
1294
            case VISION_MODE_PRED_SEEPREDTECH:
 
 
1295
            {
 
 
1296
                int b = MUL_FIXED(lPtr->RedScale + lPtr->GreenScale + lPtr->BlueScale, lPtr->LightBright) >> 10;
 
 
1297
 
 
 
1298
                if (b > 255)
 
 
1299
                    b = 255;
 
 
1300
 
 
 
1301
                colour = 0xff000000 + (b << 16) + ((b >> 1) << 8);
 
 
1302
            }
 
 
1303
        }
 
 
1304
 
 
 
1305
        RenderLightFlare(&objectPtr->ObWorld, colour);
 
 
1306
    }
 
 
1307
}
 
 
1308
 
 
 
1309
static void HandleRipples()
 
 
1310
{
 
 
1311
    int i;
 
 
1312
 
 
 
1313
    for(i=0; i < MAX_NO_OF_RIPPLES; i++)
 
 
1314
    {
 
 
1315
        if (RippleStorage[i].Active)
 
 
1316
        {
 
 
1317
            RippleStorage[i].Radius    += MUL_FIXED(2400, NormalFrameTime);
 
 
1318
            RippleStorage[i].InvRadius = DIV_FIXED(4090, RippleStorage[i].Radius);
 
 
1319
            RippleStorage[i].Amplitude -= MUL_FIXED(50, NormalFrameTime);
 
 
1320
 
 
 
1321
            if (RippleStorage[i].Amplitude < 0)
 
 
1322
                RippleStorage[i].Active = 0;
 
 
1323
        }
 
 
1324
    }
 
 
1325
}
 
 
1326
 
 
 
1327
static void HandleVolumetricExplosion()
 
 
1328
{
 
 
1329
    int x;
 
 
1330
    for (x = 0; x < CurrentExplosionIndex;) 
 
 
1331
    {
 
 
1332
        struct VOLUMETRIC_EXPLOSION *expPtr = active_volumetric_explosion[x];
 
 
1333
        RenderExplosionSurface(expPtr);
 
 
1334
 
 
 
1335
        int i, v_temp = DIV_FIXED(SPHERE_VERTICES, expPtr->NumberVerticesMoving+1) + ONE_FIXED;
 
 
1336
        int velocityModifier = MUL_FIXED(GetSin(expPtr->LifeTime/64)/16, v_temp);
 
 
1337
        PARTICLE particle;
 
 
1338
        particle.ParticleID = PARTICLE_EXPLOSIONFIRE;
 
 
1339
 
 
 
1340
        for(i=0; i < SPHERE_VERTICES; i++)
 
 
1341
        {
 
 
1342
            if (expPtr->Velocity[i].vx || expPtr->Velocity[i].vy || expPtr->Velocity[i].vz)
 
 
1343
            {
 
 
1344
                particle.Velocity = expPtr->Velocity[i];
 
 
1345
                int v = GetSin((CloakingPhase*4+expPtr->RipplePhase[i]) & 4095) / 4;
 
 
1346
                v = velocityModifier + MUL_FIXED(v, velocityModifier);
 
 
1347
                particle.Velocity.vx = MUL_FIXED(particle.Velocity.vx, v);
 
 
1348
                particle.Velocity.vy = MUL_FIXED(particle.Velocity.vy, v);
 
 
1349
                particle.Velocity.vz = MUL_FIXED(particle.Velocity.vz, v);
 
 
1350
                particle.Position = expPtr->Position[i];
 
 
1351
 
 
 
1352
                if(expPtr->UseCollisions)
 
 
1353
                {
 
 
1354
                    VECTORCH obstacleNormal;
 
 
1355
                    int moduleIndex;
 
 
1356
 
 
 
1357
                    if(ParticleDynamics(&particle, &obstacleNormal, &moduleIndex))
 
 
1358
                    {
 
 
1359
                        if(-1 != moduleIndex) // make explosion deformable against none modules?
 
 
1360
                        {
 
 
1361
                        /*
 
 
1362
                            int magOfPerpImp = DotProduct(&obstacleNormal, &expPtr->Velocity[i]);
 
 
1363
                            expPtr->Velocity[i].vx -= MUL_FIXED(obstacleNormal.vx, magOfPerpImp);
 
 
1364
                            expPtr->Velocity[i].vy -= MUL_FIXED(obstacleNormal.vy, magOfPerpImp);
 
 
1365
                            expPtr->Velocity[i].vz -= MUL_FIXED(obstacleNormal.vz, magOfPerpImp);
 
 
1366
                        */
 
 
1367
                            expPtr->Velocity[i] = particle.Velocity;
 
 
1368
 
 
 
1369
                            if(!expPtr->BeenStopped[i])
 
 
1370
                            {
 
 
1371
                                expPtr->BeenStopped[i] = 1;
 
 
1372
                                expPtr->NumberVerticesMoving--;
 
 
1373
                                MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particle.Position, moduleIndex);
 
 
1374
                            }
 
 
1375
                        }
 
 
1376
                    }
 
 
1377
                }
 
 
1378
                else
 
 
1379
                {
 
 
1380
                    particle.Position.vx += MUL_FIXED(particle.Velocity.vx, NormalFrameTime);
 
 
1381
                    particle.Position.vy += MUL_FIXED(particle.Velocity.vy, NormalFrameTime);
 
 
1382
                    particle.Position.vz += MUL_FIXED(particle.Velocity.vz, NormalFrameTime);
 
 
1383
                }
 
 
1384
 
 
 
1385
                expPtr->Position[i] = particle.Position;
 
 
1386
            }
 
 
1387
        }
 
 
1388
 
 
 
1389
        expPtr->LifeTime -= NormalFrameTime;
 
 
1390
 
 
 
1391
        if (expPtr->LifeTime <= 0)
 
 
1392
        {
 
 
1393
            if(--CurrentExplosionIndex)
 
 
1394
            {
 
 
1395
                active_volumetric_explosion[x] = active_volumetric_explosion[CurrentExplosionIndex];
 
 
1396
                continue;
 
 
1397
            }
 
 
1398
            else
 
 
1399
            {
 
 
1400
                return;
 
 
1401
            }
 
 
1402
        }
 
 
1403
    x++;
 
 
1404
    }
 
 
1405
}
 
 
1406
 
 
 
1407
static void DrawXenoborgMainLaserbeam(LASER_BEAM_DESC *laserPtr)
 
 
1408
{
 
 
1409
    if (laserPtr->BeamHasHitPlayer)
 
 
1410
    {
 
 
1411
        int colour;
 
 
1412
        switch (PlayerStatus.VisionMode)
 
 
1413
        {
 
 
1414
            default:
 
 
1415
            case VISION_MODE_NORMAL:
 
 
1416
                colour = 0xff0000ff;
 
 
1417
            break;
 
 
1418
            case VISION_MODE_IMAGEINTENSIFIER:
 
 
1419
                colour = 0xffffffff;
 
 
1420
            break;
 
 
1421
            case VISION_MODE_PRED_THERMAL:
 
 
1422
            case VISION_MODE_PRED_SEEALIENS:
 
 
1423
            case VISION_MODE_PRED_SEEPREDTECH:
 
 
1424
                colour = 0xffff8000; 
 
 
1425
        }
 
 
1426
 
 
 
1427
        RenderLightFlare(&laserPtr->SourcePosition, colour);
 
 
1428
        RenderLightFlare(&laserPtr->SourcePosition, 0xffffffff);
 
 
1429
    }
 
 
1430
    else
 
 
1431
    {
 
 
1432
        PARTICLE particle;
 
 
1433
        switch (PlayerStatus.VisionMode)
 
 
1434
        {
 
 
1435
            default:
 
 
1436
            case VISION_MODE_NORMAL:
 
 
1437
                particle.Colour = RGBA_MAKE(0,0,255,255);
 
 
1438
            break;
 
 
1439
            case VISION_MODE_IMAGEINTENSIFIER:
 
 
1440
                particle.Colour = RGBA_MAKE(255,255,255,255);
 
 
1441
            break;
 
 
1442
            case VISION_MODE_PRED_THERMAL:
 
 
1443
            case VISION_MODE_PRED_SEEALIENS:
 
 
1444
            case VISION_MODE_PRED_SEEPREDTECH:
 
 
1445
                particle.Colour = RGBA_MAKE(255,128,0,255);
 
 
1446
        }
 
 
1447
         particle.Colour = RGBA_MAKE(255,255,255,255);
 
 
1448
        particle.ParticleID = PARTICLE_PLASMABEAM;
 
 
1449
        particle.Position = laserPtr->SourcePosition;
 
 
1450
        particle.Offset = laserPtr->TargetPosition;
 
 
1451
        particle.Size = 32;
 
 
1452
        RenderParticle(&particle);
 
 
1453
     //    particle.Colour = RGBA_MAKE(255,255,255,255);
 
 
1454
     //    particle.Size = 20;
 
 
1455
     //    RenderParticle(&particle);
 
 
1456
    }
 
 
1457
}
 
 
1458
 
 
 
1459
#include "frustum.h"
 
 
1460
static void RenderTrailSegment(PHEROMONE_TRAIL *trailPtr)
 
 
1461
{
 
 
1462
    extern int CloudyImageNumber;
 
 
1463
    RENDERVERTEX *VerticesBuffer = VerticesUnClipped;
 
 
1464
    VECTORCH temp;
 
 
1465
    int Uoffset = GetCos(CloakingPhase & 4095) * 128;
 
 
1466
    int Voffset = GetSin(CloakingPhase & 4095) * 128;
 
 
1467
    int i;
 
 
1468
 
 
 
1469
    temp.vx = trailPtr->Vertex[0].vx - MUL_FIXED(trailPtr->Perp[0].vx, trailPtr->Size[0]/65536);
 
 
1470
    temp.vy = trailPtr->Vertex[0].vy - MUL_FIXED(trailPtr->Perp[0].vy, trailPtr->Size[0]/65536);
 
 
1471
    temp.vz    = trailPtr->Vertex[0].vz - MUL_FIXED(trailPtr->Perp[0].vz, trailPtr->Size[0]/65536);
 
 
1472
    VerticesBuffer[0].U = (temp.vx+temp.vz)*8192+Uoffset;
 
 
1473
    VerticesBuffer[0].V = (temp.vy+temp.vz)*8192+Voffset;
 
 
1474
    TranslatePointIntoViewspace(&temp);
 
 
1475
    VerticesBuffer[0].X = temp.vx;
 
 
1476
    VerticesBuffer[0].Y = temp.vy;
 
 
1477
    VerticesBuffer[0].Z    = temp.vz;
 
 
1478
//    VerticesBuffer[0].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2;
 
 
1479
//    VerticesBuffer[0].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2;
 
 
1480
 
 
 
1481
    temp.vx = trailPtr->Vertex[0].vx + MUL_FIXED(trailPtr->Perp[0].vx,trailPtr->Size[0]/65536);
 
 
1482
    temp.vy = trailPtr->Vertex[0].vy + MUL_FIXED(trailPtr->Perp[0].vy,trailPtr->Size[0]/65536);
 
 
1483
    temp.vz    = trailPtr->Vertex[0].vz + MUL_FIXED(trailPtr->Perp[0].vz,trailPtr->Size[0]/65536);
 
 
1484
    VerticesBuffer[1].U = (temp.vx+temp.vz)*8192+Uoffset;
 
 
1485
    VerticesBuffer[1].V = (temp.vy+temp.vz)*8192+Voffset;
 
 
1486
    TranslatePointIntoViewspace(&temp);
 
 
1487
    VerticesBuffer[1].X = temp.vx;
 
 
1488
    VerticesBuffer[1].Y = temp.vy;
 
 
1489
    VerticesBuffer[1].Z    = temp.vz;
 
 
1490
//    VerticesBuffer[1].U = ParticleDescription[PARTICLE_PLASMABEAM].StartU/2;
 
 
1491
//    VerticesBuffer[1].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2;
 
 
1492
 
 
 
1493
    temp.vx = trailPtr->Vertex[1].vx + MUL_FIXED(trailPtr->Perp[1].vx,trailPtr->Size[1]/65536);
 
 
1494
    temp.vy = trailPtr->Vertex[1].vy + MUL_FIXED(trailPtr->Perp[1].vy,trailPtr->Size[1]/65536);
 
 
1495
    temp.vz    = trailPtr->Vertex[1].vz + MUL_FIXED(trailPtr->Perp[1].vz,trailPtr->Size[1]/65536);
 
 
1496
    VerticesBuffer[2].U = (temp.vx+temp.vz)*8192+Uoffset;
 
 
1497
    VerticesBuffer[2].V = (temp.vy+temp.vz)*8192+Voffset;
 
 
1498
    TranslatePointIntoViewspace(&temp);
 
 
1499
    VerticesBuffer[2].X = temp.vx;
 
 
1500
    VerticesBuffer[2].Y = temp.vy;
 
 
1501
    VerticesBuffer[2].Z    = temp.vz;
 
 
1502
//    VerticesBuffer[2].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2;
 
 
1503
//    VerticesBuffer[2].V = ParticleDescription[PARTICLE_PLASMABEAM].EndV/2;
 
 
1504
 
 
 
1505
    temp.vx = trailPtr->Vertex[1].vx - MUL_FIXED(trailPtr->Perp[1].vx, trailPtr->Size[1]/65536);
 
 
1506
    temp.vy = trailPtr->Vertex[1].vy - MUL_FIXED(trailPtr->Perp[1].vy, trailPtr->Size[1]/65536);
 
 
1507
    temp.vz    = trailPtr->Vertex[1].vz - MUL_FIXED(trailPtr->Perp[1].vz, trailPtr->Size[1]/65536);
 
 
1508
    VerticesBuffer[3].U = (temp.vx+temp.vz)*8192+Uoffset;
 
 
1509
    VerticesBuffer[3].V = (temp.vy+temp.vz)*8192+Voffset;
 
 
1510
    TranslatePointIntoViewspace(&temp);
 
 
1511
    VerticesBuffer[3].X = temp.vx;
 
 
1512
    VerticesBuffer[3].Y = temp.vy;
 
 
1513
    VerticesBuffer[3].Z    = temp.vz;
 
 
1514
//    VerticesBuffer[3].U = ParticleDescription[PARTICLE_PLASMABEAM].EndU/2;
 
 
1515
//    VerticesBuffer[3].V = ParticleDescription[PARTICLE_PLASMABEAM].StartV/2;
 
 
1516
 
 
 
1517
    for (i=0; i < 4; i++) 
 
 
1518
    {
 
 
1519
        VerticesBuffer[i].A = trailPtr->Size[i/2]/65536;
 
 
1520
 
 
 
1521
        VerticesBuffer[i].R = 255;
 
 
1522
        VerticesBuffer[i].G    = 255;
 
 
1523
        VerticesBuffer[i].B = 255;
 
 
1524
        VerticesBuffer[i].SpecularR = 0;
 
 
1525
        VerticesBuffer[i].SpecularG = 0;
 
 
1526
        VerticesBuffer[i].SpecularB = 0;
 
 
1527
 
 
 
1528
    }
 
 
1529
 
 
 
1530
    if(PolyWithinFrustrum(4))
 
 
1531
    TexturedPolygon(CloudyImageNumber, RenderPolygon.Vertices, TRANSLUCENCY_GLOWING);
 
 
1532
}
 
 
1533
 
 
 
1534
static void HandlePheromoneTrails()
 
 
1535
{
 
 
1536
    int i = NumActiveTrails;
 
 
1537
    PHEROMONE_TRAIL *trailPtr = TrailStorage;
 
 
1538
    int decayDelta = MUL_FIXED(TRAIL_DECAY_SPEED, NormalFrameTime);
 
 
1539
    //printf("Pheromone Segments active:%d\n", NumActiveTrails);
 
 
1540
 
 
 
1541
    while(i)
 
 
1542
    {
 
 
1543
        --i;
 
 
1544
        trailPtr->Size[0] -= decayDelta;
 
 
1545
        trailPtr->Size[1] -= decayDelta;
 
 
1546
 
 
 
1547
        if (trailPtr->Size[1] < 0)
 
 
1548
            trailPtr->Size[1] = 0;
 
 
1549
 
 
 
1550
        if (trailPtr->Size[0] < 0)
 
 
1551
        {
 
 
1552
            *trailPtr = TrailStorage[--NumActiveTrails];
 
 
1553
        }
 
 
1554
        else
 
 
1555
        {
 
 
1556
            RenderTrailSegment(trailPtr);    
 
 
1557
            trailPtr++;
 
 
1558
        }
 
 
1559
    }
 
 
1560
}
 
 
1561
 
 
 
1562
void DrawMuzzleFlash(VECTORCH *positionPtr, VECTORCH *directionPtr, enum MUZZLE_FLASH_ID muzzleFlashID)
 
 
1563
{
 
 
1564
    int i;
 
 
1565
    const PARTICLE_DESC *particleDescPtr = &ParticleDescription[PARTICLE_MUZZLEFLASH];
 
 
1566
    PARTICLE particle;
 
 
1567
    particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
1568
    particle.Position = *positionPtr;
 
 
1569
    particle.Size = particleDescPtr->Size;
 
 
1570
DecalSystem_Setup();
 
 
1571
 
 
 
1572
    particle.Colour =
 
 
1573
            RGBA_MAKE(particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
1574
                particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
1575
                particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
1576
                particleDescPtr->Alpha);
 
 
1577
 
 
 
1578
    switch (muzzleFlashID)
 
 
1579
    {
 
 
1580
        case MUZZLE_FLASH_AMORPHOUS:
 
 
1581
        {
 
 
1582
            RenderParticle(&particle);
 
 
1583
    /*
 
 
1584
            particle.Position.vx += MUL_FIXED(100, directionPtr->vx);
 
 
1585
            particle.Position.vy += MUL_FIXED(100, directionPtr->vy);
 
 
1586
            particle.Position.vz += MUL_FIXED(100, directionPtr->vz);
 
 
1587
            RenderParticle(&particle);
 
 
1588
    */
 
 
1589
 
 
 
1590
    /*
 
 
1591
            particle.Position.vx += MUL_FIXED(100, directionPtr->vx);
 
 
1592
            particle.Position.vy += MUL_FIXED(100, directionPtr->vy);
 
 
1593
            particle.Position.vz += MUL_FIXED(100, directionPtr->vz);
 
 
1594
            RenderParticle(&particle);
 
 
1595
    */
 
 
1596
 
 
 
1597
    /*
 
 
1598
            particle.Size = 20;
 
 
1599
 
 
 
1600
            for (i=0; i < 16; i++)
 
 
1601
            {
 
 
1602
                RenderParticle(&particle);
 
 
1603
                particle.Position.vx = positionPtr->vx + MUL_FIXED(100, directionPtr->vx) + (FastRandom()&127)-64;
 
 
1604
                particle.Position.vy = positionPtr->vy + MUL_FIXED(100, directionPtr->vy) + (FastRandom()&127)-64;
 
 
1605
                particle.Position.vz = positionPtr->vz + MUL_FIXED(100, directionPtr->vz) + (FastRandom()&127)-64;
 
 
1606
            }
 
 
1607
    */
 
 
1608
        }
 
 
1609
        break;
 
 
1610
        case MUZZLE_FLASH_SMARTGUN:
 
 
1611
        {
 
 
1612
            MATRIXCH muzzleMatrix;
 
 
1613
            MATRIXCH rotmat;
 
 
1614
            MakeMatrixFromDirection(directionPtr, &muzzleMatrix);
 
 
1615
 
 
 
1616
            {
 
 
1617
                   int angle = 4096/12;
 
 
1618
                   int cos = GetCos(angle);
 
 
1619
                   int sin = GetSin(angle);
 
 
1620
                   rotmat.mat11 = cos;
 
 
1621
                   rotmat.mat12 = sin;
 
 
1622
                   rotmat.mat13 = 0;
 
 
1623
                   rotmat.mat21 = -sin;
 
 
1624
                   rotmat.mat22 = cos;
 
 
1625
                   rotmat.mat23 = 0;
 
 
1626
                   rotmat.mat31 = 0;
 
 
1627
                   rotmat.mat32 = 0;
 
 
1628
                   rotmat.mat33 = 65536;
 
 
1629
            }
 
 
1630
 
 
 
1631
            {
 
 
1632
                particle.Position.vx += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vx);
 
 
1633
                particle.Position.vy += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vy);
 
 
1634
                particle.Position.vz += MUL_FIXED(100 - (FastRandom()&15), directionPtr->vz);
 
 
1635
 
 
 
1636
                for (i=0; i < 16; i++)
 
 
1637
                {
 
 
1638
                    RenderParticle(&particle);
 
 
1639
                    particle.Position.vx += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vx);
 
 
1640
                    particle.Position.vy += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vy);
 
 
1641
                    particle.Position.vz += MUL_FIXED(50 - (FastRandom()&15), directionPtr->vz);
 
 
1642
                    particle.Size -= (FastRandom()&3)+3;
 
 
1643
                }
 
 
1644
            }
 
 
1645
 
 
 
1646
            for (i = 0; i < 12; i++)
 
 
1647
            {
 
 
1648
                int j = 8;
 
 
1649
 
 
 
1650
                particle.Position = *positionPtr;
 
 
1651
                particle.Position.vx += -MUL_FIXED(200,directionPtr->vx) + MUL_FIXED(50, muzzleMatrix.mat21);
 
 
1652
                particle.Position.vy += -MUL_FIXED(200,directionPtr->vy) + MUL_FIXED(50, muzzleMatrix.mat22);
 
 
1653
                particle.Position.vz += -MUL_FIXED(200,directionPtr->vz) + MUL_FIXED(50, muzzleMatrix.mat23);
 
 
1654
 
 
 
1655
                particle.Size = 50;
 
 
1656
 
 
 
1657
                if (!(i & 1))
 
 
1658
                    j += 8;
 
 
1659
 
 
 
1660
                while(j--)
 
 
1661
                {
 
 
1662
                    RenderParticle(&particle);
 
 
1663
                    particle.Position.vx += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat21);
 
 
1664
                    particle.Position.vy += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat22);
 
 
1665
                    particle.Position.vz += MUL_FIXED((FastRandom()&31)+16, muzzleMatrix.mat23);
 
 
1666
                    particle.Size += (FastRandom()&15);
 
 
1667
                }
 
 
1668
 
 
 
1669
                MatrixMultiply(&muzzleMatrix, &rotmat, &muzzleMatrix);
 
 
1670
            }
 
 
1671
        }
 
 
1672
        break;
 
 
1673
        case MUZZLE_FLASH_SKEETER:
 
 
1674
        {
 
 
1675
            RenderParticle(&particle);
 
 
1676
            particle.Position.vx += MUL_FIXED(20, directionPtr->vx);
 
 
1677
            particle.Position.vy += MUL_FIXED(20, directionPtr->vy);
 
 
1678
            particle.Position.vz += MUL_FIXED(20, directionPtr->vz);
 
 
1679
            RenderParticle(&particle);
 
 
1680
            particle.Position.vx += MUL_FIXED(20, directionPtr->vx);
 
 
1681
            particle.Position.vy += MUL_FIXED(20, directionPtr->vy);
 
 
1682
            particle.Position.vz += MUL_FIXED(20, directionPtr->vz);
 
 
1683
            RenderParticle(&particle);
 
 
1684
            particle.Size = 20;
 
 
1685
 
 
 
1686
            for(i=0; i < 16; i++)
 
 
1687
            {
 
 
1688
                RenderParticle(&particle);
 
 
1689
                particle.Position.vx = positionPtr->vx + MUL_FIXED(100, directionPtr->vx) + (FastRandom()&127)-64;
 
 
1690
                particle.Position.vy = positionPtr->vy + MUL_FIXED(100, directionPtr->vy) + (FastRandom()&127)-64;
 
 
1691
                particle.Position.vz = positionPtr->vz + MUL_FIXED(100, directionPtr->vz) + (FastRandom()&127)-64;
 
 
1692
            }
 
 
1693
        }
 
 
1694
    }
 
 
1695
DecalSystem_End();
 
 
1696
}
 
 
1697
 
 
 
1698
static void DrawSfxObject(DISPLAYBLOCK *dispPtr)
 
 
1699
{
 
 
1700
    struct sfxblock *sfxPtr = dispPtr->SfxPtr;
 
 
1701
 
 
 
1702
    switch(sfxPtr->SfxID)
 
 
1703
    {
 
 
1704
        case SFX_MUZZLE_FLASH_AMORPHOUS:
 
 
1705
        {
 
 
1706
            sfxPtr->EffectDrawnLastFrame = !sfxPtr->EffectDrawnLastFrame;
 
 
1707
 
 
 
1708
            if (sfxPtr->EffectDrawnLastFrame)
 
 
1709
            {
 
 
1710
                VECTORCH direction;
 
 
1711
 
 
 
1712
                direction.vx = dispPtr->ObMat.mat31;
 
 
1713
                direction.vy = dispPtr->ObMat.mat32;
 
 
1714
                direction.vz = dispPtr->ObMat.mat33;
 
 
1715
                DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_AMORPHOUS);
 
 
1716
            }
 
 
1717
        }
 
 
1718
        break;
 
 
1719
        case SFX_MUZZLE_FLASH_SMARTGUN:
 
 
1720
        {
 
 
1721
            VECTORCH direction;
 
 
1722
 
 
 
1723
            direction.vx = dispPtr->ObMat.mat31;
 
 
1724
            direction.vy = dispPtr->ObMat.mat32;
 
 
1725
            direction.vz = dispPtr->ObMat.mat33;
 
 
1726
            DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_SMARTGUN);
 
 
1727
        }
 
 
1728
        break;
 
 
1729
        case SFX_MUZZLE_FLASH_SKEETER:
 
 
1730
        {
 
 
1731
            sfxPtr->EffectDrawnLastFrame = !sfxPtr->EffectDrawnLastFrame;
 
 
1732
 
 
 
1733
            if (sfxPtr->EffectDrawnLastFrame)
 
 
1734
            {
 
 
1735
                VECTORCH direction;
 
 
1736
 
 
 
1737
                direction.vx = dispPtr->ObMat.mat31;
 
 
1738
                direction.vy = dispPtr->ObMat.mat32;
 
 
1739
                direction.vz = dispPtr->ObMat.mat33;
 
 
1740
                DrawMuzzleFlash(&dispPtr->ObWorld, &direction, MUZZLE_FLASH_SKEETER);
 
 
1741
            }
 
 
1742
        }
 
 
1743
        break;
 
 
1744
        case SFX_FRISBEE_PLASMA_BOLT:
 
 
1745
        {
 
 
1746
            int i;
 
 
1747
            PARTICLE particle;
 
 
1748
            VECTORCH direction;
 
 
1749
            direction.vx = dispPtr->ObMat.mat31;
 
 
1750
            direction.vy = dispPtr->ObMat.mat32;
 
 
1751
            direction.vz = dispPtr->ObMat.mat33;
 
 
1752
            particle.Position = dispPtr->ObWorld;
 
 
1753
            particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
1754
            particle.Colour = RGBA_MAKE(255,255,255,255);
 
 
1755
            particle.Size = 200;
 
 
1756
 
 
 
1757
            for(i=0; i < 16; i++)
 
 
1758
            {
 
 
1759
                RenderParticle(&particle);
 
 
1760
                particle.Position.vx -= MUL_FIXED(50, direction.vx);
 
 
1761
                particle.Position.vy -= MUL_FIXED(50, direction.vy);
 
 
1762
                particle.Position.vz -= MUL_FIXED(50, direction.vz);
 
 
1763
                particle.Size -= 10;
 
 
1764
            }
 
 
1765
        }
 
 
1766
        break;
 
 
1767
        case SFX_PREDATOR_PLASMA_BOLT:
 
 
1768
        {
 
 
1769
            int i;
 
 
1770
            PARTICLE particle;
 
 
1771
            VECTORCH direction;
 
 
1772
            direction.vx = dispPtr->ObMat.mat31;
 
 
1773
            direction.vy = dispPtr->ObMat.mat32;
 
 
1774
            direction.vz = dispPtr->ObMat.mat33;
 
 
1775
            particle.Position = dispPtr->ObWorld;
 
 
1776
            particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
1777
            particle.Colour = RGBA_MAKE(50,255,255,255);
 
 
1778
            particle.Size = 200;
 
 
1779
 
 
 
1780
            for (i=0; i < 16; i++)
 
 
1781
            {
 
 
1782
                RenderParticle(&particle);
 
 
1783
                particle.Position.vx -= MUL_FIXED(50, direction.vx);
 
 
1784
                particle.Position.vy -= MUL_FIXED(50, direction.vy);
 
 
1785
                particle.Position.vz -= MUL_FIXED(50, direction.vz);
 
 
1786
                particle.Size -= 10;
 
 
1787
            }
 
 
1788
        }
 
 
1789
        break;
 
 
1790
        case SFX_SMALL_PREDATOR_PLASMA_BOLT:
 
 
1791
        {
 
 
1792
            PARTICLE particle;
 
 
1793
            particle.Position = dispPtr->ObWorld;
 
 
1794
            particle.ParticleID = PARTICLE_ELECTRICALPLASMASPHERE;
 
 
1795
            particle.Colour = RGBA_MAKE(255,255,255,128);
 
 
1796
            particle.Size = 200;
 
 
1797
            RenderParticle(&particle);
 
 
1798
            particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
1799
            particle.Colour = RGBA_MAKE(255,255,255,64);
 
 
1800
            particle.Size = 1000;
 
 
1801
            RenderParticle(&particle);
 
 
1802
            //RenderParticle(&particle);
 
 
1803
        }
 
 
1804
        default:
 
 
1805
        break;
 
 
1806
    }
 
 
1807
}
 
 
1808
 
 
 
1809
static void NoneBloodParticles()
 
 
1810
{
 
 
1811
    int i;
 
 
1812
 
 
 
1813
    for(i = 0; i < NumActiveParticles; i++)
 
 
1814
    {
 
 
1815
        PARTICLE *particlePtr = &ParticleStorage[i];
 
 
1816
        const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
 
 
1817
 
 
 
1818
        switch(particlePtr->ParticleID)
 
 
1819
        {
 
 
1820
            case PARTICLE_IMPACTSMOKE:
 
 
1821
            case PARTICLE_BLACKSMOKE:
 
 
1822
            {
 
 
1823
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
1824
 
 
 
1825
                if (particlePtr->Velocity.vy > -1300)
 
 
1826
                    particlePtr->Velocity.vy -= MUL_FIXED(3000, NormalFrameTime);
 
 
1827
 
 
 
1828
                if (particlePtr->Velocity.vx > 0)
 
 
1829
                {
 
 
1830
                    particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime);
 
 
1831
 
 
 
1832
                    if (particlePtr->Velocity.vx < 0)
 
 
1833
                        particlePtr->Velocity.vx = 0;
 
 
1834
                }
 
 
1835
                else if (particlePtr->Velocity.vx < 0)
 
 
1836
                {
 
 
1837
                    particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime);
 
 
1838
 
 
 
1839
                    if (particlePtr->Velocity.vx > 0)
 
 
1840
                        particlePtr->Velocity.vx = 0;
 
 
1841
                }
 
 
1842
 
 
 
1843
                if (particlePtr->Velocity.vz > 0)
 
 
1844
                {
 
 
1845
                    particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime);
 
 
1846
 
 
 
1847
                    if (particlePtr->Velocity.vz < 0)
 
 
1848
                        particlePtr->Velocity.vz = 0;
 
 
1849
                }
 
 
1850
                else if (particlePtr->Velocity.vz < 0)
 
 
1851
                {
 
 
1852
                    particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime);
 
 
1853
 
 
 
1854
                    if (particlePtr->Velocity.vz > 0)
 
 
1855
                        particlePtr->Velocity.vz = 0;
 
 
1856
                }
 
 
1857
 
 
 
1858
particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED
 
 
1859
( -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime );
 
 
1860
 
 
 
1861
particlePtr->Position.vz += MUL_FIXED
 
 
1862
( particlePtr->Velocity.vz+ MUL_FIXED ( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ),
NormalFrameTime );
 
 
1863
 
 
 
1864
                {
 
 
1865
                    int colour = particlePtr->LifeTime >> 11;
 
 
1866
                      particlePtr->Colour = RGBA_MAKE(colour, colour, colour, 255);
 
 
1867
                }
 
 
1868
            }
 
 
1869
            break;
 
 
1870
            case PARTICLE_GUNMUZZLE_SMOKE:
 
 
1871
            {
 
 
1872
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
1873
 
 
 
1874
                if (particlePtr->Velocity.vy > -1300)
 
 
1875
                    particlePtr->Velocity.vy -= MUL_FIXED(1024/4, NormalFrameTime);
 
 
1876
 
 
 
1877
                if (particlePtr->Velocity.vx > 0)
 
 
1878
                {
 
 
1879
                    particlePtr->Velocity.vx -= MUL_FIXED(1024/4, NormalFrameTime);
 
 
1880
 
 
 
1881
                    if (particlePtr->Velocity.vx < 0)
 
 
1882
                        particlePtr->Velocity.vx = 0;
 
 
1883
                }
 
 
1884
                else if (particlePtr->Velocity.vx < 0)
 
 
1885
                {
 
 
1886
                    particlePtr->Velocity.vx += MUL_FIXED(1024/4, NormalFrameTime);
 
 
1887
 
 
 
1888
                    if (particlePtr->Velocity.vx > 0)
 
 
1889
                        particlePtr->Velocity.vx = 0;
 
 
1890
                }
 
 
1891
 
 
 
1892
                if (particlePtr->Velocity.vz > 0)
 
 
1893
                {
 
 
1894
                    particlePtr->Velocity.vz -= MUL_FIXED(1024/4, NormalFrameTime);
 
 
1895
 
 
 
1896
                    if (particlePtr->Velocity.vz < 0)
 
 
1897
                        particlePtr->Velocity.vz = 0;
 
 
1898
                }
 
 
1899
                else if (particlePtr->Velocity.vz < 0)
 
 
1900
                {
 
 
1901
                    particlePtr->Velocity.vz += MUL_FIXED(1024/4, NormalFrameTime);
 
 
1902
 
 
 
1903
                    if (particlePtr->Velocity.vz > 0)
 
 
1904
                        particlePtr->Velocity.vz = 0;
 
 
1905
                }
 
 
1906
 
 
 
1907
particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED
 
 
1908
( -GetSin(((particlePtr->Position.vz+particlePtr->Position.vy)*16)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime );
 
 
1909
 
 
 
1910
particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED
 
 
1911
( GetCos(((particlePtr->Position.vx+particlePtr->Position.vy)*16)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime );
 
 
1912
 
 
 
1913
                particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime, 48);
 
 
1914
                {
 
 
1915
                    int colour = particlePtr->LifeTime >> 11;
 
 
1916
                      particlePtr->Colour = RGBA_MAKE(32,32,32,colour);
 
 
1917
                }
 
 
1918
            }
 
 
1919
            break;
 
 
1920
            case PARTICLE_FLARESMOKE:
 
 
1921
            {
 
 
1922
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
1923
 
 
 
1924
                if (particlePtr->Velocity.vy > -1300)
 
 
1925
                    particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime);
 
 
1926
 
 
 
1927
                if (particlePtr->Velocity.vx > 0)
 
 
1928
                {
 
 
1929
                    particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime);
 
 
1930
 
 
 
1931
                    if (particlePtr->Velocity.vx < 0)
 
 
1932
                        particlePtr->Velocity.vx = 0;
 
 
1933
                }
 
 
1934
                else if (particlePtr->Velocity.vx < 0)
 
 
1935
                {
 
 
1936
                    particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime);
 
 
1937
 
 
 
1938
                    if (particlePtr->Velocity.vx > 0)
 
 
1939
                        particlePtr->Velocity.vx = 0;
 
 
1940
                }
 
 
1941
 
 
 
1942
                if (particlePtr->Velocity.vz > 0)
 
 
1943
                {
 
 
1944
                    particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime);
 
 
1945
 
 
 
1946
                    if (particlePtr->Velocity.vz < 0)
 
 
1947
                        particlePtr->Velocity.vz = 0;
 
 
1948
                }
 
 
1949
                else if (particlePtr->Velocity.vz < 0)
 
 
1950
                {
 
 
1951
                    particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime);
 
 
1952
 
 
 
1953
                    if (particlePtr->Velocity.vz > 0)
 
 
1954
                        particlePtr->Velocity.vz = 0;
 
 
1955
                }
 
 
1956
 
 
 
1957
particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+ MUL_FIXED 
 
 
1958
( -GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime );
 
 
1959
 
 
 
1960
particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED
 
 
1961
( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime );
 
 
1962
 
 
 
1963
particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
1964
                      particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
1965
                      particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
1966
                      (particlePtr->LifeTime >> 10));
 
 
1967
 
 
 
1968
                particlePtr->Size = MUL_FIXED(ONE_FIXED-particlePtr->LifeTime,200)+50;
 
 
1969
            }
 
 
1970
            break;
 
 
1971
            case PARTICLE_RICOCHET_SPARK:
 
 
1972
            {
 
 
1973
                particlePtr->Offset = particlePtr->Position;
 
 
1974
 
 
 
1975
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
1976
                particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
1977
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
1978
                particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
1979
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
1980
                particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
1981
 
 
 
1982
                {
 
 
1983
                    int l = particlePtr->LifeTime*8;
 
 
1984
                    l = MUL_FIXED(255,l);
 
 
1985
 
 
 
1986
                    if (l > 255)
 
 
1987
                    {
 
 
1988
                        switch (PlayerStatus.VisionMode)
 
 
1989
                        {
 
 
1990
                            default:
 
 
1991
                            case VISION_MODE_NORMAL:
 
 
1992
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
1993
                            break;
 
 
1994
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
1995
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
1996
                            break;
 
 
1997
                            case VISION_MODE_PRED_THERMAL:
 
 
1998
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
1999
                            break;
 
 
2000
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2001
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2002
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
2003
                        }
 
 
2004
                    }
 
 
2005
                    else
 
 
2006
                    {
 
 
2007
                        switch (PlayerStatus.VisionMode)
 
 
2008
                        {
 
 
2009
                            default:
 
 
2010
                            case VISION_MODE_NORMAL:
 
 
2011
                                  particlePtr->Colour = RGBA_MAKE(255,l,0,l);
 
 
2012
                            break;
 
 
2013
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2014
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l);
 
 
2015
                            break;
 
 
2016
                            case VISION_MODE_PRED_THERMAL:
 
 
2017
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2018
                            break;
 
 
2019
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2020
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2021
                                  particlePtr->Colour = RGBA_MAKE(l,l,0,l);
 
 
2022
                        }
 
 
2023
                    }
 
 
2024
                }
 
 
2025
            }
 
 
2026
            break;
 
 
2027
            case PARTICLE_SPARK:
 
 
2028
            {
 
 
2029
                particlePtr->Offset = particlePtr->Position;
 
 
2030
 
 
 
2031
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2032
                particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2033
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2034
                particlePtr->Velocity.vy += MUL_FIXED(5000, NormalFrameTime);
 
 
2035
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2036
                particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2037
 
 
 
2038
                {
 
 
2039
                    int l = particlePtr->LifeTime * 2;
 
 
2040
                    l = MUL_FIXED(255,l);
 
 
2041
 
 
 
2042
                    if (l > 255)
 
 
2043
                    {
 
 
2044
                        switch (PlayerStatus.VisionMode)
 
 
2045
                        {
 
 
2046
                            default:
 
 
2047
                            case VISION_MODE_NORMAL:
 
 
2048
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,255,255);
 
 
2049
                            break;
 
 
2050
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2051
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
2052
                            break;
 
 
2053
                            case VISION_MODE_PRED_THERMAL:
 
 
2054
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
2055
                            break;
 
 
2056
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2057
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2058
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
2059
                        }
 
 
2060
                    }
 
 
2061
                    else
 
 
2062
                    {
 
 
2063
                        switch (PlayerStatus.VisionMode)
 
 
2064
                        {
 
 
2065
                            default:
 
 
2066
                            case VISION_MODE_NORMAL:
 
 
2067
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l,l);
 
 
2068
                            break;
 
 
2069
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2070
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l);
 
 
2071
                            break;
 
 
2072
                            case VISION_MODE_PRED_THERMAL:
 
 
2073
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2074
                            break;
 
 
2075
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2076
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2077
                                  particlePtr->Colour = RGBA_MAKE(l,l,0,l);
 
 
2078
                        }
 
 
2079
                    }
 
 
2080
                }
 
 
2081
            }
 
 
2082
            break;
 
 
2083
            case PARTICLE_FLAME:
 
 
2084
            case PARTICLE_NONDAMAGINGFLAME:
 
 
2085
            {
 
 
2086
                particlePtr->Size = 20+(ONE_FIXED/2-particlePtr->LifeTime)/64;     
 
 
2087
 
 
 
2088
                if (particlePtr->LifeTime == ONE_FIXED / 2)
 
 
2089
                {
 
 
2090
                    switch (PlayerStatus.VisionMode)
 
 
2091
                    {
 
 
2092
                        default:
 
 
2093
                        case VISION_MODE_NORMAL:
 
 
2094
                            particlePtr->Colour = RGBA_MAKE(16, 16, 128, (particlePtr->LifeTime >>8) | 9);
 
 
2095
                        break;
 
 
2096
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
2097
                            particlePtr->Colour = RGBA_MAKE(0, 32, 0, (particlePtr->LifeTime >> 8 ) | 9);
 
 
2098
                        break;
 
 
2099
                        case VISION_MODE_PRED_THERMAL:
 
 
2100
                            particlePtr->Colour = RGBA_MAKE(0, 0, 128, (particlePtr->LifeTime >> 8) | 9);
 
 
2101
                        break;
 
 
2102
                        case VISION_MODE_PRED_SEEALIENS:
 
 
2103
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2104
                            particlePtr->Colour = RGBA_MAKE(192, 128, 32, (particlePtr->LifeTime >> 8) | 9);
 
 
2105
                    }
 
 
2106
                }
 
 
2107
                else
 
 
2108
                {
 
 
2109
                    particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
2110
                                    particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
2111
                                    particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
2112
                                    (particlePtr->LifeTime >> 8) | 9);
 
 
2113
                }
 
 
2114
            }
 
 
2115
            break;
 
 
2116
            case PARTICLE_FIRE:
 
 
2117
                particlePtr->Size = 300 - (FastRandom() & 127);
 
 
2118
            break;
 
 
2119
            case PARTICLE_MOLOTOVFLAME:
 
 
2120
            {
 
 
2121
                VECTORCH obstacleNormal;
 
 
2122
                int moduleIndex;
 
 
2123
 
 
 
2124
                particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
2125
                                particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
2126
                                particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
2127
                                (particlePtr->LifeTime >> 10) | 9);
 
 
2128
 
 
 
2129
                particlePtr->Velocity.vy += MUL_FIXED(8000, NormalFrameTime);
 
 
2130
 
 
 
2131
                ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex);
 
 
2132
 
 
 
2133
                particlePtr->Size = 800 - (FastRandom() & 255);
 
 
2134
            }
 
 
2135
            break;
 
 
2136
            case PARTICLE_NONCOLLIDINGFLAME:
 
 
2137
                particlePtr->Size = 20 + (ONE_FIXED / 2 - particlePtr->LifeTime) / 64;     
 
 
2138
            break;
 
 
2139
            case PARTICLE_ORANGE_SPARK:
 
 
2140
            {
 
 
2141
                particlePtr->Offset = particlePtr->Position;
 
 
2142
 
 
 
2143
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2144
                particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2145
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2146
                particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2147
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2148
                particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2149
 
 
 
2150
                {
 
 
2151
                    int l = particlePtr->LifeTime * 8;
 
 
2152
                    l = MUL_FIXED(255, l);
 
 
2153
 
 
 
2154
                    if (l > 255)
 
 
2155
                    {
 
 
2156
                        switch (PlayerStatus.VisionMode)
 
 
2157
                        {
 
 
2158
                            default:
 
 
2159
                            case VISION_MODE_NORMAL:
 
 
2160
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
2161
                            break;
 
 
2162
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2163
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
2164
                            break;
 
 
2165
                            case VISION_MODE_PRED_THERMAL:
 
 
2166
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2167
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2168
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
2169
                        }
 
 
2170
                    }
 
 
2171
                    else
 
 
2172
                    {
 
 
2173
                        switch (PlayerStatus.VisionMode)
 
 
2174
                        {
 
 
2175
                            default:
 
 
2176
                            case VISION_MODE_NORMAL:
 
 
2177
                                  particlePtr->Colour = RGBA_MAKE(255,l,0,l);
 
 
2178
                            break;
 
 
2179
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2180
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l);
 
 
2181
                            break;
 
 
2182
                            case VISION_MODE_PRED_THERMAL:
 
 
2183
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2184
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2185
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2186
                        }
 
 
2187
                    }
 
 
2188
                }
 
 
2189
            }
 
 
2190
            break;
 
 
2191
            case PARTICLE_ORANGE_PLASMA:
 
 
2192
            {
 
 
2193
                particlePtr->Offset = particlePtr->Position;
 
 
2194
 
 
 
2195
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2196
                particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2197
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2198
                particlePtr->Velocity.vy -= MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2199
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2200
                particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2201
 
 
 
2202
                {
 
 
2203
                    int l = particlePtr->LifeTime * 16;
 
 
2204
                    l = MUL_FIXED(255,l);
 
 
2205
 
 
 
2206
                    if (l > 255)
 
 
2207
                    {
 
 
2208
                        switch (PlayerStatus.VisionMode)
 
 
2209
                        {
 
 
2210
                            default:
 
 
2211
                            case VISION_MODE_NORMAL:
 
 
2212
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
2213
                            break;
 
 
2214
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2215
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
2216
                            break;
 
 
2217
                            case VISION_MODE_PRED_THERMAL:
 
 
2218
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2219
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2220
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
2221
                        }
 
 
2222
                    }
 
 
2223
                    else
 
 
2224
                    {
 
 
2225
                        switch (PlayerStatus.VisionMode)
 
 
2226
                        {
 
 
2227
                            default:
 
 
2228
                            case VISION_MODE_NORMAL:
 
 
2229
                                  particlePtr->Colour = RGBA_MAKE(255,l,0,l);
 
 
2230
                            break;
 
 
2231
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2232
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l);
 
 
2233
                            break;
 
 
2234
                            case VISION_MODE_PRED_THERMAL:
 
 
2235
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2236
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2237
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2238
                        }
 
 
2239
                    }
 
 
2240
                }
 
 
2241
            }
 
 
2242
            break;
 
 
2243
            case PARTICLE_DEWLINE:
 
 
2244
            {
 
 
2245
                int l = (particlePtr->LifeTime)/64/4;
 
 
2246
 
 
 
2247
                if (l > 255)
 
 
2248
                {
 
 
2249
                    switch (PlayerStatus.VisionMode)
 
 
2250
                    {
 
 
2251
                        default:
 
 
2252
                        case VISION_MODE_NORMAL:
 
 
2253
                            particlePtr->Colour = RGBA_MAKE(255,255,255,255);
 
 
2254
                        break;
 
 
2255
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
2256
                            particlePtr->Colour = RGBA_MAKE(0,255,0,255);
 
 
2257
                        break;
 
 
2258
                        case VISION_MODE_PRED_THERMAL:
 
 
2259
                            particlePtr->Colour = RGBA_MAKE(255,0,0,255);
 
 
2260
                        break;
 
 
2261
                        case VISION_MODE_PRED_SEEALIENS:
 
 
2262
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2263
                            particlePtr->Colour = RGBA_MAKE(255,128,64,255);
 
 
2264
                    }
 
 
2265
                }
 
 
2266
                else
 
 
2267
                {
 
 
2268
                     particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2269
                     particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2270
                     particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2271
 
 
 
2272
                    switch (PlayerStatus.VisionMode)
 
 
2273
                    {
 
 
2274
                        default:
 
 
2275
                        case VISION_MODE_NORMAL:
 
 
2276
                            particlePtr->Colour = RGBA_MAKE(255,128+(l/2),64+((3*l)/4),l);
 
 
2277
                        break;
 
 
2278
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
2279
                            particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l);
 
 
2280
                        break;
 
 
2281
                        case VISION_MODE_PRED_THERMAL:
 
 
2282
                            particlePtr->Colour = RGBA_MAKE(255,l/2,l/2,l);
 
 
2283
                        break;
 
 
2284
                        case VISION_MODE_PRED_SEEALIENS:
 
 
2285
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2286
                            particlePtr->Colour = RGBA_MAKE(255,l/2,l/4,l);
 
 
2287
                    }
 
 
2288
 
 
 
2289
                    particlePtr->Size = 32+(FastRandom()&31);
 
 
2290
                }
 
 
2291
            }
 
 
2292
            break;
 
 
2293
            case PARTICLE_PLASMATRAIL:
 
 
2294
            {
 
 
2295
                int l = (particlePtr->LifeTime)/64/4;
 
 
2296
 
 
 
2297
                if (l > 255)
 
 
2298
                {
 
 
2299
                    switch (PlayerStatus.VisionMode)
 
 
2300
                    {
 
 
2301
                        default:
 
 
2302
                        case VISION_MODE_NORMAL:
 
 
2303
                            particlePtr->Colour = RGBA_MAKE(0,0,255,255);
 
 
2304
                        break;
 
 
2305
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
2306
                            particlePtr->Colour = RGBA_MAKE(0,255,0,255);
 
 
2307
                        break;
 
 
2308
                        case VISION_MODE_PRED_THERMAL:
 
 
2309
                            particlePtr->Colour = RGBA_MAKE(0,0,255,255);
 
 
2310
                        break;
 
 
2311
                        case VISION_MODE_PRED_SEEALIENS:
 
 
2312
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2313
                            particlePtr->Colour = RGBA_MAKE(255,128,64,255);
 
 
2314
                    }
 
 
2315
                }
 
 
2316
                else
 
 
2317
                {
 
 
2318
                     particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
 
 
2319
                     particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
 
 
2320
                     particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
 
 
2321
 
 
 
2322
                    switch (PlayerStatus.VisionMode)
 
 
2323
                    {
 
 
2324
                        default:
 
 
2325
                        case VISION_MODE_NORMAL:
 
 
2326
                            particlePtr->Colour = RGBA_MAKE(l/4,l/2,255,l);
 
 
2327
                        break;
 
 
2328
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
2329
                            particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l);
 
 
2330
                        break;
 
 
2331
                        case VISION_MODE_PRED_THERMAL:
 
 
2332
                            particlePtr->Colour = RGBA_MAKE(l/4,l/2,255,l);
 
 
2333
                        break;
 
 
2334
                        case VISION_MODE_PRED_SEEALIENS:
 
 
2335
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2336
                            particlePtr->Colour = RGBA_MAKE(255,l/2,l/4,l);
 
 
2337
                    }
 
 
2338
 
 
 
2339
                    particlePtr->Size = 32+(FastRandom()&31);
 
 
2340
                }
 
 
2341
            }
 
 
2342
            break;
 
 
2343
            case PARTICLE_WATERSPRAY:
 
 
2344
            {
 
 
2345
                particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
2346
                                particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
2347
                                particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
2348
                                particleDescPtr->Alpha);
 
 
2349
 
 
 
2350
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
 
 
2351
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
 
 
2352
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
 
 
2353
                particlePtr->Velocity.vy += MUL_FIXED(10000,NormalFrameTime);
 
 
2354
            }
 
 
2355
            break;
 
 
2356
            case PARTICLE_WATERFALLSPRAY:
 
 
2357
            {
 
 
2358
                extern int WaterFallBase;
 
 
2359
                int y = particlePtr->Position.vy;
 
 
2360
                particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
2361
                                particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
2362
                                particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
2363
                                particleDescPtr->Alpha);
 
 
2364
 
 
 
2365
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2366
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2367
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2368
                particlePtr->Velocity.vy += MUL_FIXED(10000+(FastRandom()&511), NormalFrameTime);
 
 
2369
 
 
 
2370
                if(particlePtr->Position.vz < 54885 && particlePtr->Position.vx < 179427)
 
 
2371
                {
 
 
2372
                    if (y < 4742 && particlePtr->Position.vy > 4742)
 
 
2373
                    {
 
 
2374
                        particlePtr->Position.vy = 4742;
 
 
2375
                        particlePtr->Velocity.vy = -MUL_FIXED(particlePtr->Velocity.vy, ONE_FIXED/2-(FastRandom()&16384));                        
 
 
2376
                    }
 
 
2377
                }
 
 
2378
                else if (particlePtr->Position.vz < 58600)
 
 
2379
                {
 
 
2380
                    int l = DIV_FIXED(particlePtr->Position.vz - 54885,58600-54885);
 
 
2381
 
 
 
2382
                    if (particlePtr->Position.vx < 179427 - MUL_FIXED(l,179427-175545))
 
 
2383
                    {
 
 
2384
                        int yThreshold = 4742 + MUL_FIXED(l,8635-4742);
 
 
2385
 
 
 
2386
                        if (y < yThreshold && particlePtr->Position.vy > yThreshold)
 
 
2387
                        {
 
 
2388
                            particlePtr->Position.vy = yThreshold;
 
 
2389
                            particlePtr->Velocity.vy = -MUL_FIXED(particlePtr->Velocity.vy,ONE_FIXED/2-(FastRandom()&16384));                        
 
 
2390
                        }
 
 
2391
                    }
 
 
2392
                }
 
 
2393
 
 
 
2394
                particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/4;
 
 
2395
                particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/4;
 
 
2396
                particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/4;
 
 
2397
 
 
 
2398
                if (particlePtr->Position.vy > WaterFallBase)
 
 
2399
                    particlePtr->LifeTime = 0;
 
 
2400
            }
 
 
2401
            break;
 
 
2402
            case PARTICLE_FLECHETTE:
 
 
2403
            case PARTICLE_FLECHETTE_NONDAMAGING:
 
 
2404
            {
 
 
2405
                {
 
 
2406
                    int l = particlePtr->LifeTime/4;
 
 
2407
                    l = MUL_FIXED(255,l);
 
 
2408
 
 
 
2409
                    if (l > 255)
 
 
2410
                    {
 
 
2411
                        switch (PlayerStatus.VisionMode)
 
 
2412
                        {
 
 
2413
                            default:
 
 
2414
                            case VISION_MODE_NORMAL:
 
 
2415
                                  particlePtr->Colour = RGBA_MAKE((l-255)/2+32,0,0,255);
 
 
2416
                            break;
 
 
2417
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2418
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
2419
                            break;
 
 
2420
                            case VISION_MODE_PRED_THERMAL:
 
 
2421
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2422
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2423
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
2424
                        }
 
 
2425
                    }
 
 
2426
                    else
 
 
2427
                    {
 
 
2428
                        switch (PlayerStatus.VisionMode)
 
 
2429
                        {
 
 
2430
                            default:
 
 
2431
                            case VISION_MODE_NORMAL:
 
 
2432
                                  particlePtr->Colour = RGBA_MAKE(32,0,0,l);
 
 
2433
                            break;
 
 
2434
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2435
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,l);
 
 
2436
                            break;
 
 
2437
                            case VISION_MODE_PRED_THERMAL:
 
 
2438
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2439
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2440
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2441
                        }
 
 
2442
                    }
 
 
2443
                }
 
 
2444
 
 
 
2445
                if (particlePtr->Offset.vy) //particlePtr->Velocity.vx || particlePtr->Velocity.vy || particlePtr->Velocity.vz)
 
 
2446
                {
 
 
2447
                    VECTORCH obstacleNormal;
 
 
2448
                    int moduleIndex;
 
 
2449
                    VECTORCH velocityBackup = particlePtr->Velocity;
 
 
2450
 
 
 
2451
                    if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2452
                    {
 
 
2453
                        if(moduleIndex == -1)
 
 
2454
                        {
 
 
2455
                            particlePtr->LifeTime = 0;
 
 
2456
                        }
 
 
2457
                        else
 
 
2458
                        {
 
 
2459
                            particlePtr->Offset.vy = 0;
 
 
2460
                            particlePtr->Velocity = velocityBackup;
 
 
2461
                            particlePtr->Position.vx += particlePtr->Velocity.vx >> 10;
 
 
2462
                            particlePtr->Position.vy += particlePtr->Velocity.vy >> 10;
 
 
2463
                            particlePtr->Position.vz += particlePtr->Velocity.vz >> 10;
 
 
2464
                        }
 
 
2465
                    }
 
 
2466
                }
 
 
2467
            }
 
 
2468
            break;
 
 
2469
            case PARTICLE_SMOKECLOUD:
 
 
2470
            {
 
 
2471
                if (particlePtr->LifeTime < ONE_FIXED*8)
 
 
2472
                {
 
 
2473
                    int colour = (particlePtr->LifeTime/(8*256*4));
 
 
2474
                      particlePtr->Colour = RGBA_MAKE(255,255,255,colour);
 
 
2475
                }
 
 
2476
                else
 
 
2477
                {
 
 
2478
                      particlePtr->Colour = RGBA_MAKE(255,255,255,64);
 
 
2479
                }
 
 
2480
 
 
 
2481
                particlePtr->Size = 1000+500-(particlePtr->LifeTime>>10);
 
 
2482
 
 
 
2483
                AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*64);
 
 
2484
            }
 
 
2485
            break;
 
 
2486
            case PARTICLE_ELECTRICALPLASMASPHERE:
 
 
2487
            {
 
 
2488
                int colour = (particlePtr->LifeTime/128);
 
 
2489
                particlePtr->Size = 200+(ONE_FIXED-particlePtr->LifeTime)/16;
 
 
2490
                  particlePtr->Colour = RGBA_MAKE(255,255,255,colour);
 
 
2491
            }
 
 
2492
            break;
 
 
2493
            case PARTICLE_STEAM:
 
 
2494
            {
 
 
2495
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2496
 
 
 
2497
                if (particlePtr->Velocity.vy > -1300)
 
 
2498
                    particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime);
 
 
2499
 
 
 
2500
                if (particlePtr->Velocity.vx > 0)
 
 
2501
                {
 
 
2502
                    particlePtr->Velocity.vx -= MUL_FIXED(2000, NormalFrameTime);
 
 
2503
 
 
 
2504
                    if (particlePtr->Velocity.vx < 0)
 
 
2505
                        particlePtr->Velocity.vx = 0;
 
 
2506
                }
 
 
2507
                else if (particlePtr->Velocity.vx < 0)
 
 
2508
                {
 
 
2509
                    particlePtr->Velocity.vx += MUL_FIXED(2000, NormalFrameTime);
 
 
2510
 
 
 
2511
                    if (particlePtr->Velocity.vx > 0)
 
 
2512
                        particlePtr->Velocity.vx = 0;
 
 
2513
                }
 
 
2514
 
 
 
2515
                if (particlePtr->Velocity.vz > 0)
 
 
2516
                {
 
 
2517
                    particlePtr->Velocity.vz -= MUL_FIXED(2000, NormalFrameTime);
 
 
2518
 
 
 
2519
                    if (particlePtr->Velocity.vz < 0)
 
 
2520
                        particlePtr->Velocity.vz = 0;
 
 
2521
                }
 
 
2522
                else if (particlePtr->Velocity.vz < 0)
 
 
2523
                {
 
 
2524
                    particlePtr->Velocity.vz += MUL_FIXED(2000, NormalFrameTime);
 
 
2525
 
 
 
2526
                    if (particlePtr->Velocity.vz > 0)
 
 
2527
                        particlePtr->Velocity.vz = 0;
 
 
2528
                }
 
 
2529
 
 
 
2530
particlePtr->Position.vx += MUL_FIXED ( particlePtr->Velocity.vx+
 
 
2531
MUL_FIXED(-GetSin((particlePtr->Position.vz+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vx ), NormalFrameTime );
 
 
2532
 
 
 
2533
particlePtr->Position.vz += MUL_FIXED ( particlePtr->Velocity.vz+ MUL_FIXED
 
 
2534
( GetCos((particlePtr->Position.vx+particlePtr->Position.vy)&4095)/4, particlePtr->Offset.vz ), NormalFrameTime );
 
 
2535
 
 
 
2536
particlePtr->Colour = RGBA_MAKE (
 
 
2537
                    particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
2538
                      particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
2539
                      particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
2540
                    (particlePtr->LifeTime >> 14) + 17
 
 
2541
                  );
 
 
2542
            }
 
 
2543
            default:
 
 
2544
            {
 
 
2545
                /* particle initialised wrongly */
 
 
2546
                assert(0);
 
 
2547
                break;
 
 
2548
            }
 
 
2549
        }
 
 
2550
    }
 
 
2551
 
 
 
2552
    i = NumActiveParticles;
 
 
2553
 
 
 
2554
    while(i)
 
 
2555
    {
 
 
2556
        PARTICLE *particlePtr = &ParticleStorage[--i];
 
 
2557
 
 
 
2558
        //printf("Active particle %d id %d\n ", NumActiveParticles, particlePtr->ParticleID);
 
 
2559
        VECTORCH position = particlePtr->Position;
 
 
2560
        TranslatePointIntoViewspace(&position);
 
 
2561
 
 
 
2562
        switch(particlePtr->ParticleID)
 
 
2563
        {
 
 
2564
            case PARTICLE_FLARESMOKE:
 
 
2565
            {
 
 
2566
                VECTORCH impulse = {0,0,0};
 
 
2567
                int t = MUL_FIXED(NormalFrameTime, NormalFrameTime*4);
 
 
2568
                AddEffectsOfForceGenerators(&particlePtr->Position, &impulse, 8);
 
 
2569
                particlePtr->Position.vx += MUL_FIXED(impulse.vx, t);
 
 
2570
                particlePtr->Position.vy += MUL_FIXED(impulse.vy, t);
 
 
2571
                particlePtr->Position.vz += MUL_FIXED(impulse.vz, t);
 
 
2572
                RenderParticle(particlePtr);
 
 
2573
            }
 
 
2574
            break;
 
 
2575
            case PARTICLE_FLAME:
 
 
2576
            case PARTICLE_NONDAMAGINGFLAME:
 
 
2577
            {
 
 
2578
                VECTORCH obstacleNormal;
 
 
2579
                int moduleIndex;
 
 
2580
                RenderParticle(particlePtr);
 
 
2581
 
 
 
2582
                ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex);
 
 
2583
 
 
 
2584
                particlePtr->Velocity.vy -= MUL_FIXED(8000, NormalFrameTime);
 
 
2585
 
 
 
2586
                //if(!(FastRandom() & 15) && ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2587
                if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2588
                {
 
 
2589
                    if(-1 != moduleIndex)
 
 
2590
                    MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particlePtr->Position, moduleIndex);
 
 
2591
                    //particlePtr->LifeTime = 0;
 
 
2592
                }
 
 
2593
                else
 
 
2594
                {
 
 
2595
                    AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16);
 
 
2596
                }
 
 
2597
            }
 
 
2598
            break;
 
 
2599
            case PARTICLE_FIRE:
 
 
2600
            {
 
 
2601
                RenderParticle(particlePtr);
 
 
2602
 
 
 
2603
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2604
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2605
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2606
                particlePtr->Velocity.vy -= MUL_FIXED(4000, NormalFrameTime);
 
 
2607
            }
 
 
2608
            break;
 
 
2609
            case PARTICLE_NONCOLLIDINGFLAME:
 
 
2610
            {                
 
 
2611
                RenderParticle(particlePtr);
 
 
2612
 
 
 
2613
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2614
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2615
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2616
                particlePtr->Velocity.vy -= MUL_FIXED(8000, NormalFrameTime);
 
 
2617
            }
 
 
2618
            break;
 
 
2619
            case PARTICLE_IMPACTSMOKE:
 
 
2620
            case PARTICLE_RICOCHET_SPARK:
 
 
2621
            case PARTICLE_SPARK:
 
 
2622
            case PARTICLE_STEAM:
 
 
2623
            case PARTICLE_BLACKSMOKE:
 
 
2624
            case PARTICLE_GUNMUZZLE_SMOKE:
 
 
2625
            case PARTICLE_MOLOTOVFLAME:
 
 
2626
            case PARTICLE_ORANGE_SPARK:
 
 
2627
            case PARTICLE_ORANGE_PLASMA:
 
 
2628
            case PARTICLE_PLASMATRAIL:
 
 
2629
            case PARTICLE_DEWLINE:
 
 
2630
            case PARTICLE_WATERSPRAY:
 
 
2631
            case PARTICLE_WATERFALLSPRAY:
 
 
2632
            case PARTICLE_SMOKECLOUD:
 
 
2633
            case PARTICLE_ELECTRICALPLASMASPHERE:
 
 
2634
                RenderParticle(particlePtr);
 
 
2635
            break;
 
 
2636
            case PARTICLE_FLECHETTE:
 
 
2637
            case PARTICLE_FLECHETTE_NONDAMAGING:
 
 
2638
                RenderFlechetteParticle(particlePtr);
 
 
2639
            break;
 
 
2640
            default:
 
 
2641
            {
 
 
2642
                /* particle initialised wrongly */
 
 
2643
                assert(0);
 
 
2644
                break;
 
 
2645
            }
 
 
2646
        }
 
 
2647
 
 
 
2648
        particlePtr->LifeTime -= NormalFrameTime;
 
 
2649
 
 
 
2650
        if (particlePtr->LifeTime <= 0)
 
 
2651
        {
 
 
2652
            switch(particlePtr->ParticleID)
 
 
2653
            {
 
 
2654
                case PARTICLE_MOLOTOVFLAME:
 
 
2655
                case PARTICLE_NONCOLLIDINGFLAME:
 
 
2656
                    if ( (FastRandom() & 65535) < 4096)
 
 
2657
                    {
 
 
2658
                        VECTORCH zero = {0,0,0};
 
 
2659
                        MakeParticle(&particlePtr->Position, &zero, PARTICLE_IMPACTSMOKE);
 
 
2660
                    }
 
 
2661
                default:
 
 
2662
                break;
 
 
2663
            }
 
 
2664
 
 
 
2665
            *particlePtr = ParticleStorage[--NumActiveParticles];
 
 
2666
        }
 
 
2667
    }
 
 
2668
}
 
 
2669
 
 
 
2670
static void blood_particles()
 
 
2671
{
 
 
2672
    int i;
 
 
2673
 
 
 
2674
    for(i = NumberOfBloodParticles-1; i >= 0; i--)
 
 
2675
    {
 
 
2676
        PARTICLE *particlePtr = &BloodParticleStorage[i];
 
 
2677
        //printf("Active blood particle %d id %d\n ", NumberOfBloodParticles, particlePtr->ParticleID);
 
 
2678
 
 
 
2679
        VECTORCH position = particlePtr->Position;
 
 
2680
        TranslatePointIntoViewspace(&position);
 
 
2681
 
 
 
2682
        switch(particlePtr->ParticleID)
 
 
2683
        {
 
 
2684
            case PARTICLE_ALIEN_BLOOD:
 
 
2685
            {
 
 
2686
                VECTORCH obstacleNormal;
 
 
2687
                int moduleIndex;
 
 
2688
                //particlePtr->Size = 64 - (FastRandom() & 31);
 
 
2689
                particlePtr->Size = 20;
 
 
2690
                particlePtr->Offset    = particlePtr->Position;
 
 
2691
                particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4;
 
 
2692
                particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4;
 
 
2693
                particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4;
 
 
2694
 
 
 
2695
                if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2696
                {
 
 
2697
                    MATRIXCH orientation;
 
 
2698
                    VECTORCH velocity;
 
 
2699
                    MakeMatrixFromDirection(&obstacleNormal, &orientation);
 
 
2700
                    velocity.vx = ((FastRandom()&1023) - 512);
 
 
2701
                    velocity.vy = ((FastRandom()&1023) - 512);
 
 
2702
                    velocity.vz = (255+(FastRandom()&255));
 
 
2703
                    RotateVector(&velocity, &orientation);
 
 
2704
                    MakeParticle(&particlePtr->Position, &velocity, PARTICLE_IMPACTSMOKE);
 
 
2705
                    if(-1 != moduleIndex)
 
 
2706
                    MakeDecal(DECAL_SCORCHED, &obstacleNormal, &particlePtr->Position, moduleIndex);
 
 
2707
 
 
 
2708
                    if((FastRandom() & 255) < 16)
 
 
2709
                        Sound_Play(SID_ACID_SPRAY, "dpv", &particlePtr->Position, (FastRandom() & 255) - 128, 40);
 
 
2710
 
 
 
2711
                    particlePtr->LifeTime = 0;
 
 
2712
                }
 
 
2713
                else
 
 
2714
                {
 
 
2715
                    particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime);
 
 
2716
                    AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16);
 
 
2717
                    RenderParticle(particlePtr);
 
 
2718
                }
 
 
2719
            }
 
 
2720
            break;
 
 
2721
            case PARTICLE_HUMAN_BLOOD:
 
 
2722
            {
 
 
2723
                VECTORCH obstacleNormal;
 
 
2724
                int moduleIndex;
 
 
2725
                //particlePtr->Size = 64 - (FastRandom() & 31);
 
 
2726
                particlePtr->Size = 20;
 
 
2727
                particlePtr->Offset    = particlePtr->Position;
 
 
2728
                particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4;
 
 
2729
                particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4;
 
 
2730
                particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4;
 
 
2731
 
 
 
2732
                if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2733
                {
 
 
2734
                    if(-1 != moduleIndex)
 
 
2735
                    MakeDecal(DECAL_HUMAN_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex);
 
 
2736
                    particlePtr->LifeTime = 0;
 
 
2737
                }
 
 
2738
                else
 
 
2739
                {
 
 
2740
                    particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime);
 
 
2741
                    AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16);
 
 
2742
                    RenderParticle(particlePtr);
 
 
2743
                }
 
 
2744
            }
 
 
2745
            break;
 
 
2746
            case PARTICLE_PREDATOR_BLOOD:
 
 
2747
            {
 
 
2748
                VECTORCH obstacleNormal;
 
 
2749
                int moduleIndex;
 
 
2750
                //particlePtr->Size = 64 - (FastRandom() & 31);
 
 
2751
                particlePtr->Size = 20;
 
 
2752
                particlePtr->Offset    = particlePtr->Position;
 
 
2753
                particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4;
 
 
2754
                particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4;
 
 
2755
                particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4;
 
 
2756
 
 
 
2757
                if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2758
                {
 
 
2759
                    if(-1 != moduleIndex)
 
 
2760
                    MakeDecal(DECAL_PREDATOR_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex);
 
 
2761
                    particlePtr->LifeTime = 0;
 
 
2762
                }
 
 
2763
                else
 
 
2764
                {
 
 
2765
                    particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime);
 
 
2766
                    AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16);
 
 
2767
                    RenderParticle(particlePtr);
 
 
2768
                }
 
 
2769
            }
 
 
2770
            break;
 
 
2771
            case PARTICLE_ANDROID_BLOOD:
 
 
2772
            {
 
 
2773
                VECTORCH obstacleNormal;
 
 
2774
                int moduleIndex;
 
 
2775
                //particlePtr->Size = 64 - (FastRandom() & 31);
 
 
2776
                particlePtr->Size = 20;
 
 
2777
                particlePtr->Offset    = particlePtr->Position;
 
 
2778
                particlePtr->Offset.vx += particlePtr->Velocity.vx >> 4;
 
 
2779
                particlePtr->Offset.vy += particlePtr->Velocity.vy >> 4;
 
 
2780
                particlePtr->Offset.vz += particlePtr->Velocity.vz >> 4;
 
 
2781
 
 
 
2782
                if(ParticleDynamics(particlePtr, &obstacleNormal, &moduleIndex))
 
 
2783
                {
 
 
2784
                    if(-1 != moduleIndex)
 
 
2785
                    MakeDecal(DECAL_ANDROID_BLOOD, &obstacleNormal, &particlePtr->Position, moduleIndex);
 
 
2786
                    particlePtr->LifeTime = 0;
 
 
2787
                }
 
 
2788
                else
 
 
2789
                {
 
 
2790
                    particlePtr->Velocity.vy += MUL_FIXED(10000, NormalFrameTime);
 
 
2791
                    AddEffectsOfForceGenerators(&particlePtr->Position, &particlePtr->Velocity, 32*16);
 
 
2792
                    RenderParticle(particlePtr);
 
 
2793
                }
 
 
2794
            }
 
 
2795
            break;
 
 
2796
            case PARTICLE_SPARK:
 
 
2797
            {
 
 
2798
                particlePtr->Offset = particlePtr->Position;
 
 
2799
 
 
 
2800
                particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2801
                particlePtr->Velocity.vx -= MUL_FIXED(particlePtr->Velocity.vx, NormalFrameTime);
 
 
2802
                particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy, NormalFrameTime);
 
 
2803
                particlePtr->Velocity.vy += MUL_FIXED(5000, NormalFrameTime);
 
 
2804
                particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2805
                particlePtr->Velocity.vz -= MUL_FIXED(particlePtr->Velocity.vz, NormalFrameTime);
 
 
2806
 
 
 
2807
                {
 
 
2808
                    int l = particlePtr->LifeTime * 2;
 
 
2809
                    l = MUL_FIXED(255,l);
 
 
2810
 
 
 
2811
                    if (l > 255)
 
 
2812
                    {
 
 
2813
                        switch (PlayerStatus.VisionMode)
 
 
2814
                        {
 
 
2815
                            default:
 
 
2816
                            case VISION_MODE_NORMAL:
 
 
2817
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,255,255);
 
 
2818
                            break;
 
 
2819
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2820
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l/2,255);
 
 
2821
                            break;
 
 
2822
                            case VISION_MODE_PRED_THERMAL:
 
 
2823
                                  particlePtr->Colour = RGBA_MAKE(l-255,255,255,255);
 
 
2824
                            break;
 
 
2825
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2826
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2827
                                  particlePtr->Colour = RGBA_MAKE(255,255,l-255,255);
 
 
2828
                        }
 
 
2829
                    }
 
 
2830
                    else
 
 
2831
                    {
 
 
2832
                        switch (PlayerStatus.VisionMode)
 
 
2833
                        {
 
 
2834
                            default:
 
 
2835
                            case VISION_MODE_NORMAL:
 
 
2836
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,l,l);
 
 
2837
                            break;
 
 
2838
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
2839
                                  particlePtr->Colour = RGBA_MAKE(l/2,l/2,128,l);
 
 
2840
                            break;
 
 
2841
                            case VISION_MODE_PRED_THERMAL:
 
 
2842
                                  particlePtr->Colour = RGBA_MAKE(0,l,l,l);
 
 
2843
                            break;
 
 
2844
                            case VISION_MODE_PRED_SEEALIENS:
 
 
2845
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
2846
                                  particlePtr->Colour = RGBA_MAKE(l,l,0,l);
 
 
2847
                        }
 
 
2848
                    }
 
 
2849
                }
 
 
2850
            }
 
 
2851
            default:
 
 
2852
            break;
 
 
2853
        }
 
 
2854
 
 
 
2855
        particlePtr->LifeTime -= NormalFrameTime;
 
 
2856
 
 
 
2857
        if (particlePtr->LifeTime <= 0)
 
 
2858
            *particlePtr = BloodParticleStorage[--NumberOfBloodParticles];
 
 
2859
 
 
 
2860
    }
 
 
2861
}
 
 
2862
 
 
 
2863
void HandleParticleSystem()
 
 
2864
{
 
 
2865
    int i;
 
 
2866
    HandleRipples();
 
 
2867
 
 
 
2868
DecalSystem_Setup();
 
 
2869
    HandleDecalSystem();
 
 
2870
    PostLandscapeRendering();
 
 
2871
//DecalSystem_End();
 
 
2872
    DecalSystem_Setup();
 
 
2873
    OutputTranslucentPolyList();
 
 
2874
    NoneBloodParticles();
 
 
2875
    blood_particles();
 
 
2876
 
 
 
2877
    for(i=0; i < numVisObjs; ++i)
 
 
2878
    {
 
 
2879
        DISPLAYBLOCK *objectPtr = VisibleObjects[i].DispPtr;
 
 
2880
        STRATEGYBLOCK *sbPtr = objectPtr->ObStrategyBlock;
 
 
2881
 
 
 
2882
        if (objectPtr->SfxPtr)
 
 
2883
        {
 
 
2884
            DrawSfxObject(objectPtr);
 
 
2885
        }
 
 
2886
        else if (NULL != sbPtr)
 
 
2887
        {
 
 
2888
            if (objectPtr->HModelControlBlock)
 
 
2889
                ScanHModelForDecals(objectPtr, objectPtr->HModelControlBlock->section_data);
 
 
2890
 
 
 
2891
            switch(sbPtr->type)
 
 
2892
            {
 
 
2893
                case I_BehaviourFlare:
 
 
2894
                    if (UserProfile.GameOptions.LightCoronas)
 
 
2895
                        DoFlareCorona(objectPtr);
 
 
2896
                break;
 
 
2897
                case I_BehaviourNetGhost:
 
 
2898
                {
 
 
2899
                    NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2900
 
 
 
2901
                    if (ghostDataPtr->type == I_BehaviourFlare && UserProfile.GameOptions.LightCoronas)
 
 
2902
                        DoFlareCorona(objectPtr);
 
 
2903
                }
 
 
2904
                break;
 
 
2905
                case I_BehaviourXenoborg:
 
 
2906
                {
 
 
2907
                    XENO_STATUS_BLOCK *statusPtr = (XENO_STATUS_BLOCK *)sbPtr->dataptr;
 
 
2908
                    LASER_BEAM_DESC *laserPtr = statusPtr->TargetingLaser;
 
 
2909
                    int i;
 
 
2910
                    for (i=0; i < 3; ++i)
 
 
2911
                    {
 
 
2912
                        if (laserPtr->BeamIsOn)
 
 
2913
                        {
 
 
2914
                            if (laserPtr->BeamHasHitPlayer)
 
 
2915
                            {              
 
 
2916
                                int colour;
 
 
2917
                                switch (PlayerStatus.VisionMode)
 
 
2918
                                {
 
 
2919
                                    default:
 
 
2920
                                    case VISION_MODE_NORMAL:
 
 
2921
                                        colour = 0xffff0000;
 
 
2922
                                    break;
 
 
2923
                                    case VISION_MODE_IMAGEINTENSIFIER:
 
 
2924
                                        colour = 0xffffffff;
 
 
2925
                                    break;
 
 
2926
                                    case VISION_MODE_PRED_THERMAL:
 
 
2927
                                    case VISION_MODE_PRED_SEEALIENS:
 
 
2928
                                    case VISION_MODE_PRED_SEEPREDTECH:
 
 
2929
                                        colour = 0xffff8000;
 
 
2930
                                }
 
 
2931
 
 
 
2932
                                RenderLightFlare(&laserPtr->SourcePosition, colour);
 
 
2933
                            }
 
 
2934
                            else
 
 
2935
                            {
 
 
2936
                                PARTICLE particle;
 
 
2937
                                switch (PlayerStatus.VisionMode)
 
 
2938
                                {
 
 
2939
                                    default:
 
 
2940
                                    case VISION_MODE_NORMAL:
 
 
2941
                                        particle.Colour = RGBA_MAKE(255,0,0,255);
 
 
2942
                                    break;
 
 
2943
                                    case VISION_MODE_IMAGEINTENSIFIER:
 
 
2944
                                        particle.Colour = RGBA_MAKE(255,255,255,255);
 
 
2945
                                    break;
 
 
2946
                                    case VISION_MODE_PRED_THERMAL:
 
 
2947
                                    case VISION_MODE_PRED_SEEALIENS:
 
 
2948
                                    case VISION_MODE_PRED_SEEPREDTECH:
 
 
2949
                                        particle.Colour = RGBA_MAKE(255,128,0,255);
 
 
2950
                                }
 
 
2951
 
 
 
2952
                                particle.ParticleID = PARTICLE_LASERBEAM;
 
 
2953
                                particle.Position = laserPtr->SourcePosition;
 
 
2954
                                particle.Offset = laserPtr->TargetPosition;
 
 
2955
                                particle.Size = 20;
 
 
2956
                                RenderParticle(&particle);
 
 
2957
                            }
 
 
2958
                        }
 
 
2959
                        laserPtr++;
 
 
2960
                    }
 
 
2961
 
 
 
2962
                    if (statusPtr->LeftMainBeam.BeamIsOn)
 
 
2963
                        DrawXenoborgMainLaserbeam(&statusPtr->LeftMainBeam);
 
 
2964
 
 
 
2965
                    if (statusPtr->RightMainBeam.BeamIsOn)
 
 
2966
                        DrawXenoborgMainLaserbeam(&statusPtr->RightMainBeam);
 
 
2967
                }
 
 
2968
                break;
 
 
2969
                case I_BehaviourSpeargunBolt:
 
 
2970
                {
 
 
2971
                    SPEAR_BEHAV_BLOCK *bbPtr = (SPEAR_BEHAV_BLOCK * ) sbPtr->dataptr;
 
 
2972
 
 
 
2973
                    if (bbPtr->SpearThroughFragment)
 
 
2974
                    {
 
 
2975
                        extern const DISPLAYBLOCK Zero_Displayblock;
 
 
2976
                        DISPLAYBLOCK displayblock = Zero_Displayblock;
 
 
2977
 
 
 
2978
                        displayblock.ObWorld.vx = bbPtr->Position.vx + sbPtr->DynPtr->Position.vx;
 
 
2979
                        displayblock.ObWorld.vy = bbPtr->Position.vy + sbPtr->DynPtr->Position.vy;
 
 
2980
                        displayblock.ObWorld.vz = bbPtr->Position.vz + sbPtr->DynPtr->Position.vz;
 
 
2981
                        displayblock.ObMat = bbPtr->Orient;
 
 
2982
                        displayblock.ObShape = GetLoadedShapeMSL("spear");
 
 
2983
                        displayblock.ShapeData = GetShapeData(displayblock.ObShape);
 
 
2984
 
 
 
2985
                        displayblock.ObView.vx = displayblock.ObWorld.vx - Global_VDB.VDB_World.vx;
 
 
2986
                        displayblock.ObView.vy = displayblock.ObWorld.vy - Global_VDB.VDB_World.vy;
 
 
2987
                        displayblock.ObView.vz = displayblock.ObWorld.vz - Global_VDB.VDB_World.vz;
 
 
2988
 
 
 
2989
                        RotateVector(&displayblock.ObView, &Global_VDB.VDB_Mat);
 
 
2990
                        AttachSpearGunArrow(&displayblock);
 
 
2991
                    }
 
 
2992
                }
 
 
2993
                default:
 
 
2994
                break;
 
 
2995
            }
 
 
2996
        }
 
 
2997
    }
 
 
2998
 
 
 
2999
    HandlePheromoneTrails();
 
 
3000
    HandleVolumetricExplosion();
 
 
3001
    DecalSystem_End();
 
 
3002
}
 
 
3003
 
 
 
3004
static void AddRipple(int x, int z, int amplitude)
 
 
3005
{
 
 
3006
    RippleStorage[ActiveRippleNumber].Active = 1;
 
 
3007
    RippleStorage[ActiveRippleNumber].X = x;
 
 
3008
    RippleStorage[ActiveRippleNumber].Z = z;
 
 
3009
    RippleStorage[ActiveRippleNumber].Radius = 200;
 
 
3010
    RippleStorage[ActiveRippleNumber].Amplitude = amplitude;
 
 
3011
 
 
 
3012
    if (++ActiveRippleNumber == MAX_NO_OF_RIPPLES)
 
 
3013
        ActiveRippleNumber = 0;
 
 
3014
}
 
 
3015
 
 
 
3016
void HandleRainDrops(MODULE *modulePtr, int numberOfRaindrops)
 
 
3017
{
 
 
3018
    int i;
 
 
3019
 
 
 
3020
    for(i=0; i < numberOfRaindrops; ++i)
 
 
3021
    {
 
 
3022
        PARTICLE *particlePtr = &RainDropStorage[i];
 
 
3023
 
 
 
3024
        if((particlePtr->Position.vy > modulePtr->m_world.vy+modulePtr->m_maxy-500)
 
 
3025
         ||(particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx)
 
 
3026
         ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx)
 
 
3027
         ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz)
 
 
3028
         ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz))
 
 
3029
        {
 
 
3030
            AddRipple(particlePtr->Position.vx, particlePtr->Position.vz,400);
 
 
3031
            particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_miny;
 
 
3032
            particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx));
 
 
3033
            particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz));
 
 
3034
  //        particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
 
 
3035
  //        particlePtr->Velocity.vx = (FastRandom()&255)+5000;
 
 
3036
 //            particlePtr->Velocity.vz = (FastRandom()&255)-128;
 
 
3037
            particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
 
 
3038
            particlePtr->Velocity.vx = (FastRandom()&255)-128;
 
 
3039
            particlePtr->Velocity.vz = (FastRandom()&255)-128;
 
 
3040
            {
 
 
3041
                particlePtr->Offset.vx = -particlePtr->Velocity.vz;
 
 
3042
                particlePtr->Offset.vy = 0;
 
 
3043
                particlePtr->Offset.vz = particlePtr->Velocity.vx;
 
 
3044
                Normalise(&(particlePtr->Offset));
 
 
3045
//                particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
 
 
3046
//                particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
 
 
3047
                particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,50);
 
 
3048
                particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,50);
 
 
3049
            }
 
 
3050
        }
 
 
3051
        {
 
 
3052
            VECTORCH prevPosition = particlePtr->Position;
 
 
3053
 
 
 
3054
            particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
 
 
3055
            particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
 
 
3056
            particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
 
 
3057
 
 
 
3058
            if (particlePtr->Position.vy > modulePtr->m_world.vy + modulePtr->m_maxy - 500)
 
 
3059
                particlePtr->Position.vy = modulePtr->m_world.vy+modulePtr->m_maxy-495;
 
 
3060
 
 
 
3061
            DrawParticle_Rain(particlePtr, &prevPosition);
 
 
3062
        }
 
 
3063
    }
 
 
3064
}
 
 
3065
 
 
 
3066
void HandleRain(int numberOfRaindrops)
 
 
3067
{
 
 
3068
    int i;
 
 
3069
    /* KJL 15:23:37 12/8/97 - this is written to work with the yard in genshd1 */
 
 
3070
 
 
 
3071
    assert( numberOfRaindrops < MAX_RAINDROPS);
 
 
3072
 
 
 
3073
    for (i=0; i < numberOfRaindrops; i++)
 
 
3074
    {
 
 
3075
        PARTICLE *particlePtr = &RainDropStorage[i];
 
 
3076
        int killDrop = 0;
 
 
3077
 
 
 
3078
        if((particlePtr->Position.vx > -10418)
 
 
3079
         &&(particlePtr->Position.vy > -4030)
 
 
3080
         &&(particlePtr->Position.vz < 35070)
 
 
3081
         &&(particlePtr->Position.vz > -11600))
 
 
3082
        {
 
 
3083
            killDrop = 1;
 
 
3084
        }
 
 
3085
        if((particlePtr->Position.vx > -45486)
 
 
3086
         &&(particlePtr->Position.vx < -29901)
 
 
3087
         &&(particlePtr->Position.vy > -6000)
 
 
3088
         &&(particlePtr->Position.vz < -50656)
 
 
3089
         &&(particlePtr->Position.vz > -70130))
 
 
3090
        {
 
 
3091
            killDrop = 1;
 
 
3092
        }
 
 
3093
 
 
 
3094
        if((particlePtr->Position.vy > 3000)
 
 
3095
         ||(particlePtr->Position.vx < -77000)
 
 
3096
         ||(particlePtr->Position.vx > 134000)
 
 
3097
         ||(particlePtr->Position.vz < -145000)//modulePtr->m_world.vz+modulePtr->m_minz)
 
 
3098
         ||(particlePtr->Position.vz > 48706))
 
 
3099
        {
 
 
3100
            killDrop = 1;
 
 
3101
        }
 
 
3102
 
 
 
3103
        if (killDrop)
 
 
3104
        {
 
 
3105
            particlePtr->Position.vy = -10000;
 
 
3106
            particlePtr->Position.vx = -77000+(FastRandom()%(211000));
 
 
3107
            particlePtr->Position.vz = -145000+(FastRandom()%(145000+49000));
 
 
3108
              particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
 
 
3109
              particlePtr->Velocity.vx = (FastRandom()&255)+5000;
 
 
3110
             particlePtr->Velocity.vz = (FastRandom()&255)-128;
 
 
3111
            {
 
 
3112
                particlePtr->Offset.vx = -particlePtr->Velocity.vz;
 
 
3113
                particlePtr->Offset.vy = 0;
 
 
3114
                particlePtr->Offset.vz = particlePtr->Velocity.vx;
 
 
3115
                Normalise(&(particlePtr->Offset));
 
 
3116
                particlePtr->Offset.vx = MUL_FIXED(particlePtr->Offset.vx,20);
 
 
3117
                particlePtr->Offset.vz = MUL_FIXED(particlePtr->Offset.vz,20);
 
 
3118
            }
 
 
3119
        }
 
 
3120
        {
 
 
3121
            VECTORCH prevPosition = particlePtr->Position;
 
 
3122
 
 
 
3123
            particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
 
 
3124
            particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
 
 
3125
            particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
 
 
3126
            DrawParticle_Rain(particlePtr,&prevPosition);
 
 
3127
        }
 
 
3128
    }
 
 
3129
}
 
 
3130
 
 
 
3131
void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops)
 
 
3132
{
 
 
3133
    int i;
 
 
3134
    const PARTICLE_DESC *particleDescPtr = &ParticleDescription[PARTICLE_WATERFALLSPRAY];
 
 
3135
 
 
 
3136
    assert(numberOfRaindrops < MAX_RAINDROPS);
 
 
3137
 
 
 
3138
    for (i=0; i < numberOfRaindrops; ++i)
 
 
3139
    {
 
 
3140
        PARTICLE *particlePtr = &RainDropStorage[i];
 
 
3141
 
 
 
3142
        if((particlePtr->Position.vx < modulePtr->m_world.vx+modulePtr->m_minx)
 
 
3143
         ||(particlePtr->Position.vx > modulePtr->m_world.vx+modulePtr->m_maxx)
 
 
3144
         ||(particlePtr->Position.vz < modulePtr->m_world.vz+modulePtr->m_minz)
 
 
3145
         ||(particlePtr->Position.vz > modulePtr->m_world.vz+modulePtr->m_maxz))
 
 
3146
        {
 
 
3147
            particlePtr->LifeTime = 0;
 
 
3148
        }
 
 
3149
        else if(particlePtr->Position.vy > bottomY)
 
 
3150
        {
 
 
3151
            particlePtr->Position.vy = bottomY;
 
 
3152
              particlePtr->Velocity.vy = -particlePtr->Velocity.vy;
 
 
3153
              particlePtr->Velocity.vx = particlePtr->Velocity.vx;
 
 
3154
             particlePtr->Velocity.vz = particlePtr->Velocity.vz;
 
 
3155
            particlePtr->LifeTime = 1;
 
 
3156
            particlePtr->Size = 100;
 
 
3157
            AddRipple(particlePtr->Position.vx, particlePtr->Position.vz, 100);
 
 
3158
        }
 
 
3159
 
 
 
3160
        if (particlePtr->LifeTime <= 0)
 
 
3161
        {
 
 
3162
            particlePtr->Position.vy = topY;
 
 
3163
            particlePtr->Position.vx = modulePtr->m_world.vx+modulePtr->m_minx+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minx));
 
 
3164
            particlePtr->Position.vz = modulePtr->m_world.vz+modulePtr->m_minz+(FastRandom()%(modulePtr->m_maxz-modulePtr->m_minz));
 
 
3165
              particlePtr->Velocity.vy = (FastRandom()&8191)+15000;
 
 
3166
              particlePtr->Velocity.vx = (FastRandom()&1023)-512;
 
 
3167
             particlePtr->Velocity.vz = (FastRandom()&1023)-512;
 
 
3168
            particlePtr->LifeTime = 100*ONE_FIXED;
 
 
3169
            particlePtr->ParticleID = PARTICLE_WATERFALLSPRAY;
 
 
3170
            particlePtr->Colour = RGBA_MAKE ( particleDescPtr->RedScale[PlayerStatus.VisionMode],
 
 
3171
                            particleDescPtr->GreenScale[PlayerStatus.VisionMode],
 
 
3172
                            particleDescPtr->BlueScale[PlayerStatus.VisionMode],
 
 
3173
                            particleDescPtr->Alpha);
 
 
3174
            particlePtr->Size = 20;
 
 
3175
        }
 
 
3176
        else
 
 
3177
        {
 
 
3178
            particlePtr->LifeTime -= NormalFrameTime;
 
 
3179
        }
 
 
3180
 
 
 
3181
        {
 
 
3182
            particlePtr->Position.vx += MUL_FIXED(particlePtr->Velocity.vx,NormalFrameTime);
 
 
3183
            particlePtr->Position.vy += MUL_FIXED(particlePtr->Velocity.vy,NormalFrameTime);
 
 
3184
            particlePtr->Position.vz += MUL_FIXED(particlePtr->Velocity.vz,NormalFrameTime);
 
 
3185
            particlePtr->Offset.vx = particlePtr->Position.vx - particlePtr->Velocity.vx/16;
 
 
3186
            particlePtr->Offset.vy = particlePtr->Position.vy - particlePtr->Velocity.vy/16;
 
 
3187
            particlePtr->Offset.vz = particlePtr->Position.vz - particlePtr->Velocity.vz/16;
 
 
3188
 
 
 
3189
            RenderParticle(particlePtr);
 
 
3190
        }
 
 
3191
    }
 
 
3192
}
 
 
3193
 
 
 
3194
int EffectOfRipples(VECTORCH *point)
 
 
3195
{
 
 
3196
    int i;
 
 
3197
     int offset = GetSin((point->vx+point->vz+CloakingPhase)&4095)>>11;
 
 
3198
     offset += GetSin((point->vx-point->vz*2+CloakingPhase/2)&4095)>>12;
 
 
3199
 
 
 
3200
    for(i=0; i < MAX_NO_OF_RIPPLES; i++)
 
 
3201
    {
 
 
3202
        if (RippleStorage[i].Active)
 
 
3203
        {
 
 
3204
            int dx = point->vx - RippleStorage[i].X;
 
 
3205
            int dz = point->vz - RippleStorage[i].Z;
 
 
3206
 
 
 
3207
            if (dx < 0)
 
 
3208
                dx = -dx;
 
 
3209
            if (dz < 0)
 
 
3210
                dz = -dz;
 
 
3211
 
 
 
3212
            {
 
 
3213
                int a;
 
 
3214
 
 
 
3215
                if (dx > dz)
 
 
3216
                    a = dx + (dz >> 1);
 
 
3217
                else
 
 
3218
                    a = dz + (dx >> 1);
 
 
3219
 
 
 
3220
                if (a < RippleStorage[i].Radius)
 
 
3221
                {
 
 
3222
                    a = MUL_FIXED(a, RippleStorage[i].InvRadius);
 
 
3223
 
 
 
3224
                    offset += MUL_FIXED(RippleStorage[i].Amplitude, GetSin(a));
 
 
3225
                }
 
 
3226
            }
 
 
3227
        }
 
 
3228
    }
 
 
3229
 
 
 
3230
    if (offset > 256)
 
 
3231
        offset = 256;
 
 
3232
    else if (offset < -256)
 
 
3233
        offset = -256;
 
 
3234
 
 
 
3235
return offset;
 
 
3236
}
 
 
3237
 
 
 
3238
void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY)
 
 
3239
{
 
 
3240
    int i;
 
 
3241
    //printf("ACTIVE OBJCE %d\n", NumActiveBlocks);
 
 
3242
    for(i = 0; i < NumActiveBlocks; ++i)
 
 
3243
    {
 
 
3244
        DISPLAYBLOCK* objectPtr = ActiveBlockList[i];
 
 
3245
 
 
 
3246
        if(objectPtr->ObStrategyBlock)
 
 
3247
        {
 
 
3248
            DYNAMICSBLOCK *dynPtr = objectPtr->ObStrategyBlock->DynPtr;
 
 
3249
 
 
 
3250
            if (dynPtr)
 
 
3251
            {
 
 
3252
                int overlapInY;
 
 
3253
                int overlapInX;
 
 
3254
                int overlapInZ;
 
 
3255
 
 
 
3256
                /* floating objects are ignored to avoid positive feedback */
 
 
3257
                if(!DynamicObjectIsMoving(dynPtr) || dynPtr->IsFloating)
 
 
3258
                    continue;
 
 
3259
 
 
 
3260
                if (dynPtr->Position.vy > dynPtr->PrevPosition.vy)
 
 
3261
                {
 
 
3262
                    overlapInY = ((dynPtr->Position.vy + objectPtr->extent.radius > averageY) && (dynPtr->PrevPosition.vy -
objectPtr->extent.radius < averageY));
 
 
3263
                }
 
 
3264
                else
 
 
3265
                {
 
 
3266
                    overlapInY = ((dynPtr->PrevPosition.vy + objectPtr->extent.radius > averageY) && (dynPtr->Position.vy -
objectPtr->extent.radius < averageY));
 
 
3267
                }
 
 
3268
 
 
 
3269
                if (!overlapInY) continue;
 
 
3270
 
 
 
3271
                if (dynPtr->Position.vx > dynPtr->PrevPosition.vx)
 
 
3272
                {
 
 
3273
                    overlapInX = ((dynPtr->Position.vx + objectPtr->extent.radius > minX) && (dynPtr->PrevPosition.vx -
objectPtr->extent.radius < maxX));
 
 
3274
                }
 
 
3275
                else
 
 
3276
                {
 
 
3277
                    overlapInX = ((dynPtr->PrevPosition.vx + objectPtr->extent.radius > minX) && (dynPtr->Position.vx -
objectPtr->extent.radius < maxX));
 
 
3278
                }
 
 
3279
 
 
 
3280
                if (!overlapInX) continue;
 
 
3281
 
 
 
3282
                if (dynPtr->Position.vz > dynPtr->PrevPosition.vz)
 
 
3283
                {
 
 
3284
                    overlapInZ = ((dynPtr->Position.vz + objectPtr->extent.radius > minZ) && (dynPtr->PrevPosition.vz -
objectPtr->extent.radius < maxZ));
 
 
3285
                }
 
 
3286
                else
 
 
3287
                {
 
 
3288
                    overlapInZ = ((dynPtr->PrevPosition.vz + objectPtr->extent.radius > minZ) && (dynPtr->Position.vz -
objectPtr->extent.radius < maxZ));
 
 
3289
                }
 
 
3290
 
 
 
3291
                if (!overlapInZ) continue;
 
 
3292
 
 
 
3293
                //if (!overlapInY && !overlapInX && !overlapInZ) continue;
 
 
3294
//puts("        OVERLAP ");
 
 
3295
                /* we have an overlap */
 
 
3296
 
 
 
3297
                switch(objectPtr->ObStrategyBlock->type)
 
 
3298
                {
 
 
3299
                    case I_BehaviourFlare:
 
 
3300
                    {
 
 
3301
                        VECTORCH upwards = {0, -65536, 0};
 
 
3302
                        dynPtr->IsFloating = 1;
 
 
3303
                        dynPtr->GravityOn = 0;
 
 
3304
                        dynPtr->Elasticity = 0;
 
 
3305
                        MakeMatrixFromDirection(&upwards, &dynPtr->OrientMat);
 
 
3306
                    }
 
 
3307
                    break;
 
 
3308
                    case I_BehaviourPredatorPlayer:
 
 
3309
                    {
 
 
3310
                        PlayerStatus.CloakingEffectiveness -= NormalFrameTime / 4;
 
 
3311
 
 
 
3312
                        if(PlayerStatus.CloakingEffectiveness < 0)
 
 
3313
                            PlayerStatus.CloakingEffectiveness = 0;
 
 
3314
                    } // no break
 
 
3315
                    case I_BehaviourAlienPlayer:
 
 
3316
                    case I_BehaviourMarinePlayer:
 
 
3317
                    {
 
 
3318
                        if(SOUND_NOACTIVEINDEX == PlayerStatus.sound_watersplash)
 
 
3319
                        {
 
 
3320
                            switch (FastRandom() & 3)
 
 
3321
                            {
 
 
3322
                                case 0:
 
 
3323
                                    Sound_Play(SID_SPLASH1, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash);
 
 
3324
                                break;
 
 
3325
                                case 1:
 
 
3326
                                    Sound_Play(SID_SPLASH2, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash);
 
 
3327
                                break;
 
 
3328
                                case 2:
 
 
3329
                                    Sound_Play(SID_SPLASH3, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash);
 
 
3330
                                break;
 
 
3331
                                default:
 
 
3332
                                    Sound_Play(SID_SPLASH4, "de", &dynPtr->Position, &PlayerStatus.sound_watersplash);
 
 
3333
                            }
 
 
3334
    //printf("playing water splash %d\n", random());
 
 
3335
                        }
 
 
3336
 
 
 
3337
                        if (PlayerStatus.sbptr->DamageBlock.IsOnFire)
 
 
3338
                            Sound_Stop(PlayerStatus.soundCracklingFire);
 
 
3339
                    }
 
 
3340
                    default:
 
 
3341
                    break;
 
 
3342
                }
 
 
3343
 
 
 
3344
                /* KJL 16:37:29 27/08/98 - if object is on fire its now put out */
 
 
3345
                objectPtr->ObStrategyBlock->DamageBlock.IsOnFire = 0;
 
 
3346
 
 
 
3347
                AddRipple(dynPtr->Position.vx, dynPtr->Position.vz, 100);
 
 
3348
            }
 
 
3349
        }
 
 
3350
    }
 
 
3351
}
 
 
3352
 
 
 
3353
void MakeFlareParticle(DYNAMICSBLOCK *dynPtr)
 
 
3354
{
 
 
3355
    VECTORCH velocity;
 
 
3356
    velocity.vx = ((FastRandom()&2047) - 1024);
 
 
3357
    velocity.vy = ((FastRandom()&2047) - 1024);
 
 
3358
    velocity.vz = (1000+(FastRandom()&255))*2;
 
 
3359
    RotateVector(&velocity, &dynPtr->OrientMat);
 
 
3360
    MakeParticle(&dynPtr->Position, &velocity, PARTICLE_FLARESMOKE);
 
 
3361
}
 
 
3362
 
 
 
3363
void MakeRocketTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr)
 
 
3364
{
 
 
3365
    VECTORCH disp;
 
 
3366
 
 
 
3367
    disp.vx = positionPtr->vx - prevPositionPtr->vx;
 
 
3368
    disp.vy = positionPtr->vy - prevPositionPtr->vy;
 
 
3369
    disp.vz = positionPtr->vz - prevPositionPtr->vz;
 
 
3370
 
 
 
3371
    if (disp.vx || disp.vy || disp.vz)
 
 
3372
    {
 
 
3373
        int i = 1;
 
 
3374
        //int i = 16;
 
 
3375
        //do
 
 
3376
        {
 
 
3377
            VECTORCH position;
 
 
3378
            VECTORCH velocity;
 
 
3379
            velocity.vx = (FastRandom()&1023) - 512;
 
 
3380
            velocity.vy = (FastRandom()&1023) - 512;
 
 
3381
            velocity.vz = (FastRandom()&1023) - 512;
 
 
3382
 
 
 
3383
            position.vx = prevPositionPtr->vx + (disp.vx*i)/16;
 
 
3384
            position.vy = prevPositionPtr->vy + (disp.vy*i)/16;
 
 
3385
            position.vz = prevPositionPtr->vz + (disp.vz*i)/16;
 
 
3386
 
 
 
3387
            MakeParticle(&position, &velocity, PARTICLE_BLACKSMOKE);
 
 
3388
 
 
 
3389
        }// while(i--);
 
 
3390
    }
 
 
3391
}
 
 
3392
 
 
 
3393
void MakeGrenadeTrailParticles(VECTORCH *prevPositionPtr, VECTORCH *positionPtr)
 
 
3394
{
 
 
3395
    VECTORCH disp;
 
 
3396
 
 
 
3397
    disp.vx = positionPtr->vx - prevPositionPtr->vx;
 
 
3398
    disp.vy = positionPtr->vy - prevPositionPtr->vy;
 
 
3399
    disp.vz = positionPtr->vz - prevPositionPtr->vz;
 
 
3400
 
 
 
3401
    if (disp.vx || disp.vy || disp.vz)
 
 
3402
    {
 
 
3403
        int i = 8;
 
 
3404
        do
 
 
3405
        {
 
 
3406
            VECTORCH position;
 
 
3407
            VECTORCH velocity;
 
 
3408
            velocity.vx = (FastRandom()&1023) - 512;
 
 
3409
            velocity.vy = (FastRandom()&1023) - 512;
 
 
3410
            velocity.vz = (FastRandom()&1023) - 512;
 
 
3411
 
 
 
3412
            position.vx = prevPositionPtr->vx + (disp.vx*i)/16;
 
 
3413
            position.vy = prevPositionPtr->vy + (disp.vy*i)/16;
 
 
3414
            position.vz = prevPositionPtr->vz + (disp.vz*i)/16;
 
 
3415
 
 
 
3416
            MakeParticle(&position, &velocity, PARTICLE_FLARESMOKE);
 
 
3417
 
 
 
3418
        } while(i--);
 
 
3419
    }
 
 
3420
}
 
 
3421
 
 
 
3422
void MakeImpactSmoke(MATRIXCH *orientationPtr, VECTORCH *positionPtr)
 
 
3423
{
 
 
3424
    //int i = 5;
 
 
3425
    //while(i--)
 
 
3426
    {
 
 
3427
        VECTORCH velocity;
 
 
3428
        //velocity.vx = ((FastRandom() & 1023) - 512);
 
 
3429
        //velocity.vy = ((FastRandom() & 1023) - 512);
 
 
3430
        //velocity.vz = (255+ (FastRandom() & 255));
 
 
3431
        velocity.vx = ((FastRandom() & 3));
 
 
3432
        velocity.vy = ((FastRandom() & 3));
 
 
3433
        velocity.vz = ((FastRandom() & 3));
 
 
3434
        RotateVector(&velocity, orientationPtr);
 
 
3435
        MakeParticle(positionPtr, &velocity, PARTICLE_IMPACTSMOKE);
 
 
3436
    }
 
 
3437
}
 
 
3438
 
 
 
3439
void GunMuzzleSmoke(MATRIXCH *orientationPtr, VECTORCH *positionPtr)
 
 
3440
{
 
 
3441
    //int i = 5;
 
 
3442
    //while(i--)
 
 
3443
    {
 
 
3444
        VECTORCH velocity;
 
 
3445
        //velocity.vx = ((FastRandom() & 1023) - 512);
 
 
3446
        //velocity.vy = ((FastRandom() & 1023) - 512);
 
 
3447
        //velocity.vz = (255+ (FastRandom() & 255));
 
 
3448
        velocity.vx = ((FastRandom() & 3)) ;
 
 
3449
        velocity.vy = ((FastRandom() & 3)) ;
 
 
3450
        velocity.vz = ((FastRandom() & 3));
 
 
3451
        RotateVector(&velocity, orientationPtr);
 
 
3452
        MakeParticle(positionPtr, &velocity, PARTICLE_GUNMUZZLE_SMOKE);
 
 
3453
    }
 
 
3454
}
 
 
3455
 
 
 
3456
static void MakeRicochetSound(VECTORCH *position)
 
 
3457
{
 
 
3458
    switch(NormalFrameTime & 0x3)
 
 
3459
    {
 
 
3460
        case 0:
 
 
3461
            Sound_Play(SID_RICOCH1, "pd", ((FastRandom()&255)-128),position);     
 
 
3462
        break;
 
 
3463
        case 1:
 
 
3464
            Sound_Play(SID_RICOCH2, "pd", ((FastRandom()&255)-128),position);     
 
 
3465
        break;
 
 
3466
        case 2:
 
 
3467
            Sound_Play(SID_RICOCH3, "pd", ((FastRandom()&255)-128),position);     
 
 
3468
        break;
 
 
3469
        case 3:
 
 
3470
            Sound_Play(SID_RICOCH4, "pd", ((FastRandom()&255)-128),position);     
 
 
3471
        default:
 
 
3472
            break;
 
 
3473
    }
 
 
3474
}
 
 
3475
 
 
 
3476
void MakeImpactSparks(VECTORCH *incidentPtr, VECTORCH *normalPtr, VECTORCH *positionPtr)
 
 
3477
{
 
 
3478
    int noOfSparks = 5;
 
 
3479
 
 
 
3480
    VECTORCH velocity;
 
 
3481
    int d = -2 * DotProduct(incidentPtr, normalPtr);
 
 
3482
    velocity.vx = (incidentPtr->vx + MUL_FIXED(d, normalPtr->vx)) >> 3;
 
 
3483
    velocity.vy = (incidentPtr->vy + MUL_FIXED(d, normalPtr->vy)) >> 3;
 
 
3484
    velocity.vz = (incidentPtr->vz + MUL_FIXED(d, normalPtr->vz)) >>  3;
 
 
3485
 
 
 
3486
    do
 
 
3487
    {
 
 
3488
        velocity.vx = velocity.vx + (FastRandom() & 2047) - 1024;
 
 
3489
        velocity.vy = velocity.vy + (FastRandom() & 2047) - 1024;
 
 
3490
        velocity.vz = velocity.vz + (FastRandom() & 2047) - 1024;
 
 
3491
        MakeParticle(positionPtr, &velocity,PARTICLE_RICOCHET_SPARK);    
 
 
3492
 
 
 
3493
    } while(--noOfSparks);
 
 
3494
 
 
 
3495
    MakeRicochetSound(positionPtr);
 
 
3496
}
 
 
3497
 
 
 
3498
void MakeSprayOfSparks(MATRIXCH *orientationPtr, VECTORCH *positionPtr)
 
 
3499
{
 
 
3500
    int noOfSparks = 15;
 
 
3501
 
 
 
3502
    do
 
 
3503
    {
 
 
3504
        VECTORCH velocity;
 
 
3505
        velocity.vx = (FastRandom()&2047)-1024;
 
 
3506
        velocity.vy = (FastRandom()&2047);
 
 
3507
        velocity.vz = -(FastRandom()&2047)-1024;
 
 
3508
        RotateVector(&velocity, orientationPtr);
 
 
3509
        MakeParticle(positionPtr, &velocity, PARTICLE_SPARK);    
 
 
3510
 
 
 
3511
    } while(--noOfSparks);
 
 
3512
 
 
 
3513
    MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_SPARKS);
 
 
3514
}
 
 
3515
 
 
 
3516
void MakeMolotovExplosionAt(VECTORCH *positionPtr)
 
 
3517
{
 
 
3518
    /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
 
 
3519
    if (ModuleFromPosition(positionPtr, NULL))
 
 
3520
    {
 
 
3521
        int i = 0;
 
 
3522
        int seed = 0;
 
 
3523
 
 
 
3524
        //need to get a random number seed for this explosion
 
 
3525
        while(!seed)
 
 
3526
            seed = FastRandom();
 
 
3527
 
 
 
3528
        SetSeededFastRandom(seed);
 
 
3529
 
 
 
3530
        for (; i < 100; i++)
 
 
3531
        {
 
 
3532
            VECTORCH velocity;
 
 
3533
            int phi = SeededFastRandom()&4095;
 
 
3534
 
 
 
3535
            velocity.vy = -(SeededFastRandom()&65535);
 
 
3536
            {
 
 
3537
                float y = ((float)velocity.vy)/65536.0;
 
 
3538
                y = sqrt(1-y*y);
 
 
3539
 
 
 
3540
                velocity.vx = ((float)GetCos(phi) * y);
 
 
3541
                velocity.vz = ((float)GetSin(phi) * y);
 
 
3542
            }
 
 
3543
            velocity.vx /= 8;
 
 
3544
            velocity.vy /= 16;
 
 
3545
            velocity.vz /= 8;
 
 
3546
 
 
 
3547
            MakeParticle(positionPtr, &velocity, PARTICLE_MOLOTOVFLAME);
 
 
3548
        }
 
 
3549
    }
 
 
3550
}
 
 
3551
 
 
 
3552
void MakeElectricalExplosion(const VECTORCH *positionPtr)
 
 
3553
{
 
 
3554
    Sound_Play(SID_PRED_PISTOL_EXPLOSION, "d", positionPtr);
 
 
3555
    MakeParticle(positionPtr, positionPtr, PARTICLE_ELECTRICALPLASMASPHERE);
 
 
3556
    MakeLightElement(positionPtr, LIGHTELEMENT_ELECTRICAL_EXPLOSION);
 
 
3557
 
 
 
3558
    //if(SinglePlayer != AvP.PlayMode) AddNetMsg_MakeExplosion(centrePtr, EXPLOSION_PREDATORPISTOL);
 
 
3559
}
 
 
3560
 
 
 
3561
void MakeVolumetricExplosionAt(VECTORCH *positionPtr, enum EXPLOSION_ID explosionID)
 
 
3562
{
 
 
3563
    unsigned int i;
 
 
3564
    struct VOLUMETRIC_EXPLOSION *expPtr = AllocateVolumetricExplosion();
 
 
3565
 
 
 
3566
    for(i=0; i < SPHERE_VERTICES; i++)
 
 
3567
    {
 
 
3568
        expPtr->Position[i] = *positionPtr;
 
 
3569
        expPtr->Velocity[i].vx = SphereVertex[i].vx;
 
 
3570
        expPtr->Velocity[i].vy = SphereVertex[i].vy;
 
 
3571
        expPtr->Velocity[i].vz = SphereVertex[i].vz;
 
 
3572
        expPtr->BeenStopped[i] = 0;
 
 
3573
        expPtr->RipplePhase[i] = FastRandom() & 4095;
 
 
3574
        expPtr->NumberVerticesMoving = SPHERE_VERTICES;
 
 
3575
    }
 
 
3576
 
 
 
3577
    if ((positionPtr->vx != PlayerStatus.DisplayBlock->ObWorld.vx)
 
 
3578
        || (positionPtr->vy != PlayerStatus.DisplayBlock->ObWorld.vy)
 
 
3579
        || (positionPtr->vz != PlayerStatus.DisplayBlock->ObWorld.vz))
 
 
3580
    MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
 
 
3581
 
 
 
3582
    switch (explosionID)
 
 
3583
    {
 
 
3584
        case EXPLOSION_SADAR_BLAST:
 
 
3585
        {
 
 
3586
            expPtr->UseCollisions = 1;
 
 
3587
            expPtr->LifeTime = ONE_FIXED-1;// + 20000;
 
 
3588
 
 
 
3589
            for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion; i++)
 
 
3590
            {
 
 
3591
                VECTORCH position = *positionPtr;
 
 
3592
                position.vx += (FastRandom() & 2047) - 1024;
 
 
3593
                position.vy += (FastRandom() & 2047) - 1024;
 
 
3594
                position.vz += (FastRandom() & 2047) - 1024;
 
 
3595
                MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD);
 
 
3596
            }
 
 
3597
        }
 
 
3598
        break;
 
 
3599
        case EXPLOSION_GRENADE_BLAST:
 
 
3600
        case EXPLOSION_GRENADE_NOCOLLISIONS:
 
 
3601
        {
 
 
3602
            expPtr->UseCollisions = (EXPLOSION_GRENADE_BLAST == explosionID);
 
 
3603
            expPtr->LifeTime = ONE_FIXED-1;
 
 
3604
 
 
 
3605
            for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromLargeExplosion; i++)
 
 
3606
            {
 
 
3607
                VECTORCH position = *positionPtr;
 
 
3608
                position.vx += (FastRandom() & 2047) - 1024;
 
 
3609
                position.vy += (FastRandom() & 2047) - 1024;
 
 
3610
                position.vz += (FastRandom() & 2047) - 1024;
 
 
3611
                MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD);
 
 
3612
            }
 
 
3613
        }
 
 
3614
        break;
 
 
3615
        case EXPLOSION_PULSEGRENADE:
 
 
3616
        case EXPLOSION_SMALL_NOCOLLISIONS:
 
 
3617
        {
 
 
3618
            expPtr->UseCollisions = (EXPLOSION_PULSEGRENADE == explosionID);
 
 
3619
            expPtr->LifeTime = ONE_FIXED/2;
 
 
3620
 
 
 
3621
            i = LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion;
 
 
3622
 
 
 
3623
            for (i=0; i < LocalDetailLevels.NumberOfSmokeParticlesFromSmallExplosion; i++)
 
 
3624
            {
 
 
3625
                VECTORCH position = *positionPtr;
 
 
3626
                position.vx += (FastRandom() & 1023)-512;
 
 
3627
                position.vy += (FastRandom() & 1023)-512;
 
 
3628
                position.vz += (FastRandom() & 1023)-512;
 
 
3629
                MakeParticle(&position, positionPtr, PARTICLE_SMOKECLOUD);
 
 
3630
            }
 
 
3631
        }
 
 
3632
        default:
 
 
3633
        return;
 
 
3634
    }
 
 
3635
 
 
 
3636
    //if(SinglePlayer != AvP.PlayMode) AddNetMsg_MakeExplosion(positionPtr, explosionID);
 
 
3637
}
 
 
3638
 
 
 
3639
void MakeFlechetteExplosionAt(VECTORCH *positionPtr, int seed)
 
 
3640
{
 
 
3641
    extern SOUND3DDATA Explosion_SoundData;
 
 
3642
    int i;
 
 
3643
    enum PARTICLE_ID particle_to_use;
 
 
3644
 
 
 
3645
    Explosion_SoundData.position = *positionPtr;
 
 
3646
    Sound_Play(SID_FRAG_RICOCHETS, "n", &Explosion_SoundData);
 
 
3647
 
 
 
3648
    if(!seed)
 
 
3649
    {
 
 
3650
        //need to get a random number seed for this explosion
 
 
3651
        while(!seed)
 
 
3652
            seed = FastRandom();
 
 
3653
 
 
 
3654
        //explosion originated on this computer , so use damaging type
 
 
3655
        particle_to_use = PARTICLE_FLECHETTE;
 
 
3656
 
 
 
3657
        //if in a network game , send explosion to other players
 
 
3658
        if(SinglePlayer != AvP.PlayMode)
 
 
3659
            AddNetMsg_MakeFlechetteExplosion(positionPtr, seed);
 
 
3660
    }
 
 
3661
    else
 
 
3662
    {
 
 
3663
        //explosion passed across the network
 
 
3664
        //use the nondamaging flechette
 
 
3665
        particle_to_use = PARTICLE_FLECHETTE_NONDAMAGING;
 
 
3666
    }
 
 
3667
 
 
 
3668
    SetSeededFastRandom(seed);
 
 
3669
 
 
 
3670
    /* KJL 11:49:25 19/08/98 - check to see if explosion is inside environment */
 
 
3671
    if (ModuleFromPosition(positionPtr, NULL))
 
 
3672
    {
 
 
3673
        for (i=0; i < 100; i++)
 
 
3674
        {
 
 
3675
            VECTORCH velocity;
 
 
3676
            int phi = SeededFastRandom() & 4095;
 
 
3677
 
 
 
3678
            velocity.vy = -(SeededFastRandom() & 65535);
 
 
3679
 
 
 
3680
            {
 
 
3681
                float y = ((float)velocity.vy)/65536.0;
 
 
3682
                y = sqrt(1-y*y);
 
 
3683
 
 
 
3684
                velocity.vx = ((float)GetCos(phi) * y);
 
 
3685
                velocity.vz = ((float)GetSin(phi) * y);
 
 
3686
            }
 
 
3687
 
 
 
3688
            MakeParticle(positionPtr, &velocity, particle_to_use);
 
 
3689
        }
 
 
3690
 
 
 
3691
        MakeLightElement(positionPtr, LIGHTELEMENT_EXPLOSION);
 
 
3692
    }
 
 
3693
}
 
 
3694
 
 
 
3695
void MakeFocusedExplosion(VECTORCH *originPtr, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID)
 
 
3696
{
 
 
3697
    VECTORCH blastDir;
 
 
3698
    int i;
 
 
3699
 
 
 
3700
    blastDir.vx = originPtr->vx - blastPositionPtr->vx;
 
 
3701
    blastDir.vy = originPtr->vy - blastPositionPtr->vy;
 
 
3702
    blastDir.vz = originPtr->vz - blastPositionPtr->vz;
 
 
3703
 
 
 
3704
    for (i=0; i < noOfParticles; i++)
 
 
3705
    {
 
 
3706
        VECTORCH velocity,position;
 
 
3707
        int phi = FastRandom() & 4095;
 
 
3708
        int speed = FastRandom() & 2047;
 
 
3709
 
 
 
3710
        velocity.vz = (FastRandom() & 131071) - ONE_FIXED;
 
 
3711
        {
 
 
3712
            float z = ((float)velocity.vz)/65536.0;
 
 
3713
            z = sqrt(1-z*z);
 
 
3714
 
 
 
3715
            velocity.vx = ((float)GetCos(phi) * z);
 
 
3716
            velocity.vy = ((float)GetSin(phi) * z);
 
 
3717
        }
 
 
3718
 
 
 
3719
        if (DotProduct(&velocity,&blastDir) < 0)
 
 
3720
        {
 
 
3721
            velocity.vx = -velocity.vx; 
 
 
3722
            velocity.vy = -velocity.vy;
 
 
3723
            velocity.vz = -velocity.vz; 
 
 
3724
        }
 
 
3725
 
 
 
3726
        int r = FastRandom() % 127;
 
 
3727
        position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r);
 
 
3728
        position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r);
 
 
3729
        position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r);
 
 
3730
 
 
 
3731
        velocity.vx = MUL_FIXED(velocity.vx, speed);
 
 
3732
        velocity.vy = MUL_FIXED(velocity.vy, speed);
 
 
3733
        velocity.vz = MUL_FIXED(velocity.vz, speed);
 
 
3734
 
 
 
3735
        MakeParticle(&position, &velocity, particleID);
 
 
3736
    }
 
 
3737
}
 
 
3738
 
 
 
3739
void MakeBloodExplosion(VECTORCH *originPtr, int creationRadius, VECTORCH *blastPositionPtr, int noOfParticles, enum PARTICLE_ID particleID)
 
 
3740
{
 
 
3741
    VECTORCH blastDir;
 
 
3742
    int i;
 
 
3743
 
 
 
3744
    blastDir.vx = originPtr->vx - blastPositionPtr->vx;
 
 
3745
    blastDir.vy = originPtr->vy - blastPositionPtr->vy;
 
 
3746
    blastDir.vz = originPtr->vz - blastPositionPtr->vz;
 
 
3747
 
 
 
3748
    for (i=0; i < noOfParticles; i++)
 
 
3749
    {
 
 
3750
        VECTORCH velocity;
 
 
3751
        VECTORCH position;
 
 
3752
        int phi = FastRandom()&4095;
 
 
3753
        int speed = 6000+(FastRandom()&4095);
 
 
3754
        int r;
 
 
3755
        //speed = FastRandom()&2047;
 
 
3756
 
 
 
3757
        velocity.vz = (FastRandom()&131071) - ONE_FIXED;
 
 
3758
        {
 
 
3759
            float z = ((float)velocity.vz)/65536.0;
 
 
3760
            z = sqrt(1-z*z);
 
 
3761
 
 
 
3762
            velocity.vx = ((float)GetCos(phi) * z);
 
 
3763
            velocity.vy = ((float)GetSin(phi) * z);
 
 
3764
        }
 
 
3765
 
 
 
3766
        if (DotProduct(&velocity, &blastDir) < 0)
 
 
3767
        {
 
 
3768
            velocity.vx = -velocity.vx; 
 
 
3769
            velocity.vy = -velocity.vy;
 
 
3770
            velocity.vz = -velocity.vz; 
 
 
3771
        }
 
 
3772
 
 
 
3773
        r = FastRandom() % creationRadius;
 
 
3774
        position.vx = originPtr->vx + MUL_FIXED(velocity.vx,r);
 
 
3775
        position.vy = originPtr->vy + MUL_FIXED(velocity.vy,r);
 
 
3776
        position.vz = originPtr->vz + MUL_FIXED(velocity.vz,r);
 
 
3777
 
 
 
3778
        velocity.vx = MUL_FIXED(velocity.vx,speed);
 
 
3779
        velocity.vy = MUL_FIXED(velocity.vy,speed);
 
 
3780
        velocity.vz = MUL_FIXED(velocity.vz,speed);
 
 
3781
 
 
 
3782
        MakeBloodParticle(&position, &velocity, particleID);
 
 
3783
    }
 
 
3784
}
 
 
3785
 
 
 
3786
void MakePlasmaExplosion(VECTORCH *positionPtr, VECTORCH *fromPositionPtr, enum EXPLOSION_ID explosionID)
 
 
3787
{
 
 
3788
    if(EXPLOSION_DISSIPATINGPLASMA == explosionID)
 
 
3789
    {
 
 
3790
        MakeLightElement(positionPtr, LIGHTELEMENT_PLASMACASTERHIT);
 
 
3791
        //MakeBloodExplosion(fromPositionPtr, 127, positionPtr, 200, PARTICLE_ORANGE_SPARK);
 
 
3792
        MakeFocusedExplosion(fromPositionPtr, positionPtr, 200, PARTICLE_ORANGE_SPARK);
 
 
3793
        Sound_Play(SID_PLASMABOLT_DISSIPATE, "d", positionPtr);
 
 
3794
    }
 
 
3795
    else // should be EXPLOSION_FOCUSEDPLASMA
 
 
3796
    {
 
 
3797
        MakeLightElement(positionPtr, LIGHTELEMENT_PLASMACASTERHIT);
 
 
3798
        MakeFocusedExplosion(fromPositionPtr, positionPtr, 100, PARTICLE_ORANGE_PLASMA);
 
 
3799
        Sound_Play(SID_PLASMABOLT_HIT, "d", positionPtr);
 
 
3800
    }
 
 
3801
}
 
 
3802
 
 
 
3803
void MakePlasmaTrailParticles(DYNAMICSBLOCK *dynPtr, int number)
 
 
3804
{
 
 
3805
    VECTORCH disp;
 
 
3806
 
 
 
3807
    disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
 
 
3808
    disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
 
 
3809
    disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
 
 
3810
 
 
 
3811
    int i = number;
 
 
3812
    do
 
 
3813
    {
 
 
3814
        VECTORCH velocity;
 
 
3815
        VECTORCH position;
 
 
3816
        int phi = FastRandom()&4095;
 
 
3817
        int speed = 512;
 
 
3818
 
 
 
3819
        velocity.vz = (FastRandom() & 131071) - ONE_FIXED;
 
 
3820
 
 
 
3821
        {
 
 
3822
            float z = ((float)velocity.vz)/65536.0;
 
 
3823
            z = sqrt(1-z*z);
 
 
3824
 
 
 
3825
            velocity.vx = ((float)GetCos(phi) * z);
 
 
3826
            velocity.vy = ((float)GetSin(phi) * z);
 
 
3827
        }
 
 
3828
 
 
 
3829
        velocity.vx = MUL_FIXED(velocity.vx, speed);//+dynPtr->LinVelocity.vx/32;
 
 
3830
        velocity.vy = MUL_FIXED(velocity.vy, speed);//+dynPtr->LinVelocity.vy/32;
 
 
3831
        velocity.vz = MUL_FIXED(velocity.vz, speed);//+dynPtr->LinVelocity.vz/32;
 
 
3832
        position.vx = dynPtr->PrevPosition.vx + (disp.vx*i) / number;
 
 
3833
        position.vy = dynPtr->PrevPosition.vy + (disp.vy*i) / number;
 
 
3834
        position.vz = dynPtr->PrevPosition.vz + (disp.vz*i) / number;
 
 
3835
 
 
 
3836
        MakeParticle(&position, &velocity, PARTICLE_PLASMATRAIL);
 
 
3837
 
 
 
3838
    } while(i--);
 
 
3839
}
 
 
3840
 
 
 
3841
void MakeDewlineTrailParticles(DYNAMICSBLOCK *dynPtr, int number)
 
 
3842
{
 
 
3843
    VECTORCH disp;
 
 
3844
 
 
 
3845
    disp.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
 
 
3846
    disp.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
 
 
3847
    disp.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
 
 
3848
 
 
 
3849
  //    if (disp.vx!=0 || disp.vy!=0 || disp.vz!=0)
 
 
3850
    {
 
 
3851
        int i=number;
 
 
3852
        do
 
 
3853
        {
 
 
3854
            VECTORCH velocity;
 
 
3855
            VECTORCH position;
 
 
3856
            int phi = FastRandom()&4095;
 
 
3857
            int speed = 256; //512
 
 
3858
 
 
 
3859
            velocity.vz = (FastRandom()&131071) - ONE_FIXED;
 
 
3860
            {
 
 
3861
                float z = ((float)velocity.vz)/65536.0;
 
 
3862
                z = sqrt(1-z*z);
 
 
3863
 
 
 
3864
                velocity.vx = ((float)GetCos(phi) * z);
 
 
3865
                velocity.vy = ((float)GetSin(phi) * z);
 
 
3866
            }
 
 
3867
 
 
 
3868
            velocity.vx = MUL_FIXED(velocity.vx,speed);//+dynPtr->LinVelocity.vx/32;
 
 
3869
            velocity.vy = MUL_FIXED(velocity.vy,speed);//+dynPtr->LinVelocity.vy/32;
 
 
3870
            velocity.vz = MUL_FIXED(velocity.vz,speed);//+dynPtr->LinVelocity.vz/32;
 
 
3871
            position.vx = dynPtr->PrevPosition.vx + (disp.vx*i)/number;
 
 
3872
            position.vy = dynPtr->PrevPosition.vy + (disp.vy*i)/number;
 
 
3873
            position.vz = dynPtr->PrevPosition.vz + (disp.vz*i)/number;
 
 
3874
 
 
 
3875
            MakeParticle(&position, &velocity, PARTICLE_DEWLINE);
 
 
3876
 
 
 
3877
        } while(i--);
 
 
3878
    }
 
 
3879
}
 
 
3880
 
 
 
3881
/* KJL 16:37:03 20/06/98 - stupid but quick implementation */
 
 
3882
#define NO_OF_VERTICES_IN_TRAIL 300
 
 
3883
PHEROMONE_TRAIL Trail[NO_OF_VERTICES_IN_TRAIL];
 
 
3884
 
 
 
3885
void NewTrailPoint(DYNAMICSBLOCK *dynPtr)
 
 
3886
{
 
 
3887
     PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail();
 
 
3888
 
 
 
3889
    if (NULL != trailPtr)
 
 
3890
    {
 
 
3891
        assert(dynPtr);
 
 
3892
        trailPtr->Vertex[0] = dynPtr->Position;
 
 
3893
       //    trailPtr->Vertex[0].vy -=1000;
 
 
3894
 
 
 
3895
        trailPtr->Perp[0] = *((VECTORCH*)&(dynPtr->OrientMat.mat11));
 
 
3896
        trailPtr->Size[0] = 127*65536;
 
 
3897
 
 
 
3898
        trailPtr->Vertex[1] = dynPtr->PrevPosition;
 
 
3899
       //    trailPtr->Vertex[1].vy -=1000;
 
 
3900
        trailPtr->Perp[1] = *((VECTORCH*)&(dynPtr->PrevOrientMat.mat11));
 
 
3901
        trailPtr->Size[1] = 127*65536-MUL_FIXED(TRAIL_DECAY_SPEED,PrevNormalFrameTime);
 
 
3902
    }
 
 
3903
}
 
 
3904
 
 
 
3905
void PlayerPheromoneTrail(DYNAMICSBLOCK *dynPtr)
 
 
3906
{
 
 
3907
     PHEROMONE_TRAIL *trailPtr = AllocatePheromoneTrail();
 
 
3908
 
 
 
3909
    if (NULL != trailPtr)
 
 
3910
    {
 
 
3911
        VECTORCH disp;
 
 
3912
        disp.vx = dynPtr->Position.vx-dynPtr->PrevPosition.vx;
 
 
3913
        disp.vy = dynPtr->Position.vy-dynPtr->PrevPosition.vy;
 
 
3914
        disp.vz = dynPtr->Position.vz-dynPtr->PrevPosition.vz;
 
 
3915
 
 
 
3916
        trailPtr->Vertex[0] = dynPtr->Position;
 
 
3917
        trailPtr->Vertex[0].vx -= dynPtr->OrientMat.mat21>>6;
 
 
3918
        trailPtr->Vertex[0].vy -= dynPtr->OrientMat.mat22>>6;
 
 
3919
        trailPtr->Vertex[0].vz -= dynPtr->OrientMat.mat23>>6;
 
 
3920
 
 
 
3921
        trailPtr->Perp[0] = *((VECTORCH*) & dynPtr->OrientMat.mat11);
 
 
3922
        trailPtr->Size[0] = 127*65536*4;
 
 
3923
 
 
 
3924
        trailPtr->Vertex[1] = dynPtr->PrevPosition;
 
 
3925
        trailPtr->Vertex[1].vx -= dynPtr->PrevOrientMat.mat21 >> 6;
 
 
3926
        trailPtr->Vertex[1].vy -= dynPtr->PrevOrientMat.mat22 >> 6;
 
 
3927
        trailPtr->Vertex[1].vz -= dynPtr->PrevOrientMat.mat23 >> 6;
 
 
3928
 
 
 
3929
        trailPtr->Perp[1] = *((VECTORCH*)&dynPtr->PrevOrientMat.mat11);
 
 
3930
        trailPtr->Size[1] = 127*65536*4 - MUL_FIXED(TRAIL_DECAY_SPEED, PrevNormalFrameTime);
 
 
3931
    }
 
 
3932
}
 
 
3933
 
 
 
3934
void RenderParticlesInMirror()
 
 
3935
{
 
 
3936
    int i = NumActiveParticles;
 
 
3937
    PARTICLE *particlePtr = ParticleStorage;
 
 
3938
 
 
 
3939
    DecalSystem_Setup();
 
 
3940
 
 
 
3941
    while(i--)
 
 
3942
    {
 
 
3943
        switch(particlePtr->ParticleID)
 
 
3944
        {
 
 
3945
            case PARTICLE_FLARESMOKE:
 
 
3946
            case PARTICLE_STEAM:
 
 
3947
            case PARTICLE_BLACKSMOKE:
 
 
3948
            case PARTICLE_IMPACTSMOKE:
 
 
3949
            case PARTICLE_SMOKECLOUD:
 
 
3950
                particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx;
 
 
3951
                RenderParticle(particlePtr);
 
 
3952
                particlePtr->Position.vx = MirroringAxis - particlePtr->Position.vx;
 
 
3953
            default:
 
 
3954
                break;
 
 
3955
        }
 
 
3956
        particlePtr++;
 
 
3957
    }
 
 
3958
 
 
 
3959
    int numOfObjects = numVisObjs;
 
 
3960
 
 
 
3961
    while(numOfObjects--)
 
 
3962
    {
 
 
3963
        DISPLAYBLOCK *objectPtr = VisibleObjects[numOfObjects].DispPtr;
 
 
3964
 
 
 
3965
        if (objectPtr->SfxPtr)
 
 
3966
            DrawSfxObject(objectPtr);
 
 
3967
    }
 
 
3968
 
 
 
3969
    DecalSystem_End();
 
 
3970
}
 
 
3971
 
 
 
3972
void TimeScaleThingy()
 
 
3973
{
 
 
3974
    extern int TimeScale;
 
 
3975
    extern int RealFrameTime;
 
 
3976
    int DesiredTimeScale = ONE_FIXED;
 
 
3977
    int i = 0;
 
 
3978
 
 
 
3979
    for(; i < NumActiveBlocks; i++)
 
 
3980
    {
 
 
3981
        STRATEGYBLOCK* sbPtr = ActiveBlockList[i]->ObStrategyBlock;
 
 
3982
 
 
 
3983
        if(sbPtr)
 
 
3984
        {
 
 
3985
            switch(sbPtr->type)
 
 
3986
            {
 
 
3987
                case I_BehaviourAlien:
 
 
3988
                case I_BehaviourQueenAlien:
 
 
3989
                case I_BehaviourFaceHugger:
 
 
3990
                case I_BehaviourPredator:
 
 
3991
                case I_BehaviourXenoborg:
 
 
3992
                case I_BehaviourMarine:
 
 
3993
                case I_BehaviourAutoGun:
 
 
3994
                    DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.8);
 
 
3995
                break;
 
 
3996
                case I_BehaviourGrenade:
 
 
3997
                case I_BehaviourRocket:
 
 
3998
                case I_BehaviourFrisbee:
 
 
3999
                case I_BehaviourPulseGrenade:
 
 
4000
                case I_BehaviourMolotov:
 
 
4001
                    DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.7);
 
 
4002
                default:
 
 
4003
                break;
 
 
4004
            }
 
 
4005
        }
 
 
4006
    }
 
 
4007
 
 
 
4008
    for(i=0; i < CurrentExplosionIndex; i++)
 
 
4009
        DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.5);
 
 
4010
 
 
 
4011
    if(DesiredTimeScale < ONE_FIXED)
 
 
4012
        DesiredTimeScale = MUL_FIXED(DesiredTimeScale, ONE_FIXED*.8);
 
 
4013
 
 
 
4014
    if(DesiredTimeScale < ONE_FIXED/10)
 
 
4015
        DesiredTimeScale = ONE_FIXED/10;
 
 
4016
 
 
 
4017
    if(TimeScale < DesiredTimeScale)
 
 
4018
    {
 
 
4019
        TimeScale += RealFrameTime/8;
 
 
4020
 
 
 
4021
        if(TimeScale > DesiredTimeScale)
 
 
4022
            TimeScale = DesiredTimeScale;
 
 
4023
    }
 
 
4024
    else if (TimeScale > DesiredTimeScale)
 
 
4025
    {
 
 
4026
        TimeScale -= RealFrameTime;
 
 
4027
 
 
 
4028
        if(TimeScale < DesiredTimeScale)
 
 
4029
            TimeScale = DesiredTimeScale;
 
 
4030
    }
 
 
4031
}
 
 
4032
 
 
 
4033
/*----------------------**
 
 
4034
**  Load/Save particles **
 
 
4035
**----------------------*/
 
 
4036
 
 
 
4037
typedef struct particle_save_block_header
 
 
4038
{
 
 
4039
    SAVE_BLOCK_HEADER header;
 
 
4040
 
 
 
4041
    int NumActiveParticles;
 
 
4042
    int NumberOfBloodParticles;
 
 
4043
 
 
 
4044
    //followed by paricle array after this block
 
 
4045
 
 
 
4046
} PARTICLE_SAVE_BLOCK_HEADER;
 
 
4047
 
 
 
4048
void Load_Particles(SAVE_BLOCK_HEADER* header)
 
 
4049
{
 
 
4050
    PARTICLE_SAVE_BLOCK_HEADER* block = (PARTICLE_SAVE_BLOCK_HEADER*) header;
 
 
4051
    PARTICLE* saved_particle = (PARTICLE*)(block+1);
 
 
4052
    int expected_size;
 
 
4053
    int i;
 
 
4054
 
 
 
4055
    //make sure the block is the correct size
 
 
4056
    expected_size = sizeof(*block);
 
 
4057
    expected_size += sizeof(PARTICLE) * block->NumActiveParticles;
 
 
4058
    if(header->size != expected_size)
 
 
4059
        return;
 
 
4060
 
 
 
4061
    //right copy the stuff then
 
 
4062
    NumActiveParticles = block->NumActiveParticles;
 
 
4063
    NumberOfBloodParticles = block->NumberOfBloodParticles;
 
 
4064
 
 
 
4065
    for(i=0; i < NumActiveParticles; i++)
 
 
4066
        ParticleStorage[i] = *saved_particle++;
 
 
4067
}
 
 
4068
 
 
 
4069
void Save_Particles()
 
 
4070
{
 
 
4071
    PARTICLE_SAVE_BLOCK_HEADER* block;
 
 
4072
 
 
 
4073
    if(NumActiveParticles > 0)
 
 
4074
    {
 
 
4075
        int i;
 
 
4076
        //get memory for header
 
 
4077
        GET_SAVE_BLOCK_POINTER(block);
 
 
4078
 
 
 
4079
        //fill in header
 
 
4080
        block->header.type = SaveBlock_Particles;
 
 
4081
        block->header.size = sizeof(*block) + NumActiveParticles * sizeof(PARTICLE);
 
 
4082
 
 
 
4083
        block->NumActiveParticles = NumActiveParticles;
 
 
4084
        block->NumberOfBloodParticles = NumberOfBloodParticles;
 
 
4085
 
 
 
4086
        //now save the particles
 
 
4087
        for(i=0; i < NumActiveParticles; i++)
 
 
4088
        {
 
 
4089
            PARTICLE* particle = GetPointerForSaveBlock(sizeof(PARTICLE));
 
 
4090
            *particle = ParticleStorage[i];
 
 
4091
        }    
 
 
4092
    }
 
 
4093
}
 
 
4094
 
 
 
4095
/*----------------------**
 
 
4096
** Load/Save Explosions **
 
 
4097
**----------------------*/
 
 
4098
 
 
 
4099
typedef struct explosion_save_block_header
 
 
4100
{
 
 
4101
    SAVE_BLOCK_HEADER header;
 
 
4102
 
 
 
4103
    int NumActiveExplosions;
 
 
4104
    //followed by explosion array after this block
 
 
4105
 
 
 
4106
} EXPLOSION_SAVE_BLOCK_HEADER;
 
 
4107
 
 
 
4108
void Load_VolumetricExplosions(SAVE_BLOCK_HEADER* header)
 
 
4109
{
 
 
4110
    int i;
 
 
4111
    EXPLOSION_SAVE_BLOCK_HEADER* block = (EXPLOSION_SAVE_BLOCK_HEADER*) header;
 
 
4112
    struct VOLUMETRIC_EXPLOSION* saved_explosion = (struct VOLUMETRIC_EXPLOSION*) (block+1);
 
 
4113
 
 
 
4114
    //make sure the block is the correct size
 
 
4115
    int expected_size = sizeof(*block);
 
 
4116
    expected_size += sizeof(struct VOLUMETRIC_EXPLOSION) * block->NumActiveExplosions;
 
 
4117
 
 
 
4118
    if(header->size == expected_size)
 
 
4119
    {
 
 
4120
        for(i=0; i < block->NumActiveExplosions; i++)
 
 
4121
        {
 
 
4122
            struct VOLUMETRIC_EXPLOSION* explosion = AllocateVolumetricExplosion();
 
 
4123
            *explosion = *saved_explosion++;
 
 
4124
        }
 
 
4125
    }
 
 
4126
}
 
 
4127
 
 
 
4128
void Save_VolumetricExplosions()
 
 
4129
{
 
 
4130
    if(CurrentExplosionIndex > 0)
 
 
4131
    {
 
 
4132
        int i;
 
 
4133
        EXPLOSION_SAVE_BLOCK_HEADER* block;
 
 
4134
 
 
 
4135
        //get memory for header
 
 
4136
        GET_SAVE_BLOCK_POINTER(block);
 
 
4137
 
 
 
4138
        //fill in header
 
 
4139
        block->header.type = SaveBlock_VolumetricExplosions;
 
 
4140
        block->header.size = sizeof(*block) + CurrentExplosionIndex * sizeof(struct VOLUMETRIC_EXPLOSION);
 
 
4141
 
 
 
4142
        block->NumActiveExplosions = CurrentExplosionIndex;
 
 
4143
 
 
 
4144
        for(i=0; i < CurrentExplosionIndex; i++)
 
 
4145
        {
 
 
4146
            struct VOLUMETRIC_EXPLOSION* explosion = GetPointerForSaveBlock(sizeof(struct VOLUMETRIC_EXPLOSION));
 
 
4147
            *explosion = *active_volumetric_explosion[i];
 
 
4148
        }
 
 
4149
    }
 
 
4150
}
 
 
4151
 
 
 
4152
/*----------------------------**
 
 
4153
** Load/Save pheromone trails **
 
 
4154
**----------------------------*/
 
 
4155
 
 
 
4156
typedef struct pheromone_save_block_header
 
 
4157
{
 
 
4158
    SAVE_BLOCK_HEADER header;
 
 
4159
 
 
 
4160
    int NumActiveTrails;
 
 
4161
    //followed by pheromone array after this block
 
 
4162
 
 
 
4163
} PHEROMONE_SAVE_BLOCK_HEADER;
 
 
4164
 
 
 
4165
void Load_PheromoneTrails(SAVE_BLOCK_HEADER* header)
 
 
4166
{
 
 
4167
    int i;
 
 
4168
    PHEROMONE_SAVE_BLOCK_HEADER* block = (PHEROMONE_SAVE_BLOCK_HEADER*) header;
 
 
4169
    PHEROMONE_TRAIL* saved_trail = (PHEROMONE_TRAIL*) (block+1);
 
 
4170
    int expected_size;
 
 
4171
 
 
 
4172
    //make sure the block is the correct size
 
 
4173
    expected_size = sizeof(*block);
 
 
4174
    expected_size += sizeof(PHEROMONE_TRAIL) * block->NumActiveTrails;
 
 
4175
    if(header->size != expected_size)
 
 
4176
        return;
 
 
4177
 
 
 
4178
    for(i=0; i < block->NumActiveTrails; i++)
 
 
4179
    {
 
 
4180
        PHEROMONE_TRAIL* trail = AllocatePheromoneTrail();
 
 
4181
 
 
 
4182
        if(trail) 
 
 
4183
            *trail = *saved_trail++;    
 
 
4184
    }
 
 
4185
}
 
 
4186
 
 
 
4187
void Save_PheromoneTrails()
 
 
4188
{
 
 
4189
    if(NumActiveTrails > 0)
 
 
4190
    {
 
 
4191
        PHEROMONE_SAVE_BLOCK_HEADER* block;
 
 
4192
        int i;
 
 
4193
 
 
 
4194
        //get memory for header
 
 
4195
        GET_SAVE_BLOCK_POINTER(block);
 
 
4196
 
 
 
4197
        //fill in header
 
 
4198
        block->header.type = SaveBlock_PheromoneTrail;
 
 
4199
        block->header.size = sizeof(*block) + NumActiveTrails * sizeof(PHEROMONE_TRAIL);
 
 
4200
 
 
 
4201
        block->NumActiveTrails = NumActiveTrails;
 
 
4202
 
 
 
4203
        //now save the trails
 
 
4204
        for(i=0; i < NumActiveTrails; i++)
 
 
4205
        {
 
 
4206
            PHEROMONE_TRAIL* trail = GET_SAVE_BLOCK_POINTER(trail);
 
 
4207
            *trail = TrailStorage[i];
 
 
4208
        }
 
 
4209
    }
 
 
4210
}