4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "npc_common.h"
 
 
2
#include "dynamics.h"
 
 
3
#include "prototyp.h"
 
 
4
#include "switchdoor.h"
 
 
5
#include "liftdoor.h"
 
 
6
#include "platformlift.h"
 
 
7
#include "weaponbehaviour.h"
 
 
8
#include "debris.h"
 
 
9
#include "lighting.h"
 
 
10
#include "linkswitch.h"
 
 
11
#include "binaryswitch.h"
 
 
12
#include "npc_xenoborg.h"
 
 
13
#include "npc_queen.h"
 
 
14
#include "npc_sentrygun.h"
 
 
15
#include "npc_dummy.h"
 
 
16
#include "npc_facehugger.h"
 
 
17
#include "lift.h"
 
 
18
#include "bh_spcl.h"
 
 
19
#include "bh_ltfx.h"
 
 
20
#include "bh_snds.h"
 
 
21
#include "placedhierarchy.h"
 
 
22
#include "bh_light.h"
 
 
23
#include "bh_cable.h"
 
 
24
#include "bh_deathvol.h"
 
 
25
#include "bh_selfdest.h"
 
 
26
#include "mission.h"
 
 
27
#include "fan.h"
 
 
28
#include "particlegenerator.h"
 
 
29
#include "particle.h"
 
 
30
#include "videoscreen.h"
 
 
31
#include "savegame.h"
 
 
32
#include <stdlib.h>
 
 
33
#include <string.h>
 
 
34
 
 
 
35
extern int GlobalFrameCounter;
 
 
36
extern SCENEMODULE MainScene;
 
 
37
 
 
 
38
extern void MaintainPlayersInventory(STRATEGYBLOCK *collidedWith);
 
 
39
extern void UpdateMorphing(MORPHCTRL *mcptr);
 
 
40
extern void GrapplingHookBehaviour(STRATEGYBLOCK *sbPtr);
 
 
41
extern void InitXenoMorphRoom (void * bhdata, STRATEGYBLOCK * sbptr);
 
 
42
extern void XenoMorphRoomBehaviour (STRATEGYBLOCK * sbptr);
 
 
43
extern void HierarchicalFragmentBehaviour(STRATEGYBLOCK *sptr);
 
 
44
extern void Xeno_Enter_PowerUp_State(STRATEGYBLOCK *sbPtr);
 
 
45
extern void Xeno_Enter_PowerDown_State(STRATEGYBLOCK *sbPtr);
 
 
46
 
 
 
47
#define ObjectRequest_AdjustIntegrity 0x00000001
 
 
48
#define PLAYER_PICKUP_OBJECT_RADIUS 1600
 
 
49
 
 
 
50
const NPC_DATA NpcDataList[I_NPC_End] =
 
 
51
{
 
 
52
    {
 
 
53
        I_NPC_Civilian,
 
 
54
        {
 
 
55
            50,    /* Health */
 
 
56
            0,    /* Armour */
 
 
57
            0,    /* IsOnFire */
 
 
58
            0,    /* Acid Resistant */
 
 
59
            0,    /* Fire Resistant */
 
 
60
            0,    /* Electric Resistant */
 
 
61
            0,    /* Perfect Armour */
 
 
62
            0,    /* Electric Sensitive */
 
 
63
            1,    /* Combustability */
 
 
64
            0    /* Indestructable */
 
 
65
        },
 
 
66
    },
 
 
67
    {
 
 
68
        I_NPC_FaceHugger,
 
 
69
        {
 
 
70
            10,    /* Health */
 
 
71
            0,    /* Armour */
 
 
72
            0,    /* IsOnFire */
 
 
73
            1,    /* Acid Resistant */
 
 
74
            0,    /* Fire Resistant */
 
 
75
            0,    /* Electric Resistant */
 
 
76
            0,    /* Perfect Armour */
 
 
77
            1,    /* Electric Sensitive */
 
 
78
            0,    /* Combustability */
 
 
79
            0    /* Indestructable */
 
 
80
        },
 
 
81
    },
 
 
82
    {
 
 
83
        I_NPC_Alien,
 
 
84
        {
 
 
85
            300,    /* Health */
 
 
86
            100,    /* Armour */
 
 
87
            0,    /* IsOnFire */
 
 
88
            1,    /* Acid Resistant */
 
 
89
            1,    /* Fire Resistant */
 
 
90
            0,    /* Electric Resistant */
 
 
91
            1,    /* Perfect Armour */
 
 
92
            1,    /* Electric Sensitive */
 
 
93
            0,    /* Combustability */
 
 
94
            0    /* Indestructable */
 
 
95
        },
 
 
96
    },
 
 
97
    {
 
 
98
        I_NPC_Xenoborg,
 
 
99
        {
 
 
100
            750,    /* Health */
 
 
101
            120,    /* Armour */
 
 
102
            0,    /* IsOnFire */
 
 
103
            1,    /* Acid Resistant */
 
 
104
            0,    /* Fire Resistant */
 
 
105
            0,    /* Electric Resistant */
 
 
106
            0,    /* Perfect Armour */
 
 
107
            1,    /* Electric Sensitive */
 
 
108
            0,    /* Combustability */
 
 
109
            0    /* Indestructable */
 
 
110
        },
 
 
111
    },
 
 
112
    {
 
 
113
        I_NPC_Marine,
 
 
114
        {
 
 
115
            80,    /* Health */
 
 
116
            50,    /* Armour */
 
 
117
            0,    /* IsOnFire */
 
 
118
            0,    /* Acid Resistant */
 
 
119
            0,    /* Fire Resistant */
 
 
120
            0,    /* Electric Resistant */
 
 
121
            0,    /* Perfect Armour */
 
 
122
            0,    /* Electric Sensitive */
 
 
123
            1,    /* Combustability */
 
 
124
            0    /* Indestructable */
 
 
125
        },
 
 
126
    },
 
 
127
    {
 
 
128
        I_NPC_PredatorAlien,
 
 
129
        {
 
 
130
            400,    /* Health */
 
 
131
            150,    /* Armour */
 
 
132
            0,    /* IsOnFire */
 
 
133
            1,    /* Acid Resistant */
 
 
134
            0,    /* Fire Resistant */
 
 
135
            0,    /* Electric Resistant */
 
 
136
            0,    /* Perfect Armour */
 
 
137
            0,    /* Electric Sensitive */
 
 
138
            1,    /* Combustability */
 
 
139
            0    /* Indestructable */
 
 
140
        },
 
 
141
    },
 
 
142
    {
 
 
143
        I_NPC_Predator,
 
 
144
        {
 
 
145
            350,    /* Health */
 
 
146
            200,    /* Armour */
 
 
147
            0,    /* IsOnFire */
 
 
148
            0,    /* Acid Resistant */
 
 
149
            0,    /* Fire Resistant */
 
 
150
            0,    /* Electric Resistant */
 
 
151
            0,    /* Perfect Armour */
 
 
152
            0,    /* Electric Sensitive */
 
 
153
            1,    /* Combustability */
 
 
154
            0    /* Indestructable */
 
 
155
        },
 
 
156
    },
 
 
157
    {
 
 
158
        I_NPC_PraetorianGuard,
 
 
159
        {
 
 
160
            1000,    /* Health */
 
 
161
            400,    /* Armour */
 
 
162
            0,    /* IsOnFire */
 
 
163
            1,    /* Acid Resistant */
 
 
164
            1,    /* Fire Resistant */
 
 
165
            0,    /* Electric Resistant */
 
 
166
            1,    /* Perfect Armour */
 
 
167
            1,    /* Electric Sensitive */
 
 
168
            0,    /* Combustability */
 
 
169
            0    /* Indestructable */
 
 
170
        },
 
 
171
    },
 
 
172
    {
 
 
173
        I_NPC_AlienQueen,
 
 
174
        {
 
 
175
            4000,    /* Health */
 
 
176
            1000,    /* Armour */
 
 
177
            0,    /* IsOnFire */
 
 
178
            1,    /* Acid Resistant */
 
 
179
            1,    /* Fire Resistant */
 
 
180
            0,    /* Electric Resistant */
 
 
181
            1,    /* Perfect Armour */
 
 
182
            0,    /* Electric Sensitive */
 
 
183
            0,    /* Combustability */
 
 
184
            0    /* Indestructable */
 
 
185
        },
 
 
186
    },
 
 
187
    {
 
 
188
        I_NPC_DefaultInanimate,
 
 
189
        {
 
 
190
            15,    /* Health */
 
 
191
            4,    /* Armour */
 
 
192
            0,    /* IsOnFire */
 
 
193
            0,    /* Acid Resistant */
 
 
194
            0,    /* Fire Resistant */
 
 
195
            0,    /* Electric Resistant */
 
 
196
            0,    /* Perfect Armour */
 
 
197
            0,    /* Electric Sensitive */
 
 
198
            1,    /* Combustability */
 
 
199
            0    /* Indestructable */
 
 
200
        },
 
 
201
    },
 
 
202
    {
 
 
203
        I_PC_Alien_MaxStats,
 
 
204
        {
 
 
205
            180,    /* Health */
 
 
206
            30,    /* Armour (was 6) */
 
 
207
            0,    /* IsOnFire */
 
 
208
            1,    /* Acid Resistant */
 
 
209
            0,    /* Fire Resistant */
 
 
210
            0,    /* Electric Resistant */
 
 
211
            0,    /* Perfect Armour */  /* Disabled, CDF 28/7/98 */
 
 
212
            0,    /* Electric Sensitive */
 
 
213
            0,    /* Combustability */
 
 
214
            0    /* Indestructable */
 
 
215
        },
 
 
216
    },
 
 
217
    {
 
 
218
        I_NPC_SentryGun,
 
 
219
        {
 
 
220
            500,    /* Health */
 
 
221
            400,    /* Armour */
 
 
222
            0,    /* IsOnFire */
 
 
223
            0,    /* Acid Resistant */
 
 
224
            1,    /* Fire Resistant */
 
 
225
            0,    /* Electric Resistant */
 
 
226
            0,    /* Perfect Armour */
 
 
227
            1,    /* Electric Sensitive */
 
 
228
            0,    /* Combustability */
 
 
229
            0    /* Indestructable */
 
 
230
        },
 
 
231
    },
 
 
232
    {
 
 
233
        I_NPC_Android,
 
 
234
        {
 
 
235
            200,    /* Health */
 
 
236
            200,    /* Armour */
 
 
237
            0,    /* IsOnFire */
 
 
238
            0,    /* Acid Resistant */
 
 
239
            0,    /* Fire Resistant */
 
 
240
            0,    /* Electric Resistant */
 
 
241
            0,    /* Perfect Armour */
 
 
242
            1,    /* Electric Sensitive */
 
 
243
            1,    /* Combustability */
 
 
244
            0    /* Indestructable */
 
 
245
        },
 
 
246
    }
 
 
247
};
 
 
248
 
 
 
249
void RemoveBehaviourStrategy(STRATEGYBLOCK* sbptr)
 
 
250
{
 
 
251
    assert(sbptr);
 
 
252
 
 
 
253
    /* Andy 16/8/97  - Updated to cope with partially allocated strategy blocks 
 
 
254
     We need to check that each allocation has been completed before
 
 
255
      trying to deallocate */
 
 
256
 
 
 
257
    /* CDF 12/11/96 - Destroys ANY strategyblock. *
 
 
258
    * Please maintain...                         */
 
 
259
 
 
 
260
    // this notifies the game flow system that an object has been destroyed
 
 
261
    switch(sbptr->type) 
 
 
262
    {
 
 
263
        case I_BehaviourFragment: // this happens a lot
 
 
264
        break;
 
 
265
        case I_BehaviourHierarchicalFragment:
 
 
266
        {
 
 
267
            HDEBRIS_BEHAV_BLOCK *hdbblk = (HDEBRIS_BEHAV_BLOCK *)sbptr->dataptr;
 
 
268
 
 
 
269
            Dispel_HModel(&hdbblk->HModelController);
 
 
270
        }
 
 
271
        break;
 
 
272
        case I_BehaviourCorpse:
 
 
273
        {
 
 
274
            CORPSEDATABLOCK *corpseData = (CORPSEDATABLOCK *)(sbptr->dataptr);    
 
 
275
 
 
 
276
            if(corpseData)
 
 
277
            {
 
 
278
                if(corpseData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
279
                    Sound_Stop(corpseData->SoundHandle);
 
 
280
 
 
 
281
                Dispel_HModel(&corpseData->HModelController);
 
 
282
            }
 
 
283
        }    
 
 
284
        break;
 
 
285
        case I_BehaviourInanimateObject:
 
 
286
        {
 
 
287
            INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = (INANIMATEOBJECT_STATUSBLOCK*)sbptr->dataptr;
 
 
288
 
 
 
289
            if (objectstatusptr)
 
 
290
            {
 
 
291
                if(objectstatusptr->event_target)
 
 
292
                    free(objectstatusptr->event_target);
 
 
293
 
 
 
294
                if(!objectstatusptr->inan_tac)
 
 
295
                {
 
 
296
                    TXACTRLBLK *txactrl_next = objectstatusptr->inan_tac;
 
 
297
 
 
 
298
                    while(txactrl_next)
 
 
299
                    {
 
 
300
                        TXACTRLBLK *txactrl = txactrl_next;
 
 
301
                        txactrl_next = txactrl->tac_next;
 
 
302
                        free((void*)txactrl);
 
 
303
                    }
 
 
304
                }
 
 
305
            }
 
 
306
        }
 
 
307
        break;
 
 
308
        case I_BehaviourVideoScreen:
 
 
309
        {
 
 
310
            VIDEO_SCREEN_BEHAV_BLOCK* videoScreen = (VIDEO_SCREEN_BEHAV_BLOCK*)sbptr->dataptr;
 
 
311
 
 
 
312
            if (videoScreen && videoScreen->inan_tac)
 
 
313
            {
 
 
314
                TXACTRLBLK *txactrl_next = videoScreen->inan_tac;
 
 
315
 
 
 
316
                while(txactrl_next)
 
 
317
                {
 
 
318
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
319
                    txactrl_next = txactrl->tac_next;
 
 
320
                    free((void*)txactrl);
 
 
321
                }
 
 
322
            }
 
 
323
        }
 
 
324
        break;
 
 
325
        case I_BehaviourPlacedLight:
 
 
326
        {
 
 
327
            PLACED_LIGHT_BEHAV_BLOCK* pl_bhv=(PLACED_LIGHT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
328
 
 
 
329
            if (pl_bhv)
 
 
330
            {
 
 
331
                //set num lights to zero so it doesn't attempt to deallocate the light
 
 
332
                if(sbptr->DisplayBlock)
 
 
333
                    sbptr->DisplayBlock->ObNumLights = 0;
 
 
334
 
 
 
335
                //reset vaules in lightblock
 
 
336
                pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
337
                pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
338
                pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
339
                pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
340
 
 
 
341
                if(!pl_bhv->inan_tac)
 
 
342
                    break;
 
 
343
 
 
 
344
                TXACTRLBLK *txactrl_next = pl_bhv->inan_tac;
 
 
345
 
 
 
346
                while(txactrl_next)
 
 
347
                {
 
 
348
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
349
                    txactrl_next = txactrl->tac_next;
 
 
350
                    free((void*)txactrl);
 
 
351
                }
 
 
352
            }
 
 
353
        }
 
 
354
        break;
 
 
355
        case I_BehaviourLightFX:
 
 
356
        {
 
 
357
            LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbptr->dataptr;
 
 
358
 
 
 
359
            if(lfxbb)
 
 
360
            {
 
 
361
                TXACTRLBLK *txactrl_next = lfxbb->anim_control;
 
 
362
 
 
 
363
                while(txactrl_next)
 
 
364
                {
 
 
365
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
366
                    txactrl_next = txactrl->tac_next;
 
 
367
                    free((void*)txactrl);
 
 
368
                }
 
 
369
            }
 
 
370
        }
 
 
371
        break;
 
 
372
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
373
        {
 
 
374
              PC_PRED_DISC_BEHAV_BLOCK *bblk = (PC_PRED_DISC_BEHAV_BLOCK *)(sbptr->dataptr);    
 
 
375
 
 
 
376
            if(bblk)
 
 
377
            {
 
 
378
                if (bblk->soundHandle != SOUND_NOACTIVEINDEX)
 
 
379
                    Sound_Stop(bblk->soundHandle);
 
 
380
 
 
 
381
                Dispel_HModel(&bblk->HModelController);
 
 
382
            }
 
 
383
        }
 
 
384
        break;
 
 
385
        case I_BehaviourPredatorEnergyBolt:
 
 
386
        case I_BehaviourFrisbeeEnergyBolt:
 
 
387
        {
 
 
388
              CASTER_BOLT_BEHAV_BLOCK *bblk = (CASTER_BOLT_BEHAV_BLOCK *)(sbptr->dataptr);    
 
 
389
 
 
 
390
            if(bblk)
 
 
391
            {
 
 
392
                if (bblk->soundHandle != SOUND_NOACTIVEINDEX)
 
 
393
                    Sound_Stop(bblk->soundHandle);
 
 
394
            }
 
 
395
        }
 
 
396
        break;
 
 
397
        case I_BehaviourFrisbee:
 
 
398
        {
 
 
399
              FRISBEE_BEHAV_BLOCK *fblk = (FRISBEE_BEHAV_BLOCK *)(sbptr->dataptr);    
 
 
400
 
 
 
401
            if(fblk)
 
 
402
            {
 
 
403
                if (fblk->soundHandle != SOUND_NOACTIVEINDEX)
 
 
404
                    Sound_Stop(fblk->soundHandle);
 
 
405
 
 
 
406
                Dispel_HModel(&fblk->HModelController);
 
 
407
            }
 
 
408
        }
 
 
409
        break;
 
 
410
        case I_BehaviourFaceHugger:
 
 
411
        {
 
 
412
            FACEHUGGER_STATUS_BLOCK *fhugStatusPointer = (FACEHUGGER_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
413
 
 
 
414
            if(fhugStatusPointer)
 
 
415
            {
 
 
416
                if (fhugStatusPointer->soundHandle_fire != SOUND_NOACTIVEINDEX)
 
 
417
                    Sound_Stop(fhugStatusPointer->soundHandle_fire);
 
 
418
 
 
 
419
                Dispel_HModel(&fhugStatusPointer->HModelController);
 
 
420
            }
 
 
421
        }
 
 
422
        break;
 
 
423
        case I_BehaviourXenoborg:
 
 
424
        {
 
 
425
            /* need to get rid of the animations...*/
 
 
426
            XENO_STATUS_BLOCK *xenoStatus = (XENO_STATUS_BLOCK*)(sbptr->dataptr);
 
 
427
 
 
 
428
            if(xenoStatus)
 
 
429
            {
 
 
430
                Dispel_HModel(&xenoStatus->HModelController);
 
 
431
                /* Zounds! */
 
 
432
                if(xenoStatus->soundHandle1 != SOUND_NOACTIVEINDEX)
 
 
433
                    Sound_Stop(xenoStatus->soundHandle1);
 
 
434
 
 
 
435
                if(xenoStatus->soundHandle2 != SOUND_NOACTIVEINDEX)
 
 
436
                    Sound_Stop(xenoStatus->soundHandle2);
 
 
437
 
 
 
438
                if(xenoStatus->head_whirr!= SOUND_NOACTIVEINDEX)
 
 
439
                    Sound_Stop(xenoStatus->head_whirr);
 
 
440
 
 
 
441
                if(xenoStatus->left_arm_whirr != SOUND_NOACTIVEINDEX)
 
 
442
                    Sound_Stop(xenoStatus->left_arm_whirr);
 
 
443
 
 
 
444
                if(xenoStatus->right_arm_whirr != SOUND_NOACTIVEINDEX)
 
 
445
                    Sound_Stop(xenoStatus->right_arm_whirr);
 
 
446
 
 
 
447
                if(xenoStatus->torso_whirr != SOUND_NOACTIVEINDEX)
 
 
448
                    Sound_Stop(xenoStatus->torso_whirr);
 
 
449
            }
 
 
450
        }            
 
 
451
        break;
 
 
452
        case I_BehaviourAlien:
 
 
453
        {
 
 
454
            ALIEN_STATUS_BLOCK *asb = (ALIEN_STATUS_BLOCK *)(sbptr->dataptr);
 
 
455
            Dispel_HModel(&asb->HModelController);
 
 
456
        }
 
 
457
        break;
 
 
458
        case I_BehaviourMarine:
 
 
459
        {
 
 
460
            MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
461
 
 
 
462
            if(marineStatusPointer)
 
 
463
            {
 
 
464
                Dispel_HModel(&marineStatusPointer->HModelController);
 
 
465
 
 
 
466
                if(marineStatusPointer->myGunFlash)
 
 
467
                    DestroyActiveObject(&marineStatusPointer->myGunFlash);
 
 
468
 
 
 
469
                if(marineStatusPointer->soundHandle != SOUND_NOACTIVEINDEX)
 
 
470
                    Sound_Stop(marineStatusPointer->soundHandle);
 
 
471
            }
 
 
472
        }
 
 
473
        break;
 
 
474
        case I_BehaviourPredator:
 
 
475
        {
 
 
476
            PREDATOR_STATUS_BLOCK *predatorStatusPointer = (PREDATOR_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
477
 
 
 
478
            if(predatorStatusPointer)
 
 
479
            {
 
 
480
                if(predatorStatusPointer->soundHandle != SOUND_NOACTIVEINDEX)
 
 
481
                    Sound_Stop(predatorStatusPointer->soundHandle);
 
 
482
 
 
 
483
                Dispel_HModel(&predatorStatusPointer->HModelController);
 
 
484
            }
 
 
485
        }
 
 
486
        break;
 
 
487
        case I_BehaviourQueenAlien:
 
 
488
        {
 
 
489
            QUEEN_STATUS_BLOCK *queenStatusPointer = (QUEEN_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
490
 
 
 
491
            if(queenStatusPointer)
 
 
492
            {
 
 
493
                Dispel_HModel(&queenStatusPointer->HModelController);
 
 
494
 
 
 
495
                //stop any sound the queen is making
 
 
496
                if(queenStatusPointer->soundHandle != SOUND_NOACTIVEINDEX)
 
 
497
                    Sound_Stop(queenStatusPointer->soundHandle);
 
 
498
            }
 
 
499
        }
 
 
500
        break;
 
 
501
        case I_BehaviourNetGhost:
 
 
502
        {
 
 
503
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)(sbptr->dataptr);    
 
 
504
 
 
 
505
            if(ghostData)
 
 
506
            {
 
 
507
                if(ghostData->myGunFlash)
 
 
508
                    DestroyActiveObject(&ghostData->myGunFlash);
 
 
509
 
 
 
510
                if(ghostData->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
511
                    Sound_Stop(ghostData->SoundHandle);
 
 
512
 
 
 
513
                if(ghostData->SoundHandle2 != SOUND_NOACTIVEINDEX)
 
 
514
                    Sound_Stop(ghostData->SoundHandle2);
 
 
515
 
 
 
516
                if(ghostData->SoundHandle3 != SOUND_NOACTIVEINDEX)
 
 
517
                    Sound_Stop(ghostData->SoundHandle3);
 
 
518
 
 
 
519
                Dispel_HModel(&ghostData->HModelController);
 
 
520
            }
 
 
521
        }
 
 
522
        break;
 
 
523
        case I_BehaviourXenoborgMorphRoom:
 
 
524
        {
 
 
525
            XENO_MORPH_ROOM_DATA * xmrd = (XENO_MORPH_ROOM_DATA *)sbptr->dataptr;
 
 
526
 
 
 
527
            if(xmrd)
 
 
528
            {
 
 
529
                if (sbptr->morphctrl && sbptr->morphctrl->ObMorphHeader && sbptr->morphctrl->ObMorphHeader->mph_frames) 
 
 
530
                {
 
 
531
                    free(sbptr->morphctrl->ObMorphHeader->mph_frames);
 
 
532
                    free(sbptr->morphctrl->ObMorphHeader);
 
 
533
                    free(sbptr->morphctrl);
 
 
534
                }
 
 
535
 
 
 
536
                if (xmrd->tacb)
 
 
537
                {
 
 
538
                    TXACTRLBLK *txactrl_next = xmrd->tacb;
 
 
539
 
 
 
540
                    while(txactrl_next)
 
 
541
                    {
 
 
542
                        TXACTRLBLK *txactrl = txactrl_next;
 
 
543
                        txactrl_next = txactrl->tac_next;
 
 
544
                        free((void*)txactrl);
 
 
545
                    }
 
 
546
                }
 
 
547
            }
 
 
548
        }
 
 
549
        break;
 
 
550
        case I_BehaviourSpeargunBolt:
 
 
551
        {
 
 
552
            SPEAR_BEHAV_BLOCK *sbblk = (SPEAR_BEHAV_BLOCK *)sbptr->dataptr;
 
 
553
 
 
 
554
            /* There's a hierarchy to dispel. */
 
 
555
            if (sbblk->SpearThroughFragment)
 
 
556
                Dispel_HModel(&sbblk->HierarchicalFragment);
 
 
557
        }
 
 
558
        break;
 
 
559
        case I_BehaviourFan:
 
 
560
        {
 
 
561
            FAN_BEHAV_BLOCK* f_bhv = (FAN_BEHAV_BLOCK*)sbptr->dataptr;
 
 
562
 
 
 
563
            if(f_bhv->track)
 
 
564
                Reset_Track(f_bhv->track);
 
 
565
        }
 
 
566
        break;
 
 
567
        case I_BehaviourAutoGun:
 
 
568
        {
 
 
569
            AUTOGUN_STATUS_BLOCK *ag_bhv = (AUTOGUN_STATUS_BLOCK*)(sbptr->dataptr);
 
 
570
 
 
 
571
            if (ag_bhv)
 
 
572
            {
 
 
573
                /* patrick 7/7/97*/
 
 
574
                if(ag_bhv->soundHandle != SOUND_NOACTIVEINDEX)
 
 
575
                    Sound_Stop(ag_bhv->soundHandle);
 
 
576
 
 
 
577
                Dispel_HModel(&ag_bhv->HModelController);
 
 
578
            }
 
 
579
        }
 
 
580
        break;
 
 
581
        case I_BehaviourDummy:
 
 
582
        {
 
 
583
            DUMMY_STATUS_BLOCK *dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
584
 
 
 
585
            if(dummyStatusPointer)
 
 
586
                Dispel_HModel(&dummyStatusPointer->HModelController);
 
 
587
        }
 
 
588
        break;
 
 
589
        case I_BehaviourPlacedSound:
 
 
590
        {
 
 
591
            SOUND_BEHAV_BLOCK * sbb = (SOUND_BEHAV_BLOCK*)sbptr->dataptr;
 
 
592
 
 
 
593
            if (sbb->activ_no != SOUND_NOACTIVEINDEX)
 
 
594
                Sound_Stop(sbb->activ_no);
 
 
595
 
 
 
596
            if (sbb->wav_name)
 
 
597
                free (sbb->wav_name);
 
 
598
        }
 
 
599
        break;
 
 
600
        case I_BehaviourMissionComplete:
 
 
601
        {
 
 
602
            MISSION_COMPLETE_BEHAV_BLOCK *mc_bhv = (MISSION_COMPLETE_BEHAV_BLOCK*)sbptr->dataptr;
 
 
603
            if(mc_bhv)
 
 
604
            {
 
 
605
                assert((mc_bhv->bhvr_type == I_BehaviourMissionComplete));
 
 
606
                ResetMission(mc_bhv->mission_objective_ptr); 
 
 
607
            }
 
 
608
        }
 
 
609
        break;
 
 
610
        case I_BehaviourTrackObject:
 
 
611
        {
 
 
612
            TRACK_OBJECT_BEHAV_BLOCK *to_bhv = (TRACK_OBJECT_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
613
 
 
 
614
            if (to_bhv)
 
 
615
            {
 
 
616
                assert(to_bhv->bhvr_type == I_BehaviourTrackObject);
 
 
617
 
 
 
618
                if(to_bhv->to_track)
 
 
619
                    Reset_Track(to_bhv->to_track);
 
 
620
 
 
 
621
                TXACTRLBLK *txactrl_next = to_bhv->to_tac;
 
 
622
 
 
 
623
                while(txactrl_next)
 
 
624
                {    
 
 
625
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
626
                    txactrl_next = txactrl->tac_next;
 
 
627
                    free((void*)txactrl);
 
 
628
                }
 
 
629
            }
 
 
630
        }
 
 
631
        break;
 
 
632
        case I_BehaviourPlacedHierarchy:
 
 
633
        {
 
 
634
            PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
635
            assert(ph_bhv->bhvr_type == I_BehaviourPlacedHierarchy);
 
 
636
 
 
 
637
            if (ph_bhv)
 
 
638
                DeletePlacedHierarchy(ph_bhv);
 
 
639
        }
 
 
640
        break;
 
 
641
        case I_BehaviourParticleGenerator:
 
 
642
        {
 
 
643
            PARTICLE_GENERATOR_BEHAV_BLOCK* pargen = (PARTICLE_GENERATOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
644
 
 
 
645
            if(pargen->sound)
 
 
646
                Stop_Track_Sound(pargen->sound);
 
 
647
        }
 
 
648
        break;
 
 
649
        case I_BehaviourPlatform:
 
 
650
        {
 
 
651
            PLATFORMLIFT_BEHAVIOUR_BLOCK* pl_bhv = (PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbptr->dataptr;
 
 
652
 
 
 
653
            if(pl_bhv->sound)
 
 
654
                Stop_Track_Sound(pl_bhv->sound);
 
 
655
 
 
 
656
            if(pl_bhv->start_sound)
 
 
657
                Stop_Track_Sound(pl_bhv->start_sound);
 
 
658
 
 
 
659
            if(pl_bhv->end_sound)
 
 
660
                Stop_Track_Sound(pl_bhv->end_sound);
 
 
661
        }
 
 
662
        break;    
 
 
663
        case I_BehaviourProximityDoor:
 
 
664
        {
 
 
665
            /* patrick 7/7/97: remove sound handle, if we have one*/
 
 
666
            PROXDOOR_BEHAV_BLOCK *doorbhv = (PROXDOOR_BEHAV_BLOCK *)(sbptr->dataptr);
 
 
667
 
 
 
668
            if(doorbhv)
 
 
669
            {
 
 
670
                if(doorbhv->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
671
                    Sound_Stop(doorbhv->SoundHandle);
 
 
672
 
 
 
673
                if (sbptr->morphctrl && sbptr->morphctrl->ObMorphHeader && sbptr->morphctrl->ObMorphHeader->mph_frames) 
 
 
674
                {
 
 
675
                    free(sbptr->morphctrl->ObMorphHeader->mph_frames);
 
 
676
                    free(sbptr->morphctrl->ObMorphHeader);
 
 
677
                    free(sbptr->morphctrl);
 
 
678
                }
 
 
679
            }
 
 
680
        }    
 
 
681
        break;
 
 
682
        case I_BehaviourLiftDoor:
 
 
683
        {
 
 
684
            //     Deallocater for the doors hack
 
 
685
            /* patrick 7/7/97: remove sound handle, if we have one*/
 
 
686
            LIFT_DOOR_BEHAV_BLOCK *doorbhv = (LIFT_DOOR_BEHAV_BLOCK *)(sbptr->dataptr);
 
 
687
 
 
 
688
            if(doorbhv)
 
 
689
            {
 
 
690
                if(doorbhv->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
691
                    Sound_Stop(doorbhv->SoundHandle);
 
 
692
 
 
 
693
                if (sbptr->morphctrl && sbptr->morphctrl->ObMorphHeader && sbptr->morphctrl->ObMorphHeader->mph_frames) 
 
 
694
                {
 
 
695
                    free(sbptr->morphctrl->ObMorphHeader->mph_frames);
 
 
696
                    free(sbptr->morphctrl->ObMorphHeader);
 
 
697
                    free(sbptr->morphctrl);
 
 
698
                }
 
 
699
            }
 
 
700
        }
 
 
701
        break;
 
 
702
        case I_BehaviourSwitchDoor:
 
 
703
        {
 
 
704
            /* patrick 7/7/97: remove sound handle, if we have one*/
 
 
705
            SWITCH_DOOR_BEHAV_BLOCK *doorbhv = (SWITCH_DOOR_BEHAV_BLOCK *)(sbptr->dataptr);
 
 
706
 
 
 
707
            if(doorbhv)
 
 
708
            {
 
 
709
                if(doorbhv->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
710
                    Sound_Stop(doorbhv->SoundHandle);
 
 
711
 
 
 
712
                if (sbptr->morphctrl && sbptr->morphctrl->ObMorphHeader && sbptr->morphctrl->ObMorphHeader->mph_frames) 
 
 
713
                {
 
 
714
                    free(sbptr->morphctrl->ObMorphHeader->mph_frames);
 
 
715
                    free(sbptr->morphctrl->ObMorphHeader);
 
 
716
                    free(sbptr->morphctrl);
 
 
717
                }
 
 
718
            }
 
 
719
        }
 
 
720
        break;
 
 
721
        case I_BehaviourSimpleAnimation:
 
 
722
        {
 
 
723
            SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
724
 
 
 
725
            if (sanimbhv)
 
 
726
            {
 
 
727
                assert(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation);
 
 
728
 
 
 
729
                TXACTRLBLK *txactrl_next = sanimbhv->tacbSimple;
 
 
730
 
 
 
731
                while(txactrl_next)
 
 
732
                {
 
 
733
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
734
                    txactrl_next = txactrl->tac_next;
 
 
735
                    free((void*)txactrl);
 
 
736
                }
 
 
737
            }
 
 
738
        }
 
 
739
        break;
 
 
740
        case I_BehaviourBinarySwitch:
 
 
741
        {
 
 
742
            BINARY_SWITCH_BEHAV_BLOCK *bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
743
 
 
 
744
            if (bs_bhv)
 
 
745
            {
 
 
746
                assert(bs_bhv->bhvr_type == I_BehaviourBinarySwitch);
 
 
747
 
 
 
748
                 /* Andy 20/8/97: remove sound handle, if we have one*/
 
 
749
                 if(bs_bhv->soundHandle != SOUND_NOACTIVEINDEX)
 
 
750
                    Sound_Stop(bs_bhv->soundHandle);
 
 
751
 
 
 
752
                if(bs_bhv->bs_track)
 
 
753
                    Reset_Track(bs_bhv->bs_track);
 
 
754
 
 
 
755
                TXACTRLBLK *txactrl_next = bs_bhv->bs_tac;
 
 
756
 
 
 
757
                while(txactrl_next)
 
 
758
                {    
 
 
759
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
760
                    txactrl_next = txactrl->tac_next;
 
 
761
                    free((void*)txactrl);
 
 
762
                }
 
 
763
 
 
 
764
                if(bs_bhv->num_targets)
 
 
765
                {
 
 
766
                    if (bs_bhv->target_names)
 
 
767
                        free (bs_bhv->target_names);
 
 
768
 
 
 
769
                    if (bs_bhv->bs_targets)
 
 
770
                        free (bs_bhv->bs_targets);
 
 
771
 
 
 
772
                    if (bs_bhv->request_messages)
 
 
773
                        free(bs_bhv->request_messages);
 
 
774
                }
 
 
775
            }
 
 
776
         }
 
 
777
        break;
 
 
778
        case I_BehaviourLinkSwitch:
 
 
779
        {
 
 
780
            LINK_SWITCH_BEHAV_BLOCK *bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
781
 
 
 
782
            if (bs_bhv)
 
 
783
            {
 
 
784
                assert(bs_bhv->bhvr_type == I_BehaviourLinkSwitch);
 
 
785
 
 
 
786
                 /* Andy 20/8/97: remove sound handle, if we have one*/
 
 
787
                 if(bs_bhv->soundHandle != SOUND_NOACTIVEINDEX)
 
 
788
                    Sound_Stop(bs_bhv->soundHandle);
 
 
789
 
 
 
790
                if(bs_bhv->ls_track)
 
 
791
                    Reset_Track(bs_bhv->ls_track);
 
 
792
 
 
 
793
                TXACTRLBLK *txactrl_next = bs_bhv->ls_tac;
 
 
794
 
 
 
795
                while(txactrl_next)
 
 
796
                {
 
 
797
                    TXACTRLBLK *txactrl = txactrl_next;
 
 
798
                    txactrl_next = txactrl->tac_next;
 
 
799
                    free((void*)txactrl);
 
 
800
                }
 
 
801
 
 
 
802
                if (bs_bhv->ls_targets)
 
 
803
                    free ((void *)bs_bhv->ls_targets);
 
 
804
 
 
 
805
                if (bs_bhv->lswitch_list)
 
 
806
                    free ((void *)bs_bhv->lswitch_list);
 
 
807
            }
 
 
808
        }
 
 
809
        break;
 
 
810
        case I_BehaviourLift:
 
 
811
        {
 
 
812
            LIFT_BEHAV_BLOCK *lift_bhv = (LIFT_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
813
 
 
 
814
            if (lift_bhv && lift_bhv->controller)
 
 
815
            {
 
 
816
                if(lift_bhv->lift_control->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
817
                    Sound_Stop(lift_bhv->lift_control->SoundHandle);
 
 
818
 
 
 
819
                if (lift_bhv->lift_control)
 
 
820
                {
 
 
821
                    free(lift_bhv->lift_control);
 
 
822
 
 
 
823
                    if (lift_bhv->lift_control->lift_stations)
 
 
824
                        free(lift_bhv->lift_control->lift_stations);
 
 
825
                }
 
 
826
            }
 
 
827
        }
 
 
828
        break;
 
 
829
        case I_BehaviourMarinePlayer:
 
 
830
        case I_BehaviourAlienPlayer:
 
 
831
        case I_BehaviourPredatorPlayer:
 
 
832
            Dispel_HModel(sbptr->DisplayBlock->HModelControlBlock);
 
 
833
            DestroyActiveObject(&sbptr->DisplayBlock);
 
 
834
            DeallocateDynamicsBlock(sbptr->DynPtr);
 
 
835
            DestroyActiveStrategyBlock(sbptr);
 
 
836
            return;
 
 
837
        default:
 
 
838
        break;
 
 
839
    }
 
 
840
 
 
 
841
    free(sbptr->dataptr);
 
 
842
    sbptr->dataptr = NULL;
 
 
843
 
 
 
844
    if (sbptr->DisplayBlock) 
 
 
845
        DestroyActiveObject(&sbptr->DisplayBlock);
 
 
846
 
 
 
847
    if (sbptr->DynPtr) 
 
 
848
        DeallocateDynamicsBlock(sbptr->DynPtr);
 
 
849
 
 
 
850
    DestroyActiveStrategyBlock(sbptr);
 
 
851
}
 
 
852
 
 
 
853
static void DoorProxBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
 
 
854
{
 
 
855
    MODULE * my_mod;
 
 
856
 
 
 
857
    PROXDOOR_BEHAV_BLOCK *doorbhv = sbptr->dataptr = malloc(sizeof(PROXDOOR_BEHAV_BLOCK));
 
 
858
    MORPHCTRL* morphctrl = malloc(sizeof(MORPHCTRL));
 
 
859
    MORPHHEADER* morphheader = malloc(sizeof(MORPHHEADER));
 
 
860
    MORPHFRAME* morphframe = malloc(sizeof(MORPHFRAME));
 
 
861
 
 
 
862
    if((NULL == doorbhv) || (NULL == morphctrl) || (NULL == morphheader) || (NULL == morphframe))
 
 
863
    {
 
 
864
        free(morphctrl);
 
 
865
        free(morphheader);
 
 
866
        free(morphframe);
 
 
867
        RemoveBehaviourStrategy(sbptr);
 
 
868
        return;
 
 
869
    }
 
 
870
 
 
 
871
    doorbhv->bhvr_type = I_BehaviourProximityDoor;
 
 
872
 
 
 
873
    PROX_DOOR_TOOLS_TEMPLATE *doortt = (PROX_DOOR_TOOLS_TEMPLATE*)bhdata;
 
 
874
 
 
 
875
    morphframe->mf_shape1 = doortt->shape_open;
 
 
876
    morphframe->mf_shape2 = doortt->shape_closed;
 
 
877
 
 
 
878
    morphheader->mph_numframes = 1;
 
 
879
    morphheader->mph_maxframes = ONE_FIXED;
 
 
880
    morphheader->mph_frames = morphframe;
 
 
881
 
 
 
882
    morphctrl->ObMorphCurrFrame = 0;
 
 
883
    morphctrl->ObMorphFlags = 0;
 
 
884
    morphctrl->ObMorphSpeed = 0;
 
 
885
    morphctrl->ObMorphHeader = morphheader;
 
 
886
 
 
 
887
    // Copy the name over
 
 
888
    COPY_NAME (sbptr->SBname, doortt->nameID);
 
 
889
 
 
 
890
    // Setup module ref
 
 
891
    {
 
 
892
        MREF mref = doortt->my_module;
 
 
893
        ConvertModuleNameToPointer (&mref, MainScene.sm_marray);
 
 
894
        my_mod = mref.mref_ptr;
 
 
895
    }
 
 
896
    assert (my_mod);
 
 
897
 
 
 
898
    my_mod->m_sbptr = sbptr;
 
 
899
    sbptr->moptr = my_mod;
 
 
900
 
 
 
901
    doorbhv->PDmctrl = morphctrl; 
 
 
902
    doorbhv->lockable_door = doortt->has_lock_target;
 
 
903
 
 
 
904
    doorbhv->door_opening_speed = doortt->door_opening_speed;
 
 
905
    doorbhv->door_closing_speed = doortt->door_closing_speed;
 
 
906
 
 
 
907
    if(doortt->has_lock_target)
 
 
908
    {
 
 
909
        COPY_NAME(doorbhv->target_name, doortt->target_name);
 
 
910
    }
 
 
911
 
 
 
912
    sbptr->morphctrl = doorbhv->PDmctrl;
 
 
913
    sbptr->morphctrl->ObMorphCurrFrame = 1; /* this should be closed*/
 
 
914
 
 
 
915
    doorbhv->door_state = I_door_closed;
 
 
916
    CloseDoor(sbptr->morphctrl, DOOR_CLOSEFASTSPEED);    
 
 
917
 
 
 
918
    //sbptr->moptr->m_flags |= m_flag_open;
 
 
919
    //sbptr->moptr->m_flags &= ~m_flag_open;
 
 
920
 
 
 
921
    /*-----------Patrick 9/12/96--------------
 
 
922
     a little addition...
 
 
923
     -----------------------------------------*/
 
 
924
    doorbhv->alienTrigger = 0;
 
 
925
    doorbhv->marineTrigger = 0;
 
 
926
    doorbhv->Timer = 0;
 
 
927
    doorbhv->door_locked = doortt->door_is_locked;
 
 
928
    doorbhv->SoundHandle = SOUND_NOACTIVEINDEX;
 
 
929
 
 
 
930
    {
 
 
931
        // Work out the door sound pitch
 
 
932
 
 
 
933
        int maxX = mainshapelist[morphframe->mf_shape2]->shapemaxx;
 
 
934
        int maxY = mainshapelist[morphframe->mf_shape2]->shapemaxy;
 
 
935
        int maxZ = mainshapelist[morphframe->mf_shape2]->shapemaxz;
 
 
936
 
 
 
937
        int doorSize = maxX + maxY + maxZ;
 
 
938
 
 
 
939
        if (doorSize < 3000)
 
 
940
            doorSize = 3000;
 
 
941
        else if (doorSize > 8000)
 
 
942
            doorSize = 8000;
 
 
943
 
 
 
944
        doorbhv->doorType = (3000 - doorSize) >> 4;
 
 
945
    }
 
 
946
}
 
 
947
 
 
 
948
static void SimpleAnimationBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
 
 
949
{
 
 
950
    /**RWH 10/12/96 ***************************************
 
 
951
 
 
 
952
    Simple Animation intialistation. This will set up an array
 
 
953
    of texture control blocks. Each textures controlblock will animate only 
 
 
954
    one sequence per polygon.
 
 
955
 
 
 
956
    ***********************************************************/
 
 
957
 
 
 
958
    int item_num;
 
 
959
    SIMPLE_ANIM_TOOLS_TEMPLATE * satt = (SIMPLE_ANIM_TOOLS_TEMPLATE *)bhdata;
 
 
960
    struct shapeheader* shptr = mainshapelist[sbptr->shapeIndex];
 
 
961
    MODULE * my_mod;
 
 
962
 
 
 
963
    assert(shptr);
 
 
964
    assert(shptr->numitems > 0);
 
 
965
 
 
 
966
    SIMPLE_ANIM_BEHAV_BLOCK *sabhv = malloc(sizeof(SIMPLE_ANIM_BEHAV_BLOCK));
 
 
967
 
 
 
968
    if(!sabhv) 
 
 
969
    {
 
 
970
        RemoveBehaviourStrategy(sbptr);
 
 
971
        return;
 
 
972
    }
 
 
973
 
 
 
974
    sbptr->dataptr = sabhv;
 
 
975
 
 
 
976
    sabhv->bhvr_type = I_BehaviourSimpleAnimation;
 
 
977
 
 
 
978
    // Copy the name over
 
 
979
    COPY_NAME (sbptr->SBname, satt->nameID);
 
 
980
 
 
 
981
    // Setup module ref
 
 
982
 
 
 
983
    if ('\0' != satt->my_module.mref_name[0])
 
 
984
    {
 
 
985
        MREF mref = satt->my_module;
 
 
986
        ConvertModuleNameToPointer(&mref, MainScene.sm_marray);
 
 
987
        my_mod = mref.mref_ptr;
 
 
988
 
 
 
989
        assert (my_mod);
 
 
990
 
 
 
991
        my_mod->m_sbptr = sbptr;
 
 
992
        sbptr->moptr = my_mod;
 
 
993
    }
 
 
994
 
 
 
995
    /*
 
 
996
    we need to reserve the address of where we 
 
 
997
     are going to place the new animation ctrl block.
 
 
998
 
 
 
999
     this is so that we can call the texture animation builder
 
 
1000
     in the below loop
 
 
1001
    */
 
 
1002
 
 
 
1003
    TXACTRLBLK **pptxactrlblk = &sabhv->tacbSimple;
 
 
1004
 
 
 
1005
    /*
 
 
1006
    the bhdata is a ptr to the struct shapeheader each 
 
 
1007
    animating polygon has an array of sequences, in 
 
 
1008
    this case thers is only onr sequence per array
 
 
1009
    */
 
 
1010
 
 
 
1011
    for(item_num = 0; item_num < shptr->numitems; item_num ++)
 
 
1012
    {
 
 
1013
        POLYHEADER *poly =  (POLYHEADER*)(shptr->items[item_num]);
 
 
1014
        assert(poly);
 
 
1015
 
 
 
1016
        if(poly->PolyFlags & iflag_txanim)
 
 
1017
        {
 
 
1018
            TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
1019
 
 
 
1020
            if (pnew_txactrlblk)
 
 
1021
            {
 
 
1022
                pnew_txactrlblk->tac_flags = 0;                                        
 
 
1023
                pnew_txactrlblk->tac_item = item_num;                                        
 
 
1024
                pnew_txactrlblk->tac_sequence = 0;                                        
 
 
1025
                pnew_txactrlblk->tac_node = 0;                                        
 
 
1026
                pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(sbptr->shapeIndex, item_num);                                        
 
 
1027
                pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, sbptr->shapeIndex);
 
 
1028
 
 
 
1029
                /* set the flags in the animation header */
 
 
1030
 
 
 
1031
                /* KJL 17:00:38 04/04/97 - ChrisF complained about the next line, so
 
 
1032
                I've turned it off to see if anything happens. */
 
 
1033
                /*pnew_txactrlblk->tac_txah.txa_flags = txa_flag_play; */
 
 
1034
 
 
 
1035
                /*
 
 
1036
                change the value held in pptxactrlblk
 
 
1037
                 which point to the previous structures "next" pointer
 
 
1038
                */
 
 
1039
 
 
 
1040
                *pptxactrlblk = pnew_txactrlblk;
 
 
1041
                pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
1042
            }
 
 
1043
            else
 
 
1044
            {
 
 
1045
                memoryInitialisationFailure = 1;
 
 
1046
            }
 
 
1047
        }
 
 
1048
    }
 
 
1049
 
 
 
1050
    *pptxactrlblk = 0;
 
 
1051
}
 
 
1052
 
 
 
1053
/*-----------------------Patrick 16/1/97---------------------------
 
 
1054
Inanimate object initialisation and behaviour and functions.
 
 
1055
-------------------------------------------------------------------*/
 
 
1056
static void InitInanimateObject(void* bhdata, STRATEGYBLOCK *sbPtr)
 
 
1057
{
 
 
1058
    TOOLS_DATA_INANIMATEOBJECT *toolsData = (TOOLS_DATA_INANIMATEOBJECT *)bhdata;
 
 
1059
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr = malloc(sizeof(INANIMATEOBJECT_STATUSBLOCK));
 
 
1060
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
1061
    int i;
 
 
1062
 
 
 
1063
    if((NULL == dynPtr) || (NULL == objectstatusptr))
 
 
1064
    {
 
 
1065
        RemoveBehaviourStrategy(sbPtr);
 
 
1066
        return;
 
 
1067
    }
 
 
1068
 
 
 
1069
    sbPtr->maintainVisibility = 1;
 
 
1070
    objectstatusptr->respawnTimer = 0; 
 
 
1071
    objectstatusptr->lifespanTimer = 0; 
 
 
1072
    objectstatusptr->explosionTimer = 0; 
 
 
1073
 
 
 
1074
    /* these should be loaded */
 
 
1075
    objectstatusptr->typeId = toolsData->typeId;
 
 
1076
    objectstatusptr->subType = toolsData->subType;                                  
 
 
1077
    objectstatusptr->ghosted_object = 0;
 
 
1078
    objectstatusptr->event_target = NULL;
 
 
1079
 
 
 
1080
    {
 
 
1081
        const NPC_DATA *NpcData = &NpcDataList[I_NPC_DefaultInanimate];
 
 
1082
 
 
 
1083
        sbPtr->DamageBlock = NpcData->StartingStats;
 
 
1084
        sbPtr->DamageBlock.Health = NpcData->StartingStats.Health << ONE_FIXED_SHIFT;
 
 
1085
        sbPtr->DamageBlock.Armour = NpcData->StartingStats.Armour << ONE_FIXED_SHIFT;
 
 
1086
    }
 
 
1087
 
 
 
1088
    sbPtr->DamageBlock.Health *= toolsData->integrity;
 
 
1089
    sbPtr->DamageBlock.Indestructable = (toolsData->integrity > 20);
 
 
1090
 
 
 
1091
    if(toolsData->triggering_event)
 
 
1092
    {
 
 
1093
        objectstatusptr->event_target = malloc(sizeof(OBJECT_EVENT_TARGET));
 
 
1094
        objectstatusptr->event_target->triggering_event = toolsData->triggering_event;
 
 
1095
        objectstatusptr->event_target->request = toolsData->event_request;
 
 
1096
        objectstatusptr->event_target->event_target_sbptr = 0;
 
 
1097
 
 
 
1098
        for(i=0; i < SB_NAME_LENGTH; i++)
 
 
1099
            objectstatusptr->event_target->event_target_ID[i] = toolsData->event_target_ID[i];
 
 
1100
    }
 
 
1101
 
 
 
1102
    objectstatusptr->explosionType = toolsData->explosionType;
 
 
1103
 
 
 
1104
    dynPtr->IsStatic = 0;
 
 
1105
    dynPtr->PrevPosition = dynPtr->Position = toolsData->position;
 
 
1106
    dynPtr->OrientEuler = toolsData->orientation;
 
 
1107
 
 
 
1108
    CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
1109
    TransposeMatrixCH(&dynPtr->OrientMat);      
 
 
1110
    sbPtr->containingModule = ModuleFromPosition(&dynPtr->Position, NULL);
 
 
1111
 
 
 
1112
    if(NULL == sbPtr->containingModule)
 
 
1113
    {
 
 
1114
        printf("no containing module for %d\n", sbPtr->type);
 
 
1115
        RemoveBehaviourStrategy(sbPtr);
 
 
1116
        return;
 
 
1117
    }
 
 
1118
 
 
 
1119
    switch(objectstatusptr->typeId)
 
 
1120
    {
 
 
1121
        case IOT_Static:
 
 
1122
        {
 
 
1123
            if(NULL != sbPtr->name)
 
 
1124
            {
 
 
1125
                if(!strncmp(sbPtr->name, "switch", 6))
 
 
1126
                {
 
 
1127
                    dynPtr->IsStatic = 1;
 
 
1128
                }
 
 
1129
                else if(!strncmp(sbPtr->name, "Shelf", 5))
 
 
1130
                {
 
 
1131
                    sbPtr->DamageBlock.Indestructable = 0;
 
 
1132
                    dynPtr->GravityOn = 0;
 
 
1133
                    dynPtr->IsNetGhost = 1;
 
 
1134
                }
 
 
1135
                else
 
 
1136
                {
 
 
1137
                    dynPtr->GravityOn = 0;
 
 
1138
                }
 
 
1139
            }
 
 
1140
            else
 
 
1141
            {
 
 
1142
                dynPtr->IsNetGhost = 1;
 
 
1143
            }
 
 
1144
        } // no break;
 
 
1145
        case IOT_HitMeAndIllDestroyBase:
 
 
1146
        {
 
 
1147
            sbPtr->DynPtr->Mass = toolsData->mass;
 
 
1148
        }
 
 
1149
        break;
 
 
1150
        case IOT_Furniture:     
 
 
1151
        {
 
 
1152
            dynPtr->Elasticity = 16384;
 
 
1153
            dynPtr->IsStatic = 0;
 
 
1154
            //dynPtr->IsInanimate = 1;
 
 
1155
            dynPtr->Mass = toolsData->mass;
 
 
1156
            dynPtr->Mass = 10;
 
 
1157
        }
 
 
1158
        break;
 
 
1159
        case IOT_Weapon:
 
 
1160
        {
 
 
1161
            dynPtr->Elasticity = 16384;
 
 
1162
            dynPtr->Mass = 10;
 
 
1163
            dynPtr->ToppleForce = TOPPLE_FORCE_FULL;
 
 
1164
            dynPtr->GravityOn = 0;
 
 
1165
            dynPtr->IsStatic = 0;
 
 
1166
            dynPtr->IsPickupObject = 1;
 
 
1167
 
 
 
1168
            //flamethrowers explode using a molotov explosion
 
 
1169
            //if(objectstatusptr->subType == WEAPON_FLAMETHROWER)
 
 
1170
            // need to be smartgun since WEAPON_AUTOSHOTGUN and WEAPON_PLASMAGUN was removed
 
 
1171
            if(objectstatusptr->subType == WEAPON_SADAR) // is really WEAPON_FLAMETHROWER
 
 
1172
                objectstatusptr->explosionType = 3;                            
 
 
1173
        }                               
 
 
1174
        break;
 
 
1175
        case IOT_Ammo:
 
 
1176
        {
 
 
1177
            dynPtr->Elasticity = 16384;
 
 
1178
            dynPtr->Mass = 10;
 
 
1179
            dynPtr->ToppleForce = TOPPLE_FORCE_FULL;
 
 
1180
            dynPtr->GravityOn = 0;
 
 
1181
            dynPtr->IsStatic = 0;
 
 
1182
            dynPtr->IsPickupObject = 1;
 
 
1183
 
 
 
1184
            //flamethrowers explode using a molotov explosion
 
 
1185
            if(objectstatusptr->subType == AMMO_FLAMETHROWER)
 
 
1186
                objectstatusptr->explosionType = 3;                            
 
 
1187
        }
 
 
1188
        break;
 
 
1189
        case IOT_Health:
 
 
1190
        case IOT_Armour:
 
 
1191
        case IOT_FieldCharge:
 
 
1192
        case IOT_SpecialPickupObject:
 
 
1193
        case IOT_Key:
 
 
1194
        {
 
 
1195
            dynPtr->Elasticity = 16384;
 
 
1196
            dynPtr->Mass = 3;
 
 
1197
            dynPtr->ToppleForce = TOPPLE_FORCE_FULL;
 
 
1198
            dynPtr->GravityOn = 0;
 
 
1199
            dynPtr->IsStatic = 0;
 
 
1200
            dynPtr->IsPickupObject = 1;
 
 
1201
        }
 
 
1202
        default:
 
 
1203
        break;
 
 
1204
    }
 
 
1205
 
 
 
1206
    /*check to see if object is animated.*/
 
 
1207
    {
 
 
1208
        int item_num = 0;
 
 
1209
        struct shapeheader* shptr = mainshapelist[sbPtr->shapeIndex];
 
 
1210
        TXACTRLBLK **pptxactrlblk = &objectstatusptr->inan_tac;
 
 
1211
 
 
 
1212
        for(; item_num < shptr->numitems; item_num++)
 
 
1213
        {
 
 
1214
            POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
 
 
1215
            assert(poly);
 
 
1216
 
 
 
1217
            if(poly->PolyFlags & iflag_txanim)
 
 
1218
            {
 
 
1219
                TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
1220
 
 
 
1221
                if(pnew_txactrlblk)
 
 
1222
                {
 
 
1223
                    pnew_txactrlblk->tac_flags = 0;                                                                         
 
 
1224
                    pnew_txactrlblk->tac_item = item_num;                                                                           
 
 
1225
                    pnew_txactrlblk->tac_sequence = 0;                                                                              
 
 
1226
                    pnew_txactrlblk->tac_node = 0;                                                                          
 
 
1227
                    pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(sbPtr->shapeIndex, item_num);                                                          
 
 
1228
                    pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, sbPtr->shapeIndex);
 
 
1229
 
 
 
1230
                    *pptxactrlblk = pnew_txactrlblk;
 
 
1231
                    pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
1232
                }
 
 
1233
                else
 
 
1234
                    *pptxactrlblk = NULL; 
 
 
1235
            }
 
 
1236
        }
 
 
1237
 
 
 
1238
        *pptxactrlblk = NULL;
 
 
1239
    }
 
 
1240
 
 
 
1241
    for(i=0; i < SB_NAME_LENGTH; i++)
 
 
1242
        sbPtr->SBname[i] = toolsData->nameID[i];
 
 
1243
 
 
 
1244
    if(SinglePlayer != AvP.PlayMode)
 
 
1245
    {
 
 
1246
        /* these must be initialised for respawning objects in multiplayer game */
 
 
1247
        objectstatusptr->startingHealth = sbPtr->DamageBlock.Health;
 
 
1248
        objectstatusptr->startingArmour = sbPtr->DamageBlock.Armour;
 
 
1249
        int remove = 0;
 
 
1250
 
 
 
1251
        //if in a network game , see if this is an allowable weapon
 
 
1252
        switch(objectstatusptr->typeId)
 
 
1253
        {
 
 
1254
            case IOT_Weapon:
 
 
1255
            {
 
 
1256
                switch(objectstatusptr->subType)
 
 
1257
                {
 
 
1258
                    case WEAPON_PULSERIFLE:
 
 
1259
                        remove = 1;
 
 
1260
                    break;
 
 
1261
                    case WEAPON_SMARTGUN:
 
 
1262
                        remove = netGameData.allowSmartgun;
 
 
1263
                    break;
 
 
1264
                    case WEAPON_FLAMETHROWER:
 
 
1265
                        remove = netGameData.allowFlamer;
 
 
1266
                    break;
 
 
1267
                    case WEAPON_SADAR:
 
 
1268
                        remove = netGameData.allowSadar;
 
 
1269
                    break;
 
 
1270
                    case WEAPON_GRENADELAUNCHER:
 
 
1271
                        remove = netGameData.allowGrenadeLauncher;
 
 
1272
                    break;
 
 
1273
                    case WEAPON_FRISBEE_LAUNCHER:
 
 
1274
                        remove = netGameData.allowSmartDisc;
 
 
1275
                    break;
 
 
1276
                    case WEAPON_MINIGUN:
 
 
1277
                        remove = netGameData.allowMinigun;
 
 
1278
                    break;
 
 
1279
                    case WEAPON_MARINE_PISTOL:
 
 
1280
                    case WEAPON_TWO_PISTOLS:
 
 
1281
                        remove = netGameData.allowPistols;
 
 
1282
                    break;
 
 
1283
                    default:
 
 
1284
                        remove = 0;
 
 
1285
                }
 
 
1286
 
 
 
1287
                if (!remove)
 
 
1288
                    RemoveBehaviourStrategy(sbPtr);
 
 
1289
            }
 
 
1290
            break;
 
 
1291
            case IOT_Ammo:
 
 
1292
            {
 
 
1293
                switch(objectstatusptr->subType)
 
 
1294
                {
 
 
1295
                    case AMMO_SMARTGUN:
 
 
1296
                        remove = netGameData.allowSmartgun;
 
 
1297
                    break;
 
 
1298
                    case AMMO_FLAMETHROWER:
 
 
1299
                        remove = netGameData.allowFlamer;
 
 
1300
                    break;
 
 
1301
                    case AMMO_SADAR_TOW:
 
 
1302
                        remove = netGameData.allowSadar;
 
 
1303
                    break;
 
 
1304
                    case AMMO_GRENADE:
 
 
1305
                        remove = netGameData.allowGrenadeLauncher;
 
 
1306
                    break;
 
 
1307
                    case AMMO_MARINE_PISTOL:
 
 
1308
                        remove = netGameData.allowPistols;
 
 
1309
                    break;
 
 
1310
                    case AMMO_FRISBEE:
 
 
1311
                        remove = netGameData.allowSmartDisc;
 
 
1312
                    break;
 
 
1313
                    case AMMO_MINIGUN:
 
 
1314
                        remove = netGameData.allowMinigun;
 
 
1315
                    break;
 
 
1316
                    default:
 
 
1317
                        remove = 0;
 
 
1318
                }
 
 
1319
 
 
 
1320
                if (!remove)
 
 
1321
                    RemoveBehaviourStrategy(sbPtr);
 
 
1322
            }
 
 
1323
            default:
 
 
1324
            break;
 
 
1325
        }
 
 
1326
    }
 
 
1327
}
 
 
1328
 
 
 
1329
/*----------------------------------------------------------------------
 
 
1330
  Use this function to initialise binary loaded objects
 
 
1331
  ----------------------------------------------------------------------*/
 
 
1332
 
 
 
1333
void EnableBehaviourType(STRATEGYBLOCK* sbptr, void *bhdata)
 
 
1334
{
 
 
1335
    switch(sbptr->type)
 
 
1336
    {
 
 
1337
        case I_BehaviourAlien:
 
 
1338
            InitAlienBehaviour(bhdata, sbptr);
 
 
1339
        break;
 
 
1340
        case I_BehaviourMarine:
 
 
1341
            InitMarineBehaviour(bhdata, sbptr);
 
 
1342
        break;
 
 
1343
        case I_BehaviourProximityDoor:
 
 
1344
            sbptr->DamageBlock.Indestructable = 1;
 
 
1345
            DoorProxBehaveInit(bhdata, sbptr);
 
 
1346
        break;
 
 
1347
        case I_BehaviourLiftDoor:
 
 
1348
            LiftDoorBehaveInit(bhdata, sbptr);
 
 
1349
        break;
 
 
1350
        case I_BehaviourSwitchDoor:
 
 
1351
            InitialiseSwitchDoor(bhdata, sbptr);
 
 
1352
        break;
 
 
1353
        case I_BehaviourPlatform:
 
 
1354
            sbptr->DamageBlock.Indestructable = 1;
 
 
1355
            InitialisePlatformLift(bhdata, sbptr);
 
 
1356
        break;
 
 
1357
        case I_BehaviourBinarySwitch:
 
 
1358
            sbptr->DamageBlock.Indestructable = 1;
 
 
1359
            BinarySwitchBehaveInit(bhdata, sbptr);
 
 
1360
        break;
 
 
1361
        case I_BehaviourLinkSwitch:
 
 
1362
            LinkSwitchBehaveInit(bhdata, sbptr);
 
 
1363
        break;
 
 
1364
        case I_BehaviourLift:
 
 
1365
            sbptr->DamageBlock.Indestructable = 1;
 
 
1366
            LiftBehaveInit(bhdata, sbptr);
 
 
1367
        break;
 
 
1368
        case I_BehaviourSimpleAnimation:
 
 
1369
            SimpleAnimationBehaveInit(bhdata, sbptr);
 
 
1370
        break;
 
 
1371
        case I_BehaviourGenerator:
 
 
1372
            InitGenerator(bhdata, sbptr);
 
 
1373
        break;
 
 
1374
        case I_BehaviourInanimateObject:
 
 
1375
            InitInanimateObject(bhdata, sbptr);
 
 
1376
        break;
 
 
1377
        case I_BehaviourLightFX:
 
 
1378
            LightFXBehaveInit (bhdata, sbptr);
 
 
1379
        break;
 
 
1380
        case I_BehaviourPlacedSound:
 
 
1381
            SoundBehaveInit(bhdata, sbptr);
 
 
1382
        break;
 
 
1383
        case I_BehaviourMissionComplete:
 
 
1384
            MissionCompleteBehaveInit (bhdata, sbptr);
 
 
1385
        break;
 
 
1386
        case I_BehaviourMessage:
 
 
1387
            MessageBehaveInit (bhdata, sbptr);
 
 
1388
        break;
 
 
1389
        case I_BehaviourTrackObject:
 
 
1390
            //sbptr->DamageBlock.Indestructable = 1;
 
 
1391
            TrackObjectBehaveInit(bhdata, sbptr);
 
 
1392
        break;
 
 
1393
        case I_BehaviourFan:
 
 
1394
            sbptr->DamageBlock.Indestructable = 1;
 
 
1395
            FanBehaveInit(bhdata, sbptr);
 
 
1396
        break;
 
 
1397
        case I_BehaviourPlacedHierarchy:
 
 
1398
            //sbptr->DamageBlock.Indestructable = 1;
 
 
1399
            PlacedHierarchyBehaveInit(bhdata, sbptr);
 
 
1400
        break;
 
 
1401
        case I_BehaviourPlacedLight:
 
 
1402
            InitPlacedLight(bhdata, sbptr);
 
 
1403
        break;
 
 
1404
        case I_BehaviourVideoScreen:
 
 
1405
            InitVideoScreen(bhdata, sbptr);
 
 
1406
        break;
 
 
1407
        case I_BehaviourPowerCable:
 
 
1408
            PowerCableBehaveInit(bhdata, sbptr);
 
 
1409
        break;
 
 
1410
        case I_BehaviourDeathVolume:
 
 
1411
            sbptr->DamageBlock.Indestructable = 1;
 
 
1412
            DeathVolumeBehaveInit(bhdata, sbptr);
 
 
1413
        break;
 
 
1414
        case I_BehaviourSelfDestruct:
 
 
1415
             SelfDestructBehaveInit(bhdata, sbptr);
 
 
1416
        break;
 
 
1417
        case I_BehaviourParticleGenerator:
 
 
1418
             ParticleGeneratorBehaveInit(bhdata, sbptr);
 
 
1419
        break;
 
 
1420
        case I_BehaviourAutoGun:
 
 
1421
            AutoGunBehaveInit(bhdata, sbptr);
 
 
1422
        break;
 
 
1423
        case I_BehaviourFaceHugger:
 
 
1424
            InitFacehuggerBehaviour(bhdata, sbptr);
 
 
1425
        break;
 
 
1426
        case I_BehaviourPredator:
 
 
1427
            InitPredatorBehaviour(bhdata, sbptr);
 
 
1428
        break;
 
 
1429
        case I_BehaviourXenoborg:
 
 
1430
            InitXenoborgBehaviour(bhdata, sbptr);
 
 
1431
        break;
 
 
1432
        case I_BehaviourQueenAlien:
 
 
1433
            InitQueenBehaviour(bhdata, sbptr);
 
 
1434
        break;
 
 
1435
        case I_BehaviourXenoborgMorphRoom:
 
 
1436
            InitXenoMorphRoom (bhdata, sbptr);
 
 
1437
        break;
 
 
1438
        case I_BehaviourDormantPredator:
 
 
1439
            InitDormantPredatorBehaviour(bhdata, sbptr);
 
 
1440
        default:
 
 
1441
        break;
 
 
1442
    }
 
 
1443
}
 
 
1444
 
 
 
1445
void AssignAllSBNames()
 
 
1446
{
 
 
1447
    int stratblock = NumActiveStBlocks;
 
 
1448
    assert(stratblock >= 0);
 
 
1449
 
 
 
1450
    while(--stratblock > 0)
 
 
1451
    {
 
 
1452
        STRATEGYBLOCK* sbptr = ActiveStBlockList[stratblock];
 
 
1453
        assert(sbptr);
 
 
1454
 
 
 
1455
        switch (sbptr->type)
 
 
1456
        {
 
 
1457
            case I_BehaviourBinarySwitch:
 
 
1458
            {
 
 
1459
                int i = 0;
 
 
1460
                BINARY_SWITCH_BEHAV_BLOCK *bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1461
                assert((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
 
 
1462
 
 
 
1463
                for (; i < bs_bhv->num_targets; i++)
 
 
1464
                    bs_bhv->bs_targets[i] = FindSBWithName(bs_bhv->target_names[i].name);
 
 
1465
            }
 
 
1466
            break;
 
 
1467
            case I_BehaviourLinkSwitch:
 
 
1468
            {
 
 
1469
                int i=0;
 
 
1470
                LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1471
                assert((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
1472
 
 
 
1473
                for(i=0; i < ls_bhv->num_linked_switches;i++)
 
 
1474
                    ls_bhv->lswitch_list[i].bswitch = FindSBWithName(ls_bhv->lswitch_list[i].bs_name);
 
 
1475
 
 
 
1476
                for(i=0;i < ls_bhv->num_targets; i++)
 
 
1477
                    ls_bhv->ls_targets[i].sbptr=FindSBWithName(ls_bhv->ls_targets[i].name);
 
 
1478
            }
 
 
1479
            break;
 
 
1480
            case I_BehaviourSwitchDoor:
 
 
1481
            {
 
 
1482
                SWITCH_DOOR_BEHAV_BLOCK *switchDoorBehaviourPtr = (SWITCH_DOOR_BEHAV_BLOCK *)sbptr->dataptr;
 
 
1483
                if(*((int *)switchDoorBehaviourPtr->linkedDoorName) + *( ((int *)switchDoorBehaviourPtr->linkedDoorName)+1 ) )
 
 
1484
                    switchDoorBehaviourPtr->linkedDoorPtr = FindSBWithName(switchDoorBehaviourPtr->linkedDoorName);
 
 
1485
 
 
 
1486
                /* may or may not be linked to another door */
 
 
1487
                #if DEBUG
 
 
1488
                if(switchDoorBehaviourPtr->linkedDoorPtr)
 
 
1489
                {
 
 
1490
                    assert(switchDoorBehaviourPtr->linkedDoorPtr->type == I_BehaviourSwitchDoor);
 
 
1491
                }
 
 
1492
                #endif
 
 
1493
            }
 
 
1494
            break;
 
 
1495
            case I_BehaviourProximityDoor:
 
 
1496
            {
 
 
1497
                PROXDOOR_BEHAV_BLOCK *doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1498
                assert((doorbhv->bhvr_type == I_BehaviourProximityDoor));
 
 
1499
 
 
 
1500
                if(doorbhv->lockable_door)
 
 
1501
                    doorbhv->door_lock_target = FindSBWithName(doorbhv->target_name);
 
 
1502
            }
 
 
1503
            break;
 
 
1504
            case I_BehaviourLift:
 
 
1505
            {
 
 
1506
                LIFT_BEHAV_BLOCK *lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1507
                assert((lift_bhv->bhvr_type == I_BehaviourLift));
 
 
1508
 
 
 
1509
                LIFT_STATION *curr_stn = &lift_bhv->lift_station;
 
 
1510
                assert(curr_stn);
 
 
1511
 
 
 
1512
                curr_stn->lift_call_switch = FindSBWithName(curr_stn->lift_call_switch_name);
 
 
1513
 
 
 
1514
                if((*(int*)&curr_stn->lift_floor_switch_name[0]) || (*(int*)&curr_stn->lift_floor_switch_name[4]))
 
 
1515
curr_stn->lift_floor_switch = FindSBWithName(curr_stn->lift_floor_switch_name); //lifts with switches that don't teleport,don't know about their
floor switches
 
 
1516
 
 
 
1517
                curr_stn->lift_door = FindSBWithName(curr_stn->lift_door_name);
 
 
1518
 
 
 
1519
                // find my module pointer
 
 
1520
                {
 
 
1521
                    STRATEGYBLOCK *my_sb = FindSBWithName(curr_stn->my_sb_name);
 
 
1522
 
 
 
1523
                    if (my_sb)
 
 
1524
                        curr_stn->lift_module = my_sb->moptr;
 
 
1525
                }
 
 
1526
 
 
 
1527
                // find the controlling lift behave block
 
 
1528
                lift_bhv->control_sb = FindSBWithName(lift_bhv->control_sb_name);
 
 
1529
 
 
 
1530
                assert(lift_bhv->control_sb);
 
 
1531
            /*
 
 
1532
                {
 
 
1533
                    //LIFT_STATION **lift_array;
 
 
1534
                    LIFT_BEHAV_BLOCK *cont_bhv = lift_bhv->control_sb->dataptr;
 
 
1535
                    lift_bhv->lift_control = cont_bhv->lift_control;
 
 
1536
                    //lift_array = cont_bhv->lift_control->lift_stations;
 
 
1537
                    //lift_array[curr_stn->num_floor] = curr_stn;
 
 
1538
                }
 
 
1539
            */
 
 
1540
                lift_bhv->lift_control = lift_bhv->control_sb->dataptr; //???
 
 
1541
 
 
 
1542
                if(curr_stn->starting_station)
 
 
1543
                {
 
 
1544
                    // the door on this floor is open
 
 
1545
                    // therefore, since we are all perfect
 
 
1546
                    // i can say
 
 
1547
 
 
 
1548
                    assert(lift_bhv->lift_control->curr_station == -1);
 
 
1549
 
 
 
1550
                    lift_bhv->lift_control->curr_station = curr_stn->num_floor;
 
 
1551
 
 
 
1552
                    if(curr_stn->lift_call_switch)
 
 
1553
                    {
 
 
1554
                        // turn on the floor lights
 
 
1555
                        RequestState(curr_stn->lift_call_switch, 1, 0);
 
 
1556
                        if((*(int*)&curr_stn->lift_floor_switch_name[0]) || (*(int*)&curr_stn->lift_floor_switch_name[4]))
 
 
1557
                            RequestState(curr_stn->lift_floor_switch, 1, 0);
 
 
1558
                    }
 
 
1559
                }
 
 
1560
            }
 
 
1561
            break;
 
 
1562
            case I_BehaviourXenoborgMorphRoom:
 
 
1563
            {
 
 
1564
                XENO_MORPH_ROOM_DATA * xmrd = (XENO_MORPH_ROOM_DATA *)sbptr->dataptr;
 
 
1565
 
 
 
1566
                assert (xmrd->bhvr_type == I_BehaviourXenoborgMorphRoom);
 
 
1567
 
 
 
1568
                xmrd->DoorToRoom = FindSBWithName(xmrd->doorID);
 
 
1569
            }
 
 
1570
            break;
 
 
1571
            case I_BehaviourAlien:
 
 
1572
            {
 
 
1573
                ALIEN_STATUS_BLOCK *alienStatus = (ALIEN_STATUS_BLOCK *)sbptr->dataptr;
 
 
1574
                alienStatus->death_target_sbptr = FindSBWithName(alienStatus->death_target_ID);
 
 
1575
            }
 
 
1576
            break;
 
 
1577
            case I_BehaviourMarine:
 
 
1578
            {
 
 
1579
                MARINE_STATUS_BLOCK *marineStatus = (MARINE_STATUS_BLOCK *)sbptr->dataptr;
 
 
1580
                marineStatus->death_target_sbptr = FindSBWithName(marineStatus->death_target_ID);
 
 
1581
            }
 
 
1582
            break;
 
 
1583
            case I_BehaviourPredator:
 
 
1584
            {
 
 
1585
                PREDATOR_STATUS_BLOCK *predatorStatus = (PREDATOR_STATUS_BLOCK *)sbptr->dataptr;
 
 
1586
                predatorStatus->death_target_sbptr = FindSBWithName(predatorStatus->death_target_ID);
 
 
1587
            }
 
 
1588
            break;
 
 
1589
            case I_BehaviourXenoborg:
 
 
1590
            {
 
 
1591
                XENO_STATUS_BLOCK *xenoStatus = (XENO_STATUS_BLOCK *)sbptr->dataptr;
 
 
1592
                xenoStatus->death_target_sbptr = FindSBWithName(xenoStatus->death_target_ID);
 
 
1593
            }
 
 
1594
            break;
 
 
1595
            case I_BehaviourAutoGun:
 
 
1596
            {
 
 
1597
                AUTOGUN_STATUS_BLOCK *agunStatus = (AUTOGUN_STATUS_BLOCK *)sbptr->dataptr;
 
 
1598
                agunStatus->death_target_sbptr = FindSBWithName(agunStatus->death_target_ID);
 
 
1599
            }
 
 
1600
            break;
 
 
1601
            case I_BehaviourQueenAlien:
 
 
1602
            {
 
 
1603
                QUEEN_STATUS_BLOCK *queenStatus = (QUEEN_STATUS_BLOCK *)sbptr->dataptr;
 
 
1604
                queenStatus->death_target_sbptr = FindSBWithName(queenStatus->death_target_ID);
 
 
1605
            }
 
 
1606
            break;
 
 
1607
            case I_BehaviourFaceHugger:
 
 
1608
            {
 
 
1609
                FACEHUGGER_STATUS_BLOCK *facehuggerStatus = (FACEHUGGER_STATUS_BLOCK *)sbptr->dataptr;
 
 
1610
                facehuggerStatus->death_target_sbptr = FindSBWithName(facehuggerStatus->death_target_ID);
 
 
1611
            }
 
 
1612
            break;
 
 
1613
            case I_BehaviourTrackObject:
 
 
1614
            {
 
 
1615
                int i=0;
 
 
1616
                TRACK_OBJECT_BEHAV_BLOCK *to_bhv = (TRACK_OBJECT_BEHAV_BLOCK *)sbptr->dataptr;
 
 
1617
 
 
 
1618
                for(; i < to_bhv->num_special_track_points; i++)
 
 
1619
                {
 
 
1620
                    int j=0;
 
 
1621
                    SPECIAL_TRACK_POINT* stp = &to_bhv->special_track_points[i];
 
 
1622
 
 
 
1623
                    for(; j < stp->num_targets; j++)
 
 
1624
                        stp->targets[j].target_sbptr = FindSBWithName(stp->targets[j].target_name);
 
 
1625
                }
 
 
1626
 
 
 
1627
                to_bhv->destruct_target_sbptr = FindSBWithName(to_bhv->destruct_target_ID);
 
 
1628
            }
 
 
1629
            break;
 
 
1630
            case I_BehaviourPlacedHierarchy:
 
 
1631
            {
 
 
1632
                int i = 0;
 
 
1633
                PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK *)sbptr->dataptr;
 
 
1634
 
 
 
1635
                for(; i < ph_bhv->num_special_track_points; i++)
 
 
1636
                {
 
 
1637
                    int j = 0;
 
 
1638
                    SPECIAL_TRACK_POINT* stp = &ph_bhv->special_track_points[i];
 
 
1639
 
 
 
1640
                    for(; j < stp->num_targets; j++)
 
 
1641
                        stp->targets[j].target_sbptr = FindSBWithName(stp->targets[j].target_name);
 
 
1642
                }
 
 
1643
            }
 
 
1644
            break;
 
 
1645
            case I_BehaviourInanimateObject:
 
 
1646
            {
 
 
1647
                INANIMATEOBJECT_STATUSBLOCK* objectstatusptr=(INANIMATEOBJECT_STATUSBLOCK*)sbptr->dataptr;
 
 
1648
 
 
 
1649
                if(objectstatusptr)
 
 
1650
                {
 
 
1651
                    if(objectstatusptr->event_target)
 
 
1652
                objectstatusptr->event_target->event_target_sbptr = FindSBWithName(objectstatusptr->event_target->event_target_ID);
 
 
1653
                }
 
 
1654
            }
 
 
1655
            break;
 
 
1656
            case I_BehaviourPlacedLight:
 
 
1657
            {
 
 
1658
                PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = (PLACED_LIGHT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1659
 
 
 
1660
                if(pl_bhv)
 
 
1661
                    pl_bhv->destruct_target_sbptr = FindSBWithName(pl_bhv->destruct_target_ID);
 
 
1662
            }
 
 
1663
            break;
 
 
1664
            case I_BehaviourVideoScreen:
 
 
1665
            {
 
 
1666
                VIDEO_SCREEN_BEHAV_BLOCK* videoScreen = (VIDEO_SCREEN_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1667
 
 
 
1668
                if(videoScreen)
 
 
1669
                    videoScreen->destruct_target_sbptr = FindSBWithName(videoScreen->destruct_target_ID);
 
 
1670
            }
 
 
1671
            default:
 
 
1672
            break;
 
 
1673
        }
 
 
1674
    }
 
 
1675
}
 
 
1676
 
 
 
1677
#define DOOR_OPENDISTANCE    (3000)                  /* mm */
 
 
1678
 
 
 
1679
/*---------------Patrick 6/1/97-------------------
 
 
1680
  Sorry, but I can't think of anything better than 
 
 
1681
  searching the    entire sb list for any object that
 
 
1682
  might trigger a door....
 
 
1683
  ------------------------------------------------*/
 
 
1684
static int AnythingNearProxDoor(MODULE *doorModulePtr, PROXDOOR_BEHAV_BLOCK *doorbhv)
 
 
1685
{
 
 
1686
    /* KJL 18:06:59 19/02/98 - I've rewritten this check so that it can cope with very tall doors. */    
 
 
1687
 
 
 
1688
    int i, maxY, minY, maxX, minX, maxZ, minZ;
 
 
1689
 
 
 
1690
    if (doorModulePtr->m_flags & MODULEFLAG_HORIZONTALDOOR)
 
 
1691
    {
 
 
1692
        maxY = doorModulePtr->m_world.vy + DOOR_OPENDISTANCE;
 
 
1693
        minY = doorModulePtr->m_world.vy - DOOR_OPENDISTANCE;
 
 
1694
        maxX = doorModulePtr->m_world.vx + doorModulePtr->m_maxx + DOOR_OPENDISTANCE/2;
 
 
1695
        minX = doorModulePtr->m_world.vx + doorModulePtr->m_minx - DOOR_OPENDISTANCE/2;
 
 
1696
        maxZ = doorModulePtr->m_world.vz + doorModulePtr->m_maxz + DOOR_OPENDISTANCE/2;
 
 
1697
        minZ = doorModulePtr->m_world.vz + doorModulePtr->m_minz - DOOR_OPENDISTANCE/2;
 
 
1698
    }
 
 
1699
    else
 
 
1700
    {
 
 
1701
        maxY = doorModulePtr->m_world.vy + doorModulePtr->m_maxy;
 
 
1702
        minY = doorModulePtr->m_world.vy + doorModulePtr->m_miny;
 
 
1703
        maxX = doorModulePtr->m_world.vx + DOOR_OPENDISTANCE;
 
 
1704
        minX = doorModulePtr->m_world.vx - DOOR_OPENDISTANCE;
 
 
1705
        maxZ = doorModulePtr->m_world.vz + DOOR_OPENDISTANCE;
 
 
1706
        minZ = doorModulePtr->m_world.vz - DOOR_OPENDISTANCE;
 
 
1707
    }
 
 
1708
 
 
 
1709
    /* loop thro' the strategy block list... 
 
 
1710
    looking for triggerable objects (please feel free to add any
 
 
1711
    sensible object types) */
 
 
1712
    int return_value = 0;
 
 
1713
 
 
 
1714
    for(i = 0; i < NumActiveStBlocks; i++)
 
 
1715
    {
 
 
1716
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[i];
 
 
1717
 
 
 
1718
        if(NULL != sbPtr->DisplayBlock)
 
 
1719
        {
 
 
1720
            switch(sbPtr->type)
 
 
1721
            {
 
 
1722
                case I_BehaviourPlatform:
 
 
1723
                {
 
 
1724
                    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
1725
 
 
 
1726
                    if ((dynPtr->Position.vy > minY && dynPtr->Position.vy < maxY)
 
 
1727
                    &&
 
 
1728
                    (dynPtr->Position.vx > minX && dynPtr->Position.vx < maxX)
 
 
1729
                    &&
 
 
1730
                    (dynPtr->Position.vz > minZ && dynPtr->Position.vz < maxZ))
 
 
1731
                    {
 
 
1732
                        PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
1733
                        if(PLBS_AtRest != platformliftdata->state)
 
 
1734
                        {
 
 
1735
                            doorbhv->door_locked = 2;
 
 
1736
                            return 0;
 
 
1737
                        }
 
 
1738
                        else if(2 == doorbhv->door_locked)
 
 
1739
                        {
 
 
1740
                            doorbhv->door_locked = 0;
 
 
1741
                            return 1;
 
 
1742
                        }
 
 
1743
                    }
 
 
1744
                }
 
 
1745
                case I_BehaviourAlien:
 
 
1746
                case I_BehaviourMarine:
 
 
1747
                case I_BehaviourMarinePlayer:
 
 
1748
                case I_BehaviourPredatorPlayer:
 
 
1749
                case I_BehaviourAlienPlayer:
 
 
1750
                case I_BehaviourPredator:
 
 
1751
                case I_BehaviourXenoborg:
 
 
1752
                case I_BehaviourQueenAlien:
 
 
1753
                case I_BehaviourNetGhost:
 
 
1754
                case I_BehaviourCorpse:
 
 
1755
                //case I_BehaviourHierarchicalFragment:
 
 
1756
                {
 
 
1757
                    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
1758
 
 
 
1759
                    if ((dynPtr->Position.vy > minY && dynPtr->Position.vy < maxY)
 
 
1760
                    &&
 
 
1761
                    (dynPtr->Position.vx > minX && dynPtr->Position.vx < maxX)
 
 
1762
                    &&
 
 
1763
                    (dynPtr->Position.vz > minZ && dynPtr->Position.vz < maxZ))
 
 
1764
                    {
 
 
1765
                        if (sbPtr->type == I_BehaviourMarine) 
 
 
1766
                            doorbhv->marineTrigger = 1;
 
 
1767
 
 
 
1768
                        return_value = 1;
 
 
1769
                    }
 
 
1770
                }
 
 
1771
                default:
 
 
1772
                break;
 
 
1773
            }
 
 
1774
        }
 
 
1775
    }
 
 
1776
 
 
 
1777
return return_value;
 
 
1778
}
 
 
1779
 
 
 
1780
void OpenDoor(MORPHCTRL *mctrl, int speed)
 
 
1781
{
 
 
1782
    assert(mctrl);
 
 
1783
 
 
 
1784
    mctrl->ObMorphFlags = mph_flag_play | mph_flag_noloop | mph_flag_reverse;
 
 
1785
    mctrl->ObMorphSpeed = speed;
 
 
1786
}
 
 
1787
 
 
 
1788
void CloseDoor(MORPHCTRL *mctrl, int speed)
 
 
1789
{
 
 
1790
    assert(mctrl);
 
 
1791
 
 
 
1792
    mctrl->ObMorphFlags = mph_flag_play | mph_flag_noloop;
 
 
1793
    mctrl->ObMorphFlags &= ~mph_flag_reverse;
 
 
1794
    mctrl->ObMorphSpeed = speed;
 
 
1795
}
 
 
1796
 
 
 
1797
static void DoorProxBehaveFun(STRATEGYBLOCK* sbptr)
 
 
1798
{
 
 
1799
    int open_door = 0;
 
 
1800
 
 
 
1801
    PROXDOOR_BEHAV_BLOCK *doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
1802
    assert((doorbhv->bhvr_type == I_BehaviourProximityDoor));
 
 
1803
    MORPHCTRL *mctrl = doorbhv->PDmctrl;
 
 
1804
    assert(mctrl);
 
 
1805
    MODULE *mptr = sbptr->moptr;
 
 
1806
    assert(mptr);
 
 
1807
    DISPLAYBLOCK* dptr = sbptr->DisplayBlock;
 
 
1808
 
 
 
1809
    UpdateMorphing(mctrl);
 
 
1810
 
 
 
1811
    if (!(1 == doorbhv->door_locked) && (I_door_opening != doorbhv->door_state))
 
 
1812
    {
 
 
1813
        /* if door is visible check for proximity of player, aliens, and whatever... */
 
 
1814
        /* check for an alien trigger: NB Door could be either visible or not when triggered */
 
 
1815
 
 
 
1816
        if (doorbhv->alienTrigger || doorbhv->marineTrigger)
 
 
1817
        {
 
 
1818
            open_door = 1;
 
 
1819
 
 
 
1820
            doorbhv->Timer = DOOR_FAROPENTIME;
 
 
1821
            doorbhv->alienTrigger = 0;
 
 
1822
        }
 
 
1823
        else if((SinglePlayer != AvP.PlayMode) || dptr)
 
 
1824
        {
 
 
1825
            /*-----------------Patrick 29/4/97-------------------------
 
 
1826
             Little patch for networking: doors should run the
 
 
1827
             AnythingNearProxDoor() test even when they are not visible
 
 
1828
             ----------------------------------------------------------*/ 
 
 
1829
            open_door = AnythingNearProxDoor(mptr, doorbhv);
 
 
1830
        }
 
 
1831
    }
 
 
1832
 
 
 
1833
     switch(doorbhv->door_state)
 
 
1834
    {
 
 
1835
        case I_door_opening:
 
 
1836
        {    
 
 
1837
            mptr->m_flags |= m_flag_open;
 
 
1838
 
 
 
1839
            if(mctrl->ObMorphFlags & mph_flag_finished)        
 
 
1840
            {
 
 
1841
                if (doorbhv->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
1842
                {
 
 
1843
                    Sound_Play(SID_DOOREND, (doorbhv->marineTrigger ? "dpm" : "dp"), &mptr->m_world, doorbhv->doorType);
 
 
1844
                    Sound_Stop(doorbhv->SoundHandle);
 
 
1845
                }
 
 
1846
 
 
 
1847
                doorbhv->door_state = I_door_open;
 
 
1848
                doorbhv->Timer = DOOR_FAROPENTIME;
 
 
1849
            }
 
 
1850
        }
 
 
1851
        break;
 
 
1852
        case I_door_closing:
 
 
1853
        {
 
 
1854
            if(open_door)
 
 
1855
            {
 
 
1856
                if(dptr) 
 
 
1857
                {
 
 
1858
                    OpenDoor(mctrl, doorbhv->door_opening_speed);
 
 
1859
 
 
 
1860
                    if (doorbhv->SoundHandle == SOUND_NOACTIVEINDEX)
 
 
1861
                    {
 
 
1862
                        if (doorbhv->marineTrigger)
 
 
1863
                        {
 
 
1864
                              Sound_Play(SID_DOORSTART, "dpm", &mptr->m_world, doorbhv->doorType);
 
 
1865
                             Sound_Play(SID_DOORMID, "delpm", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1866
                        }
 
 
1867
                        else
 
 
1868
                        {
 
 
1869
                              Sound_Play(SID_DOORSTART, "dp", &mptr->m_world, doorbhv->doorType);
 
 
1870
                             Sound_Play(SID_DOORMID, "delp", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1871
                        }
 
 
1872
                     }
 
 
1873
                }
 
 
1874
                else 
 
 
1875
                {
 
 
1876
                    OpenDoor(mctrl, DOOR_OPENFASTSPEED);
 
 
1877
                }
 
 
1878
 
 
 
1879
                doorbhv->door_state = I_door_opening;
 
 
1880
            }
 
 
1881
            else if(mctrl->ObMorphFlags & mph_flag_finished)
 
 
1882
            {
 
 
1883
                if (doorbhv->SoundHandle != SOUND_NOACTIVEINDEX)
 
 
1884
                {
 
 
1885
                       Sound_Play(SID_DOOREND, (doorbhv->marineTrigger ? "dpm" : "dp"), &mptr->m_world, doorbhv->doorType);
 
 
1886
                    Sound_Stop(doorbhv->SoundHandle);
 
 
1887
                }
 
 
1888
 
 
 
1889
                doorbhv->door_state = I_door_closed;
 
 
1890
                mptr->m_flags &= ~m_flag_open;
 
 
1891
            }
 
 
1892
        }
 
 
1893
        break;
 
 
1894
        case I_door_open:
 
 
1895
        {
 
 
1896
            mptr->m_flags |= m_flag_open;
 
 
1897
 
 
 
1898
            if(!open_door)
 
 
1899
            {
 
 
1900
                if(doorbhv->Timer < 0)
 
 
1901
                {
 
 
1902
                    CloseDoor(mctrl, (dptr ? doorbhv->door_closing_speed : DOOR_CLOSEFASTSPEED));
 
 
1903
                    doorbhv->door_state = I_door_closing;
 
 
1904
 
 
 
1905
                    if(dptr) 
 
 
1906
                    {
 
 
1907
                        if (doorbhv->marineTrigger)
 
 
1908
                        {
 
 
1909
                            Sound_Play(SID_DOORSTART, "dpm", &mptr->m_world, doorbhv->doorType);
 
 
1910
                            Sound_Play(SID_DOORMID, "delpm", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1911
                        }
 
 
1912
                        else
 
 
1913
                        {
 
 
1914
                            Sound_Play(SID_DOORSTART, "dp", &mptr->m_world, doorbhv->doorType);
 
 
1915
                            Sound_Play(SID_DOORMID, "delp", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1916
                        }
 
 
1917
                    }
 
 
1918
                }
 
 
1919
                else
 
 
1920
                {
 
 
1921
                    doorbhv->Timer -= NormalFrameTime;
 
 
1922
                }
 
 
1923
            }
 
 
1924
        }
 
 
1925
        break;
 
 
1926
        case I_door_closed:
 
 
1927
        {
 
 
1928
            mptr->m_flags &= ~m_flag_open;
 
 
1929
 
 
 
1930
            if(open_door)
 
 
1931
            {
 
 
1932
                 if(dptr) 
 
 
1933
                {
 
 
1934
                    if (doorbhv->marineTrigger)
 
 
1935
                    {
 
 
1936
                        Sound_Play(SID_DOORSTART, "dpm", &mptr->m_world, doorbhv->doorType);
 
 
1937
                         Sound_Play(SID_DOORMID, "delpm", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1938
                    }
 
 
1939
                    else
 
 
1940
                    {
 
 
1941
                        Sound_Play(SID_DOORSTART, "dp", &mptr->m_world, doorbhv->doorType);
 
 
1942
                        Sound_Play(SID_DOORMID, "delp", &mptr->m_world, &doorbhv->SoundHandle, doorbhv->doorType);
 
 
1943
                    }
 
 
1944
 
 
 
1945
                    OpenDoor(mctrl, doorbhv->door_opening_speed);
 
 
1946
                }
 
 
1947
                else
 
 
1948
                {
 
 
1949
                    OpenDoor(mctrl, DOOR_OPENFASTSPEED);
 
 
1950
                }
 
 
1951
 
 
 
1952
                doorbhv->door_state = I_door_opening;
 
 
1953
                mptr->m_flags |= m_flag_open;
 
 
1954
            }
 
 
1955
            else
 
 
1956
            {
 
 
1957
                doorbhv->Timer = DOOR_FAROPENTIME;
 
 
1958
            }
 
 
1959
        }
 
 
1960
        break;
 
 
1961
        default:
 
 
1962
            assert(1==0);
 
 
1963
            break;
 
 
1964
    }
 
 
1965
 
 
 
1966
    doorbhv->marineTrigger = 0;
 
 
1967
}
 
 
1968
 
 
 
1969
static void SimpleAnimBehaveFun(STRATEGYBLOCK* sbptr)
 
 
1970
{
 
 
1971
    /* this just copie the SB taccontrol into the
 
 
1972
       display bloxk if it didnt already have one*/
 
 
1973
 
 
 
1974
    SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->dataptr);
 
 
1975
 
 
 
1976
    assert(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation);
 
 
1977
 
 
 
1978
      DISPLAYBLOCK* dptr = sbptr->DisplayBlock;
 
 
1979
 
 
 
1980
    if(dptr && !dptr->ObTxAnimCtrlBlks)
 
 
1981
        dptr->ObTxAnimCtrlBlks = sanimbhv->tacbSimple;
 
 
1982
}
 
 
1983
 
 
 
1984
static void MakeObjectNear(STRATEGYBLOCK *sbPtr)
 
 
1985
{
 
 
1986
        DISPLAYBLOCK *dPtr = AllocateNewObject(sbPtr->shapeIndex); 
 
 
1987
 
 
 
1988
        if(NULL != dPtr)
 
 
1989
    {
 
 
1990
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
1991
        sbPtr->DisplayBlock = dPtr;
 
 
1992
        dPtr->ObStrategyBlock = sbPtr;
 
 
1993
 
 
 
1994
        /* also need to initialise positional information in the new display
 
 
1995
        block from the existing dynamics block: this necessary because this 
 
 
1996
        function is (usually) called between the dynamics and rendering systems
 
 
1997
        so it is not initialised by the dynamics system the first time it is
 
 
1998
        drawn. */
 
 
1999
        dPtr->ObWorld = dynPtr->Position;
 
 
2000
        dPtr->ObEuler = dynPtr->OrientEuler;
 
 
2001
        dPtr->ObMat = dynPtr->OrientMat;
 
 
2002
    }
 
 
2003
    /*else  cannot create displayblock, so leave object "far" */
 
 
2004
}
 
 
2005
 
 
 
2006
void RespawnInanimateObject(STRATEGYBLOCK *sbPtr)
 
 
2007
{
 
 
2008
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr;
 
 
2009
    assert(objectstatusptr);
 
 
2010
 
 
 
2011
    sbPtr->maintainVisibility = 1;
 
 
2012
 
 
 
2013
    /* must respawn health too... */        
 
 
2014
    sbPtr->DamageBlock.Health = objectstatusptr->startingHealth;
 
 
2015
    sbPtr->DamageBlock.Armour = objectstatusptr->startingArmour;
 
 
2016
}
 
 
2017
 
 
 
2018
void KillFragmentalObjectForRespawn(STRATEGYBLOCK *sbPtr)
 
 
2019
{
 
 
2020
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr;
 
 
2021
    assert(objectstatusptr);
 
 
2022
 
 
 
2023
    /* make the object invisible, and remove it from visibility management */
 
 
2024
    sbPtr->maintainVisibility = 0;
 
 
2025
 
 
 
2026
    DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
2027
 
 
 
2028
    /* KJL 12:44:23 24/05/98 -
 
 
2029
    Set the respawn counter to be the max allowable, so that if all the
 
 
2030
    respawn counters are set to zero, it forces all the objects that have been
 
 
2031
    destroyed (eg. glass) to respawn simultaneously.
 
 
2032
    Not a perfect solution: the object will respawn in 9.1 hours on its own.
 
 
2033
    */
 
 
2034
 
 
 
2035
    objectstatusptr->respawnTimer = OBJECT_RESPAWN_NO_RESPAWN;
 
 
2036
}
 
 
2037
 
 
 
2038
void KillInanimateObjectForRespawn(STRATEGYBLOCK *sbPtr)
 
 
2039
{
 
 
2040
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr;
 
 
2041
    assert(objectstatusptr);
 
 
2042
 
 
 
2043
    /* make the object invisible, and remove it from visibility management */
 
 
2044
    if(!objectstatusptr->lifespanTimer)
 
 
2045
    {
 
 
2046
        sbPtr->maintainVisibility = 0;
 
 
2047
 
 
 
2048
        DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
2049
 
 
 
2050
        if(netGameData.timeForRespawn>0)
 
 
2051
            objectstatusptr->respawnTimer = netGameData.timeForRespawn*ONE_FIXED;
 
 
2052
        else
 
 
2053
            objectstatusptr->respawnTimer = OBJECT_RESPAWN_NO_RESPAWN;
 
 
2054
    }
 
 
2055
    else
 
 
2056
    {
 
 
2057
        //get rid of this object permanently
 
 
2058
        sbPtr->please_destroy_me = 1;
 
 
2059
    }
 
 
2060
}
 
 
2061
 
 
 
2062
/* this global flag is used to distinguish between messages from the host, and locally caused damage */
 
 
2063
int InanimateDamageFromNetHost = 0;
 
 
2064
extern SOUND3DDATA Explosion_SoundData;
 
 
2065
 
 
 
2066
void InanimateObjectIsDamaged(STRATEGYBLOCK *sbPtr, const DAMAGE_PROFILE *damage, int multiple)
 
 
2067
{
 
 
2068
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr;
 
 
2069
 
 
 
2070
    switch(AvP.PlayMode)
 
 
2071
    {
 
 
2072
        case NetworkPeer:
 
 
2073
            if(!InanimateDamageFromNetHost)
 
 
2074
            {
 
 
2075
                /* this means that the damage was generated locally in a net-game:
 
 
2076
                in this case, just send a damage message to the host */
 
 
2077
                AddNetMsg_InanimateObjectDamaged(sbPtr, damage, multiple);
 
 
2078
                return;
 
 
2079
            }
 
 
2080
        break;
 
 
2081
        case NetworkHost:
 
 
2082
            /* if we're the host, inform everyone that the object is dead */
 
 
2083
            if(sbPtr->DamageBlock.Health <= 0)
 
 
2084
                AddNetMsg_InanimateObjectDestroyed(sbPtr);
 
 
2085
        default:
 
 
2086
        break;
 
 
2087
    }
 
 
2088
 
 
 
2089
    //if object has been destroyed , see if it has a target that it needs to notify
 
 
2090
    if((objectstatusptr->event_target) && (sbPtr->DamageBlock.Health <= 0) && (objectstatusptr->event_target->triggering_event
& ObjectEventFlag_Destroyed))
 
 
2091
    {
 
 
2092
        RequestState(objectstatusptr->event_target->event_target_sbptr, objectstatusptr->event_target->request, 0);
 
 
2093
    }
 
 
2094
 
 
 
2095
    sbPtr->DynPtr->GravityOn = 1;
 
 
2096
 
 
 
2097
    if(sbPtr->DamageBlock.Health <= 0) 
 
 
2098
    {
 
 
2099
        if (objectstatusptr->explosionType && !objectstatusptr->explosionTimer)
 
 
2100
        {
 
 
2101
            //start explosion timer
 
 
2102
            //this gives a slight time delay for object destruction, to allow for chain reactions
 
 
2103
            //(rather than all explosive objects going up in one frame)
 
 
2104
            objectstatusptr->explosionTimer = ONE_FIXED/10;
 
 
2105
            objectstatusptr->explosionStartFrame = GlobalFrameCounter;
 
 
2106
            return;
 
 
2107
        }
 
 
2108
 
 
 
2109
        switch(objectstatusptr->typeId)
 
 
2110
        {
 
 
2111
            case IOT_Weapon:
 
 
2112
            case IOT_Health:
 
 
2113
            case IOT_Armour:
 
 
2114
            case IOT_FieldCharge:
 
 
2115
            case IOT_Ammo:
 
 
2116
            case IOT_SpecialPickupObject:
 
 
2117
            {
 
 
2118
                MakeFragments(sbPtr);
 
 
2119
 
 
 
2120
                if(SinglePlayer == AvP.PlayMode)
 
 
2121
                    sbPtr->please_destroy_me = 1;
 
 
2122
                else
 
 
2123
                    KillInanimateObjectForRespawn(sbPtr);                      
 
 
2124
            }
 
 
2125
            break;
 
 
2126
            case IOT_Furniture:
 
 
2127
            {
 
 
2128
                MakeFragments(sbPtr);
 
 
2129
 
 
 
2130
                sbPtr->please_destroy_me = 1;
 
 
2131
            }
 
 
2132
            break;
 
 
2133
            case IOT_Static:
 
 
2134
            {
 
 
2135
                MakeFragments(sbPtr);
 
 
2136
 
 
 
2137
                if(SinglePlayer == AvP.PlayMode)
 
 
2138
                    sbPtr->please_destroy_me = 1;
 
 
2139
                else
 
 
2140
                    KillFragmentalObjectForRespawn(sbPtr);                     
 
 
2141
            }
 
 
2142
            break;
 
 
2143
            case IOT_BoxedSentryGun:
 
 
2144
            {
 
 
2145
                if(SinglePlayer == AvP.PlayMode)
 
 
2146
                    sbPtr->please_destroy_me = 1;
 
 
2147
                else
 
 
2148
                    KillInanimateObjectForRespawn(sbPtr);                      
 
 
2149
            }
 
 
2150
            break;
 
 
2151
            default:
 
 
2152
            {
 
 
2153
                assert(1==0);                              
 
 
2154
                break;
 
 
2155
            }
 
 
2156
        }
 
 
2157
    }
 
 
2158
}
 
 
2159
 
 
 
2160
static void InanimateObjectBehaviour(STRATEGYBLOCK *sbPtr)
 
 
2161
{
 
 
2162
    /* handle respawn timer here */
 
 
2163
    INANIMATEOBJECT_STATUSBLOCK* objectstatusptr = sbPtr->dataptr;
 
 
2164
    assert(objectstatusptr);
 
 
2165
    assert(!(objectstatusptr->respawnTimer < 0)); /* this should never happen */
 
 
2166
 
 
 
2167
    if(objectstatusptr->inan_tac)
 
 
2168
    {
 
 
2169
        DISPLAYBLOCK* dptr = sbPtr->DisplayBlock;
 
 
2170
 
 
 
2171
        /*deal with texture animation*/
 
 
2172
        if(dptr && !dptr->ObTxAnimCtrlBlks)
 
 
2173
            dptr->ObTxAnimCtrlBlks = objectstatusptr->inan_tac;
 
 
2174
    }
 
 
2175
 
 
 
2176
    if(DynamicObjectIsMoving(sbPtr->DynPtr)) //???
 
 
2177
        sbPtr->DynPtr->GravityOn = 1;
 
 
2178
 
 
 
2179
    if(objectstatusptr->explosionTimer)
 
 
2180
    {
 
 
2181
        if(objectstatusptr->explosionStartFrame == GlobalFrameCounter)
 
 
2182
        {
 
 
2183
            //the explosion was triggered earlier this frame
 
 
2184
            //therefore don't bother altering the timer until next frame
 
 
2185
            return;
 
 
2186
        }
 
 
2187
 
 
 
2188
        objectstatusptr->explosionTimer -= NormalFrameTime;
 
 
2189
 
 
 
2190
        if(objectstatusptr->explosionTimer <= 0)
 
 
2191
        {
 
 
2192
            //MakeFragments(sbPtr); ???
 
 
2193
            //do explosion effect , without the damage?
 
 
2194
            switch(objectstatusptr->explosionType)
 
 
2195
            {
 
 
2196
                case 1:
 
 
2197
                {
 
 
2198
                    MakeVolumetricExplosionAt(&sbPtr->DynPtr->Position, (InanimateDamageFromNetHost ? EXPLOSION_SMALL_NOCOLLISIONS :
EXPLOSION_PULSEGRENADE));
 
 
2199
                    Explosion_SoundData.position = sbPtr->DynPtr->Position;
 
 
2200
                    Sound_Play(SID_NADEEXPLODE, "n", &Explosion_SoundData);
 
 
2201
                }
 
 
2202
                break;
 
 
2203
                case 2:
 
 
2204
                {
 
 
2205
                    MakeVolumetricExplosionAt(&sbPtr->DynPtr->Position, (InanimateDamageFromNetHost ? EXPLOSION_GRENADE_NOCOLLISIONS :
EXPLOSION_GRENADE_BLAST));
 
 
2206
                    Explosion_SoundData.position = sbPtr->DynPtr->Position;
 
 
2207
                    Sound_Play(SID_NICE_EXPLOSION, "n", &Explosion_SoundData);
 
 
2208
                }
 
 
2209
                break;
 
 
2210
                case 3:
 
 
2211
                {
 
 
2212
                    MakeMolotovExplosionAt(&sbPtr->DynPtr->Position);
 
 
2213
                    Explosion_SoundData.position = sbPtr->DynPtr->Position;
 
 
2214
                    Sound_Play(SID_NADEEXPLODE, "n", &Explosion_SoundData);
 
 
2215
                }
 
 
2216
            }
 
 
2217
 
 
 
2218
            sbPtr->please_destroy_me = 1;
 
 
2219
            return;
 
 
2220
        }
 
 
2221
    }
 
 
2222
 
 
 
2223
    if(sbPtr->DamageBlock.IsOnFire)
 
 
2224
        CauseDamageToObject(sbPtr, &damage_profiles[FIREDAMAGE], NormalFrameTime, NULL);
 
 
2225
 
 
 
2226
    if(sbPtr->containingModule == PlayerStatus.sbptr->containingModule)
 
 
2227
    {
 
 
2228
        if(AvP.PlayerType != I_Alien)
 
 
2229
        {
 
 
2230
            if(objectstatusptr->typeId == IOT_Static)
 
 
2231
            {
 
 
2232
                if(sbPtr->name && !strncmp(sbPtr->name, "egg", 3))
 
 
2233
                {
 
 
2234
                    if (!(FastRandom() % 300))
 
 
2235
                    {
 
 
2236
                        CreateFacehuggerBot(&sbPtr->DisplayBlock->ObWorld);
 
 
2237
                        MakeFragments(sbPtr);
 
 
2238
                        sbPtr->please_destroy_me = 1;
 
 
2239
                    }
 
 
2240
                }
 
 
2241
            }
 
 
2242
 
 
 
2243
            if(sbPtr->DynPtr && sbPtr->DynPtr->IsPickupObject)
 
 
2244
            {
 
 
2245
                DYNAMICSBLOCK *dynPtr = PlayerStatus.sbptr->DynPtr;
 
 
2246
                VECTORCH disp;
 
 
2247
 
 
 
2248
                disp.vx = dynPtr->Position.vx - sbPtr->DynPtr->Position.vx;
 
 
2249
                disp.vy = dynPtr->Position.vy - sbPtr->DynPtr->Position.vy;
 
 
2250
                disp.vz = dynPtr->Position.vz - sbPtr->DynPtr->Position.vz;
 
 
2251
 
 
 
2252
                if (Approximate3dMagnitude(&disp) < PLAYER_PICKUP_OBJECT_RADIUS)
 
 
2253
                    MaintainPlayersInventory(sbPtr);
 
 
2254
            }
 
 
2255
        }
 
 
2256
    }
 
 
2257
 
 
 
2258
    if(SinglePlayer != AvP.PlayMode)
 
 
2259
    {
 
 
2260
        //see if dropped weapons have timed out
 
 
2261
        if(objectstatusptr->lifespanTimer > 0)
 
 
2262
        {
 
 
2263
            objectstatusptr->lifespanTimer -= NormalFrameTime;
 
 
2264
 
 
 
2265
            if(objectstatusptr->lifespanTimer <= 0)
 
 
2266
            {
 
 
2267
                MakeFragments(sbPtr);
 
 
2268
                sbPtr->please_destroy_me = 1;
 
 
2269
            }
 
 
2270
        return;
 
 
2271
        }
 
 
2272
 
 
 
2273
        /* do nothing if the timer is zero */
 
 
2274
        if(!objectstatusptr->respawnTimer || objectstatusptr->respawnTimer == OBJECT_RESPAWN_NO_RESPAWN)
 
 
2275
            return;
 
 
2276
 
 
 
2277
        /* printf("RESPAWN TIMER %d \n", objectstatusptr->respawnTimer); */          
 
 
2278
        /* If we get here, the object is in a respawn state: this should only happen in a net-game */
 
 
2279
        assert(!sbPtr->maintainVisibility);
 
 
2280
 
 
 
2281
        objectstatusptr->respawnTimer -= NormalFrameTime;
 
 
2282
 
 
 
2283
        if(objectstatusptr->respawnTimer <= 0)
 
 
2284
        {
 
 
2285
            /* time to respawn, then */
 
 
2286
            RespawnInanimateObject(sbPtr);
 
 
2287
            objectstatusptr->respawnTimer = 0;        
 
 
2288
        }
 
 
2289
    }
 
 
2290
}
 
 
2291
 
 
 
2292
void IdentifyObject(STRATEGYBLOCK *sbPtr) 
 
 
2293
{
 
 
2294
    if (sbPtr == NULL)
 
 
2295
    {
 
 
2296
        printf("Object is NULL!\n");
 
 
2297
        return;
 
 
2298
    }
 
 
2299
 
 
 
2300
    switch(sbPtr->type)
 
 
2301
    {
 
 
2302
        case I_BehaviourInanimateObject:
 
 
2303
        {
 
 
2304
            INANIMATEOBJECT_STATUSBLOCK* objStatPtr = sbPtr->dataptr;
 
 
2305
 
 
 
2306
            switch(objStatPtr->typeId)
 
 
2307
            {
 
 
2308
                case(IOT_Weapon):
 
 
2309
                {
 
 
2310
                    switch(objStatPtr->subType)
 
 
2311
                    {
 
 
2312
                        case WEAPON_PULSERIFLE:
 
 
2313
                        {
 
 
2314
                            printf("Object is a Pulse Rifle.\n");
 
 
2315
                            return;
 
 
2316
                        }
 
 
2317
                        case WEAPON_SMARTGUN:
 
 
2318
                        {
 
 
2319
                            printf("Object is a Smartgun.\n");
 
 
2320
                            return;
 
 
2321
                        }
 
 
2322
                        case WEAPON_FLAMETHROWER:
 
 
2323
                        {
 
 
2324
                            printf("Object is a Flamethrower.\n");
 
 
2325
                            return;
 
 
2326
                        }
 
 
2327
                        case WEAPON_SADAR:
 
 
2328
                        {
 
 
2329
                            printf("Object is a Sadar.\n");
 
 
2330
                            return;
 
 
2331
                        }
 
 
2332
                        case WEAPON_GRENADELAUNCHER:
 
 
2333
                        {
 
 
2334
                            printf("Object is a Grenade Launcher.\n");
 
 
2335
                            return;
 
 
2336
                        }
 
 
2337
                        case WEAPON_MINIGUN:
 
 
2338
                        {
 
 
2339
                            printf("Object is a Minigun.\n");
 
 
2340
                            return;
 
 
2341
                        }
 
 
2342
 
 
 
2343
                        default:
 
 
2344
                            printf("Object is unknown weapon (subtype %d).\n",(int)objStatPtr->subType);
 
 
2345
                            break;
 
 
2346
                    }
 
 
2347
                }
 
 
2348
                break;
 
 
2349
                case IOT_Ammo:
 
 
2350
                {
 
 
2351
                    switch(objStatPtr->subType)
 
 
2352
                    {
 
 
2353
                        case AMMO_10MM_CULW:
 
 
2354
                        {
 
 
2355
                            printf("Object is Pulse Rifle ammo.\n");
 
 
2356
                            break;
 
 
2357
                        }
 
 
2358
                        case AMMO_SHOTGUN:
 
 
2359
                        {
 
 
2360
                            printf("Object is Shotgun ammo.\n");
 
 
2361
                            break;
 
 
2362
                        }
 
 
2363
                        case AMMO_SMARTGUN:
 
 
2364
                        {
 
 
2365
                            printf("Object is Smartgun ammo.\n");
 
 
2366
                            break;
 
 
2367
                        }
 
 
2368
                        case AMMO_FLAMETHROWER:
 
 
2369
                        {
 
 
2370
                            printf("Object is Flamethrower ammo.\n");
 
 
2371
                            break;
 
 
2372
                        }
 
 
2373
                        case AMMO_SADAR_TOW:
 
 
2374
                        {
 
 
2375
                            printf("Object is Sadar ammo.\n");
 
 
2376
                            break;
 
 
2377
                        }
 
 
2378
                        case AMMO_GRENADE: 
 
 
2379
                        {
 
 
2380
                            printf("Object is Grenade Launcher ammo.\n");
 
 
2381
                            break;
 
 
2382
                        }
 
 
2383
                        case AMMO_MINIGUN:
 
 
2384
                        {
 
 
2385
                            printf("Object is Minigun ammo.\n");
 
 
2386
                            break;
 
 
2387
                        }
 
 
2388
                        default:
 
 
2389
                            printf("Object is unlisted ammo (subtype %d).\n",(int)objStatPtr->subType);
 
 
2390
                            break;
 
 
2391
                    }
 
 
2392
                }
 
 
2393
                break;
 
 
2394
                case IOT_Health:
 
 
2395
                {
 
 
2396
                    printf("Object is health.\n");
 
 
2397
                    break;
 
 
2398
                }
 
 
2399
                case IOT_Armour:
 
 
2400
                {
 
 
2401
                    printf("Object is armour.\n");
 
 
2402
                    break;
 
 
2403
                }
 
 
2404
                case IOT_FieldCharge:
 
 
2405
                {
 
 
2406
                    printf("Object is field charge powerup.\n");
 
 
2407
                    break;
 
 
2408
                }
 
 
2409
                default:
 
 
2410
                {
 
 
2411
                    printf("Object is unlisted subtype (%d).\n",(int)objStatPtr->subType);
 
 
2412
                }
 
 
2413
            }
 
 
2414
        }
 
 
2415
        break;
 
 
2416
        case I_BehaviourMarine:
 
 
2417
        {
 
 
2418
            printf("Object is a marine.\n");
 
 
2419
            printf("Marine is in %s\n",sbPtr->containingModule->name);
 
 
2420
        }
 
 
2421
        break;
 
 
2422
        case I_BehaviourAlien:
 
 
2423
        {
 
 
2424
            printf("Object is an alien.\n");
 
 
2425
        }
 
 
2426
        break;
 
 
2427
        case I_BehaviourPredator:
 
 
2428
        {
 
 
2429
            printf("Object is a predator.\n");
 
 
2430
        }
 
 
2431
        break;
 
 
2432
        default:
 
 
2433
        {
 
 
2434
            printf("Object is not supported - change PVisible.c for expanded diagnostics!\n");
 
 
2435
        }
 
 
2436
    }
 
 
2437
 
 
 
2438
    if (!sbPtr->DynPtr)
 
 
2439
        printf("Object has no dynamics block!\n");
 
 
2440
    else
 
 
2441
        printf("Object world co-ords: %d %d %d\n",sbPtr->DynPtr->Position.vx,sbPtr->DynPtr->Position.vy,sbPtr->DynPtr->Position.vz);
 
 
2442
}
 
 
2443
 
 
 
2444
#include "pfarlocs.h"
 
 
2445
 
 
 
2446
static void EmergencyPlaceObjectInModule(STRATEGYBLOCK *sbPtr, AIMODULE* targetModule)
 
 
2447
{
 
 
2448
    printf("Calling EmergencyPlaceObjectInModule!\n");
 
 
2449
 
 
 
2450
    /* first off, assert a few pre-conditions */
 
 
2451
    assert(AIModuleIsPhysical(targetModule));
 
 
2452
    assert(sbPtr->maintainVisibility);
 
 
2453
    assert(FALLP_EntryPoints);
 
 
2454
 
 
 
2455
    assert(FALLP_EntryPoints[(targetModule->m_index)].numEntryPoints);
 
 
2456
 
 
 
2457
    FARENTRYPOINT *entryPointsList = FALLP_EntryPoints[(targetModule->m_index)].entryPointsList;  
 
 
2458
 
 
 
2459
 
 
 
2460
    /* just use the first entry point */
 
 
2461
    VECTORCH newPosition = entryPointsList[0].position;
 
 
2462
 
 
 
2463
    /* now set the object's new position and current module. 
 
 
2464
       NB this is world position + a little extra in y to make sure */
 
 
2465
    {
 
 
2466
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
2467
        dynPtr->Position = newPosition;
 
 
2468
 
 
 
2469
        dynPtr->Position.vx += targetModule->m_world.vx;
 
 
2470
        dynPtr->Position.vy += targetModule->m_world.vy;
 
 
2471
        dynPtr->Position.vz += targetModule->m_world.vz;
 
 
2472
 
 
 
2473
        dynPtr->PrevPosition = dynPtr->Position;
 
 
2474
    }
 
 
2475
 
 
 
2476
    /* finally, update the sb's module */
 
 
2477
    sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL);
 
 
2478
}
 
 
2479
 
 
 
2480
/*----------------------Patrick 15/1/97-----------------------------
 
 
2481
This function relocates an object back into the environment:
 
 
2482
this may be an npc, inanimate object, etc.
 
 
2483
It is called if the visibility system fails to find a 
 
 
2484
containing module for the object, which may happen for a number
 
 
2485
of reasons, eg: an object is blown out of the visible part of the 
 
 
2486
environment, or an npc falls out...
 
 
2487
NB returns 0 if relocation failed.
 
 
2488
--------------------------------------------------------------------*/
 
 
2489
 
 
 
2490
int EmergencyRelocateObject(STRATEGYBLOCK *sbPtr)
 
 
2491
{
 
 
2492
    switch(sbPtr->type)
 
 
2493
    {
 
 
2494
        case I_BehaviourNetGhost:
 
 
2495
        case I_BehaviourPlatform:
 
 
2496
            return 1;
 
 
2497
        default:
 
 
2498
        break;
 
 
2499
    }
 
 
2500
 
 
 
2501
    /* first, try to reset the object's position: if it has a valid 'containingModule',
 
 
2502
    this means that it's last position was in that module, so we can use that as a reset
 
 
2503
    position. 
 
 
2504
    NB this means that NPC's will be unable to 'run away' into an invisible module. 
 
 
2505
    */
 
 
2506
 
 
 
2507
    if(NULL != sbPtr->containingModule) 
 
 
2508
    {
 
 
2509
        /* Nooo, this doesn't work! CDF 3/12/97 Hack. */
 
 
2510
 
 
 
2511
        if ((sbPtr->type != I_BehaviourAlien) && (sbPtr->type != I_BehaviourMarine))
 
 
2512
        {
 
 
2513
            if(DynamicObjectIsMoving(sbPtr->DynPtr))
 
 
2514
            {
 
 
2515
                printf("Valid containingModule.\n");
 
 
2516
                sbPtr->DynPtr->Position = sbPtr->DynPtr->PrevPosition;
 
 
2517
                return 1;
 
 
2518
            }
 
 
2519
        }
 
 
2520
    }
 
 
2521
 
 
 
2522
    /*
 
 
2523
    so, we don't have a previous module... then search the environment for the 
 
 
2524
    nearest invisible module that has entry point locations, and relocate to one of 
 
 
2525
    these locations.
 
 
2526
    */
 
 
2527
 
 
 
2528
    {
 
 
2529
        AIMODULE *targetModule = NULL;
 
 
2530
        int targetModuleDistance = 0;
 
 
2531
        int moduleCounter = 0;
 
 
2532
 
 
 
2533
        AIMODULE *moduleListPointer = AIModuleArray;
 
 
2534
 
 
 
2535
        for(; moduleCounter < AIModuleArraySize; moduleCounter++)
 
 
2536
        {
 
 
2537
            AIMODULE *thisModule = &moduleListPointer[moduleCounter]; 
 
 
2538
 
 
 
2539
            if(!ModuleCurrVisArray[thisModule->m_index] && FALLP_EntryPoints[thisModule->m_index].numEntryPoints)
 
 
2540
            {
 
 
2541
                /* a candidate */
 
 
2542
                int thisModuleDistance = VectorDistance(&thisModule->m_world, &sbPtr->DynPtr->Position);                                       
 
 
2543
 
 
 
2544
                if(!targetModule || (thisModuleDistance < targetModuleDistance))
 
 
2545
                { 
 
 
2546
                    targetModule = thisModule;
 
 
2547
                    targetModuleDistance = thisModuleDistance;
 
 
2548
                }
 
 
2549
            }
 
 
2550
        }
 
 
2551
 
 
 
2552
        if(!targetModule)
 
 
2553
        {
 
 
2554
            /* this condition shouldn't happen, but since I'm paranoid... */
 
 
2555
            //This can happen on the skirmish levels (where the whole level is visible at once)
 
 
2556
            //Therefore if the object has a previous containing module , use it.
 
 
2557
            //Otherwise get rid of it.
 
 
2558
 
 
 
2559
            if(sbPtr->containingModule) 
 
 
2560
            {
 
 
2561
                /* Nooo, this doesn't work! CDF 3/12/97 Hack. */
 
 
2562
 
 
 
2563
                printf("Valid containingModule.\n");
 
 
2564
                sbPtr->DynPtr->Position = sbPtr->DynPtr->PrevPosition;
 
 
2565
                return 1;
 
 
2566
            }
 
 
2567
 
 
 
2568
            sbPtr->please_destroy_me = 1;
 
 
2569
        return 0;
 
 
2570
        }
 
 
2571
 
 
 
2572
        EmergencyPlaceObjectInModule(sbPtr, targetModule);
 
 
2573
 
 
 
2574
        #if DEBUG
 
 
2575
        if (!sbPtr->containingModule)
 
 
2576
            printf("WARNING!! EmgcyPlcObInMod failed\n");
 
 
2577
        #endif
 
 
2578
 
 
 
2579
        return sbPtr->containingModule != NULL;
 
 
2580
    }
 
 
2581
}
 
 
2582
 
 
 
2583
static void DoObjectVisibility(STRATEGYBLOCK *sbPtr)
 
 
2584
{
 
 
2585
    if(NULL == sbPtr->DisplayBlock)
 
 
2586
    {
 
 
2587
           /* Note that we don't call modulefromposition() for far objects, as they mostly don't 
 
 
2588
        move, and those that do (eg AIs) move to precalculated positions in modules. Thus
 
 
2589
        invisible objects are responsible for looking after their own containingModule field.
 
 
2590
        This should always be ok: we should always have a correct and valid containing
 
 
2591
        module. However, we will do a paranoia check for a null containingModule... */ 
 
 
2592
 
 
 
2593
        if(NULL == sbPtr->containingModule)    
 
 
2594
        {
 
 
2595
            printf("Calling Far EmergencyRelocateObject, On object %p, type %d!\n", (void*)sbPtr, sbPtr->type);
 
 
2596
 
 
 
2597
            IdentifyObject(sbPtr);
 
 
2598
 
 
 
2599
            if(!EmergencyRelocateObject(sbPtr)) 
 
 
2600
            {
 
 
2601
                printf("Relocate failed!\n");
 
 
2602
                return;
 
 
2603
            }
 
 
2604
        }
 
 
2605
 
 
 
2606
        /* Now do the visibility check: the object has no display block, so check if 
 
 
2607
        it's module is visible. If so, make the object visibile too. */
 
 
2608
 
 
 
2609
        switch(sbPtr->type)
 
 
2610
        {
 
 
2611
            case I_BehaviourPlacedLight:
 
 
2612
            {
 
 
2613
                if (ThisObjectIsInAModuleVisibleFromCurrentlyVisibleModules(sbPtr))
 
 
2614
                    MakePlacedLightNear(sbPtr);
 
 
2615
            }
 
 
2616
            return;
 
 
2617
            case I_BehaviourNetGhost:
 
 
2618
            {
 
 
2619
                NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2620
 
 
 
2621
                if (ghostDataPtr && ghostDataPtr->type == I_BehaviourFlare)
 
 
2622
                {
 
 
2623
                    if(ThisObjectIsInAModuleVisibleFromCurrentlyVisibleModules(sbPtr))
 
 
2624
                    {
 
 
2625
                        MakeGhostNear(sbPtr);
 
 
2626
                        return;
 
 
2627
                    }
 
 
2628
                }
 
 
2629
            }
 
 
2630
            break;
 
 
2631
            case I_BehaviourPlatform:
 
 
2632
            {
 
 
2633
                PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
2634
                //platform lift needs to be made near if its module near or if it is moving
 
 
2635
 
 
 
2636
                switch(platformliftdata->state)
 
 
2637
                {
 
 
2638
                    default:
 
 
2639
                    {
 
 
2640
                        if(!ModuleCurrVisArray[sbPtr->containingModule->m_index])
 
 
2641
                            break;
 
 
2642
                    }
 
 
2643
                    case PLBS_GoingUp:
 
 
2644
                    case PLBS_GoingDown:
 
 
2645
                    MakeObjectNear(sbPtr);
 
 
2646
                }
 
 
2647
            return;
 
 
2648
            }
 
 
2649
            default:
 
 
2650
            break;
 
 
2651
        }
 
 
2652
 
 
 
2653
        if(ModuleCurrVisArray[sbPtr->containingModule->m_index] > 1)
 
 
2654
        {
 
 
2655
            /* module is visible, so make object visible too */
 
 
2656
            switch(sbPtr->type)
 
 
2657
            {
 
 
2658
                case I_BehaviourAlien:
 
 
2659
                    MakeAlienNear(sbPtr);
 
 
2660
                break;
 
 
2661
                case I_BehaviourVideoScreen:
 
 
2662
                {
 
 
2663
                    DISPLAYBLOCK *dPtr = AllocateNewObject(sbPtr->shapeIndex); 
 
 
2664
 
 
 
2665
                    if(NULL != dPtr)
 
 
2666
                    {
 
 
2667
                        sbPtr->DisplayBlock = dPtr;
 
 
2668
                        dPtr->ObStrategyBlock = sbPtr;
 
 
2669
                        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
2670
 
 
 
2671
                        /* also need to initialise positional information in the new display
 
 
2672
                        block from the existing dynamics block: this necessary because this 
 
 
2673
                        function is (usually) called between the dynamics and rendering systems
 
 
2674
                        so it is not initialised by the dynamics system the first time it is
 
 
2675
                        drawn. */
 
 
2676
                        dPtr->ObWorld = dynPtr->Position;
 
 
2677
                        dPtr->ObEuler = dynPtr->OrientEuler;
 
 
2678
                        dPtr->ObMat = dynPtr->OrientMat;
 
 
2679
                        AddLightingEffectToObject(sbPtr->DisplayBlock, LFX_FLARE);
 
 
2680
                    }
 
 
2681
                    /*else  cannot create displayblock, so leave object "far" */
 
 
2682
                }
 
 
2683
                break;
 
 
2684
        case I_BehaviourHierarchicalFragment:
 
 
2685
        case I_BehaviourFragment:
 
 
2686
        case I_BehaviourRocket:
 
 
2687
        case I_BehaviourPPPlasmaBolt:
 
 
2688
        case I_BehaviourSpeargunBolt:
 
 
2689
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
2690
        case I_BehaviourPredatorEnergyBolt:
 
 
2691
        case I_BehaviourFlare:
 
 
2692
        case I_BehaviourPulseGrenade:
 
 
2693
        case I_BehaviourGrenade:
 
 
2694
        case I_BehaviourFragmentationGrenade:
 
 
2695
        case I_BehaviourProximityGrenade:
 
 
2696
        case I_BehaviourMolotov:
 
 
2697
        case I_BehaviourDeathVolume:
 
 
2698
        case I_BehaviourFrisbee:
 
 
2699
        case I_BehaviourFrisbeeEnergyBolt:
 
 
2700
//sbPtr->DisplayBlock->ObFlags & ObFlag_NotVis;
 
 
2701
//break;
 
 
2702
 
 
 
2703
                case I_BehaviourInanimateObject:
 
 
2704
                case I_BehaviourBinarySwitch:
 
 
2705
                case I_BehaviourLinkSwitch:
 
 
2706
                case I_BehaviourFan:
 
 
2707
                case I_BehaviourTrackObject:
 
 
2708
                    MakeObjectNear(sbPtr);                                  
 
 
2709
                break;
 
 
2710
                case I_BehaviourMarine:
 
 
2711
                    MakeMarineNear(sbPtr); 
 
 
2712
                break;
 
 
2713
                case I_BehaviourPredator:
 
 
2714
                    MakePredatorNear(sbPtr);                                        
 
 
2715
                break;
 
 
2716
                case I_BehaviourFaceHugger:
 
 
2717
                    MakeFacehuggerNear(sbPtr);                                      
 
 
2718
                break;
 
 
2719
                case I_BehaviourNetGhost:
 
 
2720
                {
 
 
2721
                    NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2722
 
 
 
2723
                    /* KJL 16:42:40 23/01/99 - near behaviour is triggered differently for lightsources such as flares */
 
 
2724
                    if (ghostDataPtr && ghostDataPtr->type != I_BehaviourFlare)
 
 
2725
                        MakeGhostNear(sbPtr); 
 
 
2726
                }
 
 
2727
                break;
 
 
2728
                case I_BehaviourCorpse:
 
 
2729
                    MakeCorpseNear(sbPtr);
 
 
2730
                break;
 
 
2731
                case I_BehaviourPlacedHierarchy:
 
 
2732
                    MakePlacedHierarchyNear(sbPtr);
 
 
2733
                break;
 
 
2734
                case I_BehaviourAutoGun:
 
 
2735
                    MakeSentrygunNear(sbPtr);
 
 
2736
                break;
 
 
2737
                case I_BehaviourXenoborg:
 
 
2738
                    MakeXenoborgNear(sbPtr);
 
 
2739
                break;
 
 
2740
                case I_BehaviourQueenAlien:
 
 
2741
                    MakeQueenNear(sbPtr);
 
 
2742
                break;
 
 
2743
                case I_BehaviourDummy:
 
 
2744
                    MakeDummyNear(sbPtr);
 
 
2745
                break;
 
 
2746
                default:
 
 
2747
                {
 
 
2748
                    /* only the above object types should get here */
 
 
2749
                    assert(1==0);
 
 
2750
                }
 
 
2751
            }
 
 
2752
        }
 
 
2753
    }
 
 
2754
    else
 
 
2755
    {
 
 
2756
        if (sbPtr->type == I_BehaviourPlacedLight)
 
 
2757
        {
 
 
2758
            if(!ThisObjectIsInAModuleVisibleFromCurrentlyVisibleModules(sbPtr))
 
 
2759
                DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
2760
        }
 
 
2761
        else
 
 
2762
        {
 
 
2763
            if(!ModuleCurrVisArray[sbPtr->containingModule->m_index])
 
 
2764
            {
 
 
2765
                /* module is invisible, so make object invisible too */
 
 
2766
                switch(sbPtr->type)
 
 
2767
                {
 
 
2768
                    case I_BehaviourAlien:
 
 
2769
                        MakeAlienFar(sbPtr);
 
 
2770
                    break;
 
 
2771
        case I_BehaviourHierarchicalFragment:
 
 
2772
        case I_BehaviourFragment:
 
 
2773
        case I_BehaviourRocket:
 
 
2774
        case I_BehaviourPPPlasmaBolt:
 
 
2775
        case I_BehaviourSpeargunBolt:
 
 
2776
        case I_BehaviourPredatorDisc_SeekTrack:
 
 
2777
        case I_BehaviourPredatorEnergyBolt:
 
 
2778
        case I_BehaviourFlare:
 
 
2779
        case I_BehaviourPulseGrenade:
 
 
2780
        case I_BehaviourGrenade:
 
 
2781
        case I_BehaviourFragmentationGrenade:
 
 
2782
        case I_BehaviourProximityGrenade:
 
 
2783
        case I_BehaviourMolotov:
 
 
2784
        case I_BehaviourDeathVolume:
 
 
2785
        case I_BehaviourFrisbee:
 
 
2786
        case I_BehaviourFrisbeeEnergyBolt:
 
 
2787
        //break;
 
 
2788
                    case I_BehaviourInanimateObject:
 
 
2789
                    case I_BehaviourVideoScreen:
 
 
2790
                    case I_BehaviourBinarySwitch:
 
 
2791
                    case I_BehaviourLinkSwitch:
 
 
2792
                    case I_BehaviourPlacedHierarchy:
 
 
2793
                    case I_BehaviourTrackObject:
 
 
2794
                    case I_BehaviourCorpse:
 
 
2795
                    case I_BehaviourFan:
 
 
2796
                    case I_BehaviourNetGhost:
 
 
2797
                        DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
2798
                    break;
 
 
2799
                    case I_BehaviourMarine:
 
 
2800
                        MakeMarineFar(sbPtr);                                   
 
 
2801
                    break;
 
 
2802
                    case I_BehaviourPlatform:
 
 
2803
                    {
 
 
2804
                        PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
2805
                        //don't make platform lift far if it is currently moving
 
 
2806
                        //(otherwise the lift won't be able to move)
 
 
2807
 
 
 
2808
                        switch(platformliftdata->state)
 
 
2809
                        {
 
 
2810
                            case PLBS_GoingUp:
 
 
2811
                            case PLBS_GoingDown:
 
 
2812
                            break;
 
 
2813
                            default:
 
 
2814
                            DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
2815
                        }
 
 
2816
                    }
 
 
2817
                    break;
 
 
2818
                    case I_BehaviourFaceHugger:
 
 
2819
                        MakeFacehuggerFar(sbPtr);               
 
 
2820
                    break;
 
 
2821
                    case I_BehaviourPredator:
 
 
2822
                        MakePredatorFar(sbPtr);
 
 
2823
                    break;
 
 
2824
                    case I_BehaviourXenoborg:
 
 
2825
                        MakeXenoborgFar(sbPtr);
 
 
2826
                    break;
 
 
2827
                    case I_BehaviourQueenAlien:
 
 
2828
                        MakeQueenFar(sbPtr);
 
 
2829
                    break;
 
 
2830
                    case I_BehaviourAutoGun:
 
 
2831
                        MakeSentrygunFar(sbPtr);
 
 
2832
                    break;
 
 
2833
                    case I_BehaviourDummy:
 
 
2834
                        MakeDummyFar(sbPtr);
 
 
2835
                    break;
 
 
2836
                    default:
 
 
2837
                    {
 
 
2838
                        /* only the above object types should get here */
 
 
2839
                        assert(1==0);
 
 
2840
                    }
 
 
2841
                }
 
 
2842
            }
 
 
2843
        }
 
 
2844
    }
 
 
2845
}
 
 
2846
 
 
 
2847
static void FragmentBehaviour(STRATEGYBLOCK *sptr)
 
 
2848
{
 
 
2849
    ONE_SHOT_BEHAV_BLOCK *osbhv = (ONE_SHOT_BEHAV_BLOCK * )sptr->dataptr;    
 
 
2850
 
 
 
2851
    if (osbhv->counter < 0)
 
 
2852
    {
 
 
2853
        sptr->please_destroy_me = 1;
 
 
2854
    }
 
 
2855
    else
 
 
2856
    {
 
 
2857
        osbhv->counter -= NormalFrameTime;
 
 
2858
 
 
 
2859
        if (!sptr->DynPtr->IsInContactWithFloor && DynamicObjectIsMoving(sptr->DynPtr))
 
 
2860
            DynamicallyRotateObject(sptr->DynPtr);
 
 
2861
 
 
 
2862
        if (sptr->DisplayBlock)
 
 
2863
        {
 
 
2864
            sptr->DisplayBlock->SpecialFXFlags |= SFXFLAG_MELTINGINTOGROUND;
 
 
2865
            sptr->DisplayBlock->ObFlags2 = osbhv->counter / 2;
 
 
2866
        }
 
 
2867
    }
 
 
2868
}
 
 
2869
 
 
 
2870
void ExecuteBehaviour()
 
 
2871
{
 
 
2872
    int i; // player is 0 and is done in PlayerBehaviour
 
 
2873
 
 
 
2874
    for (i=1; i < NumActiveStBlocks; i++)
 
 
2875
    {
 
 
2876
        STRATEGYBLOCK *sbptr = ActiveStBlockList[i];
 
 
2877
 
 
 
2878
        if(sbptr->please_destroy_me)
 
 
2879
            continue;
 
 
2880
        else if(sbptr->maintainVisibility)
 
 
2881
            DoObjectVisibility(sbptr);
 
 
2882
 
 
 
2883
        switch(sbptr->type)
 
 
2884
        {
 
 
2885
            case I_BehaviourPlacedLight:
 
 
2886
                PlacedLightBehaviour(sbptr);
 
 
2887
            break;
 
 
2888
            case I_BehaviourLightFX:
 
 
2889
                LightFXBehaveFun(sbptr);
 
 
2890
            break;
 
 
2891
            case I_BehaviourPlacedSound:
 
 
2892
                SoundBehaveFun(sbptr);
 
 
2893
            break;
 
 
2894
            case I_BehaviourAlien:
 
 
2895
                if(sbptr->containingModule)
 
 
2896
                    AlienBehaviour(sbptr);
 
 
2897
                else
 
 
2898
                    sbptr->please_destroy_me = 1; // aliens sometimes climb out of the environment, remove and relocate. Note to myself fix this
 
 
2899
            break;
 
 
2900
            case I_BehaviourHierarchicalFragment:
 
 
2901
                HierarchicalFragmentBehaviour(sbptr);
 
 
2902
            break;
 
 
2903
            case I_BehaviourFragment:
 
 
2904
                FragmentBehaviour(sbptr);
 
 
2905
            break;
 
 
2906
            case I_BehaviourCorpse:
 
 
2907
                CorpseBehaveFun(sbptr);
 
 
2908
            break;
 
 
2909
            case I_BehaviourMarine:
 
 
2910
                if(sbptr->containingModule)
 
 
2911
                    MarineBehaviour(sbptr);
 
 
2912
                else
 
 
2913
                    sbptr->please_destroy_me = 1;
 
 
2914
            break;
 
 
2915
            case I_BehaviourGenerator:
 
 
2916
                GeneratorBehaviour(sbptr);
 
 
2917
            break;
 
 
2918
            case I_BehaviourParticleGenerator:
 
 
2919
                ParticleGeneratorBehaveFun(sbptr);
 
 
2920
            break;
 
 
2921
            case I_BehaviourInanimateObject:
 
 
2922
                InanimateObjectBehaviour(sbptr);
 
 
2923
            break;
 
 
2924
            case I_BehaviourVideoScreen:
 
 
2925
                VideoScreenBehaviour(sbptr);
 
 
2926
            break;
 
 
2927
            case I_BehaviourFlare:
 
 
2928
                FlareBehaviour(sbptr);
 
 
2929
            break;
 
 
2930
            case I_BehaviourPulseGrenade:
 
 
2931
                PulseGrenadeBehaviour(sbptr);
 
 
2932
            break;
 
 
2933
            case I_BehaviourRocket:
 
 
2934
                RocketBehaviour(sbptr);
 
 
2935
            break;
 
 
2936
            case I_BehaviourGrenade:
 
 
2937
                GrenadeBehaviour(sbptr);
 
 
2938
            break;
 
 
2939
            case I_BehaviourFragmentationGrenade:
 
 
2940
                FragGrenadeBehaviour(sbptr);
 
 
2941
            break;
 
 
2942
            case I_BehaviourProximityGrenade:
 
 
2943
                ProximityGrenadeBehaviour(sbptr);
 
 
2944
            break;
 
 
2945
            case I_BehaviourProximityDoor:
 
 
2946
                DoorProxBehaveFun(sbptr);
 
 
2947
            break;
 
 
2948
            case I_BehaviourBinarySwitch:
 
 
2949
                BinarySwitchBehaveFun(sbptr);
 
 
2950
            break;
 
 
2951
            case I_BehaviourLiftDoor:
 
 
2952
                LiftDoorBehaveFun(sbptr);
 
 
2953
            break;
 
 
2954
            case I_BehaviourLift:
 
 
2955
                LiftBehaveFun(sbptr);
 
 
2956
            break;
 
 
2957
            case I_BehaviourSwitchDoor:
 
 
2958
                SwitchDoorBehaviour(sbptr);
 
 
2959
            break;
 
 
2960
            case I_BehaviourLinkSwitch:
 
 
2961
                LinkSwitchBehaveFun(sbptr);
 
 
2962
            break;
 
 
2963
            case I_BehaviourPlatform:
 
 
2964
                PlatformLiftBehaviour(sbptr);
 
 
2965
            break;
 
 
2966
            case I_BehaviourSimpleAnimation:
 
 
2967
                SimpleAnimBehaveFun(sbptr);
 
 
2968
            break;
 
 
2969
            case I_BehaviourAutoGun:
 
 
2970
                AutoGunBehaveFun(sbptr);
 
 
2971
            break;
 
 
2972
            case I_BehaviourMolotov:
 
 
2973
                MolotovBehaviour(sbptr);
 
 
2974
            break;
 
 
2975
            case I_BehaviourFrisbee:
 
 
2976
                FrisbeeBehaviour(sbptr);
 
 
2977
            break;
 
 
2978
            case I_BehaviourFaceHugger:
 
 
2979
                if(sbptr->containingModule)
 
 
2980
                    FacehuggerBehaviour(sbptr);
 
 
2981
                else
 
 
2982
                    sbptr->please_destroy_me = 1; // just to make sure
 
 
2983
            break;
 
 
2984
            case I_BehaviourPredator:
 
 
2985
                if(sbptr->containingModule)
 
 
2986
                    PredatorBehaviour(sbptr);
 
 
2987
                else
 
 
2988
                    sbptr->please_destroy_me = 1; // just to make sure
 
 
2989
            break;
 
 
2990
            case I_BehaviourPPPlasmaBolt:
 
 
2991
                PPPlasmaBoltBehaviour(sbptr); 
 
 
2992
            break;
 
 
2993
            case I_BehaviourSpeargunBolt:
 
 
2994
                SpeargunBoltBehaviour(sbptr);
 
 
2995
            break;
 
 
2996
            case I_BehaviourPredatorEnergyBolt:
 
 
2997
                PredatorEnergyBoltBehaviour(sbptr); 
 
 
2998
            break;
 
 
2999
            case I_BehaviourFrisbeeEnergyBolt:
 
 
3000
                FrisbeeEnergyBoltBehaviour(sbptr); 
 
 
3001
            break;
 
 
3002
            case I_BehaviourPredatorDisc_SeekTrack:
 
 
3003
                DiscBehaviour_SeekTrack(sbptr);
 
 
3004
            break;
 
 
3005
            case I_BehaviourNetGhost:
 
 
3006
                NetGhostBehaviour(sbptr);
 
 
3007
            break;
 
 
3008
            case I_BehaviourTrackObject:
 
 
3009
                TrackObjectBehaveFun(sbptr);
 
 
3010
            break;
 
 
3011
            case I_BehaviourFan:
 
 
3012
                FanBehaveFun(sbptr);
 
 
3013
            break;
 
 
3014
            case I_BehaviourGrapplingHook:
 
 
3015
                GrapplingHookBehaviour(sbptr);
 
 
3016
            break;
 
 
3017
            case I_BehaviourPlacedHierarchy:
 
 
3018
                PlacedHierarchyBehaveFun(sbptr);
 
 
3019
            break;
 
 
3020
            case I_BehaviourPowerCable:
 
 
3021
                PowerCableBehaveFun(sbptr);
 
 
3022
            break;
 
 
3023
            case I_BehaviourDeathVolume:
 
 
3024
                DeathVolumeBehaveFun(sbptr);
 
 
3025
            break;
 
 
3026
            case I_BehaviourXenoborg:
 
 
3027
                XenoborgBehaviour(sbptr);
 
 
3028
            break;
 
 
3029
            case I_BehaviourQueenAlien:
 
 
3030
                QueenBehaviour(sbptr);
 
 
3031
            break;
 
 
3032
            case I_BehaviourXenoborgMorphRoom:
 
 
3033
                XenoMorphRoomBehaviour(sbptr);
 
 
3034
            break;
 
 
3035
            case I_BehaviourSelfDestruct:
 
 
3036
                SelfDestructBehaveFun(sbptr);
 
 
3037
            break;
 
 
3038
            case I_BehaviourDummy:
 
 
3039
                DummyBehaviour(sbptr);
 
 
3040
            default:
 
 
3041
            break;
 
 
3042
        }
 
 
3043
    }
 
 
3044
 
 
 
3045
    // RWH 5/6/97 these next two functions were 1, changed and 2, added
 
 
3046
    // to deal with deallocating stblocks at the end of behaviours
 
 
3047
    // this stops problems with accessing defunct strategy blocks
 
 
3048
    // via collision reports
 
 
3049
 
 
 
3050
    /*
 
 
3051
        Go backwards through the strategy block.
 
 
3052
        This should prevent any strategy blocks from being skipped when they
 
 
3053
        get shuffled down from the end of the array.
 
 
3054
    */
 
 
3055
 
 
 
3056
    while(i--)
 
 
3057
    {
 
 
3058
        STRATEGYBLOCK* sbptr = ActiveStBlockList[i];
 
 
3059
 
 
 
3060
        if(sbptr->please_destroy_me)
 
 
3061
            RemoveBehaviourStrategy(sbptr);
 
 
3062
    }
 
 
3063
}
 
 
3064
 
 
 
3065
static void SendRequestToInanimateObject(STRATEGYBLOCK* sbptr, int state, int extended_data)
 
 
3066
{
 
 
3067
    if(state && (extended_data & ObjectRequest_AdjustIntegrity))
 
 
3068
    {
 
 
3069
        int new_integrity = (extended_data >> 7) & 0xff;
 
 
3070
        sbptr->DamageBlock.Indestructable = (new_integrity > 20);
 
 
3071
        sbptr->DamageBlock.Health = (10 << ONE_FIXED_SHIFT) * new_integrity;        
 
 
3072
 
 
 
3073
        if(!new_integrity)
 
 
3074
            InanimateObjectIsDamaged(sbptr, &damage_profiles[CERTAINDEATH], ONE_FIXED);
 
 
3075
    }
 
 
3076
}
 
 
3077
 
 
 
3078
/********************* SUPPORT  FUNCTION ***********************/
 
 
3079
/*
 
 
3080
    these set the reqest state in a strategy block 
 
 
3081
*/
 
 
3082
 
 
 
3083
void RequestState(STRATEGYBLOCK* sbptr, int message, STRATEGYBLOCK * SBRequester)
 
 
3084
{
 
 
3085
    //lowest bit of message corresponds to old on/off state
 
 
3086
    //the rest is extended information ,the interpretation of which depends on the receiving strategy
 
 
3087
    int state = message & 1;    
 
 
3088
 
 
 
3089
    if(!sbptr)
 
 
3090
        return;
 
 
3091
 
 
 
3092
    if(sbptr->destroyed_but_preserved)
 
 
3093
        return;    //target doesn't exist anymore so ignore request.
 
 
3094
 
 
 
3095
    #if DEBUG
 
 
3096
    {
 
 
3097
        extern int GlobalFrameCounter;
 
 
3098
        //add details of request to logfile
 
 
3099
        const char* name1=0;
 
 
3100
        const char* name2 = "ANON";
 
 
3101
 
 
 
3102
        if(sbptr)
 
 
3103
            name1 = sbptr->name;
 
 
3104
 
 
 
3105
        if(SBRequester)
 
 
3106
            name2 = SBRequester->name;
 
 
3107
 
 
 
3108
        printf("Frame %d  : %s sent %s message to %s%s",GlobalFrameCounter,name2, state ? "'on'" :
"'off'",name1,(message>>1)? " with extra message data" : "");
 
 
3109
    }
 
 
3110
    #endif
 
 
3111
 
 
 
3112
    switch (sbptr->type)
 
 
3113
    {
 
 
3114
        case I_BehaviourCorpse:
 
 
3115
            /* Ulp... */
 
 
3116
            break;
 
 
3117
        case I_BehaviourBinarySwitch:
 
 
3118
        {
 
 
3119
            // 0 = rest state
 
 
3120
            // 1 = unusual state
 
 
3121
 
 
 
3122
            BINARY_SWITCH_BEHAV_BLOCK *bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3123
 
 
 
3124
            assert((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
 
 
3125
 
 
 
3126
            bs_bhv->request = state ? I_request_on : I_request_off;
 
 
3127
        }
 
 
3128
        break;
 
 
3129
        case I_BehaviourLinkSwitch:
 
 
3130
        {
 
 
3131
            // 0 = rest state
 
 
3132
            // 1 = unusual state
 
 
3133
            LINK_SWITCH_BEHAV_BLOCK *bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3134
 
 
 
3135
            assert((bs_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
3136
 
 
 
3137
            if (SBRequester)
 
 
3138
            if (SBRequester->type == I_BehaviourBinarySwitch || SBRequester->type == I_BehaviourLinkSwitch)
 
 
3139
            {
 
 
3140
                //if the request has come from one of the linked switches , ignore it
 
 
3141
                int i = 0;
 
 
3142
 
 
 
3143
                for(; i < bs_bhv->num_linked_switches; i++)
 
 
3144
                {
 
 
3145
                    if(bs_bhv->lswitch_list[i].bswitch == SBRequester)
 
 
3146
                        break;
 
 
3147
                }
 
 
3148
 
 
 
3149
                if( i < bs_bhv->num_linked_switches)
 
 
3150
                    break;
 
 
3151
            }
 
 
3152
 
 
 
3153
            bs_bhv->request = state ? I_request_on : I_request_off;
 
 
3154
        }
 
 
3155
        break;
 
 
3156
        case I_BehaviourProximityDoor:
 
 
3157
        {
 
 
3158
            PROXDOOR_BEHAV_BLOCK *door_bhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3159
            assert((door_bhv->bhvr_type == I_BehaviourProximityDoor));
 
 
3160
 
 
 
3161
            //request previously open and closed door.Now it locks or unlocks it.
 
 
3162
 
 
 
3163
            door_bhv->door_locked = (state == 1) ? 0 : 1;
 
 
3164
        }
 
 
3165
        break;
 
 
3166
        case I_BehaviourLiftDoor:
 
 
3167
        {
 
 
3168
            LIFT_DOOR_BEHAV_BLOCK *door_bhv = (LIFT_DOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3169
            assert((door_bhv->bhvr_type == I_BehaviourLiftDoor));
 
 
3170
 
 
 
3171
            door_bhv->request_state = (state == 1) ? I_door_open : I_door_closed;
 
 
3172
        }
 
 
3173
        break;
 
 
3174
        case I_BehaviourSwitchDoor:
 
 
3175
        {
 
 
3176
            SWITCH_DOOR_BEHAV_BLOCK *door_bhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3177
            assert((door_bhv->myBehaviourType == I_BehaviourSwitchDoor));
 
 
3178
 
 
 
3179
            if(state == 1)
 
 
3180
                door_bhv->requestOpen = 1;
 
 
3181
            else
 
 
3182
                door_bhv->requestClose = 1;
 
 
3183
        }
 
 
3184
        break;
 
 
3185
        case I_BehaviourLift:
 
 
3186
        {
 
 
3187
             assert(sbptr);
 
 
3188
            LIFT_BEHAV_BLOCK *lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3189
            assert((lift_bhv->bhvr_type == I_BehaviourLift));
 
 
3190
            LIFT_STATION *lift_stn = &lift_bhv->lift_station;
 
 
3191
            assert(lift_stn);
 
 
3192
 
 
 
3193
            lift_stn->called = (state == 1) ? 1 : 0;
 
 
3194
        }
 
 
3195
        break;
 
 
3196
        case I_BehaviourPlatform:
 
 
3197
        {
 
 
3198
            ((PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbptr->dataptr)->Enabled = state;
 
 
3199
        }
 
 
3200
        break;
 
 
3201
        case I_BehaviourAutoGun:
 
 
3202
        {
 
 
3203
            AUTOGUN_STATUS_BLOCK *agunStatusPointer = (AUTOGUN_STATUS_BLOCK*)sbptr->dataptr;
 
 
3204
 
 
 
3205
            if ((agunStatusPointer->behaviourState == I_inactive) && (state == 1))
 
 
3206
            {
 
 
3207
                agunStatusPointer->behaviourState = I_tracking;
 
 
3208
            }
 
 
3209
            else if ((agunStatusPointer->behaviourState == I_tracking) && !state)
 
 
3210
            {
 
 
3211
                agunStatusPointer->behaviourState = I_inactive;
 
 
3212
                Sound_Play(SID_SENTRYGUN_SHUTDOWN, "d", &sbptr->DynPtr->Position);
 
 
3213
            }
 
 
3214
        }
 
 
3215
        break;
 
 
3216
        case I_BehaviourGenerator:
 
 
3217
        {
 
 
3218
            ((GENERATOR_BLOCK*)sbptr->dataptr)->Active = state;
 
 
3219
        break;
 
 
3220
        }
 
 
3221
        case I_BehaviourLightFX:
 
 
3222
        {
 
 
3223
            LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbptr->dataptr;
 
 
3224
 
 
 
3225
            if (lfxbb->type == LFX_Switch)
 
 
3226
            {
 
 
3227
                switch (lfxbb->current_state)
 
 
3228
                {
 
 
3229
                    case LFXS_LightOn:
 
 
3230
                    {
 
 
3231
                        if(!state)
 
 
3232
                        {
 
 
3233
                            lfxbb->current_state = LFXS_LightFadingDown;
 
 
3234
                            lfxbb->timer = 0;
 
 
3235
                        }
 
 
3236
                    }
 
 
3237
                    break;
 
 
3238
                    case LFXS_LightOff:
 
 
3239
                    {
 
 
3240
                        if(state == 1)
 
 
3241
                        {
 
 
3242
                            lfxbb->current_state = LFXS_LightFadingUp;
 
 
3243
                            lfxbb->timer = 0;
 
 
3244
                        }
 
 
3245
                    }
 
 
3246
                    break;
 
 
3247
                    case LFXS_LightFadingUp:
 
 
3248
                    {
 
 
3249
                        if(!state)
 
 
3250
                        {
 
 
3251
                            lfxbb->timer = ONE_FIXED - lfxbb->timer;
 
 
3252
                            lfxbb->current_state = LFXS_LightFadingDown;
 
 
3253
                        }
 
 
3254
                    }
 
 
3255
                    break;
 
 
3256
                    case LFXS_LightFadingDown:
 
 
3257
                    {
 
 
3258
                        if(state == 1)
 
 
3259
                        {
 
 
3260
                            lfxbb->timer = ONE_FIXED - lfxbb->timer;
 
 
3261
                            lfxbb->current_state = LFXS_LightFadingUp;
 
 
3262
                        }
 
 
3263
                    }
 
 
3264
                    break;
 
 
3265
                    default:
 
 
3266
                    {
 
 
3267
                        assert (0 == "Light FX state not supported");
 
 
3268
                        break;
 
 
3269
                    }
 
 
3270
                }
 
 
3271
            }
 
 
3272
            else if (lfxbb->type == LFX_FlickySwitch)
 
 
3273
            {
 
 
3274
                switch (lfxbb->current_state)
 
 
3275
                {
 
 
3276
                    case LFXS_LightOn:
 
 
3277
                    {
 
 
3278
                        if(!state)
 
 
3279
                        {
 
 
3280
                            lfxbb->current_state = LFXS_LightFadingDown;
 
 
3281
                            lfxbb->timer = 0;
 
 
3282
                        }
 
 
3283
                    }
 
 
3284
                    break;
 
 
3285
                    case LFXS_LightOff:
 
 
3286
                    {
 
 
3287
                        if(state == 1)
 
 
3288
                        {
 
 
3289
                            lfxbb->current_state = LFXS_LightFadingUp;
 
 
3290
                            lfxbb->timer = 0;
 
 
3291
                        }
 
 
3292
                    break;
 
 
3293
                    }
 
 
3294
                    case LFXS_LightFadingUp:
 
 
3295
                    {
 
 
3296
                        if(!state)
 
 
3297
                        {
 
 
3298
                            lfxbb->multiplier = lfxbb->timer;
 
 
3299
                            lfxbb->timer = ONE_FIXED - lfxbb->timer;
 
 
3300
                            lfxbb->current_state = LFXS_LightFadingDown;
 
 
3301
                        }
 
 
3302
                    }
 
 
3303
                    break;
 
 
3304
                    case LFXS_LightFadingDown:
 
 
3305
                    {
 
 
3306
                        if(state == 1)
 
 
3307
                        {
 
 
3308
                            lfxbb->timer = ONE_FIXED - lfxbb->timer;
 
 
3309
                            lfxbb->current_state = LFXS_LightFadingUp;
 
 
3310
                        }
 
 
3311
                    break;
 
 
3312
                    }
 
 
3313
                    default:
 
 
3314
                    {
 
 
3315
                        assert (0 == "Light FX state not supported");
 
 
3316
                        break;
 
 
3317
                    }
 
 
3318
                }
 
 
3319
            }
 
 
3320
            else if(lfxbb->type == LFX_RandomFlicker)
 
 
3321
            {
 
 
3322
                switch (lfxbb->current_state)
 
 
3323
                {
 
 
3324
                    case LFXS_Flicking:
 
 
3325
                    case LFXS_NotFlicking:
 
 
3326
                        if(!state)
 
 
3327
                        {
 
 
3328
                            //switch light off
 
 
3329
                            lfxbb->current_state = LFXS_LightOff;
 
 
3330
                        }
 
 
3331
                    break;
 
 
3332
                    case LFXS_LightOff :
 
 
3333
                        if(state == 1)
 
 
3334
                        {
 
 
3335
                            //switch light on
 
 
3336
                            lfxbb->current_state = LFXS_Flicking;
 
 
3337
                        }
 
 
3338
                    break;
 
 
3339
                    default:;
 
 
3340
                    }
 
 
3341
            }
 
 
3342
        }
 
 
3343
        break;
 
 
3344
        case I_BehaviourMissionComplete:
 
 
3345
            SendRequestToMissionStrategy(sbptr, state, message >> 1);
 
 
3346
        break;
 
 
3347
        case I_BehaviourMessage:
 
 
3348
            SendRequestToMessageStrategy(sbptr, state, message >> 1);
 
 
3349
        break;
 
 
3350
        case I_BehaviourTrackObject:
 
 
3351
        {
 
 
3352
            TRACK_OBJECT_BEHAV_BLOCK *to_bhv = (TRACK_OBJECT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3353
            assert((to_bhv->bhvr_type == I_BehaviourTrackObject));
 
 
3354
 
 
 
3355
            if(state)
 
 
3356
            {
 
 
3357
                switch(message >> 1)
 
 
3358
                {
 
 
3359
                    case 0:
 
 
3360
                        to_bhv->request = track_request_start;
 
 
3361
                        break;
 
 
3362
                    case 1:
 
 
3363
                        to_bhv->request = track_request_startforward;
 
 
3364
                        break;
 
 
3365
                    case 2:
 
 
3366
                        to_bhv->request = track_request_startbackward;
 
 
3367
                        break;
 
 
3368
                }
 
 
3369
            }
 
 
3370
            else
 
 
3371
            {
 
 
3372
                to_bhv->request = track_request_stop;
 
 
3373
            }
 
 
3374
        }
 
 
3375
        break;
 
 
3376
        case I_BehaviourFan:
 
 
3377
        {
 
 
3378
            FAN_BEHAV_BLOCK *f_bhv = (FAN_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3379
 
 
 
3380
            assert((f_bhv->bhvr_type == I_BehaviourFan));
 
 
3381
 
 
 
3382
            f_bhv->spinning = state;
 
 
3383
        }
 
 
3384
        break;
 
 
3385
        case I_BehaviourPlacedSound:
 
 
3386
        {
 
 
3387
            if(state)
 
 
3388
                StartPlacedSoundPlaying(sbptr);
 
 
3389
            else
 
 
3390
                StopPlacedSoundPlaying(sbptr);
 
 
3391
        }
 
 
3392
        break;
 
 
3393
        case I_BehaviourInanimateObject:
 
 
3394
            SendRequestToInanimateObject(sbptr, state, message >> 1);
 
 
3395
        break;
 
 
3396
        case I_BehaviourPlacedHierarchy :
 
 
3397
            SendRequestToPlacedHierarchy(sbptr, state, message >> 1);
 
 
3398
        break;
 
 
3399
        case I_BehaviourPlacedLight:
 
 
3400
            SendRequestToPlacedLight(sbptr, state,message >> 1);
 
 
3401
        break;
 
 
3402
        case I_BehaviourAlien:
 
 
3403
        {
 
 
3404
            ALIEN_STATUS_BLOCK *alienStatusPointer = (ALIEN_STATUS_BLOCK*)sbptr->dataptr;
 
 
3405
 
 
 
3406
            if (alienStatusPointer->BehaviourState == ABS_Dormant)
 
 
3407
                Alien_Awaken(sbptr);
 
 
3408
        }
 
 
3409
        break;
 
 
3410
        case I_BehaviourFaceHugger:
 
 
3411
        {
 
 
3412
            FACEHUGGER_STATUS_BLOCK *facehuggerStatusPointer = (FACEHUGGER_STATUS_BLOCK *)(sbptr->dataptr);    
 
 
3413
 
 
 
3414
            if (facehuggerStatusPointer->nearBehaviourState == FHNS_Floating)
 
 
3415
            {
 
 
3416
                facehuggerStatusPointer->nearBehaviourState = FHNS_Approach;
 
 
3417
                sbptr->DynPtr->GravityOn = 1;
 
 
3418
            }
 
 
3419
        }
 
 
3420
        break;
 
 
3421
        case I_BehaviourXenoborg:
 
 
3422
        {
 
 
3423
            XENO_STATUS_BLOCK *xenoStatusPointer = (XENO_STATUS_BLOCK*)sbptr->dataptr;
 
 
3424
 
 
 
3425
            if (state)
 
 
3426
            {
 
 
3427
                if (xenoStatusPointer->behaviourState == XS_Inactive)
 
 
3428
                    Xeno_Enter_PowerUp_State(sbptr);
 
 
3429
            }
 
 
3430
            else
 
 
3431
            {
 
 
3432
                 if (xenoStatusPointer->behaviourState != XS_Inactive)
 
 
3433
                    Xeno_Enter_PowerDown_State(sbptr);
 
 
3434
            }
 
 
3435
        }
 
 
3436
        break;
 
 
3437
        case I_BehaviourDormantPredator:
 
 
3438
        {
 
 
3439
            if(state)
 
 
3440
                ActivateDormantPredator(sbptr);
 
 
3441
        }
 
 
3442
        break;
 
 
3443
        case I_BehaviourPredator:
 
 
3444
            //do nothing
 
 
3445
            //can't assert for this one since it might previously have been a dormant predator
 
 
3446
        break;
 
 
3447
        case I_BehaviourMarine:
 
 
3448
                SendRequestToMarine(sbptr, state,message >> 1);
 
 
3449
        break;
 
 
3450
        case I_BehaviourDeathVolume:
 
 
3451
        {
 
 
3452
            DEATH_VOLUME_BEHAV_BLOCK *dv_bhv = (DEATH_VOLUME_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3453
            assert((dv_bhv->bhvr_type == I_BehaviourDeathVolume));
 
 
3454
 
 
 
3455
            dv_bhv->active = state;
 
 
3456
        }
 
 
3457
        break;
 
 
3458
        case I_BehaviourSelfDestruct:
 
 
3459
        {
 
 
3460
            SELF_DESTRUCT_BEHAV_BLOCK *sd_bhv = (SELF_DESTRUCT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3461
            assert((sd_bhv->bhvr_type == I_BehaviourSelfDestruct));
 
 
3462
 
 
 
3463
            sd_bhv->active = state;
 
 
3464
        }
 
 
3465
        break;
 
 
3466
        case I_BehaviourParticleGenerator:
 
 
3467
            SendRequestToParticleGenerator(sbptr, state);
 
 
3468
        break;
 
 
3469
        default:
 
 
3470
        {
 
 
3471
            assert(2 < 1);
 
 
3472
        }
 
 
3473
      }
 
 
3474
}
 
 
3475
 
 
 
3476
int GetState(STRATEGYBLOCK* sbptr)
 
 
3477
{
 
 
3478
    assert(sbptr);
 
 
3479
 
 
 
3480
    switch (sbptr->type)
 
 
3481
    {
 
 
3482
        case I_BehaviourBinarySwitch:
 
 
3483
        {
 
 
3484
            // 0 = rest state
 
 
3485
            // 1 = unusual state
 
 
3486
 
 
 
3487
            BINARY_SWITCH_BEHAV_BLOCK *bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3488
            assert((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
 
 
3489
 
 
 
3490
        return((int)bs_bhv->state);
 
 
3491
        }
 
 
3492
        case I_BehaviourLinkSwitch:
 
 
3493
        {
 
 
3494
            // 0 = rest state
 
 
3495
            // 1 = unusual state
 
 
3496
 
 
 
3497
            LINK_SWITCH_BEHAV_BLOCK *bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3498
            assert((bs_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
3499
 
 
 
3500
        return((int)bs_bhv->state);
 
 
3501
        }
 
 
3502
        case I_BehaviourProximityDoor:
 
 
3503
        {
 
 
3504
            PROXDOOR_BEHAV_BLOCK *door_bhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3505
            assert((door_bhv->bhvr_type == I_BehaviourProximityDoor));
 
 
3506
 
 
 
3507
            // returns true only when fully open
 
 
3508
 
 
 
3509
        return (door_bhv->door_state == I_door_open);
 
 
3510
        }
 
 
3511
        case I_BehaviourSwitchDoor:
 
 
3512
        {
 
 
3513
            /* returns true if fully open (DO NOT CHANGE THIS) */
 
 
3514
            SWITCH_DOOR_BEHAV_BLOCK *door_bhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3515
            assert(door_bhv->myBehaviourType == I_BehaviourSwitchDoor);
 
 
3516
 
 
 
3517
        return (door_bhv->doorState == I_door_open);
 
 
3518
        }
 
 
3519
        case I_BehaviourLiftDoor:
 
 
3520
        {
 
 
3521
            LIFT_DOOR_BEHAV_BLOCK *door_bhv = (LIFT_DOOR_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3522
            assert((door_bhv->bhvr_type == I_BehaviourLiftDoor));
 
 
3523
 
 
 
3524
            // returns true only when fully open so that the lift
 
 
3525
            // dosn't start to move when we can still see out
 
 
3526
 
 
 
3527
        return !(door_bhv->door_state == I_door_closed);
 
 
3528
        }
 
 
3529
        case I_BehaviourLift:
 
 
3530
        {
 
 
3531
            LIFT_BEHAV_BLOCK *lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->dataptr;
 
 
3532
            assert((lift_bhv->bhvr_type == I_BehaviourLift));
 
 
3533
            LIFT_STATION *lift_stn = &lift_bhv->lift_station;
 
 
3534
            assert(lift_stn);
 
 
3535
 
 
 
3536
        return(lift_stn->called);
 
 
3537
        }
 
 
3538
        default:
 
 
3539
        {
 
 
3540
            assert(2 < 1);
 
 
3541
            return 0;
 
 
3542
        }
 
 
3543
    }
 
 
3544
}