4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
/* Patrick 14/7/97----------------------------
 
 
2
  Source for Multi-Player ghost object support header
 
 
3
  ----------------------------------------------------------------------*/
 
 
4
#include "system.h"
 
 
5
#include "stratdef.h"
 
 
6
#include "bh_types.h"
 
 
7
#include "npc_alien.h"
 
 
8
#include "npc_marine.h"
 
 
9
#include "pldghost.h"
 
 
10
#include "lighting.h"
 
 
11
#include "psndplat.h"
 
 
12
#include "corpse.h"
 
 
13
#include "weapons.h"
 
 
14
#include "weaponbehaviour.h"
 
 
15
#include <stdlib.h>
 
 
16
#include <assert.h>
 
 
17
 
 
 
18
#include "projload.hpp"
 
 
19
extern const SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char *);
 
 
20
 
 
 
21
extern int GlobalFrameCounter;
 
 
22
extern DEATH_DATA Alien_Deaths[];
 
 
23
 
 
 
24
SOUND3DDATA Ghost_Explosion_SoundData =
 
 
25
{
 
 
26
    {0,0,0,},
 
 
27
    {0,0,0,},
 
 
28
    15000,
 
 
29
    150000
 
 
30
};
 
 
31
 
 
 
32
static void SetPlayerGhostAnimationSequence(STRATEGYBLOCK *sbPtr, int sequence, int special)
 
 
33
{
 
 
34
    DELTA_CONTROLLER *FireLeft,*FireRight;
 
 
35
 
 
 
36
    assert(sbPtr);    
 
 
37
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
38
    assert(ghostData);
 
 
39
    AVP_BEHAVIOUR_TYPE type = ghostData->type;
 
 
40
 
 
 
41
    if(!sbPtr->DisplayBlock)
 
 
42
    {
 
 
43
        /* update the ghost's current sequence: do this even if we don't have a displayblock */
 
 
44
        ghostData->currentAnimSequence = sequence;
 
 
45
    return; /* no displayblock: can't actually set it */
 
 
46
    }
 
 
47
 
 
 
48
    switch(type)
 
 
49
    {
 
 
50
        case I_BehaviourMarinePlayer:
 
 
51
        {    
 
 
52
            switch((MARINE_SEQUENCE)sequence)
 
 
53
            {
 
 
54
                case MSQ_Walk:
 
 
55
                {
 
 
56
                    switch(ghostData->CurrentWeapon)
 
 
57
                    {
 
 
58
                    case WEAPON_SMARTGUN:
 
 
59
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1),1);
 
 
60
                    break;
 
 
61
                    case WEAPON_MARINE_PISTOL:
 
 
62
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1),1);
 
 
63
                    break;
 
 
64
                    case WEAPON_TWO_PISTOLS:
 
 
65
                    {
 
 
66
                        /* Oh, no. */
 
 
67
                        if (special)
 
 
68
                        {
 
 
69
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence != MRSS_Fire_From_Hips))
 
 
70
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
71
                        }
 
 
72
                        else
 
 
73
                        {
 
 
74
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence != MRSS_Standard))
 
 
75
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
76
                        }
 
 
77
                    }
 
 
78
                    break;
 
 
79
                    default:
 
 
80
                InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
81
                    }
 
 
82
                }
 
 
83
                break;
 
 
84
                case MSQ_Walk_Backwards:
 
 
85
                {
 
 
86
                    switch(ghostData->CurrentWeapon)
 
 
87
                    {
 
 
88
                        case WEAPON_SMARTGUN:
 
 
89
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
90
                        break;
 
 
91
                        case WEAPON_MARINE_PISTOL:
 
 
92
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
93
                        break;
 
 
94
                        case WEAPON_TWO_PISTOLS:
 
 
95
                        {
 
 
96
                            /* Oh, no. */
 
 
97
                            if (special)
 
 
98
                            {
 
 
99
                if ((ghostData->HModelController.Sequence_Type!=(int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Fire_From_Hips))
 
 
100
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
101
                            }
 
 
102
                            else
 
 
103
                            {
 
 
104
                    if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun)||(ghostData->HModelController.Sub_Sequence != MRSS_Standard))
 
 
105
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
106
                            }
 
 
107
                        }
 
 
108
                        break;
 
 
109
                        default:
 
 
110
                        {
 
 
111
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1));
 
 
112
                        }
 
 
113
                    }
 
 
114
                    ghostData->HModelController.Reversed = 1;
 
 
115
                }
 
 
116
                break;
 
 
117
                case MSQ_RunningFire:
 
 
118
                {
 
 
119
                    switch(ghostData->CurrentWeapon)
 
 
120
                    {
 
 
121
                        case WEAPON_MARINE_PISTOL:
 
 
122
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
123
                        break;
 
 
124
                        case WEAPON_TWO_PISTOLS:
 
 
125
                        {
 
 
126
                            FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
127
 
 
 
128
                            if (FireRight == NULL)
 
 
129
                            {
 
 
130
                                FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
131
                                FireRight->Active = 0;
 
 
132
                            }
 
 
133
 
 
 
134
                            FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
135
 
 
 
136
                            if (FireLeft == NULL)
 
 
137
                            {
 
 
138
                                FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
139
                                FireLeft->Active = 0;
 
 
140
                            }
 
 
141
 
 
 
142
                            if (special)
 
 
143
                            {
 
 
144
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Fire_From_Hips))
 
 
145
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
146
                            }
 
 
147
                            else
 
 
148
                            {
 
 
149
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence != MRSS_Standard))
 
 
150
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
151
                            }
 
 
152
 
 
 
153
                            Start_Delta_Sequence(FireRight,HMSQT_MarineStand,MSSS_Attack_Primary,-1);
 
 
154
                        }
 
 
155
                        break;
 
 
156
                        default:    
 
 
157
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
158
                    }
 
 
159
                }
 
 
160
                break;
 
 
161
                case MSQ_RunningFireSecondary:
 
 
162
                {
 
 
163
                    switch(ghostData->CurrentWeapon)
 
 
164
                    {
 
 
165
                    case WEAPON_MARINE_PISTOL:
 
 
166
                        InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
167
                    break;
 
 
168
                    case WEAPON_TWO_PISTOLS:
 
 
169
                    {
 
 
170
                        FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
171
 
 
 
172
                        if (FireRight == NULL)
 
 
173
                        {
 
 
174
                            FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
175
                            FireRight->Active = 0;
 
 
176
                        }
 
 
177
 
 
 
178
                        FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
179
 
 
 
180
                        if (FireLeft == NULL)
 
 
181
                        {
 
 
182
                            FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
183
                            FireLeft->Active = 0;
 
 
184
                        }
 
 
185
 
 
 
186
                        if (special)
 
 
187
                        {
 
 
188
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence != MRSS_Fire_From_Hips))
 
 
189
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
190
                        }
 
 
191
                        else
 
 
192
                        {
 
 
193
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence!= MRSS_Standard))
 
 
194
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
195
                        }
 
 
196
 
 
 
197
                        Start_Delta_Sequence(FireLeft,HMSQT_MarineStand,MSSS_Attack_Secondary,-1);
 
 
198
                    }
 
 
199
                    break;
 
 
200
                    default:    
 
 
201
                        InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
202
                    }
 
 
203
                }
 
 
204
                break;
 
 
205
                case MSQ_RunningFire_Backwards:
 
 
206
                {
 
 
207
                    switch(ghostData->CurrentWeapon)
 
 
208
                    {
 
 
209
                        case WEAPON_MARINE_PISTOL:
 
 
210
                        {
 
 
211
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
212
                            ghostData->HModelController.Reversed = 1;
 
 
213
                        }
 
 
214
                        break;
 
 
215
                        case WEAPON_TWO_PISTOLS:
 
 
216
                        {
 
 
217
                            FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
218
 
 
 
219
                            if (FireRight == NULL)
 
 
220
                            {
 
 
221
                                FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
222
                                FireRight->Active = 0;
 
 
223
                            }
 
 
224
 
 
 
225
                            FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
226
 
 
 
227
                            if (FireLeft == NULL)
 
 
228
                            {
 
 
229
                                FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
230
                                FireLeft->Active = 0;
 
 
231
                            }
 
 
232
 
 
 
233
                            if (special)
 
 
234
                            {
 
 
235
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Fire_From_Hips))
 
 
236
                {
 
 
237
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
238
                    ghostData->HModelController.Reversed = 1;
 
 
239
                }
 
 
240
                            }
 
 
241
                            else
 
 
242
                            {
 
 
243
                    if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Standard))
 
 
244
                    {
 
 
245
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
246
                        ghostData->HModelController.Reversed = 1;
 
 
247
                    }
 
 
248
                            }
 
 
249
 
 
 
250
                            Start_Delta_Sequence(FireRight,HMSQT_MarineStand,MSSS_Attack_Primary,-1);
 
 
251
                        }
 
 
252
                        break;
 
 
253
                        default:
 
 
254
                        {
 
 
255
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
256
                            ghostData->HModelController.Reversed = 1;
 
 
257
                        }
 
 
258
                    }
 
 
259
                }
 
 
260
                break;
 
 
261
                case MSQ_RunningFireSecondary_Backwards:
 
 
262
                {
 
 
263
                    switch(ghostData->CurrentWeapon)
 
 
264
                    {
 
 
265
                        case WEAPON_MARINE_PISTOL:
 
 
266
                        {
 
 
267
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
268
                            ghostData->HModelController.Reversed = 1;
 
 
269
                        }
 
 
270
                        break;
 
 
271
                        case WEAPON_TWO_PISTOLS:
 
 
272
                        {
 
 
273
                            FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
274
 
 
 
275
                            if (FireRight == NULL)
 
 
276
                            {
 
 
277
                                FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
278
                                FireRight->Active = 0;
 
 
279
                            }
 
 
280
 
 
 
281
                            FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
282
 
 
 
283
                            if (FireLeft == NULL)
 
 
284
                            {
 
 
285
                                FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
286
                                FireLeft->Active = 0;
 
 
287
                            }
 
 
288
 
 
 
289
                            if (special)
 
 
290
                            {
 
 
291
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Fire_From_Hips))
 
 
292
                {
 
 
293
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Fire_From_Hips,(ONE_FIXED>>1),1);
 
 
294
                ghostData->HModelController.Reversed = 1;
 
 
295
                }
 
 
296
                            }
 
 
297
                            else
 
 
298
                            {
 
 
299
                    if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineRun) || (ghostData->HModelController.Sub_Sequence !=
MRSS_Standard))
 
 
300
                    {
 
 
301
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineRun,(int)MRSS_Standard,(ONE_FIXED>>1),1);
 
 
302
                    ghostData->HModelController.Reversed = 1;
 
 
303
                    }
 
 
304
                            }
 
 
305
                            Start_Delta_Sequence(FireLeft,HMSQT_MarineStand,MSSS_Attack_Secondary,-1);
 
 
306
                        }
 
 
307
                        break;
 
 
308
                        default:    
 
 
309
                        {
 
 
310
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineRun,(int)MRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
311
                            ghostData->HModelController.Reversed = 1;
 
 
312
                        }
 
 
313
                    }
 
 
314
                }
 
 
315
                break;
 
 
316
                case MSQ_StandingFire:
 
 
317
                {
 
 
318
                    switch(ghostData->CurrentWeapon)
 
 
319
                    {
 
 
320
                        case WEAPON_TWO_PISTOLS:
 
 
321
                        {
 
 
322
                            FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
323
 
 
 
324
                            if (FireRight == NULL)
 
 
325
                            {
 
 
326
                                FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
327
                                FireRight->Active = 0;
 
 
328
                            }
 
 
329
 
 
 
330
                            FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
331
 
 
 
332
                            if (FireLeft == NULL)
 
 
333
                            {
 
 
334
                                FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
335
                                FireLeft->Active = 0;
 
 
336
                            }
 
 
337
 
 
 
338
                            if (special)
 
 
339
                            {
 
 
340
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence !=
MSSS_FireFromHips))
 
 
341
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
342
                            }
 
 
343
                            else
 
 
344
                            {
 
 
345
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence != MSSS_Standard))
 
 
346
                InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,(ONE_FIXED>>1),1);
 
 
347
                            }
 
 
348
 
 
 
349
                            Start_Delta_Sequence(FireRight,HMSQT_MarineStand,MSSS_Attack_Primary,-1);
 
 
350
                        }
 
 
351
                        break;
 
 
352
                        default:
 
 
353
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Attack_Primary,ONE_FIXED);
 
 
354
                    }
 
 
355
                }
 
 
356
                break;
 
 
357
                case MSQ_StandingFireSecondary:
 
 
358
                {
 
 
359
                    switch(ghostData->CurrentWeapon)
 
 
360
                    {
 
 
361
                        case WEAPON_TWO_PISTOLS:
 
 
362
                        {
 
 
363
                            FireRight = Get_Delta_Sequence(&ghostData->HModelController,"FireRight");
 
 
364
 
 
 
365
                            if (FireRight == NULL)
 
 
366
                            {
 
 
367
                                FireRight =
Add_Delta_Sequence(&ghostData->HModelController,"FireRight",HMSQT_MarineStand,MSSS_Attack_Primary,ONE_FIXED);
 
 
368
                                FireRight->Active = 0;
 
 
369
                            }
 
 
370
 
 
 
371
                            FireLeft = Get_Delta_Sequence(&ghostData->HModelController,"FireLeft");
 
 
372
 
 
 
373
                            if (FireLeft == NULL)
 
 
374
                            {
 
 
375
                                FireLeft =
Add_Delta_Sequence(&ghostData->HModelController,"FireLeft",HMSQT_MarineStand,MSSS_Attack_Secondary,ONE_FIXED);
 
 
376
                                FireLeft->Active = 0;
 
 
377
                            }
 
 
378
 
 
 
379
                            if (special)
 
 
380
                            {
 
 
381
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence !=
MSSS_FireFromHips))
 
 
382
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
383
                            }
 
 
384
                            else
 
 
385
                            {
 
 
386
                if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence != MSSS_Standard))
 
 
387
                InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,(ONE_FIXED>>1),1);
 
 
388
                            }
 
 
389
 
 
 
390
                            Start_Delta_Sequence(FireLeft,HMSQT_MarineStand,MSSS_Attack_Secondary,-1);
 
 
391
                        }
 
 
392
                        break;
 
 
393
                        default:
 
 
394
                            InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Attack_Primary,ONE_FIXED);
 
 
395
                    }
 
 
396
                }
 
 
397
                break;
 
 
398
                case MSQ_Stand:
 
 
399
                {
 
 
400
                    /* Removed the test for 'standing swipe'... */
 
 
401
                    if(ghostData->currentAnimSequence >= MSQ_BaseOfCudgelAttacks)
 
 
402
                    {
 
 
403
                        if((ghostData->currentAnimSequence - MSQ_BaseOfCudgelAttacks) % 2 == 1)
 
 
404
                        {
 
 
405
                            //if currently playing a standing attack allow it to finish first
 
 
406
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
407
                                return;
 
 
408
                        }
 
 
409
                    }
 
 
410
 
 
 
411
                    if (ghostData->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
412
                    {
 
 
413
                        if (special)
 
 
414
                        {
 
 
415
        if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence != MSSS_FireFromHips))
 
 
416
        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
417
                        }
 
 
418
                        else
 
 
419
                        {
 
 
420
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence != MSSS_Standard))
 
 
421
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,(ONE_FIXED>>1),1);
 
 
422
                        }
 
 
423
                    }
 
 
424
                    else
 
 
425
                    {
 
 
426
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,ONE_FIXED,1);
 
 
427
    //                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Standard,ONE_FIXED);
 
 
428
                    }
 
 
429
                }
 
 
430
                break;
 
 
431
                case MSQ_Crawl:
 
 
432
                {
 
 
433
                    if (ghostData->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
434
                    {
 
 
435
                        if (special)
 
 
436
                        {
 
 
437
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrawl) || (ghostData->HModelController.Sub_Sequence != MCSS_FireFromHips))
 
 
438
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrawl,(int)MCSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
439
                        }
 
 
440
                        else
 
 
441
                        {
 
 
442
        if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrawl) || (ghostData->HModelController.Sub_Sequence != MCSS_Standard))
 
 
443
        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrawl,(int)MCSS_Standard,(ONE_FIXED>>1),1);
 
 
444
                        }
 
 
445
                    }
 
 
446
                    else
 
 
447
                    {
 
 
448
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_MarineCrawl,(int)MCSS_Standard,(ONE_FIXED>>1),1);
 
 
449
                    }
 
 
450
                }
 
 
451
                break;
 
 
452
                case MSQ_Crawl_Backwards:
 
 
453
                {
 
 
454
                    if (ghostData->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
455
                    {
 
 
456
                        if (special)
 
 
457
                        {
 
 
458
        if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrawl) || (ghostData->HModelController.Sub_Sequence != MCSS_FireFromHips))
 
 
459
        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrawl,(int)MCSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
460
                        }
 
 
461
                        else
 
 
462
                        {
 
 
463
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrawl) || (ghostData->HModelController.Sub_Sequence != MCSS_Standard))
 
 
464
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrawl,(int)MCSS_Standard,(ONE_FIXED>>1),1);
 
 
465
                        }
 
 
466
                    }
 
 
467
                    else
 
 
468
                    {
 
 
469
                        InitHModelSequence(&ghostData->HModelController,(int)HMSQT_MarineCrawl,(int)MCSS_Standard,(ONE_FIXED>>1));
 
 
470
                    }
 
 
471
                    ghostData->HModelController.Reversed = 1;
 
 
472
                }
 
 
473
                break;
 
 
474
                case MSQ_Crouch:
 
 
475
                {
 
 
476
                    if(ghostData->currentAnimSequence >= MSQ_BaseOfCudgelAttacks)
 
 
477
                    {
 
 
478
                        if((ghostData->currentAnimSequence-MSQ_BaseOfCudgelAttacks) % 2 == 0)
 
 
479
                        {
 
 
480
                            //if currently playing a standing attack allow it to finish first
 
 
481
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController)) return;
 
 
482
                        }
 
 
483
                    }
 
 
484
 
 
 
485
                    if (ghostData->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
486
                    {
 
 
487
                        if (special)
 
 
488
                        {
 
 
489
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrouch) || (ghostData->HModelController.Sub_Sequence !=
MCrSS_FireFromHips))
 
 
490
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrouch,(int)MCrSS_FireFromHips,(ONE_FIXED>>1),1);
 
 
491
                        }
 
 
492
                        else
 
 
493
                        {
 
 
494
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineCrouch) || (ghostData->HModelController.Sub_Sequence != MCrSS_Standard))
 
 
495
            InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineCrouch,(int)MCrSS_Standard,(ONE_FIXED>>1),1);
 
 
496
                        }
 
 
497
                    }
 
 
498
                    else
 
 
499
                    {
 
 
500
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_MarineCrouch,(int)MCrSS_Standard,ONE_FIXED,1);
 
 
501
                    }
 
 
502
                }
 
 
503
                break;
 
 
504
                case MSQ_Jump:
 
 
505
                {
 
 
506
                    if (HModelSequence_Exists(&ghostData->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Jump))
 
 
507
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_MarineStand,(int)MSSS_Jump,(ONE_FIXED),0);
 
 
508
                    else
 
 
509
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,ONE_FIXED,1);
 
 
510
                }
 
 
511
                break;
 
 
512
                case MSQ_Taunt:
 
 
513
                {
 
 
514
                    if (HModelSequence_Exists(&ghostData->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Taunt_One))
 
 
515
                    {
 
 
516
            if ((ghostData->HModelController.Sequence_Type != (int)HMSQT_MarineStand) || (ghostData->HModelController.Sub_Sequence != MSSS_Taunt_One))
 
 
517
           
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_MarineStand,(int)MSSS_Taunt_One,(TAUNT_LENGTH-(ONE_FIXED>>3)),0);
 
 
518
                    }
 
 
519
                    else
 
 
520
                    {
 
 
521
                        /* Default. */
 
 
522
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_MarineStand,(int)MSSS_Standard,ONE_FIXED,1);
 
 
523
                    }
 
 
524
                }
 
 
525
                break;
 
 
526
                case MSQ_StandDieFront:
 
 
527
                case MSQ_CrouchDie:
 
 
528
                    break;
 
 
529
                default:
 
 
530
                {
 
 
531
                    int attack;
 
 
532
                    /* Now includes cudgel attacks... */
 
 
533
                    if ((int)sequence >= (int)MSQ_BaseOfCudgelAttacks)
 
 
534
                    {
 
 
535
                        attack = (int)sequence - (int)MSQ_BaseOfCudgelAttacks;
 
 
536
 
 
 
537
                        if(ghostData->currentAnimSequence >= MSQ_BaseOfCudgelAttacks)
 
 
538
                        {
 
 
539
                            //already playing some form of attack
 
 
540
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
541
                                return;
 
 
542
                        }
 
 
543
 
 
 
544
                        switch (attack)
 
 
545
                        {
 
 
546
                            case 0:
 
 
547
                                /* Crouching Primary Fire. */
 
 
548
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineCrouch,(int)MCrSS_Attack_Primary,-1,0);
 
 
549
                            break;
 
 
550
                            case 1:
 
 
551
                                /* Standing Primary Fire. */
 
 
552
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineStand,(int)MSSS_Attack_Primary,-1,0);
 
 
553
                            break;
 
 
554
                            case 2:
 
 
555
                                /* Crouching Secondary Fire. */
 
 
556
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineCrouch,(int)MCrSS_Attack_Secondary,-1,0);
 
 
557
                            break;
 
 
558
                            case 3:
 
 
559
                                /* Standing Secondary Fire. */
 
 
560
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineStand,(int)MSSS_Attack_Secondary,-1,0);
 
 
561
                            break;
 
 
562
                            default:
 
 
563
                            /* KJL 16:56:15 26/11/98 - hmm. Any 'unknown' attacks will be replaced with a fast jab */
 
 
564
                            {
 
 
565
                                if (attack & 1)
 
 
566
                                {
 
 
567
                                    /* Standing Fast Jab. */
 
 
568
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineStand,(int)MSSS_Attack_Primary,-1,0);
 
 
569
                                }
 
 
570
                                else
 
 
571
                                {
 
 
572
                                    /* Crouching Fast Jab. */
 
 
573
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_MarineCrouch,(int)MCrSS_Attack_Primary,-1,0);
 
 
574
                                }
 
 
575
                            }
 
 
576
                        }
 
 
577
                    }
 
 
578
                    else
 
 
579
                    {
 
 
580
                        attack = (int)sequence - (int)MSQ_BaseOfCudgelAttacks;
 
 
581
 
 
 
582
                        if (attack)
 
 
583
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
584
                        else
 
 
585
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Primary,-1,0);
 
 
586
                    }
 
 
587
                }
 
 
588
            }
 
 
589
        }
 
 
590
        break;
 
 
591
        case I_BehaviourAlienPlayer:
 
 
592
        case I_BehaviourAlien:
 
 
593
        {
 
 
594
            switch((ALIEN_SEQUENCE)sequence)
 
 
595
            {
 
 
596
                case ASQ_Stand:
 
 
597
                case ASQ_StandingTailPoise:
 
 
598
                {
 
 
599
                    switch(ghostData->currentAnimSequence)
 
 
600
                    {
 
 
601
                        case ASQ_StandingAttack_Claw:
 
 
602
                        case ASQ_StandingTailStrike:
 
 
603
                        case ASQ_Eat:
 
 
604
                        {
 
 
605
                            //if currently playing a standing attack allow it to finish first
 
 
606
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
607
                                    return;
 
 
608
                        }
 
 
609
                        default:
 
 
610
                        break;
 
 
611
                    }
 
 
612
 
 
 
613
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienStand,(int)ASSS_Standard,ONE_FIXED,1);
 
 
614
                break;
 
 
615
                }
 
 
616
                case ASQ_StandingAttack_Claw:
 
 
617
                {
 
 
618
                    int chosenSequence;
 
 
619
 
 
 
620
                    switch(ghostData->currentAnimSequence)
 
 
621
                    {
 
 
622
                        case ASQ_StandingAttack_Claw:
 
 
623
                        case ASQ_StandingTailStrike:
 
 
624
                        case ASQ_Eat:
 
 
625
                        {
 
 
626
                            //if already playing a standing attack allow it to finish first
 
 
627
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
628
                                return;
 
 
629
                        }
 
 
630
                        default:
 
 
631
                        break;
 
 
632
                    }
 
 
633
 
 
 
634
                    /*Pick a random claw attack*/
 
 
635
                    switch(FastRandom() % 6)
 
 
636
                    {
 
 
637
                        case 0:
 
 
638
                            chosenSequence = ASSS_Attack_Right_Swipe_In;
 
 
639
                            break;
 
 
640
                        case 1:
 
 
641
                            chosenSequence = ASSS_Attack_Left_Swipe_In;
 
 
642
                            break;
 
 
643
                        case 2:
 
 
644
                            chosenSequence = ASSS_Attack_Both_In;
 
 
645
                            break;
 
 
646
                        case 3:
 
 
647
                            chosenSequence = ASSS_Attack_Both_Down;
 
 
648
                            break;
 
 
649
                        case 4:
 
 
650
                            chosenSequence = ASSS_Attack_Low_Left_Swipe;
 
 
651
                            break;
 
 
652
                        case 5:
 
 
653
                            chosenSequence = ASSS_Attack_Low_Right_Swipe;
 
 
654
                            break;
 
 
655
                    }
 
 
656
 
 
 
657
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienStand,chosenSequence,-1/*(ONE_FIXED/6)*/,0);
 
 
658
                }
 
 
659
                break;
 
 
660
                case ASQ_StandingTailStrike:
 
 
661
                {
 
 
662
                    switch(ghostData->currentAnimSequence)
 
 
663
                    {
 
 
664
                        case ASQ_StandingAttack_Claw:
 
 
665
                        case ASQ_StandingTailStrike:
 
 
666
                        case ASQ_Eat:
 
 
667
                        {
 
 
668
                            //if already playing a standing attack allow it to finish first
 
 
669
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
670
                                    return;
 
 
671
                        }
 
 
672
                        default:
 
 
673
                        break;
 
 
674
                    }
 
 
675
 
 
 
676
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienStand,(int)ASSS_Attack_Tail,-1/*(ONE_FIXED/6)*/,0);
 
 
677
                }
 
 
678
                break;
 
 
679
                case ASQ_Eat:
 
 
680
                {
 
 
681
                    switch(ghostData->currentAnimSequence)
 
 
682
                    {
 
 
683
                        case ASQ_StandingAttack_Claw:
 
 
684
                        case ASQ_StandingTailStrike:
 
 
685
                        case ASQ_Eat:
 
 
686
                        {
 
 
687
                            //if already playing a standing attack allow it to finish first
 
 
688
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
689
                                return;
 
 
690
                        }
 
 
691
                        default:
 
 
692
                        break;
 
 
693
                    }
 
 
694
 
 
 
695
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienStand,(int)ASSS_Attack_Bite,-1,0);
 
 
696
                break;
 
 
697
                }
 
 
698
                case ASQ_Run:
 
 
699
                case ASQ_RunningTailPoise:
 
 
700
                {
 
 
701
                    switch(ghostData->currentAnimSequence)
 
 
702
                    {
 
 
703
                        case ASQ_RunningAttack_Claw:
 
 
704
                        case ASQ_RunningTailStrike:
 
 
705
                        {
 
 
706
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
707
                            {
 
 
708
                                ghostData->HModelController.Looped=0;
 
 
709
                                ghostData->HModelController.LoopAfterTweening=0;
 
 
710
                                return;
 
 
711
                            }
 
 
712
                        }
 
 
713
                        default:
 
 
714
                        break;
 
 
715
                    }
 
 
716
 
 
 
717
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienRun,(int)ARSS_Standard,ONE_FIXED,1);
 
 
718
                }
 
 
719
                break;
 
 
720
                case ASQ_Run_Backwards:
 
 
721
                case ASQ_RunningTailPoise_Backwards:
 
 
722
                {
 
 
723
                    switch(ghostData->currentAnimSequence)
 
 
724
                    {
 
 
725
                        case ASQ_RunningAttack_Claw_Backwards:
 
 
726
                        case ASQ_RunningTailStrike_Backwards:
 
 
727
                        {
 
 
728
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
729
                            {
 
 
730
                                ghostData->HModelController.Looped = 0;
 
 
731
                                ghostData->HModelController.LoopAfterTweening = 0;
 
 
732
                                return;
 
 
733
                            }
 
 
734
                        }
 
 
735
                        default:
 
 
736
                        break;
 
 
737
                    }
 
 
738
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_AlienRun,(int)ARSS_Standard,ONE_FIXED);
 
 
739
                    ghostData->HModelController.Reversed = 1;
 
 
740
                }
 
 
741
                break;
 
 
742
                case ASQ_RunningAttack_Claw:
 
 
743
                case ASQ_RunningTailStrike:
 
 
744
           
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienRun,(int)ARSS_Attack_Swipe,ONE_FIXED/*(ONE_FIXED/6)*/,1);
 
 
745
                break;
 
 
746
                case ASQ_RunningAttack_Claw_Backwards:
 
 
747
                case ASQ_RunningTailStrike_Backwards:
 
 
748
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_AlienRun,(int)ARSS_Attack_Swipe,ONE_FIXED/*(ONE_FIXED/6)*/);
 
 
749
                    ghostData->HModelController.Reversed = 1;
 
 
750
                    ghostData->HModelController.Looped = 1;
 
 
751
                break;
 
 
752
                case ASQ_Crawl:
 
 
753
                case ASQ_CrawlingTailPoise:
 
 
754
                {
 
 
755
                    switch(ghostData->currentAnimSequence)
 
 
756
                    {
 
 
757
                        case ASQ_CrawlingAttack_Claw:
 
 
758
                        case ASQ_CrawlingTailStrike:
 
 
759
                        {
 
 
760
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
761
                            {
 
 
762
                                ghostData->HModelController.Looped = 0;
 
 
763
                                ghostData->HModelController.LoopAfterTweening = 0;
 
 
764
                                return;
 
 
765
                            }
 
 
766
                        }
 
 
767
                        default:
 
 
768
                        break;
 
 
769
                    }
 
 
770
 
 
 
771
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrawl,(int)ACSS_Standard,ONE_FIXED,1);
 
 
772
                }
 
 
773
                break;
 
 
774
                case ASQ_Scamper:
 
 
775
                {
 
 
776
                    switch(ghostData->currentAnimSequence)
 
 
777
                    {
 
 
778
                        case ASQ_CrawlingAttack_Claw:
 
 
779
                        case ASQ_CrawlingTailStrike:
 
 
780
                        {
 
 
781
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
782
                            {
 
 
783
                                ghostData->HModelController.Looped = 0;
 
 
784
                                ghostData->HModelController.LoopAfterTweening = 0;
 
 
785
                                return;
 
 
786
                            }
 
 
787
                        }
 
 
788
                        default:
 
 
789
                        break;
 
 
790
                    }
 
 
791
 
 
 
792
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrawl,(int)ACSS_Scamper,ONE_FIXED,1);
 
 
793
                }
 
 
794
                break;
 
 
795
                case ASQ_Crawl_Backwards:
 
 
796
                case ASQ_CrawlingTailPoise_Backwards:
 
 
797
                {
 
 
798
                    switch(ghostData->currentAnimSequence)
 
 
799
                    {
 
 
800
                        case ASQ_CrawlingAttack_Claw_Backwards:
 
 
801
                        case ASQ_CrawlingTailStrike_Backwards:
 
 
802
                        {
 
 
803
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
804
                            {
 
 
805
                                ghostData->HModelController.Looped = 0;
 
 
806
                                ghostData->HModelController.LoopAfterTweening = 0;
 
 
807
                                return;
 
 
808
                            }
 
 
809
                        }
 
 
810
                        default:
 
 
811
                        break;
 
 
812
                    }
 
 
813
 
 
 
814
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_AlienCrawl,(int)ACSS_Standard,ONE_FIXED);
 
 
815
                    ghostData->HModelController.Reversed = 1;
 
 
816
                }
 
 
817
                break;
 
 
818
                case ASQ_Scamper_Backwards:
 
 
819
                {
 
 
820
                    switch(ghostData->currentAnimSequence)
 
 
821
                    {
 
 
822
                        case ASQ_CrawlingAttack_Claw_Backwards:
 
 
823
                        case ASQ_CrawlingTailStrike_Backwards:
 
 
824
                        {
 
 
825
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
826
                            {
 
 
827
                                ghostData->HModelController.Looped = 0;
 
 
828
                                ghostData->HModelController.LoopAfterTweening = 0;
 
 
829
                                return;
 
 
830
                            }
 
 
831
                        }
 
 
832
                        default:
 
 
833
                        break;
 
 
834
                    }
 
 
835
 
 
 
836
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_AlienCrawl,(int)ACSS_Scamper,ONE_FIXED);
 
 
837
                    ghostData->HModelController.Reversed = 1;
 
 
838
                }
 
 
839
                break;
 
 
840
                case ASQ_CrawlingAttack_Claw:
 
 
841
                case ASQ_CrawlingTailStrike:
 
 
842
       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrouch,(int)ACrSS_Attack_Swipe,ONE_FIXED/*(ONE_FIXED/6)*/,1);
 
 
843
                break;
 
 
844
                case ASQ_CrawlingAttack_Claw_Backwards:
 
 
845
                case ASQ_CrawlingTailStrike_Backwards:
 
 
846
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_AlienCrouch,(int)ACrSS_Attack_Swipe,ONE_FIXED/*(ONE_FIXED/6)*/);
 
 
847
                    ghostData->HModelController.Reversed = 1;
 
 
848
                    ghostData->HModelController.Looped = 1;
 
 
849
                break;
 
 
850
                case ASQ_Crouch:
 
 
851
                case ASQ_CrouchedTailPoise:
 
 
852
                {
 
 
853
                    switch(ghostData->currentAnimSequence)
 
 
854
                    {
 
 
855
                        case ASQ_CrouchedAttack_Claw: 
 
 
856
                        case ASQ_CrouchEat:
 
 
857
                        case ASQ_CrouchedTailStrike:
 
 
858
                        {
 
 
859
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
860
                                    return;
 
 
861
                        }
 
 
862
                        default:
 
 
863
                        break;
 
 
864
                    }
 
 
865
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrouch,(int)ACSS_Standard,ONE_FIXED,1);
 
 
866
                }
 
 
867
                break;
 
 
868
                case ASQ_CrouchedAttack_Claw:
 
 
869
                {
 
 
870
                    switch(ghostData->currentAnimSequence)
 
 
871
                    {
 
 
872
                        case ASQ_CrouchedAttack_Claw:
 
 
873
                        case ASQ_CrouchedTailStrike:
 
 
874
                        case ASQ_CrouchEat:
 
 
875
                        {
 
 
876
                            //if already playing a crouched attack allow it to finish first
 
 
877
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
878
                                    return;
 
 
879
                        }
 
 
880
                        default:
 
 
881
                        break;
 
 
882
                    }
 
 
883
               
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrouch,(int)ACrSS_Attack_Swipe,-1/*(ONE_FIXED/6)*/,0);
 
 
884
                }
 
 
885
                break;
 
 
886
                case ASQ_CrouchedTailStrike:
 
 
887
                {
 
 
888
                    switch(ghostData->currentAnimSequence)
 
 
889
                    {
 
 
890
                        case ASQ_CrouchedAttack_Claw:
 
 
891
                        case ASQ_CrouchedTailStrike:
 
 
892
                        case ASQ_CrouchEat:
 
 
893
                        {
 
 
894
                            //if already playing a crouched attack allow it to finish first
 
 
895
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController)) return;
 
 
896
                        }
 
 
897
                        default:
 
 
898
                        break;
 
 
899
                    }
 
 
900
 
 
 
901
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrouch,(int)ACrSS_Attack_Tail,-1/*(ONE_FIXED/6)*/,0);
 
 
902
                }
 
 
903
                break;
 
 
904
                case ASQ_CrouchEat:
 
 
905
                {
 
 
906
                    switch(ghostData->currentAnimSequence)
 
 
907
                    {
 
 
908
                        case ASQ_CrouchedAttack_Claw:
 
 
909
                        case ASQ_CrouchedTailStrike:
 
 
910
                        case ASQ_CrouchEat:
 
 
911
                        {
 
 
912
                            //if already playing a crouched attack allow it to finish first
 
 
913
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
914
                                return;
 
 
915
                        }
 
 
916
                        default:
 
 
917
                        break;
 
 
918
                    }
 
 
919
 
 
 
920
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienCrouch,(int)ACrSS_Attack_Bite,-1,0);
 
 
921
                }
 
 
922
                break;
 
 
923
                case ASQ_Jump:
 
 
924
                case ASQ_Pounce:
 
 
925
                case ASQ_JumpingTailPoise:
 
 
926
                case ASQ_JumpingTailStrike:
 
 
927
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienRun,(int)ARSS_Jump,ONE_FIXED,1);
 
 
928
                break;
 
 
929
                case ASQ_Taunt:
 
 
930
                    if (HModelSequence_Exists(&ghostData->HModelController,(int)HMSQT_AlienStand,(int)ASSS_Taunt))
 
 
931
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_AlienStand,(int)ASSS_Taunt,(TAUNT_LENGTH-(ONE_FIXED>>3)),0);
 
 
932
                    else /* Default. */
 
 
933
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_AlienStand,(int)ASSS_Standard,ONE_FIXED,1);
 
 
934
                break;
 
 
935
                default:
 
 
936
                {
 
 
937
                    /* no other sequences should be set */
 
 
938
                    assert("Unknown Alien anim sequence"==0);
 
 
939
                    break;
 
 
940
                }    
 
 
941
            }
 
 
942
        }
 
 
943
          break;
 
 
944
        case I_BehaviourPredatorPlayer:
 
 
945
        {
 
 
946
            switch((PREDATOR_SEQUENCE)sequence)
 
 
947
            {
 
 
948
                case PredSQ_Stand:
 
 
949
                {
 
 
950
                    if(ghostData->currentAnimSequence == PredSQ_StandingSwipe) 
 
 
951
                    {
 
 
952
                        //if currently playing a standing attack allow it to finish first
 
 
953
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
954
                            return;
 
 
955
                    }
 
 
956
                    else if(ghostData->currentAnimSequence >= PredSQ_BaseOfWristbladeAttacks)
 
 
957
                    {
 
 
958
                        if((ghostData->currentAnimSequence - PredSQ_BaseOfWristbladeAttacks) % 2 == 1)
 
 
959
                        {
 
 
960
                            //if currently playing a standing attack allow it to finish first
 
 
961
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
962
                                return;
 
 
963
                        }
 
 
964
                    }
 
 
965
 
 
 
966
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Standard,ONE_FIXED,1);
 
 
967
                }
 
 
968
                break;
 
 
969
                case PredSQ_StandingSwipe:
 
 
970
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Primary,-1,0);
 
 
971
                break;
 
 
972
                case PredSQ_RunningSwipe:
 
 
973
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorRun,(int)PRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
974
                    ghostData->HModelController.Looped = 0;
 
 
975
                break;
 
 
976
                case PredSQ_RunningSwipe_Backwards:
 
 
977
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorRun,(int)PRSS_Attack_Primary,(ONE_FIXED>>1));
 
 
978
                    ghostData->HModelController.Looped = 0;
 
 
979
                    ghostData->HModelController.Reversed = 1;
 
 
980
                break;
 
 
981
                case PredSQ_Run:
 
 
982
                {
 
 
983
                    if(ghostData->currentAnimSequence == PredSQ_RunningSwipe)
 
 
984
                    {
 
 
985
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
986
                        {
 
 
987
                            ghostData->HModelController.Looped = 0;
 
 
988
                            ghostData->HModelController.LoopAfterTweening = 0;
 
 
989
                            return;
 
 
990
                        }
 
 
991
                    }
 
 
992
 
 
 
993
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorRun,(int)PSSS_Standard,(ONE_FIXED>>1),1);
 
 
994
                }
 
 
995
                break;
 
 
996
                case PredSQ_Run_Backwards:
 
 
997
                {
 
 
998
                    if(ghostData->currentAnimSequence == PredSQ_RunningSwipe_Backwards)
 
 
999
                    {
 
 
1000
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1001
                        {
 
 
1002
                            ghostData->HModelController.Looped = 0;
 
 
1003
                            ghostData->HModelController.LoopAfterTweening = 0;
 
 
1004
                            return;
 
 
1005
                        }
 
 
1006
                    }
 
 
1007
 
 
 
1008
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorRun,(int)PSSS_Standard,(ONE_FIXED>>1));
 
 
1009
                    ghostData->HModelController.Reversed = 1;
 
 
1010
                }
 
 
1011
                break;
 
 
1012
                case PredSQ_Crawl:
 
 
1013
                {
 
 
1014
                    if(ghostData->currentAnimSequence == PredSQ_CrawlingSwipe)
 
 
1015
                    {
 
 
1016
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1017
                        {
 
 
1018
                            ghostData->HModelController.Looped = 0;
 
 
1019
                            ghostData->HModelController.LoopAfterTweening = 0;
 
 
1020
                            return;
 
 
1021
                        }
 
 
1022
                    }
 
 
1023
 
 
 
1024
                   
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorCrawl,(int)PCSS_Standard,(ONE_FIXED>>1),1);
 
 
1025
                }
 
 
1026
                break;
 
 
1027
                case PredSQ_Crawl_Backwards:
 
 
1028
                {
 
 
1029
                    if(ghostData->currentAnimSequence == PredSQ_CrawlingSwipe_Backwards)
 
 
1030
                    {
 
 
1031
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1032
                        {
 
 
1033
                            ghostData->HModelController.Looped = 0;
 
 
1034
                            ghostData->HModelController.LoopAfterTweening = 0;
 
 
1035
                            return;
 
 
1036
                        }
 
 
1037
                    }
 
 
1038
 
 
 
1039
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorCrawl,(int)PCSS_Standard,(ONE_FIXED>>1));
 
 
1040
                    ghostData->HModelController.Reversed = 1;
 
 
1041
                }
 
 
1042
                break;
 
 
1043
                case PredSQ_Crouch:
 
 
1044
                {
 
 
1045
                    int crouched_attack = 0;
 
 
1046
                    if(ghostData->currentAnimSequence == PredSQ_CrouchedSwipe) 
 
 
1047
                    {
 
 
1048
                        crouched_attack = 1;
 
 
1049
                    }
 
 
1050
                    else if(ghostData->currentAnimSequence >= PredSQ_BaseOfWristbladeAttacks)
 
 
1051
                    {
 
 
1052
                        if((ghostData->currentAnimSequence - PredSQ_BaseOfWristbladeAttacks) %2 == 0)
 
 
1053
                            crouched_attack = 1;
 
 
1054
                    }
 
 
1055
 
 
 
1056
                    if(crouched_attack)
 
 
1057
                    {
 
 
1058
                        //if currently playing a standing attack allow it to finish first
 
 
1059
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1060
                                return;
 
 
1061
                    }
 
 
1062
 
 
 
1063
                    if(ghostData->currentAnimSequence == PredSQ_CrouchedSwipe)
 
 
1064
                    {
 
 
1065
                        if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1066
                                return;
 
 
1067
                    }
 
 
1068
 
 
 
1069
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorCrouch,(int)PCrSS_Standard,ONE_FIXED,1);
 
 
1070
                }
 
 
1071
                break;
 
 
1072
                case PredSQ_CrouchedSwipe:
 
 
1073
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1074
                break;
 
 
1075
                case PredSQ_CrawlingSwipe:
 
 
1076
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorCrawl,(int)PCSS_Attack_Primary,(ONE_FIXED>>1));
 
 
1077
                    ghostData->HModelController.Looped = 0;
 
 
1078
                break;
 
 
1079
                case PredSQ_CrawlingSwipe_Backwards:
 
 
1080
                    InitHModelSequence(&ghostData->HModelController,(int)HMSQT_PredatorCrawl,(int)PCSS_Attack_Primary,(ONE_FIXED>>1));
 
 
1081
                    ghostData->HModelController.Looped = 0;
 
 
1082
                    ghostData->HModelController.Reversed = 1;
 
 
1083
                break;
 
 
1084
                case PredSQ_Jump:
 
 
1085
                {
 
 
1086
                    if (HModelSequence_Exists(&ghostData->HModelController,(int)HMSQT_PredatorStand,(int)PSSS_Jump))
 
 
1087
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Jump,(ONE_FIXED),0);
 
 
1088
                    else
 
 
1089
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_PredatorStand,(int)PSSS_Standard,ONE_FIXED,1);
 
 
1090
                break;
 
 
1091
                }
 
 
1092
                case PredSQ_Taunt:
 
 
1093
                {
 
 
1094
                    if (HModelSequence_Exists(&ghostData->HModelController,(int)HMSQT_PredatorStand,(int)PSSS_Taunt_One))
 
 
1095
                       
InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Taunt_One,(TAUNT_LENGTH-(ONE_FIXED>>3)),0);
 
 
1096
                    else
 
 
1097
                        InitHModelTweening(&ghostData->HModelController,(ONE_FIXED)>>3,(int)HMSQT_PredatorStand,(int)PSSS_Standard,ONE_FIXED,1); /*
Default. */
 
 
1098
                break;
 
 
1099
                }
 
 
1100
                case PredSQ_StandDie:
 
 
1101
                case PredSQ_CrouchDie:
 
 
1102
                    break;
 
 
1103
                default:
 
 
1104
                {
 
 
1105
                    int attack;
 
 
1106
                    /* Must cover STAFF ATTACKS, and WRISTBLADE ATTACKS! */
 
 
1107
                    if ((int)sequence >= (int)PredSQ_BaseOfWristbladeAttacks)
 
 
1108
                    {
 
 
1109
                        attack = (int)sequence-(int)PredSQ_BaseOfWristbladeAttacks;
 
 
1110
 
 
 
1111
                        if(ghostData->currentAnimSequence >= PredSQ_BaseOfWristbladeAttacks)
 
 
1112
                        {
 
 
1113
                            //already playing some form of attack
 
 
1114
                            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1115
                                    return;
 
 
1116
                        }
 
 
1117
 
 
 
1118
                        switch (attack)
 
 
1119
                        {
 
 
1120
                            case 0:
 
 
1121
                                /* Crouching Fast Jab. */
 
 
1122
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1123
                                break;
 
 
1124
                            case 1:
 
 
1125
                                /* Standing Fast Jab. */
 
 
1126
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Quick_Jab,-1,0);
 
 
1127
                                break;
 
 
1128
                            case 2:
 
 
1129
                                /* Crouching Slow Jab. */
 
 
1130
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1131
                                break;
 
 
1132
                            case 3:
 
 
1133
                                /* Standing Slow Jab. */
 
 
1134
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Primary,-1,0);
 
 
1135
                                break;
 
 
1136
                            case 4:
 
 
1137
                                /* Crouching Uppercut. */
 
 
1138
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1139
                                break;
 
 
1140
                            case 5:
 
 
1141
                                /* Standing Uppercut. */
 
 
1142
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Uppercut,-1,0);
 
 
1143
                                break;
 
 
1144
                            default:
 
 
1145
                            /* KJL 16:56:15 26/11/98 - hmm. Any 'unknown' attacks will be replaced with a fast jab */
 
 
1146
                            {
 
 
1147
                                if (attack & 1) // Standing Fast Jab.
 
 
1148
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Quick_Jab,-1,0);
 
 
1149
                                else // Crouching Fast Jab.
 
 
1150
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>4),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1151
                                break;
 
 
1152
                            }
 
 
1153
                        }
 
 
1154
                    }
 
 
1155
                    else
 
 
1156
                    {
 
 
1157
                        attack = (int)sequence-(int)PredSQ_BaseOfStaffAttacks;
 
 
1158
 
 
 
1159
                        if (attack)
 
 
1160
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorCrouch,(int)PCrSS_Attack_Primary,-1,0);
 
 
1161
                        else
 
 
1162
                    InitHModelTweening(&ghostData->HModelController,(ONE_FIXED>>3),(int)HMSQT_PredatorStand,(int)PSSS_Attack_Primary,-1,0);
 
 
1163
                    }
 
 
1164
                }
 
 
1165
            }
 
 
1166
        }
 
 
1167
        break;
 
 
1168
        default:
 
 
1169
        {
 
 
1170
            assert(1==0);
 
 
1171
            break;
 
 
1172
        }
 
 
1173
    }
 
 
1174
    /* update the ghost's current sequence*/
 
 
1175
    ghostData->currentAnimSequence = sequence;
 
 
1176
}
 
 
1177
 
 
 
1178
/* Patrick 14/7/97 -----------------------------------------------------------
 
 
1179
Shape animation control functions for player ghosts:
 
 
1180
 
 
 
1181
Init initilaises the character sequence, and should only be called when a new
 
 
1182
player ghost is created, after the sb and datablock have been set up.
 
 
1183
 
 
 
1184
Update changes the sequence if appropriate (and calls set if the sbPtr has a dptr)
 
 
1185
 
 
 
1186
Set selects the correct sequence/type, infers the speed and follow-on sequences,
 
 
1187
etc, and sets it.
 
 
1188
------------------------------------------------------------------------------*/
 
 
1189
 
 
 
1190
static void UpdatePlayerGhostAnimSequence(STRATEGYBLOCK *sbPtr, int sequence, int special)
 
 
1191
{
 
 
1192
    assert(sbPtr);
 
 
1193
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1194
    assert(ghostData);
 
 
1195
 
 
 
1196
    switch(ghostData->type)
 
 
1197
    {
 
 
1198
        case I_BehaviourMarinePlayer:
 
 
1199
        {
 
 
1200
            /* if the current sequence is the same as the new sequence, do nothing */
 
 
1201
 
 
 
1202
            if ( (MARINE_SEQUENCE)ghostData->currentAnimSequence == (MARINE_SEQUENCE)sequence)
 
 
1203
            {
 
 
1204
                switch(ghostData->CurrentWeapon)
 
 
1205
                {
 
 
1206
                    case WEAPON_TWO_PISTOLS:
 
 
1207
                    break;
 
 
1208
                    case WEAPON_MARINE_PISTOL:
 
 
1209
                        if (special)
 
 
1210
                            break;
 
 
1211
                    default:
 
 
1212
                    return;
 
 
1213
                }
 
 
1214
            }
 
 
1215
 
 
 
1216
            /* if we're dead, and passed dying, do nothing */
 
 
1217
            if(((MARINE_SEQUENCE)ghostData->currentAnimSequence == MSQ_StandDeadFront) && ((MARINE_SEQUENCE)sequence == MSQ_StandDieFront))
 
 
1218
               return;
 
 
1219
 
 
 
1220
            if(((MARINE_SEQUENCE)ghostData->currentAnimSequence == MSQ_CrouchDead) && ((MARINE_SEQUENCE)sequence == MSQ_CrouchDie))
 
 
1221
                    return;
 
 
1222
            /* need to update the anim sequence, then*/
 
 
1223
            SetPlayerGhostAnimationSequence(sbPtr, sequence, special);
 
 
1224
        }
 
 
1225
        break;
 
 
1226
        case I_BehaviourAlienPlayer:
 
 
1227
        {
 
 
1228
            /* if the current sequence is the same as the new sequence, do nothing */
 
 
1229
            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1230
            {
 
 
1231
                if((ALIEN_SEQUENCE)ghostData->currentAnimSequence == (ALIEN_SEQUENCE)sequence)
 
 
1232
                {
 
 
1233
                    switch(ghostData->currentAnimSequence)
 
 
1234
                    {
 
 
1235
                        case ASQ_RunningAttack_Claw:
 
 
1236
                        case ASQ_RunningTailStrike:
 
 
1237
                        case ASQ_RunningAttack_Claw_Backwards:
 
 
1238
                        case ASQ_RunningTailStrike_Backwards:
 
 
1239
                        case ASQ_CrawlingAttack_Claw:
 
 
1240
                        case ASQ_CrawlingAttack_Claw_Backwards:
 
 
1241
                        case ASQ_CrawlingTailStrike:
 
 
1242
                        case ASQ_CrawlingTailStrike_Backwards:
 
 
1243
                            ghostData->HModelController.Looped = 1;
 
 
1244
                            ghostData->HModelController.LoopAfterTweening = 1;
 
 
1245
                        default:
 
 
1246
                        break;
 
 
1247
                    }
 
 
1248
                return;
 
 
1249
                }
 
 
1250
            }
 
 
1251
            /* need to update the anim sequence, then*/
 
 
1252
            SetPlayerGhostAnimationSequence(sbPtr, sequence, special);
 
 
1253
        }
 
 
1254
        break;
 
 
1255
        case I_BehaviourPredatorPlayer:
 
 
1256
        {
 
 
1257
            /* if the current sequence is the same as the new sequence, do nothing */
 
 
1258
            if(!HModelAnimation_IsFinished(&ghostData->HModelController))
 
 
1259
            {
 
 
1260
                if(ghostData->currentAnimSequence == sequence)
 
 
1261
                {
 
 
1262
                    switch(ghostData->currentAnimSequence)
 
 
1263
                    {
 
 
1264
                        case PredSQ_RunningSwipe:
 
 
1265
                        case PredSQ_RunningSwipe_Backwards:
 
 
1266
                        case PredSQ_CrawlingSwipe:
 
 
1267
                        case PredSQ_CrawlingSwipe_Backwards:
 
 
1268
                            ghostData->HModelController.Looped = 1;
 
 
1269
                            ghostData->HModelController.LoopAfterTweening = 1;
 
 
1270
                        default:
 
 
1271
                        break;
 
 
1272
                    }
 
 
1273
                return;
 
 
1274
                }
 
 
1275
            }
 
 
1276
            /* if we're dead, and passed dying, do nothing */
 
 
1277
            if(((PREDATOR_SEQUENCE)ghostData->currentAnimSequence == PredSQ_StandDead)&&
 
 
1278
               ((PREDATOR_SEQUENCE)sequence == PredSQ_StandDie))
 
 
1279
               return;
 
 
1280
 
 
 
1281
            if(((PREDATOR_SEQUENCE)ghostData->currentAnimSequence == PredSQ_CrouchDead)&&
 
 
1282
               ((PREDATOR_SEQUENCE)sequence == PredSQ_CrouchDie))
 
 
1283
               return;
 
 
1284
 
 
 
1285
            /* need to update the anim sequence, then*/
 
 
1286
            SetPlayerGhostAnimationSequence(sbPtr, sequence, special);
 
 
1287
        }
 
 
1288
        break;
 
 
1289
        case I_BehaviourAlien:
 
 
1290
        {
 
 
1291
            /* if the current sequence is the same as the new sequence, do nothing */
 
 
1292
 
 
 
1293
            if(ghostData->currentAnimSequence == sequence)
 
 
1294
                return;
 
 
1295
 
 
 
1296
            /* need to update the anim sequence, then*/
 
 
1297
            SetPlayerGhostAnimationSequence(sbPtr, sequence, special);
 
 
1298
            break;
 
 
1299
        }
 
 
1300
        default:
 
 
1301
        {
 
 
1302
            assert(1==0);
 
 
1303
            break;
 
 
1304
        }
 
 
1305
    }
 
 
1306
}
 
 
1307
 
 
 
1308
static void UpdateObjectTrails(STRATEGYBLOCK *sbPtr)
 
 
1309
{
 
 
1310
    NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1311
 
 
 
1312
    switch(ghostDataPtr->type)
 
 
1313
    {
 
 
1314
        case I_BehaviourPulseGrenade:
 
 
1315
        case I_BehaviourRocket:
 
 
1316
            MakeRocketTrailParticles(&sbPtr->DynPtr->PrevPosition, &sbPtr->DynPtr->Position);
 
 
1317
        break;
 
 
1318
        case I_BehaviourPredatorEnergyBolt:
 
 
1319
              MakePlasmaTrailParticles(sbPtr->DynPtr, 32);
 
 
1320
        break;
 
 
1321
        case I_BehaviourFrisbeeEnergyBolt:
 
 
1322
              MakeDewlineTrailParticles(sbPtr->DynPtr, 32);
 
 
1323
        break;
 
 
1324
        case I_BehaviourFrisbee:
 
 
1325
        {
 
 
1326
            int l = 0;
 
 
1327
            for (; l < 4; l++)
 
 
1328
                MakeFlareParticle(sbPtr->DynPtr);
 
 
1329
        }
 
 
1330
        break;
 
 
1331
        case I_BehaviourGrenade:
 
 
1332
        case I_BehaviourProximityGrenade:
 
 
1333
            MakeGrenadeTrailParticles(&sbPtr->DynPtr->PrevPosition, &sbPtr->DynPtr->Position);
 
 
1334
        default:
 
 
1335
            break;
 
 
1336
    }
 
 
1337
}
 
 
1338
 
 
 
1339
/* updates an existing ghost's position and orientation: Before calling this
 
 
1340
need to use FindGhost to locate the ghost (which confirms it's existance) */
 
 
1341
void UpdateGhost(STRATEGYBLOCK *sbPtr,VECTORCH *position,EULER *orientation,int sequence, int special)
 
 
1342
{
 
 
1343
    assert(sbPtr);
 
 
1344
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1345
 
 
 
1346
    /* for visibility support: as ghosts can be moved when invisible, we need to work out
 
 
1347
    which module they're in    whenever we update them. We must be carefull, however, not
 
 
1348
    to set the containingModule to NULL if the object has moved outside the env, as 
 
 
1349
    the    visibility system expects that we at least know what module any object WAS in,
 
 
1350
    even if we do not now... thus, if we cannot find a containing module, we abort the update */
 
 
1351
 
 
 
1352
    /* KJL 21:01:09 23/05/98 - I've put this test here because the player's image in a mirror goes
 
 
1353
    throught this code, and it's obviously going to be outside the environment */
 
 
1354
 
 
 
1355
    if (sbPtr->type == I_BehaviourNetGhost)
 
 
1356
    {
 
 
1357
        MODULE *myContainingModule = ModuleFromPosition(position, (sbPtr->containingModule));
 
 
1358
 
 
 
1359
        if(myContainingModule == NULL)
 
 
1360
        {
 
 
1361
            //Not in any module , so don't try updating ghost,
 
 
1362
            //except for various projectiles which can be shot 
 
 
1363
            //out of the environment semi-legitamately
 
 
1364
            switch(ghostData->type)
 
 
1365
            {
 
 
1366
                case I_BehaviourGrenade:
 
 
1367
                case I_BehaviourRocket:
 
 
1368
                case I_BehaviourPPPlasmaBolt:
 
 
1369
                case I_BehaviourSpeargunBolt:
 
 
1370
                case I_BehaviourPredatorDisc_SeekTrack:
 
 
1371
                case I_BehaviourPredatorEnergyBolt:
 
 
1372
                case I_BehaviourPulseGrenade:
 
 
1373
                case I_BehaviourFlare:
 
 
1374
                case I_BehaviourFragmentationGrenade:
 
 
1375
                case I_BehaviourFrisbeeEnergyBolt:
 
 
1376
                case I_BehaviourProximityGrenade:
 
 
1377
                break;
 
 
1378
                default:
 
 
1379
                    return;    
 
 
1380
            }
 
 
1381
        }
 
 
1382
        else
 
 
1383
        {
 
 
1384
            sbPtr->containingModule = myContainingModule;
 
 
1385
        }
 
 
1386
    }
 
 
1387
 
 
 
1388
    /* CDF 29/7/98 I'll assume that stationary discs are stuck. */
 
 
1389
    if (ghostData->type == I_BehaviourPredatorDisc_SeekTrack)
 
 
1390
    {
 
 
1391
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
1392
 
 
 
1393
        if(!DynamicObjectIsMoving(sbPtr->DynPtr))
 
 
1394
        {
 
 
1395
            ghostData->HModelController.Playing = 0;
 
 
1396
        }
 
 
1397
        else
 
 
1398
        {
 
 
1399
            ghostData->HModelController.Playing = 1;
 
 
1400
            //draw the disc's trail
 
 
1401
            NewTrailPoint(dynPtr);
 
 
1402
 
 
 
1403
            //update sound for disc
 
 
1404
            if(ghostData->SoundHandle!=SOUND_NOACTIVEINDEX)
 
 
1405
                Sound_Update3d(ghostData->SoundHandle, &sbPtr->DynPtr->Position);
 
 
1406
            else
 
 
1407
                 Sound_Play(SID_PREDATOR_DISK_FLYING, "del", &sbPtr->DynPtr->Position, &ghostData->SoundHandle);
 
 
1408
        }
 
 
1409
    }
 
 
1410
 
 
 
1411
    if (ghostData->type == I_BehaviourFrisbee)
 
 
1412
    {
 
 
1413
        //update sound for disc
 
 
1414
        if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
1415
            Sound_Update3d(ghostData->SoundHandle, &sbPtr->DynPtr->Position);
 
 
1416
    }
 
 
1417
 
 
 
1418
    /* update the dynamics block */
 
 
1419
    {
 
 
1420
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
1421
//        dynPtr->Position = dynPtr->PrevPosition = *position;
 
 
1422
        dynPtr->PrevPosition = dynPtr->Position;
 
 
1423
        dynPtr->PrevOrientMat = dynPtr->OrientMat;
 
 
1424
        dynPtr->Position = *position;
 
 
1425
        dynPtr->OrientEuler = *orientation;
 
 
1426
        CreateEulerMatrix(&dynPtr->OrientEuler,&dynPtr->OrientMat);
 
 
1427
        TransposeMatrixCH(&dynPtr->OrientMat);
 
 
1428
    }
 
 
1429
 
 
 
1430
    UpdateObjectTrails(sbPtr);
 
 
1431
 
 
 
1432
    /* if we're a player type, update the animation sequence */
 
 
1433
    switch(ghostData->type)
 
 
1434
    {
 
 
1435
        case I_BehaviourMarinePlayer:
 
 
1436
        case I_BehaviourAlienPlayer:
 
 
1437
        case I_BehaviourPredatorPlayer:
 
 
1438
        if(sequence != -1)
 
 
1439
            UpdatePlayerGhostAnimSequence(sbPtr,sequence, special);
 
 
1440
        break;
 
 
1441
        case I_BehaviourMarine:
 
 
1442
        case I_BehaviourAlien:
 
 
1443
        case I_BehaviourPredator:
 
 
1444
            /* KJL 16:58:04 17/06/98 - we want to update anims differently for NPCS */
 
 
1445
            UpdatePlayerGhostAnimSequence(sbPtr,sequence, special);
 
 
1446
        default:
 
 
1447
        break;
 
 
1448
    }
 
 
1449
 
 
 
1450
    /* refresh integrity */
 
 
1451
    ghostData->integrity = GHOST_INTEGRITY;        
 
 
1452
}
 
 
1453
 
 
 
1454
void RemoveGhost(STRATEGYBLOCK *sbPtr)
 
 
1455
{
 
 
1456
    assert(sbPtr);
 
 
1457
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1458
    assert(ghostData);
 
 
1459
 
 
 
1460
    /* this is where we add fragmentation and explosion    effects to destroyed ghosts */
 
 
1461
    switch(ghostData->type)
 
 
1462
    {
 
 
1463
        case I_BehaviourAlienPlayer:
 
 
1464
        case I_BehaviourMarinePlayer:
 
 
1465
        case I_BehaviourPredatorPlayer:    
 
 
1466
            //Extreme_Gibbing(sbPtr,ghostData->HModelController.section_data,ONE_FIXED); // jadda
 
 
1467
        break;
 
 
1468
        case I_BehaviourGrenade:
 
 
1469
            if (sbPtr->containingModule)
 
 
1470
            {
 
 
1471
                Ghost_Explosion_SoundData.position=sbPtr->DynPtr->Position;
 
 
1472
                Sound_Play(SID_GRENADE_EXPLOSION, "n", &Ghost_Explosion_SoundData);
 
 
1473
            }
 
 
1474
        break;
 
 
1475
        case I_BehaviourRocket:
 
 
1476
            if (sbPtr->containingModule)
 
 
1477
            {
 
 
1478
                Ghost_Explosion_SoundData.position=sbPtr->DynPtr->Position;
 
 
1479
                Sound_Play(SID_NICE_EXPLOSION, "n", &Ghost_Explosion_SoundData);
 
 
1480
            }
 
 
1481
        break;
 
 
1482
        case I_BehaviourProximityGrenade:
 
 
1483
            if (sbPtr->containingModule)
 
 
1484
            {
 
 
1485
                Ghost_Explosion_SoundData.position=sbPtr->DynPtr->Position;
 
 
1486
                Sound_Play(SID_GRENADE_PROXEXPLOSION, "n", &Ghost_Explosion_SoundData);
 
 
1487
            }
 
 
1488
        break;
 
 
1489
        case I_BehaviourFragmentationGrenade:
 
 
1490
            if (sbPtr->containingModule)
 
 
1491
            {
 
 
1492
                Ghost_Explosion_SoundData.position=sbPtr->DynPtr->Position;
 
 
1493
                Sound_Play(SID_NADEEXPLODE, "n", &Ghost_Explosion_SoundData);
 
 
1494
            }
 
 
1495
        break;
 
 
1496
        case I_BehaviourPulseGrenade:
 
 
1497
            if (sbPtr->containingModule)
 
 
1498
            {
 
 
1499
                Ghost_Explosion_SoundData.position=sbPtr->DynPtr->Position;
 
 
1500
                Sound_Play(SID_NADEEXPLODE, "n", &Ghost_Explosion_SoundData);
 
 
1501
            }
 
 
1502
        break;
 
 
1503
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
1504
            /* MakeAnExplosion... ?    */
 
 
1505
            Sound_Play(SID_NADEEXPLODE, "d", &sbPtr->DynPtr->Position);
 
 
1506
        break;
 
 
1507
        case I_BehaviourFrisbee:
 
 
1508
            //Ghost_Explosion_SoundData.position = sbPtr->DynPtr->Position;
 
 
1509
            //Sound_Play(SID_NICE_EXPLOSION, "n", &Ghost_Explosion_SoundData);
 
 
1510
        case I_BehaviourPPPlasmaBolt:
 
 
1511
        case I_BehaviourCorpse:
 
 
1512
        default:
 
 
1513
        {
 
 
1514
            /* do absolutely bugger all, probably:
 
 
1515
            remaining cases are: predator energy bolt;flame;predator disc;flare;
 
 
1516
            and AUTOGUN */
 
 
1517
            break;
 
 
1518
        }
 
 
1519
    }
 
 
1520
 
 
 
1521
    /* see if we've got a sound... */
 
 
1522
    if(ghostData->SoundHandle  != SOUND_NOACTIVEINDEX)
 
 
1523
        Sound_Stop(ghostData->SoundHandle);
 
 
1524
 
 
 
1525
    if(ghostData->SoundHandle2 != SOUND_NOACTIVEINDEX)
 
 
1526
        Sound_Stop(ghostData->SoundHandle2);
 
 
1527
 
 
 
1528
    if(ghostData->SoundHandle3 != SOUND_NOACTIVEINDEX)
 
 
1529
        Sound_Stop(ghostData->SoundHandle3);
 
 
1530
 
 
 
1531
    if(ghostData->SoundHandle4 != SOUND_NOACTIVEINDEX)
 
 
1532
        Sound_Stop(ghostData->SoundHandle4);
 
 
1533
 
 
 
1534
    DestroyActiveObject(&ghostData->myGunFlash);
 
 
1535
 
 
 
1536
    sbPtr->please_destroy_me = 1;
 
 
1537
}
 
 
1538
 
 
 
1539
/* removes a given player's ghost, and all associated ghosts, eg when a player
 
 
1540
leaves the game... */
 
 
1541
void RemovePlayersGhosts(int id)
 
 
1542
{
 
 
1543
    int sbIndex = 0;
 
 
1544
 
 
 
1545
    while(sbIndex < NumActiveStBlocks)
 
 
1546
    {    
 
 
1547
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++];
 
 
1548
 
 
 
1549
        if(sbPtr->type == I_BehaviourNetGhost)
 
 
1550
        {
 
 
1551
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1552
            assert(ghostData);            
 
 
1553
            if(ghostData->playerId == id)
 
 
1554
                RemoveGhost(sbPtr);
 
 
1555
        }
 
 
1556
    }
 
 
1557
}
 
 
1558
 
 
 
1559
/* locates a ghost from Id and ObId */
 
 
1560
STRATEGYBLOCK *FindGhost(int Id, int obId)
 
 
1561
{
 
 
1562
    int sbIndex = 0;
 
 
1563
 
 
 
1564
    while(sbIndex < NumActiveStBlocks)
 
 
1565
    {    
 
 
1566
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++];
 
 
1567
 
 
 
1568
        if(sbPtr->type == I_BehaviourNetGhost)
 
 
1569
        {
 
 
1570
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
1571
            assert(ghostData);            
 
 
1572
 
 
 
1573
            if((ghostData->playerId == Id) && (ghostData->playerObjectId == obId))
 
 
1574
                return sbPtr;    
 
 
1575
        }
 
 
1576
    }    
 
 
1577
 
 
 
1578
return NULL;
 
 
1579
}
 
 
1580
 
 
 
1581
extern HIERARCHY_VARIANT_DATA* GetHierarchyAlternateShapeSetCollectionFromLibrary(const char* rif_name,int index);
 
 
1582
void ChangeGhostMarineAccoutrementSet(HMODELCONTROLLER *HModelController,int playerId)
 
 
1583
{
 
 
1584
    int index = 0;
 
 
1585
 
 
 
1586
    assert(HModelController);
 
 
1587
 
 
 
1588
    //find the index for this player
 
 
1589
    if(playerId)
 
 
1590
    {
 
 
1591
        for(; index < NET_MAXPLAYERS; index++)
 
 
1592
        {
 
 
1593
            if(netGameData.playerData[index].playerId == playerId)
 
 
1594
                break;
 
 
1595
        }
 
 
1596
    }
 
 
1597
 
 
 
1598
    HIERARCHY_VARIANT_DATA* variant_data = GetHierarchyAlternateShapeSetCollectionFromLibrary("hnpcmarine", index + 1);
 
 
1599
 
 
 
1600
    if (variant_data == NULL)
 
 
1601
        return;
 
 
1602
 
 
 
1603
    HIERARCHY_SHAPE_REPLACEMENT* replacement_array = (HIERARCHY_SHAPE_REPLACEMENT*)variant_data->replacements;
 
 
1604
 
 
 
1605
    if (replacement_array == NULL)
 
 
1606
        return;
 
 
1607
 
 
 
1608
    int a = 0;
 
 
1609
 
 
 
1610
    while (replacement_array[a].replaced_section_name != NULL) 
 
 
1611
    {
 
 
1612
        SECTION_DATA *target_section = GetThisSectionData(HModelController->section_data,
 
 
1613
 
 
 
1614
        replacement_array[a].replaced_section_name);
 
 
1615
 
 
 
1616
        if (target_section)
 
 
1617
        {
 
 
1618
            target_section->Shape = replacement_array[a].replacement_shape;
 
 
1619
            target_section->ShapeNum = replacement_array[a].replacement_shape_index;
 
 
1620
            Setup_Texture_Animation_For_Section(target_section);
 
 
1621
        }
 
 
1622
        a++;
 
 
1623
    }
 
 
1624
}
 
 
1625
 
 
 
1626
static void CreateMarineHModel(NETGHOSTDATABLOCK *ghostDataPtr, int weapon)
 
 
1627
{
 
 
1628
    const SECTION *root_section;
 
 
1629
 
 
 
1630
    /* KJL 11:09:14 27/01/98 - pick which model to create based on the character's weapon */
 
 
1631
    switch (weapon)
 
 
1632
    {
 
 
1633
        default:
 
 
1634
        case WEAPON_PULSERIFLE:
 
 
1635
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","marine with pulse rifle");
 
 
1636
        break;
 
 
1637
        case WEAPON_TWO_PISTOLS:
 
 
1638
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","Two Pistol");
 
 
1639
        break;
 
 
1640
        case WEAPON_MARINE_PISTOL:
 
 
1641
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","PISTOL");
 
 
1642
        break;
 
 
1643
        case WEAPON_FLAMETHROWER:
 
 
1644
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","marine with flame thrower");
 
 
1645
        break;
 
 
1646
        case WEAPON_SMARTGUN:
 
 
1647
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","marine with smart gun");
 
 
1648
        break;
 
 
1649
        case WEAPON_MINIGUN:
 
 
1650
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","Marine with Mini Gun");
 
 
1651
        break;
 
 
1652
        case WEAPON_SADAR:
 
 
1653
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","marine with SADAR");
 
 
1654
        break;
 
 
1655
        case WEAPON_GRENADELAUNCHER:
 
 
1656
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","marine + grenade launcher");
 
 
1657
        break;
 
 
1658
        case WEAPON_CUDGEL:
 
 
1659
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","Cudgel");
 
 
1660
        break;
 
 
1661
        case WEAPON_FRISBEE_LAUNCHER:
 
 
1662
            root_section = GetNamedHierarchyFromLibrary("hnpcmarine","skeeter");
 
 
1663
    }
 
 
1664
 
 
 
1665
    Create_HModel(&ghostDataPtr->HModelController, root_section);
 
 
1666
    ghostDataPtr->CurrentWeapon = weapon;
 
 
1667
 
 
 
1668
    ChangeGhostMarineAccoutrementSet(&ghostDataPtr->HModelController, ghostDataPtr->playerId);
 
 
1669
 
 
 
1670
    /* KJL 11:09:38 27/01/98 - set a default anim sequence to use */
 
 
1671
    ghostDataPtr->currentAnimSequence = MSQ_Stand;
 
 
1672
    InitHModelSequence(&ghostDataPtr->HModelController, (int)HMSQT_MarineStand, (int)MSSS_Standard,ONE_FIXED);
 
 
1673
 
 
 
1674
    /* KJL 11:09:52 27/01/98 - find the section which hold the muzzle flash data */
 
 
1675
    ghostDataPtr->GunflashSectionPtr = GetThisSectionData(ghostDataPtr->HModelController.section_data, "dum flash");
 
 
1676
    assert(ghostDataPtr->GunflashSectionPtr);
 
 
1677
 
 
 
1678
    /* CDF 8/4/98 Elevation Delta Sequence. */
 
 
1679
    {
 
 
1680
        DELTA_CONTROLLER *delta = Add_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation",(int)HMSQT_MarineStand,(int)MSSS_Elevation,0);
 
 
1681
        assert(delta);
 
 
1682
        delta->timer = 32767;
 
 
1683
    }
 
 
1684
    //add hit delta
 
 
1685
    if (HModelSequence_Exists(&ghostDataPtr->HModelController, (int)HMSQT_MarineStand, (int)MSSS_HitChestFront)) 
 
 
1686
    {
 
 
1687
        Add_Delta_Sequence(&ghostDataPtr->HModelController, "HitDelta", (int)HMSQT_MarineStand, (int)MSSS_HitChestFront, (ONE_FIXED>>2));
 
 
1688
    }
 
 
1689
 
 
 
1690
    ghostDataPtr->hltable = (HITLOCATIONTABLE*)GetThisHitLocationTable("marine with pulse rifle");
 
 
1691
}
 
 
1692
 
 
 
1693
static void CreateAlienHModel(NETGHOSTDATABLOCK *ghostDataPtr,int alienType)
 
 
1694
{
 
 
1695
    const SECTION *root_section;
 
 
1696
 
 
 
1697
    switch(alienType)
 
 
1698
    {
 
 
1699
        case Predalien :
 
 
1700
            root_section = GetNamedHierarchyFromLibrary("hnpcpred_alien","TEMPLATE");
 
 
1701
            ghostDataPtr->hltable = GetThisHitLocationTable("predalien");
 
 
1702
        break;
 
 
1703
        case Praetorian :
 
 
1704
            root_section = GetNamedHierarchyFromLibrary("hnpcpretorian","Template");
 
 
1705
            ghostDataPtr->hltable = GetThisHitLocationTable("praetorian");
 
 
1706
        break;
 
 
1707
        default:
 
 
1708
            root_section = GetNamedHierarchyFromLibrary("hnpcalien","alien");
 
 
1709
            ghostDataPtr->hltable = GetThisHitLocationTable("alien");
 
 
1710
    }
 
 
1711
 
 
 
1712
    Create_HModel(&ghostDataPtr->HModelController,root_section);
 
 
1713
    ghostDataPtr->currentAnimSequence = ASQ_Stand;
 
 
1714
    InitHModelSequence(&ghostDataPtr->HModelController,(int)HMSQT_AlienStand,(int)ASSS_Standard,ONE_FIXED);
 
 
1715
 
 
 
1716
    ghostDataPtr->CurrentWeapon = 0;
 
 
1717
 
 
 
1718
    /* CDF 12/4/98 Elevation Delta Sequence. */
 
 
1719
    {
 
 
1720
        DELTA_CONTROLLER *delta =
Add_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation",(int)HMSQT_AlienStand,(int)ASSS_Standard_Elevation,0);
 
 
1721
        assert(delta);
 
 
1722
        delta->timer = 32767;
 
 
1723
 
 
 
1724
        delta->Active = 0; /* Default for predator. */
 
 
1725
    }
 
 
1726
}
 
 
1727
 
 
 
1728
static void CreatePredatorHModel(NETGHOSTDATABLOCK *ghostDataPtr, int weapon)
 
 
1729
{
 
 
1730
    const SECTION *root_section;
 
 
1731
    /* KJL 11:09:14 27/01/98 - pick which model to create based on the character's weapon */
 
 
1732
    switch (weapon)
 
 
1733
    {
 
 
1734
        default:
 
 
1735
        case WEAPON_PRED_WRISTBLADE:
 
 
1736
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","pred with wristblade");
 
 
1737
        break;
 
 
1738
/*
 
 
1739
        case WEAPON_PRED_STAFF:
 
 
1740
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","pred with staff");
 
 
1741
        break;
 
 
1742
*/
 
 
1743
        case WEAPON_PRED_RIFLE:
 
 
1744
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","Speargun");
 
 
1745
        break;
 
 
1746
        case WEAPON_PRED_PISTOL:
 
 
1747
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","pred + pistol");
 
 
1748
        break;
 
 
1749
        case WEAPON_PRED_SHOULDERCANNON:
 
 
1750
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","pred with Plasma Caster");
 
 
1751
        break;
 
 
1752
        case WEAPON_PRED_DISC:
 
 
1753
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","pred with disk");
 
 
1754
        break;
 
 
1755
        case WEAPON_PRED_MEDICOMP:
 
 
1756
            root_section = GetNamedHierarchyFromLibrary("hnpcpredator","medicomp");
 
 
1757
        break;
 
 
1758
    }
 
 
1759
 
 
 
1760
    Create_HModel(&ghostDataPtr->HModelController,root_section);
 
 
1761
    ghostDataPtr->CurrentWeapon = weapon;
 
 
1762
 
 
 
1763
    assert(ghostDataPtr->HModelController.Root_Section==root_section);
 
 
1764
 
 
 
1765
    InitHModelSequence(&ghostDataPtr->HModelController,(int)HMSQT_PredatorStand,(int)PSSS_Standard,ONE_FIXED);
 
 
1766
    ghostDataPtr->currentAnimSequence = PredSQ_Stand;
 
 
1767
 
 
 
1768
//    ghostDataPtr->GunflashSectionPtr=GetThisSectionData(ghostDataPtr->HModelController.section_data,"dum flash");
 
 
1769
//    assert(ghostDataPtr->GunflashSectionPtr);
 
 
1770
 
 
 
1771
    /* CDF 11/4/98 Elevation Delta Sequence. */
 
 
1772
    {
 
 
1773
        DELTA_CONTROLLER *delta =
Add_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation",(int)HMSQT_PredatorStand,(int)PSSS_Elevation,0);
 
 
1774
        assert(delta);
 
 
1775
        delta->timer = 32767;
 
 
1776
        delta->Active = 0; /* Default for predator. */
 
 
1777
    }
 
 
1778
 
 
 
1779
    if (HModelSequence_Exists(&ghostDataPtr->HModelController,(int)HMSQT_PredatorStand,(int)PSSS_HitChestFront)) 
 
 
1780
    {
 
 
1781
        Add_Delta_Sequence(&ghostDataPtr->HModelController,"HitDelta",(int)HMSQT_PredatorStand,(int)PSSS_HitChestFront,-1);
 
 
1782
    }
 
 
1783
 
 
 
1784
    ghostDataPtr->hltable = GetThisHitLocationTable("predator");
 
 
1785
}
 
 
1786
 
 
 
1787
/* create a new ghost: doesn't do shape animation stuff: this is performed using a seperate set of functions */
 
 
1788
 
 
 
1789
STRATEGYBLOCK *CreateNetGhost(int playerId, int objectId, VECTORCH *position, EULER* orientation, AVP_BEHAVIOUR_TYPE type, uint8_t IOType, uint8_t subtype)
 
 
1790
{
 
 
1791
    int i;
 
 
1792
 
 
 
1793
    /* first check that the position we've been passed is in a module */
 
 
1794
    MODULE *myContainingModule = ModuleFromPosition(position, NULL);
 
 
1795
 
 
 
1796
    if(myContainingModule == NULL)
 
 
1797
        return NULL;
 
 
1798
 
 
 
1799
    /* create a strategy block */    
 
 
1800
    STRATEGYBLOCK *sbPtr = CreateActiveStrategyBlock(I_BehaviourNetGhost);
 
 
1801
 
 
 
1802
    if(!sbPtr) 
 
 
1803
        return NULL;
 
 
1804
 
 
 
1805
    for(i = 0; i < SB_NAME_LENGTH; i++) sbPtr->SBname[i] = '\0';    
 
 
1806
        AssignNewSBName(sbPtr);
 
 
1807
 
 
 
1808
    /* dynamics block */
 
 
1809
    {
 
 
1810
        /* need different templates for objects and sprites */
 
 
1811
    #if EXTRAPOLATION_TEST
 
 
1812
        DYNAMICSBLOCK *dynPtr;
 
 
1813
        switch(type)
 
 
1814
        {
 
 
1815
            case I_BehaviourMarinePlayer:
 
 
1816
                dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT);
 
 
1817
            break;
 
 
1818
            case I_BehaviourPredatorPlayer:
 
 
1819
                dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT);
 
 
1820
                dynPtr->Mass = 180;
 
 
1821
            break;
 
 
1822
            case I_BehaviourAlienPlayer:
 
 
1823
            case I_BehaviourAlien:
 
 
1824
                dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_DEFAULT);
 
 
1825
                dynPtr->ToppleForce = TOPPLE_FORCE_ALIEN;    
 
 
1826
                dynPtr->Mass = 160;
 
 
1827
            break;
 
 
1828
            default:
 
 
1829
                dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
1830
        }
 
 
1831
    #else
 
 
1832
        DYNAMICSBLOCK *dynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
1833
    #endif
 
 
1834
        if(!dynPtr) 
 
 
1835
        {
 
 
1836
            /* allocation failed */
 
 
1837
            RemoveBehaviourStrategy(sbPtr);
 
 
1838
            return NULL;
 
 
1839
        }
 
 
1840
 
 
 
1841
        sbPtr->DynPtr = dynPtr;
 
 
1842
        dynPtr->GravityOn = 0;
 
 
1843
        dynPtr->IsStatic = 0;
 
 
1844
        dynPtr->IsNetGhost = 1;
 
 
1845
        dynPtr->Position = dynPtr->PrevPosition = *position;
 
 
1846
        dynPtr->OrientEuler = *orientation;
 
 
1847
        CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
1848
        TransposeMatrixCH(&dynPtr->OrientMat);
 
 
1849
    }
 
 
1850
 
 
 
1851
    /* data block */
 
 
1852
    {
 
 
1853
        NETGHOSTDATABLOCK *ghostData = malloc(sizeof(NETGHOSTDATABLOCK)); 
 
 
1854
 
 
 
1855
        if(!ghostData) 
 
 
1856
        {
 
 
1857
            /* allocation failed */
 
 
1858
            RemoveBehaviourStrategy(sbPtr);
 
 
1859
            return NULL;
 
 
1860
        }        
 
 
1861
 
 
 
1862
        sbPtr->dataptr = (void *)ghostData;
 
 
1863
        ghostData->playerId = playerId;
 
 
1864
        ghostData->playerObjectId = objectId;
 
 
1865
        ghostData->type = type;
 
 
1866
        ghostData->IOType = (INANIMATEOBJECT_TYPE)IOType;
 
 
1867
        ghostData->subtype = (int)subtype;
 
 
1868
        ghostData->myGunFlash = NULL;
 
 
1869
        ghostData->GunFlashFrameStamp = GlobalFrameCounter;
 
 
1870
        ghostData->SoundHandle  = SOUND_NOACTIVEINDEX;
 
 
1871
        ghostData->SoundHandle2 = SOUND_NOACTIVEINDEX;
 
 
1872
        ghostData->SoundHandle3 = SOUND_NOACTIVEINDEX;
 
 
1873
        ghostData->SoundHandle4 = SOUND_NOACTIVEINDEX;
 
 
1874
        ghostData->currentAnimSequence = 0;
 
 
1875
        ghostData->timer = 0;
 
 
1876
        ghostData->CloakingEffectiveness = 0;
 
 
1877
        ghostData->IgnitionHandshaking = 0;
 
 
1878
        ghostData->soundStartFlag = 0;
 
 
1879
        ghostData->FlameHitCount = 0;
 
 
1880
        ghostData->FlechetteHitCount = 0;
 
 
1881
        ghostData->invulnerable = 0;
 
 
1882
        ghostData->onlyValidFar = 0;
 
 
1883
 
 
 
1884
        #if EXTRAPOLATION_TEST
 
 
1885
        ghostData->velocity.vx = 0;
 
 
1886
        ghostData->velocity.vy = 0;
 
 
1887
        ghostData->velocity.vz = 0;
 
 
1888
        ghostData->extrapTimerLast = 0;
 
 
1889
        ghostData->extrapTimer = 0;
 
 
1890
        #endif
 
 
1891
 
 
 
1892
        /* Clear HModelController. */
 
 
1893
        ghostData->HModelController.Seconds_For_Sequence = 0;
 
 
1894
        ghostData->HModelController.timer_increment = 0;
 
 
1895
        ghostData->HModelController.Sequence_Type = 0;
 
 
1896
        ghostData->HModelController.Sub_Sequence = 0;
 
 
1897
        ghostData->HModelController.sequence_timer = 0;
 
 
1898
        ghostData->HModelController.FrameStamp = 0;
 
 
1899
        ghostData->HModelController.keyframe_flags = 0;
 
 
1900
        ghostData->HModelController.Deltas = NULL;
 
 
1901
        ghostData->HModelController.Root_Section = NULL;
 
 
1902
        ghostData->HModelController.section_data = NULL;
 
 
1903
        ghostData->HModelController.After_Tweening_Sequence_Type = 0;
 
 
1904
        ghostData->HModelController.After_Tweening_Sub_Sequence = 0;
 
 
1905
        ghostData->HModelController.AT_seconds_for_sequence = 0;
 
 
1906
        ghostData->HModelController.Playing = 0;
 
 
1907
        ghostData->HModelController.Reversed = 0;
 
 
1908
        ghostData->HModelController.Looped = 0;
 
 
1909
        ghostData->HModelController.Tweening = 0;
 
 
1910
        ghostData->HModelController.LoopAfterTweening = 0;
 
 
1911
        ghostData->HModelController.ElevationTweening = 0;
 
 
1912
        /* Whew. */
 
 
1913
        ghostData->hltable = 0;
 
 
1914
        /* init the integrity */
 
 
1915
        ghostData->integrity = GHOST_INTEGRITY;        
 
 
1916
 
 
 
1917
         /* set the shape */
 
 
1918
        switch(type)
 
 
1919
        {
 
 
1920
            case I_BehaviourMarinePlayer:
 
 
1921
                CreateMarineHModel(ghostData,WEAPON_PULSERIFLE);
 
 
1922
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1923
            break;
 
 
1924
            case I_BehaviourAlienPlayer:
 
 
1925
                CreateAlienHModel(ghostData,0);
 
 
1926
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1927
            break;
 
 
1928
             case I_BehaviourPredatorPlayer:
 
 
1929
                CreatePredatorHModel(ghostData,WEAPON_PRED_WRISTBLADE);
 
 
1930
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1931
            break;
 
 
1932
            /* KJL 16:57:14 17/06/98 - NPC characters */
 
 
1933
            case I_BehaviourAlien:
 
 
1934
                CreateAlienHModel(ghostData,subtype);
 
 
1935
 
 
 
1936
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1937
            break;
 
 
1938
            case I_BehaviourGrenade:
 
 
1939
            case I_BehaviourPulseGrenade:
 
 
1940
                sbPtr->shapeIndex = GetLoadedShapeMSL("Shell");
 
 
1941
            break;
 
 
1942
            case I_BehaviourFragmentationGrenade:
 
 
1943
                sbPtr->shapeIndex = GetLoadedShapeMSL("Cluster");
 
 
1944
            break;
 
 
1945
            case I_BehaviourRocket:
 
 
1946
                sbPtr->shapeIndex = GetLoadedShapeMSL("missile");
 
 
1947
            break;
 
 
1948
            case I_BehaviourPredatorEnergyBolt:
 
 
1949
                sbPtr->shapeIndex = 0; // uses a special effect
 
 
1950
                //need to play the energy bolt being fired sound
 
 
1951
                Sound_Play(SID_PRED_LAUNCHER, "hpd", (FastRandom()&255)-128, &sbPtr->DynPtr->Position);
 
 
1952
            break;
 
 
1953
            case I_BehaviourFrisbeeEnergyBolt:
 
 
1954
                sbPtr->shapeIndex = 0; // uses a special effect
 
 
1955
                //need to play the energy bolt being fired sound
 
 
1956
                Sound_Play(SID_PRED_LAUNCHER, "hpd", (FastRandom()&255)-128, &sbPtr->DynPtr->Position);
 
 
1957
            break;
 
 
1958
            case I_BehaviourPPPlasmaBolt:
 
 
1959
                sbPtr->shapeIndex = 0; // uses a special effect
 
 
1960
            break;
 
 
1961
            case I_BehaviourPredatorDisc_SeekTrack:
 
 
1962
            {
 
 
1963
                const SECTION *root_section = GetNamedHierarchyFromLibrary("disk","Disk");
 
 
1964
 
 
 
1965
                assert(root_section);
 
 
1966
 
 
 
1967
                Create_HModel(&ghostData->HModelController,root_section);
 
 
1968
                InitHModelSequence(&ghostData->HModelController,HMSQT_MarineStand,MSSS_Minigun_Delta,ONE_FIXED);
 
 
1969
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1970
 
 
 
1971
                /* Just to make sure. */
 
 
1972
                sbPtr->shapeIndex = GetLoadedShapeMSL("Shell");
 
 
1973
            }
 
 
1974
            break;
 
 
1975
            case I_BehaviourFrisbee:
 
 
1976
            {
 
 
1977
                const SECTION *root_section = GetNamedHierarchyFromLibrary("mdisk","Mdisk");
 
 
1978
 
 
 
1979
                assert(root_section);
 
 
1980
 
 
 
1981
                Create_HModel(&ghostData->HModelController,root_section);
 
 
1982
                InitHModelSequence(&ghostData->HModelController,HMSQT_MarineStand,MSSS_Minigun_Delta,(ONE_FIXED>>1));
 
 
1983
                ProveHModel_Far(&ghostData->HModelController,sbPtr);
 
 
1984
 
 
 
1985
                /* Just to make sure. */
 
 
1986
                sbPtr->shapeIndex = GetLoadedShapeMSL("Shell");
 
 
1987
 
 
 
1988
                //Sound_Play(SID_ED_SKEETERLAUNCH, "hd", &sbPtr->DynPtr->Position);
 
 
1989
            }
 
 
1990
            break;
 
 
1991
            case I_BehaviourInanimateObject:
 
 
1992
            /* That *should* only happen for pred discs at this stage */
 
 
1993
            //Now there are also weapons that appear when players die
 
 
1994
                if(IOType==IOT_Weapon)
 
 
1995
                {
 
 
1996
                    switch(subtype)
 
 
1997
                    {
 
 
1998
                         case WEAPON_MARINE_PISTOL:
 
 
1999
                         case WEAPON_PULSERIFLE:
 
 
2000
                            sbPtr->shapeIndex = GetLoadedShapeMSL("pulse");
 
 
2001
                        break;
 
 
2002
                        case WEAPON_SMARTGUN:
 
 
2003
                            sbPtr->shapeIndex = GetLoadedShapeMSL("smart");
 
 
2004
                        break;
 
 
2005
                        case WEAPON_FLAMETHROWER:
 
 
2006
                            sbPtr->shapeIndex = GetLoadedShapeMSL("flame");
 
 
2007
                        break;
 
 
2008
                        case WEAPON_SADAR:
 
 
2009
                            sbPtr->shapeIndex = GetLoadedShapeMSL("sadar");
 
 
2010
                        break;
 
 
2011
                        case WEAPON_GRENADELAUNCHER:
 
 
2012
                            sbPtr->shapeIndex = GetLoadedShapeMSL("grenade");
 
 
2013
                        break;
 
 
2014
                        case WEAPON_MINIGUN:
 
 
2015
                            sbPtr->shapeIndex = GetLoadedShapeMSL("minigun");
 
 
2016
                        break;
 
 
2017
                        case WEAPON_FRISBEE_LAUNCHER:
 
 
2018
                            sbPtr->shapeIndex = GetLoadedShapeMSL("sadar");
 
 
2019
                        break;
 
 
2020
                        default:
 
 
2021
                        {
 
 
2022
                            assert(0=="Unexpected weapon type");
 
 
2023
                        }
 
 
2024
                    }
 
 
2025
 
 
 
2026
                    sbPtr->DynPtr->IsPickupObject = 1;
 
 
2027
                    assert(sbPtr->shapeIndex != -1);
 
 
2028
                }
 
 
2029
                else
 
 
2030
                {
 
 
2031
                    const SECTION *root_section = GetNamedHierarchyFromLibrary("disk","Disk");
 
 
2032
 
 
 
2033
                    assert(IOType == IOT_Ammo);
 
 
2034
                    assert(subtype == AMMO_PRED_DISC);
 
 
2035
                    assert(root_section);
 
 
2036
 
 
 
2037
                    /* Now it's not hierarchical! */
 
 
2038
                    const SECTION *disc_section  = GetThisSection(root_section, "disk");
 
 
2039
                    assert(disc_section);
 
 
2040
 
 
 
2041
                    sbPtr->shapeIndex = disc_section->ShapeNum;
 
 
2042
                }
 
 
2043
            break;
 
 
2044
            case I_BehaviourFlare:
 
 
2045
                sbPtr->shapeIndex = GetLoadedShapeMSL("Flare");
 
 
2046
                ghostData->timer = FLARE_LIFETIME*ONE_FIXED;
 
 
2047
            break;
 
 
2048
            case I_BehaviourProximityGrenade:
 
 
2049
                sbPtr->shapeIndex = GetLoadedShapeMSL("Proxmine");
 
 
2050
                ghostData->timer = PROX_GRENADE_LIFETIME*ONE_FIXED*2;
 
 
2051
            break;
 
 
2052
            case I_BehaviourAutoGun:
 
 
2053
                sbPtr->shapeIndex = GetLoadedShapeMSL("Sentry01");
 
 
2054
            break;
 
 
2055
            case I_BehaviourSpeargunBolt:
 
 
2056
                sbPtr->shapeIndex = GetLoadedShapeMSL("spear");
 
 
2057
                //speargun bolt won't get any location updates , so set integrity 
 
 
2058
                //to be the standard speargun timeout time.
 
 
2059
                ghostData->integrity = 20*ONE_FIXED;        
 
 
2060
 
 
 
2061
                //play the sound for the bolt as well
 
 
2062
                Sound_Play(SID_SPEARGUN_HITTING_WALL, "d", &sbPtr->DynPtr->Position);  
 
 
2063
                //and make the sparks
 
 
2064
                {
 
 
2065
                    VECTORCH pos = sbPtr->DynPtr->Position;
 
 
2066
                    pos.vx += sbPtr->DynPtr->OrientMat.mat31;
 
 
2067
                    pos.vy += sbPtr->DynPtr->OrientMat.mat32;
 
 
2068
                    pos.vz += sbPtr->DynPtr->OrientMat.mat33;
 
 
2069
                    MakeFocusedExplosion(&(sbPtr->DynPtr->Position), &pos, 20, PARTICLE_SPARK);
 
 
2070
                }
 
 
2071
            default:
 
 
2072
                break;
 
 
2073
        }
 
 
2074
 
 
 
2075
        assert(sbPtr->shapeIndex != -1);    
 
 
2076
    }
 
 
2077
 
 
 
2078
    /* strategy block initialisation, after dynamics block creation */
 
 
2079
    sbPtr->maintainVisibility = 1;          
 
 
2080
     sbPtr->containingModule = myContainingModule;
 
 
2081
 
 
 
2082
     return sbPtr;
 
 
2083
}
 
 
2084
 
 
 
2085
#if EXTRAPOLATION_TEST
 
 
2086
int UseExtrapolation = 1;
 
 
2087
void PlayerGhostExtrapolation()
 
 
2088
{
 
 
2089
    int sbIndex = 0;
 
 
2090
 
 
 
2091
    //search for all ghosts of players
 
 
2092
    while(sbIndex < NumActiveStBlocks)
 
 
2093
    {    
 
 
2094
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++];
 
 
2095
 
 
 
2096
        if(sbPtr->type == I_BehaviourNetGhost)
 
 
2097
        {
 
 
2098
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2099
 
 
 
2100
            switch(ghostData->type)
 
 
2101
            {
 
 
2102
            case I_BehaviourMarinePlayer:
 
 
2103
            case I_BehaviourAlienPlayer:
 
 
2104
            case I_BehaviourAlien:
 
 
2105
            case I_BehaviourPredatorPlayer:
 
 
2106
            {
 
 
2107
                int time;
 
 
2108
                DYNAMICSBLOCK* dynPtr= sbPtr->DynPtr;
 
 
2109
                if(ghostData->onlyValidFar)
 
 
2110
                    continue;
 
 
2111
 
 
 
2112
                if(UseExtrapolation)
 
 
2113
                {
 
 
2114
                    dynPtr->LinVelocity.vx = 0;
 
 
2115
                    dynPtr->LinVelocity.vy = 0;
 
 
2116
                    dynPtr->LinVelocity.vz = 0;
 
 
2117
 
 
 
2118
                    dynPtr->IsNetGhost = 0;
 
 
2119
 
 
 
2120
                    ghostData->extrapTimer += NormalFrameTime;
 
 
2121
                    if(ghostData->extrapTimer < 0)
 
 
2122
                        ghostData->extrapTimer=0;
 
 
2123
 
 
 
2124
                    if(ghostData->extrapTimer > ONE_FIXED/2)
 
 
2125
                        ghostData->extrapTimer=ONE_FIXED/2;
 
 
2126
 
 
 
2127
                    time = ghostData->extrapTimer - ghostData->extrapTimerLast;
 
 
2128
                    ghostData->extrapTimerLast = ghostData->extrapTimer;
 
 
2129
 
 
 
2130
                    if(!ghostData->velocity.vx && !ghostData->velocity.vy && !ghostData->velocity.vz)
 
 
2131
                    {
 
 
2132
                        /*
 
 
2133
                        Not moving , so alter the dynamics block settings to match those of a non-extrapolated
 
 
2134
                        net ghost.
 
 
2135
                        */
 
 
2136
                        dynPtr->LinImpulse.vx = dynPtr->LinImpulse.vy = dynPtr->LinImpulse.vz = 0;
 
 
2137
 
 
 
2138
                        ghostData->extrapTimerLast = ghostData->extrapTimer = 0;
 
 
2139
                        dynPtr->IsNetGhost = 1;
 
 
2140
                        dynPtr->UseStandardGravity = 1;
 
 
2141
                        sbPtr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
2142
                    }
 
 
2143
                    else if(time > 0)
 
 
2144
                    {
 
 
2145
                        dynPtr->LinVelocity = ghostData->velocity;
 
 
2146
 
 
 
2147
                        if(time != NormalFrameTime)
 
 
2148
                        {
 
 
2149
                            //only doing interpolation for a fraction of a frame
 
 
2150
                            //so we need to scale the velocity accordingly
 
 
2151
                            dynPtr->LinVelocity.vx = WideMulNarrowDiv(dynPtr->LinVelocity.vx,time,NormalFrameTime);
 
 
2152
                            dynPtr->LinVelocity.vy = WideMulNarrowDiv(dynPtr->LinVelocity.vy,time,NormalFrameTime);
 
 
2153
                            dynPtr->LinVelocity.vz = WideMulNarrowDiv(dynPtr->LinVelocity.vz,time,NormalFrameTime);
 
 
2154
                        }
 
 
2155
                    }
 
 
2156
 
 
 
2157
                    /*
 
 
2158
                    if(sbPtr->DisplayBlock)
 
 
2159
                        sbPtr->DisplayBlock->ObRadius=1200;
 
 
2160
                    */
 
 
2161
                }
 
 
2162
                else
 
 
2163
                {
 
 
2164
                    //not using extrapolation , so make sure dynamics block
 
 
2165
                    //contains normal ghost settings
 
 
2166
                    dynPtr->LinImpulse.vx = 0;
 
 
2167
                    dynPtr->LinImpulse.vy = 0;
 
 
2168
                    dynPtr->LinImpulse.vz = 0;
 
 
2169
                    dynPtr->LinVelocity.vx = 0;
 
 
2170
                    dynPtr->LinVelocity.vy = 0;
 
 
2171
                    dynPtr->LinVelocity.vz = 0;
 
 
2172
                    dynPtr->UseStandardGravity = 1;
 
 
2173
                    dynPtr->IsNetGhost = 1;
 
 
2174
                       sbPtr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
2175
                }
 
 
2176
            }
 
 
2177
            default:
 
 
2178
            break;
 
 
2179
            }
 
 
2180
        }
 
 
2181
    }
 
 
2182
}
 
 
2183
 
 
 
2184
static DISPLAYBLOCK* AddNPCGunFlashEffect(VECTORCH *position, MATRIXCH* orientation, enum SFX_ID sfxID)
 
 
2185
{
 
 
2186
    DISPLAYBLOCK *dPtr = CreateSFXObject(sfxID);
 
 
2187
 
 
 
2188
    if(dPtr)
 
 
2189
    {
 
 
2190
        dPtr->ObWorld = *position;
 
 
2191
        dPtr->ObMat = *orientation;
 
 
2192
        AddLightingEffectToObject(dPtr, LFX_MUZZLEFLASH);
 
 
2193
        dPtr->SfxPtr->EffectDrawnLastFrame = 0;
 
 
2194
    }
 
 
2195
 
 
 
2196
return dPtr;
 
 
2197
}
 
 
2198
 
 
 
2199
/* This function maintains a player ghost's gunflash effect, and is called from 
 
 
2200
processmsg_playerstate(). It maintains the ghost given by index, and takes as a 
 
 
2201
parameter the state of the net-player's muzzle flash, as indicated in the last
 
 
2202
network message.  It */ 
 
 
2203
void HandleGhostGunFlashEffect(STRATEGYBLOCK *sbPtr, int gunFlashOn)
 
 
2204
{
 
 
2205
    assert(sbPtr);
 
 
2206
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2207
    assert(ghostData);
 
 
2208
 
 
 
2209
    /* aliens shouldn't have gun flashes */
 
 
2210
    switch(ghostData->type)
 
 
2211
    {
 
 
2212
        case I_BehaviourAlienPlayer:
 
 
2213
        case I_BehaviourPredatorPlayer:
 
 
2214
            ghostData->myGunFlash = NULL;
 
 
2215
        return;
 
 
2216
        case I_BehaviourMarinePlayer:
 
 
2217
        {
 
 
2218
            if (gunFlashOn == 2)
 
 
2219
            {
 
 
2220
                ghostData->GunflashSectionPtr=GetThisSectionData(ghostData->HModelController.section_data,"dum L flash");
 
 
2221
 
 
 
2222
                if (ghostData->GunflashSectionPtr == NULL)
 
 
2223
                    ghostData->GunflashSectionPtr = GetThisSectionData(ghostData->HModelController.section_data,"dum flash");
 
 
2224
            }
 
 
2225
            else if (gunFlashOn == 1)
 
 
2226
            {
 
 
2227
                ghostData->GunflashSectionPtr=GetThisSectionData(ghostData->HModelController.section_data,"dum flash");
 
 
2228
            }
 
 
2229
            /*
 
 
2230
            else if (gunFlashOn == 3)
 
 
2231
            {
 
 
2232
                // Extrapolation.
 
 
2233
            }
 
 
2234
            */
 
 
2235
        }
 
 
2236
        default:
 
 
2237
        break;
 
 
2238
    }
 
 
2239
 
 
 
2240
    //assert((ghostData->type == I_BehaviourMarinePlayer)|| (ghostData->type == I_BehaviourPredatorPlayer));
 
 
2241
 
 
 
2242
    /* Handle two pistols? */
 
 
2243
 
 
 
2244
    if(ghostData->myGunFlash)
 
 
2245
    {
 
 
2246
        /* I've already got a gun flash... */
 
 
2247
        if(gunFlashOn)
 
 
2248
        {
 
 
2249
            /* Maintain existing gun flash */
 
 
2250
            assert(ghostData->GunflashSectionPtr);
 
 
2251
 
 
 
2252
            if (sbPtr->DisplayBlock)
 
 
2253
            {
 
 
2254
                ProveHModel(&ghostData->HModelController,sbPtr->DisplayBlock);
 
 
2255
                ghostData->myGunFlash->ObWorld = ghostData->GunflashSectionPtr->World_Offset;
 
 
2256
                ghostData->myGunFlash->ObMat = ghostData->GunflashSectionPtr->SecMat;
 
 
2257
                AddLightingEffectToObject(ghostData->myGunFlash, LFX_MUZZLEFLASH);
 
 
2258
            }
 
 
2259
        }
 
 
2260
        else
 
 
2261
        {
 
 
2262
            if (ghostData->GunFlashFrameStamp != GlobalFrameCounter)
 
 
2263
            {
 
 
2264
                /* Maintain for at least one frame. */
 
 
2265
                DestroyActiveObject(&ghostData->myGunFlash);
 
 
2266
            }
 
 
2267
        } 
 
 
2268
    }
 
 
2269
    else
 
 
2270
    {
 
 
2271
        if(gunFlashOn)
 
 
2272
        {
 
 
2273
            /* new flash */
 
 
2274
            assert(ghostData->GunflashSectionPtr);
 
 
2275
            ghostData->GunFlashFrameStamp = GlobalFrameCounter;
 
 
2276
 
 
 
2277
             if (sbPtr->DisplayBlock)
 
 
2278
             {
 
 
2279
                 ProveHModel(&ghostData->HModelController,sbPtr->DisplayBlock);
 
 
2280
 
 
 
2281
                switch(ghostData->CurrentWeapon)
 
 
2282
                {
 
 
2283
                    case WEAPON_SMARTGUN:
 
 
2284
                    {
 
 
2285
                        ghostData->myGunFlash = AddNPCGunFlashEffect
 
 
2286
                        (
 
 
2287
                            &ghostData->GunflashSectionPtr->World_Offset,
 
 
2288
                            &ghostData->GunflashSectionPtr->SecMat,
 
 
2289
                            SFX_MUZZLE_FLASH_SMARTGUN
 
 
2290
                        );
 
 
2291
                    }
 
 
2292
                    break;
 
 
2293
                    case WEAPON_FRISBEE_LAUNCHER:
 
 
2294
                    {
 
 
2295
                        ghostData->myGunFlash = AddNPCGunFlashEffect
 
 
2296
                        (
 
 
2297
                            &ghostData->GunflashSectionPtr->World_Offset,
 
 
2298
                            &ghostData->GunflashSectionPtr->SecMat,
 
 
2299
                            SFX_MUZZLE_FLASH_SKEETER
 
 
2300
                        );
 
 
2301
                    }
 
 
2302
                    break;
 
 
2303
                    default:
 
 
2304
                    {
 
 
2305
                        ghostData->myGunFlash = AddNPCGunFlashEffect
 
 
2306
                        (
 
 
2307
                            &ghostData->GunflashSectionPtr->World_Offset,
 
 
2308
                            &ghostData->GunflashSectionPtr->SecMat,
 
 
2309
                            SFX_MUZZLE_FLASH_AMORPHOUS
 
 
2310
                        );
 
 
2311
                    }
 
 
2312
                }
 
 
2313
            }
 
 
2314
        }
 
 
2315
    }
 
 
2316
}
 
 
2317
 
 
 
2318
#endif //EXTRAPOLATION_TEST
 
 
2319
 
 
 
2320
/* these functions are called directly by the visibility management system */
 
 
2321
void MakeGhostNear(STRATEGYBLOCK *sbPtr)
 
 
2322
{
 
 
2323
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2324
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
2325
    SFXBLOCK *sfxPtr = NULL;
 
 
2326
 
 
 
2327
    assert(ghostData);
 
 
2328
 
 
 
2329
    /* KJL 11:56:09 08/05/98 - if shape doesn't exist, use a sfx */
 
 
2330
 
 
 
2331
    switch(ghostData->type)
 
 
2332
    {
 
 
2333
        case I_BehaviourPredatorEnergyBolt:
 
 
2334
        case I_BehaviourFrisbeeEnergyBolt:
 
 
2335
        case I_BehaviourPPPlasmaBolt:
 
 
2336
        {
 
 
2337
            sfxPtr = AllocateSfxBlock();
 
 
2338
            // if we haven't got a free sfx block, return */
 
 
2339
            if (!sfxPtr)
 
 
2340
                return;
 
 
2341
        }
 
 
2342
        default:
 
 
2343
        break;
 
 
2344
    }
 
 
2345
 
 
 
2346
    if(ghostData->onlyValidFar)
 
 
2347
        return; //Far alien ai , don't have enough information to make it near
 
 
2348
 
 
 
2349
    assert(dynPtr);
 
 
2350
    assert(sbPtr->DisplayBlock == NULL);
 
 
2351
 
 
 
2352
    DISPLAYBLOCK *dPtr = AllocateNewObject(sbPtr->shapeIndex);
 
 
2353
 
 
 
2354
    if(dPtr == NULL)
 
 
2355
        return; /* cannot create displayblock, so leave object "far" */
 
 
2356
 
 
 
2357
    sbPtr->DisplayBlock = dPtr;
 
 
2358
    dPtr->ObStrategyBlock = sbPtr;
 
 
2359
 
 
 
2360
     /* set the animation sequence, if we're a player ghost */
 
 
2361
    if(ghostData->playerObjectId == GHOST_PLAYEROBJECTID)
 
 
2362
    {
 
 
2363
        assert((ghostData->type == I_BehaviourMarinePlayer)||
 
 
2364
            (ghostData->type == I_BehaviourPredatorPlayer)||
 
 
2365
            (ghostData->type == I_BehaviourAlienPlayer));
 
 
2366
 
 
 
2367
        dPtr->HModelControlBlock = &ghostData->HModelController;
 
 
2368
        ProveHModel(dPtr->HModelControlBlock, dPtr);
 
 
2369
    }
 
 
2370
    else
 
 
2371
    {
 
 
2372
        switch(ghostData->type)
 
 
2373
        {
 
 
2374
            case I_BehaviourAlien:
 
 
2375
            case I_BehaviourPredatorDisc_SeekTrack:
 
 
2376
            case I_BehaviourFrisbee:
 
 
2377
            case I_BehaviourCorpse:
 
 
2378
                dPtr->HModelControlBlock = &ghostData->HModelController;
 
 
2379
                ProveHModel(dPtr->HModelControlBlock, dPtr);
 
 
2380
            default:
 
 
2381
            break;
 
 
2382
        }
 
 
2383
    }
 
 
2384
 
 
 
2385
    /* need to initialise positional information in the new display block */ 
 
 
2386
    dPtr->ObWorld = dynPtr->Position;
 
 
2387
    dPtr->ObEuler = dynPtr->OrientEuler;
 
 
2388
    dPtr->ObMat = dynPtr->OrientMat;    
 
 
2389
    dPtr->SfxPtr = sfxPtr;
 
 
2390
 
 
 
2391
    /* finally, need to add lighting effects to the displayblock */
 
 
2392
    switch(ghostData->type)
 
 
2393
    {
 
 
2394
        case I_BehaviourPulseGrenade:
 
 
2395
        case I_BehaviourRocket:
 
 
2396
            AddLightingEffectToObject(dPtr,LFX_ROCKETJET);
 
 
2397
        break;        
 
 
2398
        case I_BehaviourPredatorEnergyBolt:
 
 
2399
            sfxPtr->SfxID = SFX_PREDATOR_PLASMA_BOLT;
 
 
2400
            AddLightingEffectToObject(dPtr,LFX_PLASMA_BOLT);
 
 
2401
        break;
 
 
2402
        case I_BehaviourFrisbeeEnergyBolt:
 
 
2403
            sfxPtr->SfxID = SFX_FRISBEE_PLASMA_BOLT;
 
 
2404
            AddLightingEffectToObject(dPtr,LFX_PLASMA_BOLT);
 
 
2405
        break;
 
 
2406
        case I_BehaviourPPPlasmaBolt:
 
 
2407
            sfxPtr->SfxID = SFX_SMALL_PREDATOR_PLASMA_BOLT;
 
 
2408
            AddLightingEffectToObject(dPtr,LFX_PLASMA_BOLT);
 
 
2409
        break;
 
 
2410
        case I_BehaviourFlare:
 
 
2411
            AddLightingEffectToObject(dPtr,LFX_FLARE);
 
 
2412
        default:
 
 
2413
            break;
 
 
2414
    }
 
 
2415
}
 
 
2416
 
 
 
2417
/* this function handles damage to a netghost object: 
 
 
2418
basically, it just sends a network message, which should be picked up by the owning object */
 
 
2419
void DamageNetworkGhost(STRATEGYBLOCK *sbPtr, const DAMAGE_PROFILE *damage, int multiple, SECTION_DATA *section,VECTORCH* incoming)
 
 
2420
{
 
 
2421
    int delta_seq = -1;
 
 
2422
    int delta_sub_seq = -1;
 
 
2423
 
 
 
2424
    assert(AvP.Network != I_No_Network);
 
 
2425
 
 
 
2426
    if(section)
 
 
2427
    {
 
 
2428
        //get the appropriate delta sequence
 
 
2429
        int frontback = 1;
 
 
2430
 
 
 
2431
        if (incoming && incoming->vz >= 0)
 
 
2432
            frontback = 0;
 
 
2433
 
 
 
2434
        NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2435
 
 
 
2436
        switch(ghostData->type)
 
 
2437
        {
 
 
2438
            case I_BehaviourMarinePlayer:
 
 
2439
            {
 
 
2440
                int CrouchSubSequence;
 
 
2441
                int StandSubSequence;
 
 
2442
 
 
 
2443
                if (section == NULL) 
 
 
2444
                {
 
 
2445
                    if (!frontback) 
 
 
2446
                    {
 
 
2447
                        CrouchSubSequence = MCrSS_HitChestBack;
 
 
2448
                        StandSubSequence = MSSS_HitChestBack;
 
 
2449
                    } 
 
 
2450
                    else 
 
 
2451
                    {
 
 
2452
                        CrouchSubSequence = MCrSS_HitChestFront;
 
 
2453
                        StandSubSequence = MSSS_HitChestFront;
 
 
2454
                    }
 
 
2455
                }
 
 
2456
                else if (section->sempai->flags & section_flag_head) 
 
 
2457
                {
 
 
2458
                    if (!frontback) 
 
 
2459
                    {
 
 
2460
                        CrouchSubSequence = MCrSS_HitHeadBack;
 
 
2461
                        StandSubSequence = MSSS_HitHeadBack;
 
 
2462
                    }
 
 
2463
                    else 
 
 
2464
                    {
 
 
2465
                        CrouchSubSequence = MCrSS_HitHeadFront;
 
 
2466
                        StandSubSequence = MSSS_HitHeadFront;
 
 
2467
                    }
 
 
2468
                }
 
 
2469
                else if ((section->sempai->flags & section_flag_left_arm)
 
 
2470
                    ||(section->sempai->flags & section_flag_left_hand)) 
 
 
2471
                {
 
 
2472
                    if (!frontback) 
 
 
2473
                    {
 
 
2474
                        CrouchSubSequence = MCrSS_HitRightArm;
 
 
2475
                        StandSubSequence = MSSS_HitRightArm;
 
 
2476
                    }
 
 
2477
                    else
 
 
2478
                    {
 
 
2479
                        CrouchSubSequence = MCrSS_HitLeftArm;
 
 
2480
                        StandSubSequence = MSSS_HitLeftArm;
 
 
2481
                    }
 
 
2482
                }
 
 
2483
                else if ((section->sempai->flags & section_flag_right_arm)
 
 
2484
                    ||(section->sempai->flags & section_flag_right_hand)) 
 
 
2485
                {
 
 
2486
                    if (!frontback) 
 
 
2487
                    {
 
 
2488
                        CrouchSubSequence = MCrSS_HitLeftArm;
 
 
2489
                        StandSubSequence = MSSS_HitLeftArm;
 
 
2490
                    }
 
 
2491
                    else
 
 
2492
                    {
 
 
2493
                        CrouchSubSequence = MCrSS_HitRightArm;
 
 
2494
                        StandSubSequence = MSSS_HitRightArm;
 
 
2495
                    }
 
 
2496
                }
 
 
2497
                else if ((section->sempai->flags & section_flag_left_leg)
 
 
2498
                    ||(section->sempai->flags & section_flag_left_foot)) 
 
 
2499
                {
 
 
2500
                    CrouchSubSequence = MCrSS_HitLeftLeg;
 
 
2501
                    StandSubSequence = MSSS_HitLeftLeg;
 
 
2502
                }
 
 
2503
                else if ((section->sempai->flags & section_flag_right_leg)
 
 
2504
                    ||(section->sempai->flags & section_flag_right_foot)) 
 
 
2505
                {
 
 
2506
                    CrouchSubSequence = MCrSS_HitRightLeg;
 
 
2507
                    StandSubSequence = MSSS_HitRightLeg;
 
 
2508
                }
 
 
2509
                else
 
 
2510
                {
 
 
2511
                    /* Chest or misc. hit. */
 
 
2512
                    if (!frontback)
 
 
2513
                    {
 
 
2514
                        CrouchSubSequence = MCrSS_HitChestBack;
 
 
2515
                        StandSubSequence = MSSS_HitChestBack;
 
 
2516
                    }
 
 
2517
                    else
 
 
2518
                    {
 
 
2519
                        CrouchSubSequence = MCrSS_HitChestFront;
 
 
2520
                        StandSubSequence= MSSS_HitChestFront;
 
 
2521
                    }
 
 
2522
                }
 
 
2523
 
 
 
2524
                switch(ghostData->currentAnimSequence)
 
 
2525
                {
 
 
2526
                    case MSQ_Crawl:
 
 
2527
                    case MSQ_Crawl_Backwards:
 
 
2528
                    case MSQ_Crouch:
 
 
2529
                        delta_seq = (int)HMSQT_MarineCrouch;
 
 
2530
                        delta_sub_seq = (int)CrouchSubSequence;
 
 
2531
                    break;
 
 
2532
                    default:
 
 
2533
                        delta_seq = (int)HMSQT_MarineStand;
 
 
2534
                        delta_sub_seq = (int)StandSubSequence;
 
 
2535
                }
 
 
2536
 
 
 
2537
                PlayHitDeltaOnGhost(sbPtr,delta_seq,delta_sub_seq);
 
 
2538
            }
 
 
2539
            break;
 
 
2540
            case I_BehaviourPredatorPlayer:
 
 
2541
            {
 
 
2542
                int CrouchSubSequence;
 
 
2543
                int StandSubSequence;
 
 
2544
 
 
 
2545
                if (section == NULL) 
 
 
2546
                {
 
 
2547
                    if (!frontback) 
 
 
2548
                    {
 
 
2549
                        CrouchSubSequence = PCrSS_HitChestBack;
 
 
2550
                        StandSubSequence = PSSS_HitChestBack;
 
 
2551
                    }
 
 
2552
                    else
 
 
2553
                    {
 
 
2554
                        CrouchSubSequence = PCrSS_HitChestFront;
 
 
2555
                        StandSubSequence = PSSS_HitChestFront;
 
 
2556
                    }
 
 
2557
                }
 
 
2558
                else if (section->sempai->flags & section_flag_head) 
 
 
2559
                {
 
 
2560
                    if (!frontback) 
 
 
2561
                    {
 
 
2562
                        CrouchSubSequence = PCrSS_HitHeadBack;
 
 
2563
                        StandSubSequence = PSSS_HitHeadBack;
 
 
2564
                    }
 
 
2565
                    else
 
 
2566
                    {
 
 
2567
                        CrouchSubSequence = PCrSS_HitHeadFront;
 
 
2568
                        StandSubSequence = PSSS_HitHeadFront;
 
 
2569
                    }
 
 
2570
                }
 
 
2571
                else if ((section->sempai->flags & section_flag_left_arm)
 
 
2572
                ||(section->sempai->flags & section_flag_left_hand)) 
 
 
2573
                {
 
 
2574
                    if (!frontback) 
 
 
2575
                    {
 
 
2576
                        CrouchSubSequence = PCrSS_HitRightArm;
 
 
2577
                        StandSubSequence = PSSS_HitRightArm;
 
 
2578
                    }
 
 
2579
                    else
 
 
2580
                    {
 
 
2581
                        CrouchSubSequence = PCrSS_HitLeftArm;
 
 
2582
                        StandSubSequence = PSSS_HitLeftArm;
 
 
2583
                    }
 
 
2584
                }
 
 
2585
                else if ((section->sempai->flags & section_flag_right_arm)
 
 
2586
                ||(section->sempai->flags & section_flag_right_hand)) 
 
 
2587
                {
 
 
2588
                    if (!frontback) 
 
 
2589
                    {
 
 
2590
                        CrouchSubSequence = PCrSS_HitLeftArm;
 
 
2591
                        StandSubSequence = PSSS_HitLeftArm;
 
 
2592
                    }
 
 
2593
                    else
 
 
2594
                    {
 
 
2595
                        CrouchSubSequence = PCrSS_HitRightArm;
 
 
2596
                        StandSubSequence = PSSS_HitRightArm;
 
 
2597
                    }
 
 
2598
                }
 
 
2599
                else if ((section->sempai->flags & section_flag_left_leg)
 
 
2600
                ||(section->sempai->flags & section_flag_left_foot))
 
 
2601
                {
 
 
2602
                    CrouchSubSequence = PCrSS_HitLeftLeg;
 
 
2603
                    StandSubSequence = PSSS_HitLeftLeg;
 
 
2604
 
 
 
2605
                }
 
 
2606
                else if ((section->sempai->flags & section_flag_right_leg)
 
 
2607
                ||(section->sempai->flags & section_flag_right_foot))
 
 
2608
                {
 
 
2609
                    CrouchSubSequence = PCrSS_HitRightLeg;
 
 
2610
                    StandSubSequence = PSSS_HitRightLeg;
 
 
2611
                }
 
 
2612
                else
 
 
2613
                {
 
 
2614
                    /* Chest or misc. hit. */
 
 
2615
                    if (!frontback)
 
 
2616
                    {
 
 
2617
                        CrouchSubSequence = PCrSS_HitChestBack;
 
 
2618
                        StandSubSequence = PSSS_HitChestBack;
 
 
2619
                    }
 
 
2620
                    else
 
 
2621
                    {
 
 
2622
                        CrouchSubSequence = PCrSS_HitChestFront;
 
 
2623
                        StandSubSequence = PSSS_HitChestFront;
 
 
2624
                    }
 
 
2625
                }
 
 
2626
 
 
 
2627
                switch(ghostData->currentAnimSequence)
 
 
2628
                {
 
 
2629
                    case PredSQ_Crawl:
 
 
2630
                    case PredSQ_Crawl_Backwards:
 
 
2631
                    case PredSQ_Crouch:
 
 
2632
                    case PredSQ_CrouchedSwipe:
 
 
2633
                    case PredSQ_CrawlingSwipe:
 
 
2634
                    case PredSQ_CrawlingSwipe_Backwards:
 
 
2635
                        delta_seq = (int)HMSQT_PredatorCrouch;
 
 
2636
                        delta_sub_seq = (int)CrouchSubSequence;
 
 
2637
                    break;
 
 
2638
                    default:
 
 
2639
                        delta_seq = (int)HMSQT_PredatorStand;
 
 
2640
                        delta_sub_seq = (int)StandSubSequence;
 
 
2641
                }
 
 
2642
 
 
 
2643
                PlayHitDeltaOnGhost(sbPtr,delta_seq,delta_sub_seq);
 
 
2644
            }
 
 
2645
            default:
 
 
2646
            break;
 
 
2647
        }
 
 
2648
    }
 
 
2649
 
 
 
2650
    {
 
 
2651
    int sectionID;
 
 
2652
    if (section)
 
 
2653
        sectionID = section->sempai->IDnumber;
 
 
2654
    else
 
 
2655
        sectionID = -1;
 
 
2656
 
 
 
2657
    AddNetMsg_LocalObjectDamaged(sbPtr, damage, multiple,sectionID,delta_seq,delta_sub_seq,incoming);
 
 
2658
    }
 
 
2659
}
 
 
2660
 
 
 
2661
/* Patrick 5/8/97 --------------------------------------------------
 
 
2662
Handles the player's weapon sound effects... this should be called
 
 
2663
after update ghost/create ghost has been called for player ghost
 
 
2664
in processnetmsg_playerstate().
 
 
2665
---------------------------------------------------------------------*/
 
 
2666
void HandlePlayerGhostWeaponSound(STRATEGYBLOCK *sbPtr, int weapon, int firingPrimary, int firingSecondary)
 
 
2667
{
 
 
2668
    assert(sbPtr);
 
 
2669
    assert(sbPtr->DynPtr);
 
 
2670
    assert(weapon>=0);
 
 
2671
 
 
 
2672
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2673
    assert(ghostData);
 
 
2674
 
 
 
2675
    switch((enum WEAPON_ID)weapon)
 
 
2676
    {
 
 
2677
        case NULL_WEAPON:
 
 
2678
            /* stop sound if we've got it */
 
 
2679
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2680
                Sound_Stop(ghostData->SoundHandle);
 
 
2681
        break;
 
 
2682
        case WEAPON_CUDGEL:
 
 
2683
            //no sound for the moment.
 
 
2684
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2685
                Sound_Stop(ghostData->SoundHandle);
 
 
2686
        break;
 
 
2687
        case WEAPON_PULSERIFLE:
 
 
2688
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2689
 
 
 
2690
            if(firingPrimary)
 
 
2691
            {
 
 
2692
                if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2693
                       Sound_Play(SID_PULSE_LOOP, "elhd", &ghostData->SoundHandle, &sbPtr->DynPtr->Position);                    
 
 
2694
                else
 
 
2695
                    Sound_Update3d(ghostData->SoundHandle, &(sbPtr->DynPtr->Position));
 
 
2696
            }
 
 
2697
            else
 
 
2698
            {
 
 
2699
                if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX) 
 
 
2700
                {    
 
 
2701
                    Sound_Stop(ghostData->SoundHandle);                
 
 
2702
                    Sound_Play(SID_PULSE_END, "hd", &sbPtr->DynPtr->Position);                    
 
 
2703
                }
 
 
2704
 
 
 
2705
                if(firingSecondary)
 
 
2706
                    Sound_Play(SID_PULSEGRENADELAUNCH, "hd", &sbPtr->DynPtr->Position);            
 
 
2707
            }
 
 
2708
        break;
 
 
2709
        case WEAPON_TWO_PISTOLS:
 
 
2710
        case WEAPON_MARINE_PISTOL:
 
 
2711
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2712
            /* stop sound if we've got it */
 
 
2713
 
 
 
2714
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2715
                Sound_Stop(ghostData->SoundHandle);
 
 
2716
 
 
 
2717
            if (firingPrimary || firingSecondary)
 
 
2718
                Sound_Play(SID_SHOTGUN, "hd", &sbPtr->DynPtr->Position);
 
 
2719
        break;
 
 
2720
        case WEAPON_SMARTGUN:
 
 
2721
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2722
            if(firingPrimary)
 
 
2723
            {
 
 
2724
                if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2725
                {
 
 
2726
                    switch (FastRandom() % 3)
 
 
2727
                    {
 
 
2728
                        case 0:
 
 
2729
                            Sound_Play(SID_SMART1, "ehpd", &ghostData->SoundHandle, ((FastRandom()&255)-128),
&sbPtr->DynPtr->Position);                    
 
 
2730
                        break;
 
 
2731
                        case 1:
 
 
2732
                            Sound_Play(SID_SMART2, "ehpd", &ghostData->SoundHandle, ((FastRandom()&255)-128),
&sbPtr->DynPtr->Position);                    
 
 
2733
                        break;
 
 
2734
                        case 2:
 
 
2735
                            Sound_Play(SID_SMART3, "ehpd", &ghostData->SoundHandle, ((FastRandom()&255)-128),
&sbPtr->DynPtr->Position);                    
 
 
2736
                        default:
 
 
2737
                        break;
 
 
2738
                    }
 
 
2739
                }
 
 
2740
                else
 
 
2741
                {
 
 
2742
                    Sound_Update3d(ghostData->SoundHandle, &(sbPtr->DynPtr->Position));
 
 
2743
                }
 
 
2744
            }
 
 
2745
            else
 
 
2746
            {
 
 
2747
                if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2748
                    Sound_Stop(ghostData->SoundHandle);            
 
 
2749
            }
 
 
2750
        break;
 
 
2751
        case WEAPON_FLAMETHROWER:
 
 
2752
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2753
 
 
 
2754
            if(firingPrimary)
 
 
2755
            {
 
 
2756
                if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2757
                       Sound_Play(SID_INCIN_LOOP, "elhd", &ghostData->SoundHandle, &sbPtr->DynPtr->Position);                    
 
 
2758
                else
 
 
2759
                    Sound_Update3d(ghostData->SoundHandle, &(sbPtr->DynPtr->Position));
 
 
2760
 
 
 
2761
                if (sbPtr->DisplayBlock)
 
 
2762
                {
 
 
2763
                    ProveHModel(&ghostData->HModelController,sbPtr->DisplayBlock);
 
 
2764
                    FireNetGhostFlameThrower
 
 
2765
                    (
 
 
2766
                        &ghostData->GunflashSectionPtr->World_Offset,
 
 
2767
                        &ghostData->GunflashSectionPtr->SecMat
 
 
2768
                    );
 
 
2769
 
 
 
2770
                    /* Lighting? */
 
 
2771
                    if (sbPtr->DisplayBlock)
 
 
2772
                        AddLightingEffectToObject(sbPtr->DisplayBlock,LFX_MUZZLEFLASH);
 
 
2773
                }
 
 
2774
            }
 
 
2775
            else
 
 
2776
            {
 
 
2777
                if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2778
                    Sound_Stop(ghostData->SoundHandle);                
 
 
2779
            }
 
 
2780
        break;
 
 
2781
        case WEAPON_SADAR:
 
 
2782
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2783
            /* stop sound if we've got it */
 
 
2784
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2785
                Sound_Stop(ghostData->SoundHandle);                
 
 
2786
 
 
 
2787
            if(firingPrimary)
 
 
2788
                Sound_Play(SID_SADAR_FIRE, "hd", &sbPtr->DynPtr->Position);
 
 
2789
        break;
 
 
2790
        case WEAPON_GRENADELAUNCHER:
 
 
2791
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2792
            /* stop sound if we've got it */
 
 
2793
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2794
                Sound_Stop(ghostData->SoundHandle);                
 
 
2795
 
 
 
2796
            if(firingPrimary)
 
 
2797
                Sound_Play(SID_GRENADE_LAUNCH, "hd", &sbPtr->DynPtr->Position);                        
 
 
2798
        break;
 
 
2799
        case WEAPON_MINIGUN:
 
 
2800
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2801
            if(firingPrimary)
 
 
2802
            {
 
 
2803
                if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2804
                       Sound_Play(SID_MINIGUN_LOOP, "elhd", &ghostData->SoundHandle, &sbPtr->DynPtr->Position);                    
 
 
2805
                else
 
 
2806
                    Sound_Update3d(ghostData->SoundHandle, &(sbPtr->DynPtr->Position));
 
 
2807
            }
 
 
2808
            else
 
 
2809
            {
 
 
2810
                if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX) 
 
 
2811
                {
 
 
2812
                    Sound_Stop(ghostData->SoundHandle);                
 
 
2813
                    Sound_Play(SID_MINIGUN_END, "hd", &sbPtr->DynPtr->Position);                    
 
 
2814
                }
 
 
2815
            }
 
 
2816
        break;
 
 
2817
        case WEAPON_FRISBEE_LAUNCHER:
 
 
2818
        {
 
 
2819
            assert(ghostData->type == I_BehaviourMarinePlayer);
 
 
2820
            /* stop sound if we've got it */
 
 
2821
            if (firingPrimary)
 
 
2822
            {
 
 
2823
            //    if (ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2824
            //    {
 
 
2825
                    //if (ActiveSounds[ghostData->SoundHandle].soundIndex != SID_ED_SKEETERCHARGE)
 
 
2826
                    //    Sound_Stop(ghostData->SoundHandle);
 
 
2827
            //    }
 
 
2828
                if (ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2829
                {
 
 
2830
                    if (!ghostData->soundStartFlag)
 
 
2831
                    {
 
 
2832
                        //Sound_Play(SID_ED_SKEETERCHARGE, "ehd", &ghostData->SoundHandle, &sbPtr->DynPtr->Position);
 
 
2833
                        ghostData->soundStartFlag = 1;
 
 
2834
                    }
 
 
2835
                }
 
 
2836
            }
 
 
2837
            else
 
 
2838
            {
 
 
2839
                ghostData->soundStartFlag = 0;
 
 
2840
                if (ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2841
                    Sound_Stop(ghostData->SoundHandle);
 
 
2842
            }
 
 
2843
        break;
 
 
2844
        }
 
 
2845
        case WEAPON_PRED_WRISTBLADE:
 
 
2846
            assert(ghostData->type == I_BehaviourPredatorPlayer);
 
 
2847
            /* stop sound if we've got it */
 
 
2848
            //use the sounds connected to the hierarchy
 
 
2849
            break;
 
 
2850
        case WEAPON_PRED_PISTOL:
 
 
2851
            assert(ghostData->type == I_BehaviourPredatorPlayer);
 
 
2852
            if(firingPrimary)
 
 
2853
            {
 
 
2854
                if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
2855
                       Sound_Play(SID_PRED_PISTOL, "hd", &sbPtr->DynPtr->Position);                    
 
 
2856
            }
 
 
2857
            //else
 
 
2858
            //{
 
 
2859
                //if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX) 
 
 
2860
                //{    
 
 
2861
                //    Sound_Stop(ghostData->SoundHandle);                
 
 
2862
                //    Sound_Play(SID_PULSE_END, "hd", &sbPtr->DynPtr->Position);                                    
 
 
2863
                //}
 
 
2864
            //}
 
 
2865
        break;
 
 
2866
        case WEAPON_PRED_RIFLE:
 
 
2867
            assert(ghostData->type == I_BehaviourPredatorPlayer);
 
 
2868
            /* stop sound if we've got it */
 
 
2869
 
 
 
2870
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2871
                Sound_Stop(ghostData->SoundHandle);
 
 
2872
 
 
 
2873
            if(firingPrimary)
 
 
2874
                Sound_Play(SID_PRED_LASER, "hd", &sbPtr->DynPtr->Position);
 
 
2875
        break;
 
 
2876
        case WEAPON_PRED_SHOULDERCANNON:
 
 
2877
            assert(ghostData->type == I_BehaviourPredatorPlayer);
 
 
2878
            /* stop sound if we've got it */
 
 
2879
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2880
                Sound_Stop(ghostData->SoundHandle);                
 
 
2881
 
 
 
2882
            //sound is caused by energy bolt creation               
 
 
2883
        break;
 
 
2884
        case WEAPON_PRED_DISC:
 
 
2885
            assert(ghostData->type == I_BehaviourPredatorPlayer);
 
 
2886
            /* stop sound if we've got it */
 
 
2887
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2888
                Sound_Stop(ghostData->SoundHandle);                
 
 
2889
            /* currently no sound for this */
 
 
2890
        break;
 
 
2891
        case WEAPON_ALIEN_CLAW:
 
 
2892
            //appropriate sounds should be triggered by the animation
 
 
2893
        break;
 
 
2894
        case(WEAPON_PRED_MEDICOMP):
 
 
2895
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2896
                Sound_Stop(ghostData->SoundHandle);                
 
 
2897
        break;
 
 
2898
        default:
 
 
2899
            assert(1==0);
 
 
2900
            /* stop sound if we've got it */
 
 
2901
            if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
2902
                Sound_Stop(ghostData->SoundHandle);
 
 
2903
        break;
 
 
2904
    }
 
 
2905
}
 
 
2906
 
 
 
2907
int ExtractTimerFromElevation(int elevation)
 
 
2908
{
 
 
2909
    int fake_timer,angle1;
 
 
2910
 
 
 
2911
    if (elevation > 1024)
 
 
2912
        elevation -= 4096;
 
 
2913
 
 
 
2914
    angle1 = -elevation;
 
 
2915
 
 
 
2916
    assert(angle1 >= -1024);
 
 
2917
    assert(angle1 <= 1024);
 
 
2918
 
 
 
2919
    fake_timer = 1024 - angle1;
 
 
2920
    fake_timer <<= 5;
 
 
2921
 
 
 
2922
    if (fake_timer > 65536)
 
 
2923
        fake_timer = 65535;
 
 
2924
 
 
 
2925
    assert(fake_timer >= 0);
 
 
2926
    assert(fake_timer < 65536);
 
 
2927
 
 
 
2928
return fake_timer;
 
 
2929
}
 
 
2930
 
 
 
2931
/* KJL 17:11:43 26/01/98 - weapon elevation */
 
 
2932
void HandleWeaponElevation(STRATEGYBLOCK *sbPtr, int elevation, int weapon)
 
 
2933
{
 
 
2934
    DELTA_CONTROLLER *elevation_controller;
 
 
2935
    assert(sbPtr);
 
 
2936
    NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2937
    assert(ghostDataPtr);
 
 
2938
    assert(elevation >= 0);
 
 
2939
    assert(elevation < 4096);
 
 
2940
 
 
 
2941
    if (ghostDataPtr->type == I_BehaviourMarinePlayer)
 
 
2942
    {
 
 
2943
        if (weapon != ghostDataPtr->CurrentWeapon)
 
 
2944
        {
 
 
2945
            Dispel_HModel(&ghostDataPtr->HModelController);
 
 
2946
            CreateMarineHModel(ghostDataPtr, weapon);
 
 
2947
            ProveHModel_Far(&ghostDataPtr->HModelController,sbPtr);
 
 
2948
        }
 
 
2949
 
 
 
2950
        elevation_controller = Get_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation");
 
 
2951
        /* Deal with elevation sequence. */
 
 
2952
        assert(elevation_controller);
 
 
2953
        elevation_controller->Active = 1;
 
 
2954
 
 
 
2955
        switch(ghostDataPtr->currentAnimSequence)
 
 
2956
        {
 
 
2957
            case MSQ_StandDieFront:
 
 
2958
            case MSQ_StandDieBack:
 
 
2959
            case MSQ_StandDeadFront:
 
 
2960
            case MSQ_StandDeadBack:
 
 
2961
            case MSQ_CrouchDie:
 
 
2962
            case MSQ_CrouchDead:
 
 
2963
            case MSQ_Taunt:
 
 
2964
            {
 
 
2965
                /* Force no elevation. */
 
 
2966
                elevation_controller->Active=0;
 
 
2967
                break;
 
 
2968
            }
 
 
2969
            case MSQ_RunningFire:
 
 
2970
            case MSQ_RunningFire_Backwards:
 
 
2971
                if (ghostDataPtr->CurrentWeapon == WEAPON_GRENADELAUNCHER)
 
 
2972
                {
 
 
2973
                    elevation_controller->Active = 0;
 
 
2974
                    ghostDataPtr->HModelController.Looped = 0;
 
 
2975
                break;
 
 
2976
                }
 
 
2977
                else if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
2978
                {
 
 
2979
                    if (ghostDataPtr->HModelController.Sub_Sequence == MRSS_Fire_From_Hips)
 
 
2980
                    {
 
 
2981
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
2982
                        elevation_controller->sub_sequence = (int)MSSS_Hip_Fire_Elevation;
 
 
2983
                    }
 
 
2984
                    else
 
 
2985
                    {
 
 
2986
                        if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineRun,(int)MRSS_Elevation))
 
 
2987
                        {
 
 
2988
                            elevation_controller->sequence_type = HMSQT_MarineRun;
 
 
2989
                            elevation_controller->sub_sequence = (int)MRSS_Elevation;
 
 
2990
                        }
 
 
2991
                        else
 
 
2992
                        {
 
 
2993
                            elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
2994
                            elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
2995
                        }
 
 
2996
                    }
 
 
2997
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
2998
                }
 
 
2999
                else
 
 
3000
                {
 
 
3001
                    if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineRun,(int)MRSS_Elevation))
 
 
3002
                    {
 
 
3003
                        elevation_controller->sequence_type = HMSQT_MarineRun;
 
 
3004
                        elevation_controller->sub_sequence = (int)MRSS_Elevation;
 
 
3005
                    }
 
 
3006
                    else
 
 
3007
                    {
 
 
3008
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3009
                        elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3010
                    }
 
 
3011
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3012
                    break;
 
 
3013
                }
 
 
3014
            case MSQ_StandingFire:
 
 
3015
                if (ghostDataPtr->CurrentWeapon == WEAPON_GRENADELAUNCHER)
 
 
3016
                {
 
 
3017
                    elevation_controller->Active = 0;
 
 
3018
                    ghostDataPtr->HModelController.Looped = 0;
 
 
3019
                    break;
 
 
3020
                }
 
 
3021
                else if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
3022
                {
 
 
3023
                    if (ghostDataPtr->HModelController.Sub_Sequence == MSSS_FireFromHips)
 
 
3024
                    {
 
 
3025
                        elevation_controller->sequence_type= HMSQT_MarineStand;
 
 
3026
                        elevation_controller->sub_sequence = (int)MSSS_Hip_Fire_Elevation;
 
 
3027
                    }
 
 
3028
                    else
 
 
3029
                    {
 
 
3030
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3031
                        elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3032
                    }
 
 
3033
 
 
 
3034
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3035
                }
 
 
3036
                else
 
 
3037
                {
 
 
3038
                    elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3039
                    elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3040
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3041
                    break;
 
 
3042
                }
 
 
3043
            case MSQ_Walk:
 
 
3044
            case MSQ_Walk_Backwards:
 
 
3045
                if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
3046
                {
 
 
3047
                    if (ghostDataPtr->HModelController.Sub_Sequence == MRSS_Fire_From_Hips)
 
 
3048
                    {
 
 
3049
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3050
                        elevation_controller->sub_sequence = (int)MSSS_Hip_Fire_Elevation;
 
 
3051
                    }
 
 
3052
                    else
 
 
3053
                    {
 
 
3054
                        if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineRun,(int)MRSS_Elevation))
 
 
3055
                        {
 
 
3056
                            elevation_controller->sequence_type = HMSQT_MarineRun;
 
 
3057
                            elevation_controller->sub_sequence = (int)MRSS_Elevation;
 
 
3058
                        }
 
 
3059
                        else
 
 
3060
                        {
 
 
3061
                            elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3062
                            elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3063
                        }
 
 
3064
                    }
 
 
3065
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3066
                }
 
 
3067
                else
 
 
3068
                {
 
 
3069
                    if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineRun,(int)MRSS_Elevation))
 
 
3070
                    {
 
 
3071
                        elevation_controller->sequence_type = HMSQT_MarineRun;
 
 
3072
                        elevation_controller->sub_sequence = (int)MRSS_Elevation;
 
 
3073
                    }
 
 
3074
                    else
 
 
3075
                    {
 
 
3076
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3077
                        elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3078
                    }
 
 
3079
 
 
 
3080
                    elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3081
                }
 
 
3082
            break;
 
 
3083
            case MSQ_Crawl:
 
 
3084
            case MSQ_Crawl_Backwards:
 
 
3085
                if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
3086
                {
 
 
3087
                    if (ghostDataPtr->HModelController.Sub_Sequence == MCSS_FireFromHips)
 
 
3088
                    {
 
 
3089
                        elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3090
                        elevation_controller->sub_sequence = (int)MCrSS_Hip_Fire_Elevation;
 
 
3091
                    }
 
 
3092
                    else
 
 
3093
                    {
 
 
3094
                        if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineCrawl,(int)MCSS_Elevation))
 
 
3095
                        {
 
 
3096
                            elevation_controller->sequence_type = HMSQT_MarineCrawl;
 
 
3097
                            elevation_controller->sub_sequence = (int)MCSS_Elevation;
 
 
3098
                        }
 
 
3099
                        else
 
 
3100
                        {
 
 
3101
                            elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3102
                            elevation_controller->sub_sequence = (int)MCrSS_Elevation;
 
 
3103
                        }
 
 
3104
                    }
 
 
3105
                }
 
 
3106
                else
 
 
3107
                {
 
 
3108
                    if (HModelSequence_Exists(&ghostDataPtr->HModelController, HMSQT_MarineCrawl,(int)MCSS_Elevation))
 
 
3109
                    {
 
 
3110
                        elevation_controller->sequence_type = HMSQT_MarineCrawl;
 
 
3111
                        elevation_controller->sub_sequence = (int)MCSS_Elevation;
 
 
3112
                    }
 
 
3113
                    else
 
 
3114
                    {
 
 
3115
                        elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3116
                        elevation_controller->sub_sequence = (int)MCrSS_Elevation;
 
 
3117
                    }
 
 
3118
                }
 
 
3119
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3120
            break;
 
 
3121
            case MSQ_Crouch:
 
 
3122
                if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
3123
                {
 
 
3124
                    if (ghostDataPtr->HModelController.Sub_Sequence == MCrSS_FireFromHips)
 
 
3125
                    {
 
 
3126
                        elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3127
                        elevation_controller->sub_sequence = (int)MCrSS_Hip_Fire_Elevation;
 
 
3128
                    }
 
 
3129
                    else
 
 
3130
                    {
 
 
3131
                        elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3132
                        elevation_controller->sub_sequence = (int)MCrSS_Elevation;
 
 
3133
                    }
 
 
3134
                }
 
 
3135
                else
 
 
3136
                {
 
 
3137
                    elevation_controller->sequence_type = HMSQT_MarineCrouch;
 
 
3138
                    elevation_controller->sub_sequence = (int)MCrSS_Elevation;
 
 
3139
                }
 
 
3140
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3141
            break;
 
 
3142
            case MSQ_Stand:
 
 
3143
            case MSQ_Jump:
 
 
3144
            default:
 
 
3145
                if (ghostDataPtr->CurrentWeapon == WEAPON_TWO_PISTOLS)
 
 
3146
                {
 
 
3147
                    if (ghostDataPtr->HModelController.Sub_Sequence == MSSS_FireFromHips)
 
 
3148
                    {
 
 
3149
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3150
                        elevation_controller->sub_sequence = (int)MSSS_Hip_Fire_Elevation;
 
 
3151
                    }
 
 
3152
                    else
 
 
3153
                    {
 
 
3154
                        elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3155
                        elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3156
                    }
 
 
3157
                }
 
 
3158
                else
 
 
3159
                {
 
 
3160
                    elevation_controller->sequence_type = HMSQT_MarineStand;
 
 
3161
                    elevation_controller->sub_sequence = (int)MSSS_Elevation;
 
 
3162
                }
 
 
3163
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3164
        }
 
 
3165
 
 
 
3166
        if ((HModelSequence_Exists(&ghostDataPtr->HModelController,elevation_controller->sequence_type,elevation_controller->sub_sequence))
&& elevation_controller->Active)
 
 
3167
        {
 
 
3168
            elevation_controller->Active = 1;
 
 
3169
        //    printf("Using elevation delta.\n");
 
 
3170
        }
 
 
3171
        else
 
 
3172
        {
 
 
3173
            elevation_controller->Active = 0;
 
 
3174
        }
 
 
3175
    }
 
 
3176
    else if (ghostDataPtr->type == I_BehaviourPredatorPlayer)
 
 
3177
    {
 
 
3178
        if (weapon != ghostDataPtr->CurrentWeapon)
 
 
3179
        {
 
 
3180
            Dispel_HModel(&ghostDataPtr->HModelController);
 
 
3181
            CreatePredatorHModel(ghostDataPtr, weapon);
 
 
3182
            ProveHModel_Far(&ghostDataPtr->HModelController,sbPtr);
 
 
3183
        }
 
 
3184
        elevation_controller = Get_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation");
 
 
3185
        /* Deal with elevation sequence. */
 
 
3186
        assert(elevation_controller);
 
 
3187
        elevation_controller->Active = 1; /* enabled? */
 
 
3188
 
 
 
3189
        switch(ghostDataPtr->currentAnimSequence)
 
 
3190
        {
 
 
3191
            case PredSQ_Taunt:
 
 
3192
            case PredSQ_StandDie:
 
 
3193
            case PredSQ_StandDead:
 
 
3194
            case PredSQ_CrouchDie:    
 
 
3195
            case PredSQ_CrouchDead:
 
 
3196
                elevation_controller->Active = 0;
 
 
3197
                /* Force no elevation. */
 
 
3198
            break;
 
 
3199
            case PredSQ_Run:
 
 
3200
            case PredSQ_Run_Backwards:
 
 
3201
            case PredSQ_RunningSwipe:
 
 
3202
            case PredSQ_RunningSwipe_Backwards:
 
 
3203
                elevation_controller->sequence_type = HMSQT_PredatorStand;
 
 
3204
                elevation_controller->sub_sequence = (int)PSSS_Elevation;
 
 
3205
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3206
            break;
 
 
3207
            case PredSQ_Crouch:
 
 
3208
            case PredSQ_CrouchedSwipe:
 
 
3209
                elevation_controller->sequence_type = HMSQT_PredatorCrouch;
 
 
3210
                elevation_controller->sub_sequence = (int)PCrSS_Elevation;
 
 
3211
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3212
            break;
 
 
3213
            case PredSQ_Crawl:
 
 
3214
            case PredSQ_CrawlingSwipe:
 
 
3215
            case PredSQ_Crawl_Backwards:
 
 
3216
            case PredSQ_CrawlingSwipe_Backwards:
 
 
3217
                elevation_controller->sequence_type = HMSQT_PredatorCrouch;
 
 
3218
                elevation_controller->sub_sequence = (int)PCrSS_Elevation;
 
 
3219
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3220
            break;
 
 
3221
            case PredSQ_Jump:
 
 
3222
            case PredSQ_Stand:
 
 
3223
            case PredSQ_StandingSwipe:
 
 
3224
            default:
 
 
3225
                elevation_controller->sequence_type = HMSQT_PredatorStand;
 
 
3226
                elevation_controller->sub_sequence = (int)PSSS_Elevation;
 
 
3227
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3228
        }
 
 
3229
 
 
 
3230
        if ((HModelSequence_Exists(&ghostDataPtr->HModelController,elevation_controller->sequence_type,elevation_controller->sub_sequence))
 
 
3231
            && (elevation_controller->Active))
 
 
3232
        {
 
 
3233
            elevation_controller->Active = 1;
 
 
3234
        }
 
 
3235
        else
 
 
3236
        {
 
 
3237
            elevation_controller->Active = 0;
 
 
3238
        }
 
 
3239
    }
 
 
3240
    else if (ghostDataPtr->type == I_BehaviourAlienPlayer)
 
 
3241
    {
 
 
3242
        if (ghostDataPtr->CurrentWeapon == -1)
 
 
3243
        {
 
 
3244
            //this only happens for aliens , if a player changes character
 
 
3245
            Dispel_HModel(&ghostDataPtr->HModelController);
 
 
3246
            CreateAlienHModel(ghostDataPtr,0);
 
 
3247
            ProveHModel_Far(&ghostDataPtr->HModelController,sbPtr);
 
 
3248
        }
 
 
3249
 
 
 
3250
        elevation_controller = Get_Delta_Sequence(&ghostDataPtr->HModelController,"Elevation");
 
 
3251
        /* Deal with elevation sequence. */
 
 
3252
        assert(elevation_controller);
 
 
3253
        elevation_controller->Active = 1; /* enabled? */
 
 
3254
 
 
 
3255
        switch(ghostDataPtr->currentAnimSequence)
 
 
3256
        {
 
 
3257
            case ASQ_Pain:
 
 
3258
            case ASQ_Jump:
 
 
3259
            case ASQ_Eat:
 
 
3260
            case ASQ_Pounce:
 
 
3261
            case ASQ_JumpingTailPoise:
 
 
3262
            case ASQ_JumpingTailStrike:
 
 
3263
            case ASQ_Taunt:
 
 
3264
                elevation_controller->Active = 0;
 
 
3265
                /* Force no elevation. */
 
 
3266
            break;
 
 
3267
            case ASQ_Crouch:
 
 
3268
            case ASQ_CrouchedAttack_Claw:
 
 
3269
            case ASQ_CrouchedTailPoise:
 
 
3270
            case ASQ_CrouchedTailStrike:
 
 
3271
            case ASQ_Crawl:
 
 
3272
            case ASQ_CrawlingAttack_Claw:
 
 
3273
            case ASQ_CrawlingTailPoise:
 
 
3274
            case ASQ_CrawlingTailStrike:
 
 
3275
            case ASQ_Crawl_Backwards:
 
 
3276
            case ASQ_CrawlingTailPoise_Backwards:
 
 
3277
            case ASQ_CrawlingTailStrike_Backwards:
 
 
3278
            case ASQ_CrawlingAttack_Claw_Backwards:
 
 
3279
            case ASQ_Scamper:
 
 
3280
            case ASQ_Scamper_Backwards:
 
 
3281
            case ASQ_CrouchEat :
 
 
3282
                elevation_controller->sequence_type = HMSQT_AlienCrouch;
 
 
3283
                elevation_controller->sub_sequence = (int)ACrSS_Standard_Elevation;
 
 
3284
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3285
            break;
 
 
3286
            case ASQ_Run:
 
 
3287
            case ASQ_RunningAttack_Claw:
 
 
3288
            case ASQ_RunningTailPoise:
 
 
3289
            case ASQ_RunningTailStrike:
 
 
3290
            case ASQ_Run_Backwards:
 
 
3291
            case ASQ_RunningAttack_Claw_Backwards:
 
 
3292
            case ASQ_RunningTailPoise_Backwards:
 
 
3293
            case ASQ_RunningTailStrike_Backwards:
 
 
3294
            case ASQ_Stand:
 
 
3295
            case ASQ_StandingAttack_Claw:
 
 
3296
            case ASQ_StandingTailPoise:
 
 
3297
            case ASQ_StandingTailStrike:
 
 
3298
                elevation_controller->sequence_type = HMSQT_AlienStand;
 
 
3299
                elevation_controller->sub_sequence = (int)ASSS_Standard_Elevation;
 
 
3300
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3301
            break;
 
 
3302
            default:
 
 
3303
                elevation_controller->sequence_type = HMSQT_AlienStand;
 
 
3304
                elevation_controller->sub_sequence = (int)ASSS_Standard_Elevation;
 
 
3305
                elevation_controller->timer = ExtractTimerFromElevation(elevation);
 
 
3306
        }
 
 
3307
 
 
 
3308
        if ((HModelSequence_Exists(&ghostDataPtr->HModelController,elevation_controller->sequence_type,elevation_controller->sub_sequence))
 
 
3309
            && (elevation_controller->Active))
 
 
3310
            {
 
 
3311
            elevation_controller->Active=1;
 
 
3312
        }
 
 
3313
        else
 
 
3314
        {
 
 
3315
            elevation_controller->Active=0;
 
 
3316
        }
 
 
3317
    }
 
 
3318
}
 
 
3319
 
 
 
3320
/* Patrick 15/7/97 --------------------------------------------------
 
 
3321
Manages the ghost's integrities
 
 
3322
---------------------------------------------------------------------*/
 
 
3323
void MaintainGhosts()
 
 
3324
{
 
 
3325
    int sbIndex = 0;
 
 
3326
 
 
 
3327
    /* only do this when we're playing */
 
 
3328
    if(netGameData.myGameState!=NGS_Playing) return;
 
 
3329
 
 
 
3330
    while(sbIndex < NumActiveStBlocks)
 
 
3331
    {    
 
 
3332
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++];
 
 
3333
 
 
 
3334
        if(sbPtr->type == I_BehaviourNetGhost)
 
 
3335
        {
 
 
3336
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3337
            assert(ghostData);            
 
 
3338
            ghostData->integrity -= NormalFrameTime;
 
 
3339
 
 
 
3340
            if(ghostData->integrity < 0)
 
 
3341
            {
 
 
3342
                RemoveGhost(sbPtr);
 
 
3343
            }
 
 
3344
 
 
 
3345
            else
 
 
3346
            switch (ghostData->type)
 
 
3347
            {
 
 
3348
                case I_BehaviourFlare:
 
 
3349
                {
 
 
3350
                    if (ghostData->timer > ONE_FIXED*4)
 
 
3351
                        ghostData->currentAnimSequence += NormalFrameTime;
 
 
3352
                    else
 
 
3353
                        ghostData->currentAnimSequence += MUL_FIXED(NormalFrameTime,ghostData->timer)/4;
 
 
3354
 
 
 
3355
                    while (ghostData->currentAnimSequence >= FLARE_PARTICLE_GENERATION_TIME)
 
 
3356
                    {
 
 
3357
                        ghostData->currentAnimSequence -= FLARE_PARTICLE_GENERATION_TIME;
 
 
3358
                        MakeFlareParticle(sbPtr->DynPtr);
 
 
3359
                    }
 
 
3360
 
 
 
3361
                    /* add lighting effect if near */
 
 
3362
                    if (sbPtr->DisplayBlock)
 
 
3363
                    {
 
 
3364
                        LIGHTBLOCK *lightPtr = sbPtr->DisplayBlock->ObLights[0];
 
 
3365
                        assert(sbPtr->DisplayBlock->ObNumLights==1);
 
 
3366
                        assert(lightPtr);
 
 
3367
                        lightPtr->LightBright = 1 + MUL_FIXED((ONE_FIXED*4-(FastRandom()&32767)), ghostData->timer/FLARE_LIFETIME);
 
 
3368
                    }
 
 
3369
                       ghostData->timer -= NormalFrameTime;
 
 
3370
 
 
 
3371
                    //Stop flare from disappearing from lack of update messages.
 
 
3372
                    //This is so the number of meessages sent can be reduced when the flare has stopped moving.
 
 
3373
                    ghostData->integrity = ghostData->timer;
 
 
3374
 
 
 
3375
                }
 
 
3376
                break;
 
 
3377
                case I_BehaviourProximityGrenade:
 
 
3378
                {
 
 
3379
                    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
3380
                    assert(dynPtr);
 
 
3381
                    if (ghostData->timer <= PROX_GRENADE_LIFETIME*ONE_FIXED)
 
 
3382
                    {
 
 
3383
                        {
 
 
3384
                            int scale = ONE_FIXED-ghostData->timer/PROX_GRENADE_LIFETIME;
 
 
3385
                            scale = MUL_FIXED(scale,scale);
 
 
3386
                            scale = MUL_FIXED(scale,scale)*8;
 
 
3387
 
 
 
3388
                            ghostData->currentAnimSequence += NormalFrameTime + MUL_FIXED(NormalFrameTime,scale);
 
 
3389
                           }
 
 
3390
 
 
 
3391
                        while (ghostData->currentAnimSequence >= PROX_GRENADE_SOUND_GENERATION_TIME)
 
 
3392
                        {
 
 
3393
                            ghostData->currentAnimSequence -= PROX_GRENADE_SOUND_GENERATION_TIME;
 
 
3394
                            Sound_Play(SID_PROX_GRENADE_ACTIVE, "d", &dynPtr->Position);
 
 
3395
                        }
 
 
3396
 
 
 
3397
                           ghostData->timer -= NormalFrameTime;
 
 
3398
 
 
 
3399
                           if (ghostData->timer <= PROX_GRENADE_TRIGGER_TIME && ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
3400
                            Sound_Play(SID_PROX_GRENADE_READYTOBLOW, "de", &dynPtr->Position, &ghostData->SoundHandle);
 
 
3401
 
 
 
3402
                        //Stop flare from disappearing from lack of update messages.
 
 
3403
                        //This is so the number of meessages sent can be reduced when the flare has stopped moving.
 
 
3404
                    }
 
 
3405
                    else
 
 
3406
                    {
 
 
3407
                        if(!DynamicObjectIsMoving(dynPtr))
 
 
3408
                            ghostData->timer = PROX_GRENADE_LIFETIME * ONE_FIXED;        
 
 
3409
                    }
 
 
3410
 
 
 
3411
                    if(ValidTargetForProxMine(sbPtr))
 
 
3412
                    {
 
 
3413
                        if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
3414
                        {
 
 
3415
                            if (ActiveSounds[ghostData->SoundHandle].soundIndex != SID_PROX_GRENADE_READYTOBLOW)
 
 
3416
                                Sound_Stop(ghostData->SoundHandle);
 
 
3417
 
 
 
3418
                            Sound_Play(SID_PROX_GRENADE_READYTOBLOW, "de", &dynPtr->Position, &ghostData->SoundHandle);
 
 
3419
                        }
 
 
3420
                    }
 
 
3421
 
 
 
3422
                    ghostData->integrity = ghostData->timer;
 
 
3423
                    break;
 
 
3424
                }
 
 
3425
                default:
 
 
3426
                    break;                
 
 
3427
            }
 
 
3428
        }
 
 
3429
    }
 
 
3430
}
 
 
3431
 
 
 
3432
#define AGUNGHOST_FIRINGPOINT_INFRONT    500
 
 
3433
#define AGUNGHOST_FIRINGPOINT_ACROSS    0
 
 
3434
#define AGUNGHOST_FIRINGPOINT_UP    200
 
 
3435
 
 
 
3436
static void CalculatePosnForGhostAutoGunMuzzleFlash(STRATEGYBLOCK *sbPtr,VECTORCH *position, EULER *orientation)
 
 
3437
{
 
 
3438
    VECTORCH upNormal = {0,-65536,0};
 
 
3439
    VECTORCH inFrontVec = {0,0,0};
 
 
3440
    VECTORCH toSideVec = {0,0,0};
 
 
3441
    EULER firingOrient = {0,0,0};
 
 
3442
 
 
 
3443
    /* orientation is easy */
 
 
3444
    firingOrient.EulerY = sbPtr->DynPtr->OrientEuler.EulerY;
 
 
3445
    *orientation = firingOrient;
 
 
3446
 
 
 
3447
    /* vector in front */
 
 
3448
    inFrontVec.vx = sine[firingOrient.EulerY];
 
 
3449
    inFrontVec.vz = cosine[firingOrient.EulerY];
 
 
3450
    Normalise(&inFrontVec);
 
 
3451
 
 
 
3452
    /* vectors in front, to side, and up */
 
 
3453
    CrossProduct(&inFrontVec,&upNormal,&toSideVec);
 
 
3454
    assert(toSideVec.vy == 0);
 
 
3455
    inFrontVec.vx = MUL_FIXED(inFrontVec.vx,AGUNGHOST_FIRINGPOINT_INFRONT);
 
 
3456
    inFrontVec.vz = MUL_FIXED(inFrontVec.vz,AGUNGHOST_FIRINGPOINT_INFRONT);
 
 
3457
    toSideVec.vx = MUL_FIXED(toSideVec.vx,AGUNGHOST_FIRINGPOINT_ACROSS);
 
 
3458
    toSideVec.vz = MUL_FIXED(toSideVec.vz,AGUNGHOST_FIRINGPOINT_ACROSS);
 
 
3459
 
 
 
3460
    position->vx = sbPtr->DynPtr->Position.vx + inFrontVec.vx +    toSideVec.vx;
 
 
3461
    position->vy = sbPtr->DynPtr->Position.vy - AGUNGHOST_FIRINGPOINT_UP;
 
 
3462
    position->vz = sbPtr->DynPtr->Position.vz + inFrontVec.vz +    toSideVec.vz;
 
 
3463
}
 
 
3464
 
 
 
3465
void HandleGhostAutoGunMuzzleFlash(STRATEGYBLOCK *sbPtr, int firing)
 
 
3466
{
 
 
3467
    assert(sbPtr);
 
 
3468
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3469
    assert(ghostData);
 
 
3470
    assert(ghostData->type == I_BehaviourAutoGun);
 
 
3471
 
 
 
3472
    if(ghostData->myGunFlash)
 
 
3473
    {
 
 
3474
        /* I've already got a gun flash... */
 
 
3475
        if(firing)
 
 
3476
        {
 
 
3477
            /* Maintain existing gun flash */
 
 
3478
            VECTORCH position;
 
 
3479
            EULER orientation;
 
 
3480
            MATRIXCH mat;
 
 
3481
            CalculatePosnForGhostAutoGunMuzzleFlash(sbPtr, &position, &orientation);
 
 
3482
 
 
 
3483
            CreateEulerMatrix(&orientation, &mat);
 
 
3484
            TransposeMatrixCH(&mat);    
 
 
3485
 
 
 
3486
            ghostData->myGunFlash->ObWorld  = position;
 
 
3487
            ghostData->myGunFlash->ObMat = mat;
 
 
3488
            AddLightingEffectToObject(ghostData->myGunFlash, LFX_MUZZLEFLASH);
 
 
3489
        }
 
 
3490
        else
 
 
3491
        {
 
 
3492
            DestroyActiveObject(&ghostData->myGunFlash);
 
 
3493
        } 
 
 
3494
    }
 
 
3495
    else if(firing)
 
 
3496
    {
 
 
3497
        /* Need a new gun flash */
 
 
3498
        VECTORCH position;
 
 
3499
        EULER orientation;
 
 
3500
        MATRIXCH mat;
 
 
3501
        CalculatePosnForGhostAutoGunMuzzleFlash(sbPtr, &position, &orientation);
 
 
3502
        CreateEulerMatrix(&orientation, &mat);
 
 
3503
        TransposeMatrixCH(&mat);    
 
 
3504
        ghostData->myGunFlash = AddNPCGunFlashEffect(&position, &mat, SFX_MUZZLE_FLASH_AMORPHOUS);
 
 
3505
    }
 
 
3506
}
 
 
3507
 
 
 
3508
void HandleGhostAutoGunSound(STRATEGYBLOCK *sbPtr, int firing)
 
 
3509
{
 
 
3510
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3511
 
 
 
3512
    if(firing)
 
 
3513
    {
 
 
3514
        if(ghostData->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
3515
            Sound_Play(SID_SENTRY_GUN, "eld", &ghostData->SoundHandle, &sbPtr->DynPtr->Position);                    
 
 
3516
        /* don't need sound update, as autoguns don't move */
 
 
3517
    }
 
 
3518
    else if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX) 
 
 
3519
    {    
 
 
3520
        Sound_Stop(ghostData->SoundHandle);                
 
 
3521
        Sound_Play(SID_SENTRY_END, "hd", &sbPtr->DynPtr->Position);                    
 
 
3522
    }
 
 
3523
}
 
 
3524
 
 
 
3525
/* patrick 14/10/97 : added to support cloaked predators in net game */
 
 
3526
void MaintainGhostCloakingStatus(STRATEGYBLOCK *sbPtr, int IsCloaked)
 
 
3527
{
 
 
3528
    assert(sbPtr);
 
 
3529
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3530
    assert(ghostData);
 
 
3531
    AVP_BEHAVIOUR_TYPE type = ghostData->type;
 
 
3532
 
 
 
3533
    if(type != I_BehaviourPredatorPlayer) 
 
 
3534
    {
 
 
3535
        ghostData->CloakingEffectiveness = 0;        
 
 
3536
        return;
 
 
3537
    }
 
 
3538
 
 
 
3539
    /* Handle sound playing. */
 
 
3540
    if (ghostData->CloakingEffectiveness)
 
 
3541
    {
 
 
3542
        if (!IsCloaked)
 
 
3543
        {
 
 
3544
            /* Cloak turns off. */
 
 
3545
            Sound_Play(SID_PRED_CLOAKOFF, "hd", &sbPtr->DynPtr->Position);
 
 
3546
        }
 
 
3547
    }
 
 
3548
    else
 
 
3549
    {
 
 
3550
        if (IsCloaked)
 
 
3551
        {
 
 
3552
            /* Cloak turns on. */
 
 
3553
            Sound_Play(SID_PRED_CLOAKON, "hd", &sbPtr->DynPtr->Position);
 
 
3554
        }
 
 
3555
    }
 
 
3556
 
 
 
3557
    ghostData->CloakingEffectiveness = IsCloaked;
 
 
3558
}
 
 
3559
 
 
 
3560
/* KJL 14:18:32 27/01/98 - object behaviour for network ghosts */
 
 
3561
void NetGhostBehaviour(STRATEGYBLOCK *sbPtr)
 
 
3562
{
 
 
3563
    assert(sbPtr);
 
 
3564
 
 
 
3565
    NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3566
    assert(ghostDataPtr);
 
 
3567
 
 
 
3568
    switch(ghostDataPtr->type)
 
 
3569
    {
 
 
3570
        case I_BehaviourCorpse:
 
 
3571
        {
 
 
3572
            /* A copy of the fn. for real ones, minus existance. */
 
 
3573
            DISPLAYBLOCK *dispPtr = sbPtr->DisplayBlock;
 
 
3574
 
 
 
3575
            /* do we have a displayblock? */
 
 
3576
            if (dispPtr)
 
 
3577
            {
 
 
3578
                dispPtr->SpecialFXFlags |= SFXFLAG_MELTINGINTOGROUND;
 
 
3579
                dispPtr->ObFlags2 = ghostDataPtr->timer/2;
 
 
3580
            }
 
 
3581
 
 
 
3582
            /* Does the corpse that falls when not visible make no sound? */
 
 
3583
            ProveHModel_Far(&ghostDataPtr->HModelController,sbPtr);
 
 
3584
            ghostDataPtr->timer -= NormalFrameTime;
 
 
3585
        }
 
 
3586
        default:
 
 
3587
            break;
 
 
3588
    }
 
 
3589
 
 
 
3590
    if (sbPtr->DisplayBlock)
 
 
3591
    {
 
 
3592
        if (sbPtr->DisplayBlock->HModelControlBlock)
 
 
3593
        {
 
 
3594
            /* Fire sound code. */
 
 
3595
            if(ghostDataPtr->SoundHandle3 != SOUND_NOACTIVEINDEX)
 
 
3596
                Sound_Update3d(ghostDataPtr->SoundHandle3,&(sbPtr->DynPtr->Position));
 
 
3597
 
 
 
3598
            if(ghostDataPtr->SoundHandle4 != SOUND_NOACTIVEINDEX)
 
 
3599
                Sound_Update3d(ghostDataPtr->SoundHandle4,&(sbPtr->DynPtr->Position));
 
 
3600
 
 
 
3601
            if (sbPtr->DamageBlock.IsOnFire)
 
 
3602
            {
 
 
3603
                if (!ghostDataPtr->IgnitionHandshaking)
 
 
3604
                    AddNetMsg_LocalObjectOnFire(sbPtr);
 
 
3605
 
 
 
3606
                if (ghostDataPtr->SoundHandle3 != SOUND_NOACTIVEINDEX)
 
 
3607
                {
 
 
3608
                    if (ActiveSounds[ghostDataPtr->SoundHandle3].soundIndex != SID_FIRE)
 
 
3609
                    {
 
 
3610
                        Sound_Stop(ghostDataPtr->SoundHandle3);
 
 
3611
                         Sound_Play(SID_FIRE, "dle", &sbPtr->DynPtr->Position, &ghostDataPtr->SoundHandle3);
 
 
3612
                    }
 
 
3613
                }
 
 
3614
                else
 
 
3615
                {
 
 
3616
                     Sound_Play(SID_FIRE, "dle", &sbPtr->DynPtr->Position, &ghostDataPtr->SoundHandle3);
 
 
3617
                }
 
 
3618
            }
 
 
3619
            else
 
 
3620
            {
 
 
3621
                if (ghostDataPtr->SoundHandle3 != SOUND_NOACTIVEINDEX)
 
 
3622
                    Sound_Stop(ghostDataPtr->SoundHandle3);
 
 
3623
            }
 
 
3624
        }
 
 
3625
    }
 
 
3626
 
 
 
3627
    if(ghostDataPtr->FlameHitCount)
 
 
3628
    {
 
 
3629
        //send a damage message for all the flame particles that have hit
 
 
3630
        CauseDamageToObject(sbPtr,&TemplateAmmo[AMMO_FLAMETHROWER].MaxDamage, (ONE_FIXED/400)*ghostDataPtr->FlameHitCount,NULL);
 
 
3631
        ghostDataPtr->FlameHitCount = 0;
 
 
3632
 
 
 
3633
    }
 
 
3634
 
 
 
3635
    if(ghostDataPtr->FlechetteHitCount)
 
 
3636
    {
 
 
3637
        //send a damage message for all the flechette particles that have hit
 
 
3638
        CauseDamageToObject(sbPtr, &damage_profiles[FLECHETTEDAMAGE], ONE_FIXED*ghostDataPtr->FlechetteHitCount, NULL);
 
 
3639
        ghostDataPtr->FlechetteHitCount = 0;
 
 
3640
    }
 
 
3641
}
 
 
3642
 
 
 
3643
void MaintainGhostFireStatus(STRATEGYBLOCK *sbPtr, int IsOnFire)
 
 
3644
{
 
 
3645
    assert(sbPtr);
 
 
3646
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3647
    assert(ghostData);
 
 
3648
 
 
 
3649
    if (IsOnFire)
 
 
3650
    {
 
 
3651
        if (!ghostData->IgnitionHandshaking)
 
 
3652
        {
 
 
3653
            /* Recieved confirmation. */
 
 
3654
            ghostData->IgnitionHandshaking = 1;
 
 
3655
            if (!sbPtr->DamageBlock.IsOnFire)
 
 
3656
            {
 
 
3657
                /* Set alight by something else? */
 
 
3658
                sbPtr->DamageBlock.IsOnFire = 1;
 
 
3659
            }
 
 
3660
        }
 
 
3661
        /*
 
 
3662
        else
 
 
3663
             Corroberated - do nothing.
 
 
3664
        */
 
 
3665
    }
 
 
3666
    else
 
 
3667
    {
 
 
3668
        if (ghostData->IgnitionHandshaking)
 
 
3669
        {
 
 
3670
            /* Fire gone out? */
 
 
3671
            ghostData->IgnitionHandshaking = 0;
 
 
3672
            sbPtr->DamageBlock.IsOnFire = 0;
 
 
3673
        }
 
 
3674
        /*
 
 
3675
        else
 
 
3676
             Corroberated - do nothing.
 
 
3677
        */
 
 
3678
    }
 
 
3679
}
 
 
3680
 
 
 
3681
/* Kills a ghost, to leave a corpse */
 
 
3682
void KillGhost(STRATEGYBLOCK *sbPtr,int objectId)
 
 
3683
{
 
 
3684
    assert(sbPtr);
 
 
3685
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3686
    assert(ghostData);
 
 
3687
 
 
 
3688
    /* this is where we add fragmentation and explosion    effects to destroyed ghosts */
 
 
3689
    switch(ghostData->type)
 
 
3690
    {
 
 
3691
        case I_BehaviourAlienPlayer:
 
 
3692
        case I_BehaviourMarinePlayer:
 
 
3693
        case I_BehaviourPredatorPlayer:    
 
 
3694
            /* Drop through, for the moment. */
 
 
3695
            #if EXTRAPOLATION_TEST
 
 
3696
            sbPtr->DynPtr->LinImpulse.vx = 0;
 
 
3697
            sbPtr->DynPtr->LinImpulse.vy = 0;
 
 
3698
            sbPtr->DynPtr->LinImpulse.vz = 0;
 
 
3699
               sbPtr->DynPtr->LinVelocity.vx = 0;
 
 
3700
            sbPtr->DynPtr->LinVelocity.vy = 0;
 
 
3701
            sbPtr->DynPtr->LinVelocity.vz = 0;
 
 
3702
            sbPtr->DynPtr->UseStandardGravity = 1;
 
 
3703
            sbPtr->DynPtr->IsNetGhost = 1;
 
 
3704
            sbPtr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
3705
            #endif
 
 
3706
        break;
 
 
3707
        case I_BehaviourGrenade:
 
 
3708
        case I_BehaviourRocket:
 
 
3709
        case I_BehaviourProximityGrenade:
 
 
3710
        case I_BehaviourFragmentationGrenade:
 
 
3711
        case I_BehaviourPulseGrenade:
 
 
3712
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
3713
        case I_BehaviourInanimateObject:
 
 
3714
        default:
 
 
3715
        {
 
 
3716
            /* Default to something else. */
 
 
3717
            RemoveGhost(sbPtr);
 
 
3718
            return;
 
 
3719
            break;
 
 
3720
        }
 
 
3721
    }
 
 
3722
 
 
 
3723
    /* see if we've got a sound... */
 
 
3724
    if(ghostData->SoundHandle  != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle);
 
 
3725
    if(ghostData->SoundHandle2 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle2);
 
 
3726
    if(ghostData->SoundHandle3 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle3);
 
 
3727
    if(ghostData->SoundHandle4 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle4);
 
 
3728
 
 
 
3729
    DestroyActiveObject(&ghostData->myGunFlash);
 
 
3730
 
 
 
3731
    /* Now.. you're a ghost.  Of a corpse. */
 
 
3732
 
 
 
3733
/*--------------------------------------------------------------------**
 
 
3734
**     The animation sequence we should use will come in a later message **
 
 
3735
**--------------------------------------------------------------------*/
 
 
3736
 
 
 
3737
    ghostData->subtype = ghostData->type;
 
 
3738
    ghostData->type = I_BehaviourCorpse;
 
 
3739
    ghostData->IOType = IOT_Non;
 
 
3740
    ghostData->playerObjectId = objectId;
 
 
3741
    ghostData->timer = CORPSE_EXPIRY_TIME; /* Arbitrarily */
 
 
3742
 
 
 
3743
    if (ghostData->HModelController.Deltas)
 
 
3744
        RemoveAllDeltas(&ghostData->HModelController);
 
 
3745
 
 
 
3746
    sbPtr->DynPtr->OnlyCollideWithEnvironment = 1;
 
 
3747
 
 
 
3748
    //allow the corpse to fall to the floor
 
 
3749
    sbPtr->DynPtr->GravityOn = 1;
 
 
3750
}
 
 
3751
 
 
 
3752
void ApplyGhostCorpseDeathAnim(STRATEGYBLOCK *sbPtr,int deathId)
 
 
3753
{
 
 
3754
    extern DEATH_DATA Marine_Deaths[];
 
 
3755
    extern DEATH_DATA Predator_Deaths[];
 
 
3756
    DEATH_DATA* this_death;
 
 
3757
 
 
 
3758
    assert(sbPtr);
 
 
3759
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3760
    assert(ghostData);
 
 
3761
 
 
 
3762
    if(ghostData->type != I_BehaviourCorpse)
 
 
3763
        return;
 
 
3764
 
 
 
3765
    switch(ghostData->subtype)
 
 
3766
    {
 
 
3767
        case I_BehaviourMarinePlayer:
 
 
3768
        {
 
 
3769
            this_death = GetThisDeath_FromCode(&Marine_Deaths[0],deathId);
 
 
3770
            if (this_death->Template) 
 
 
3771
            {
 
 
3772
                const SECTION* template_root = GetNamedHierarchyFromLibrary("hnpcmarine","Template");
 
 
3773
                assert(template_root);
 
 
3774
                /* Convert to template. */
 
 
3775
                Transmogrify_HModels(sbPtr,&ghostData->HModelController, template_root, 0, 0,0);
 
 
3776
            }
 
 
3777
            else
 
 
3778
            {
 
 
3779
                const SECTION* template_root = GetNamedHierarchyFromLibrary("hnpcmarine","Template");
 
 
3780
                assert(template_root);
 
 
3781
                /* Convert to template. */
 
 
3782
                TrimToTemplate(sbPtr, &ghostData->HModelController, template_root, 0);
 
 
3783
            }
 
 
3784
        }
 
 
3785
        break;
 
 
3786
        case I_BehaviourPredatorPlayer:
 
 
3787
        {
 
 
3788
            this_death = GetThisDeath_FromCode(&Predator_Deaths[0],deathId);
 
 
3789
            if (this_death->Template) 
 
 
3790
            {
 
 
3791
                const SECTION* template_root = GetNamedHierarchyFromLibrary("hnpcpredator","Template");
 
 
3792
                assert(template_root);
 
 
3793
                /* Convert to template. */
 
 
3794
                Transmogrify_HModels(sbPtr,&ghostData->HModelController, template_root, 1, 0,0);
 
 
3795
            }
 
 
3796
        }
 
 
3797
        break;
 
 
3798
        case I_BehaviourAlienPlayer :
 
 
3799
            this_death = GetThisDeath_FromCode(&Alien_Deaths[0], deathId);
 
 
3800
        break;
 
 
3801
        default :
 
 
3802
            return;
 
 
3803
    }
 
 
3804
 
 
 
3805
    if(this_death->TweeningTime <= 0)
 
 
3806
        InitHModelSequence(&ghostData->HModelController,this_death->Sequence_Type,this_death->Sub_Sequence,this_death->Sequence_Length);
 
 
3807
    else
 
 
3808
        InitHModelTweening(&ghostData->HModelController,
this_death->TweeningTime,this_death->Sequence_Type,this_death->Sub_Sequence,this_death->Sequence_Length,0);
 
 
3809
 
 
 
3810
    /* Electric death sound? */
 
 
3811
    if (this_death->Electrical)
 
 
3812
        Sound_Play(SID_ELEC_DEATH, "de", &sbPtr->DynPtr->Position, &ghostData->SoundHandle4);
 
 
3813
}
 
 
3814
 
 
 
3815
void UpdateAlienAIGhostAnimSequence(STRATEGYBLOCK *sbPtr,HMODEL_SEQUENCE_TYPES type, int subtype, int length, int tweeningtime)
 
 
3816
{
 
 
3817
    assert(sbPtr);
 
 
3818
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3819
 
 
 
3820
    assert(length != 0);
 
 
3821
 
 
 
3822
    /* Are we already playing this one? */
 
 
3823
    if ((ghostData->HModelController.Sequence_Type == type) && (ghostData->HModelController.Sub_Sequence == subtype))
 
 
3824
    {
 
 
3825
        /* Yes, but... */
 
 
3826
        /*I think we only want to change speed if we're not tweening*/
 
 
3827
        if (tweeningtime <= 0)
 
 
3828
        {
 
 
3829
            if (length != ghostData->HModelController.Seconds_For_Sequence)
 
 
3830
                HModel_ChangeSpeed(&ghostData->HModelController,length);
 
 
3831
        }
 
 
3832
 
 
 
3833
    }
 
 
3834
    else if (tweeningtime <= 0)
 
 
3835
    {
 
 
3836
        InitHModelSequence(&ghostData->HModelController,(int)type,subtype,length);
 
 
3837
    }
 
 
3838
    else
 
 
3839
    {
 
 
3840
        InitHModelTweening(&ghostData->HModelController, tweeningtime, (int)type,subtype,length, 1);
 
 
3841
    }
 
 
3842
 
 
 
3843
    ghostData->HModelController.Playing=1;
 
 
3844
    /* Might be unset... */
 
 
3845
}
 
 
3846
 
 
 
3847
void KillAlienAIGhost(STRATEGYBLOCK *sbPtr,int death_code,int death_time,int GibbFactor)
 
 
3848
{
 
 
3849
    DEATH_DATA *this_death;
 
 
3850
 
 
 
3851
    assert(sbPtr);
 
 
3852
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3853
    assert(ghostData);
 
 
3854
 
 
 
3855
    /* To ensure we know what we're doing... */
 
 
3856
    #if DEBUG
 
 
3857
    if (ghostData->type != I_BehaviourAlien)
 
 
3858
    {
 
 
3859
        assert(0);
 
 
3860
    }
 
 
3861
    #endif
 
 
3862
 
 
 
3863
    if(ghostData->onlyValidFar)
 
 
3864
    {
 
 
3865
        RemoveGhost(sbPtr);
 
 
3866
        return;
 
 
3867
    }
 
 
3868
 
 
 
3869
    this_death = GetThisDeath_FromCode(Alien_Deaths, death_code);
 
 
3870
    assert(this_death);
 
 
3871
 
 
 
3872
    /* see if we've got a sound... */
 
 
3873
    if(ghostData->SoundHandle  != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle);
 
 
3874
    if(ghostData->SoundHandle2 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle2);
 
 
3875
    if(ghostData->SoundHandle3 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle3);
 
 
3876
    if(ghostData->SoundHandle4 != SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle4);
 
 
3877
 
 
 
3878
    DestroyActiveObject(&ghostData->myGunFlash);
 
 
3879
 
 
 
3880
    /* Convert that sucker. */
 
 
3881
    ghostData->type = I_BehaviourCorpse;
 
 
3882
    /*
 
 
3883
    Alien subtype (alien/predalien/praetorian) gets shuffled down into IOType.
 
 
3884
    Not entirely appropriate , but it will do...
 
 
3885
    */
 
 
3886
    ghostData->IOType = ghostData->subtype;
 
 
3887
    ghostData->subtype = I_BehaviourAlien;
 
 
3888
    ghostData->timer = death_time;
 
 
3889
 
 
 
3890
    if (ghostData->HModelController.Deltas)
 
 
3891
        RemoveAllDeltas(&ghostData->HModelController);
 
 
3892
 
 
 
3893
    /* Now let's do the sequence. */
 
 
3894
     UpdateAlienAIGhostAnimSequence(sbPtr,this_death->Sequence_Type,this_death->Sub_Sequence, this_death->Sequence_Length,this_death->TweeningTime);
 
 
3895
    ghostData->HModelController.LoopAfterTweening = 0;
 
 
3896
 
 
 
3897
    //Allow players to walk through the corpse
 
 
3898
    sbPtr->DynPtr->OnlyCollideWithEnvironment = 1;
 
 
3899
 
 
 
3900
#if EXTRAPOLATION_TEST
 
 
3901
    sbPtr->DynPtr->LinImpulse.vx = 0;
 
 
3902
    sbPtr->DynPtr->LinImpulse.vy = 0;
 
 
3903
    sbPtr->DynPtr->LinImpulse.vz = 0;
 
 
3904
    sbPtr->DynPtr->LinVelocity.vx = 0;
 
 
3905
    sbPtr->DynPtr->LinVelocity.vy = 0;
 
 
3906
    sbPtr->DynPtr->LinVelocity.vz = 0;
 
 
3907
    sbPtr->DynPtr->UseStandardGravity = 1;
 
 
3908
    sbPtr->DynPtr->IsNetGhost = 1;
 
 
3909
    sbPtr->DynPtr->ToppleForce = TOPPLE_FORCE_NONE;
 
 
3910
#endif
 
 
3911
    //allow the corpse to fall to the floor
 
 
3912
    sbPtr->DynPtr->GravityOn = 1;
 
 
3913
 
 
 
3914
    //if (GibbFactor) Extreme_Gibbing(sbPtr,ghostData->HModelController.section_data,GibbFactor); // jadda
 
 
3915
 
 
 
3916
    /* Electric death sound? */
 
 
3917
    if (this_death->Electrical)
 
 
3918
        Sound_Play(SID_ELEC_DEATH, "de", &sbPtr->DynPtr->Position, &ghostData->SoundHandle4);
 
 
3919
}
 
 
3920
 
 
 
3921
/* This a copy of UpdateGhost, with extra parameters. */
 
 
3922
void UpdateAlienAIGhost(STRATEGYBLOCK *sbPtr,VECTORCH *position,EULER *orientation,int sequence_type,int sub_sequence, int sequence_length)
 
 
3923
{
 
 
3924
    assert(sbPtr);
 
 
3925
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
3926
 
 
 
3927
    /* for visibility support: as ghosts can be moved when invisible, we need to work out
 
 
3928
    which module they're in    whenever we update them. We must be carefull, however, not
 
 
3929
    to set the containingModule to NULL if the object has moved outside the env, as 
 
 
3930
    the    visibility system expects that we at least know what module any object WAS in,
 
 
3931
    even if we do not now... thus, if we cannot find a containing module, we abort the update */
 
 
3932
 
 
 
3933
    /* KJL 21:01:09 23/05/98 - I've put this test here because the player's image in a mirror goes
 
 
3934
    throught this code, and it's obviously going to be outside the environment */
 
 
3935
 
 
 
3936
    if (sbPtr->type == I_BehaviourNetGhost)
 
 
3937
    {
 
 
3938
        MODULE *myContainingModule = ModuleFromPosition(position, (sbPtr->containingModule));
 
 
3939
 
 
 
3940
        if(myContainingModule == NULL)
 
 
3941
            return;    
 
 
3942
 
 
 
3943
        sbPtr->containingModule = myContainingModule;
 
 
3944
    }
 
 
3945
 
 
 
3946
    #if DEBUG
 
 
3947
    if (ghostData->type != I_BehaviourAlien)
 
 
3948
    {
 
 
3949
        assert(0);
 
 
3950
    }
 
 
3951
    #endif
 
 
3952
 
 
 
3953
    //We have enough information to be able to make this alien near (should we want to)
 
 
3954
    ghostData->onlyValidFar = 0;
 
 
3955
 
 
 
3956
    /* update the dynamics block */
 
 
3957
    {
 
 
3958
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
3959
 
 
 
3960
        dynPtr->PrevPosition = dynPtr->Position;
 
 
3961
        dynPtr->PrevOrientMat = dynPtr->OrientMat;
 
 
3962
        dynPtr->Position = *position;
 
 
3963
        dynPtr->OrientEuler = *orientation;
 
 
3964
        CreateEulerMatrix(&dynPtr->OrientEuler,&dynPtr->OrientMat);
 
 
3965
        TransposeMatrixCH(&dynPtr->OrientMat);
 
 
3966
    }
 
 
3967
 
 
 
3968
    /* KJL 16:58:04 17/06/98 - we want to update anims differently for NPCS */
 
 
3969
    if ((sequence_type != -1) && (sub_sequence != -1))
 
 
3970
    {
 
 
3971
        /* Not tweening! */
 
 
3972
        UpdateAlienAIGhostAnimSequence(sbPtr,sequence_type,sub_sequence,sequence_length,(ONE_FIXED>>2));
 
 
3973
    }
 
 
3974
 
 
 
3975
    /* refresh integrity */
 
 
3976
    ghostData->integrity = GHOST_INTEGRITY;        
 
 
3977
}
 
 
3978
 
 
 
3979
void Convert_DiscGhost_To_PickupGhost(STRATEGYBLOCK *sbPtr)
 
 
3980
{
 
 
3981
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
3982
    NETGHOSTDATABLOCK *ghostData= (NETGHOSTDATABLOCK * ) sbPtr->dataptr;
 
 
3983
    /* Transmogrify a disc ghost behaviour to a disc ammo pickup! */
 
 
3984
 
 
 
3985
    /* Sort out dynamics block */
 
 
3986
    dynPtr->LinVelocity.vx = dynPtr->LinVelocity.vy = dynPtr->LinVelocity.vz = 0;
 
 
3987
    dynPtr->LinImpulse.vx = dynPtr->LinImpulse.vy = dynPtr->LinImpulse.vz = 0;
 
 
3988
 
 
 
3989
    ghostData->type = I_BehaviourInanimateObject;
 
 
3990
    ghostData->IOType = IOT_Ammo;
 
 
3991
    ghostData->subtype = AMMO_PRED_DISC;
 
 
3992
 
 
 
3993
    ghostData->HModelController.Playing = 0;
 
 
3994
    /* Deal with flip up case? */
 
 
3995
 
 
 
3996
    /* The final shape is NOT hierarchical. */
 
 
3997
    {
 
 
3998
        SECTION_DATA *disc_section = GetThisSectionData(ghostData->HModelController.section_data, "disk");
 
 
3999
        assert(disc_section);
 
 
4000
 
 
 
4001
        sbPtr->shapeIndex = disc_section->sempai->ShapeNum;
 
 
4002
 
 
 
4003
        Dispel_HModel(&ghostData->HModelController);
 
 
4004
 
 
 
4005
        if (sbPtr->DisplayBlock)
 
 
4006
        {
 
 
4007
            sbPtr->DisplayBlock->ObShape = disc_section->sempai->ShapeNum;
 
 
4008
            sbPtr->DisplayBlock->ShapeData = disc_section->sempai->Shape;
 
 
4009
            sbPtr->DisplayBlock->HModelControlBlock = NULL;
 
 
4010
        }
 
 
4011
    }
 
 
4012
 
 
 
4013
    if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX) 
 
 
4014
        Sound_Stop(ghostData->SoundHandle);
 
 
4015
 
 
 
4016
    Sound_Play(SID_DISC_STICKSINWALL, "dp", &sbPtr->DynPtr->Position, ((FastRandom()&511)-255));
 
 
4017
}
 
 
4018
 
 
 
4019
void PlayHitDeltaOnGhost(STRATEGYBLOCK *sbPtr,char delta_seq,char delta_sub_seq)
 
 
4020
{
 
 
4021
    assert(sbPtr);
 
 
4022
    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
4023
 
 
 
4024
    //only play hit deltas on marine and predator players
 
 
4025
    switch(ghostData->type)
 
 
4026
    {
 
 
4027
        case I_BehaviourMarinePlayer:
 
 
4028
        case I_BehaviourPredatorPlayer:
 
 
4029
        break;
 
 
4030
        default:
 
 
4031
        return;
 
 
4032
    }
 
 
4033
 
 
 
4034
    DELTA_CONTROLLER *hitdelta = Get_Delta_Sequence(&ghostData->HModelController,"HitDelta");
 
 
4035
 
 
 
4036
    if(hitdelta && HModelSequence_Exists(&ghostData->HModelController,(int)delta_seq,(int)delta_sub_seq)) 
 
 
4037
    {
 
 
4038
        Start_Delta_Sequence(hitdelta,(int)delta_seq,(int) delta_sub_seq,ONE_FIXED/2); 
 
 
4039
    }
 
 
4040
}
 
 
4041
 
 
 
4042
void PlayOtherSound(enum soundindex SoundIndex, VECTORCH *position, int explosion)
 
 
4043
{
 
 
4044
    if (explosion)
 
 
4045
    {
 
 
4046
        Ghost_Explosion_SoundData.position = *position;
 
 
4047
        Sound_Play(SoundIndex, "n", &Ghost_Explosion_SoundData);
 
 
4048
    }
 
 
4049
    else
 
 
4050
    {
 
 
4051
        Sound_Play(SoundIndex, "d", position);
 
 
4052
    }
 
 
4053
}