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