4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "bh_spcl.h"
 
 
4
#include "dynblock.h"
 
 
5
#include <assert.h>
 
 
6
#include <stdlib.h>
 
 
7
 
 
 
8
extern void UpdateMorphing(MORPHCTRL *mcptr);
 
 
9
signed int RequestFadeToBlackLevel = 0;
 
 
10
extern SCENEMODULE MainScene;
 
 
11
 
 
 
12
void InitXenoMorphRoom(void * bhdata, STRATEGYBLOCK * sbptr)
 
 
13
{
 
 
14
    MODULE * my_mod;
 
 
15
     assert(sbptr);
 
 
16
 
 
 
17
    XENO_MORPH_ROOM_DATA * xmrd = malloc(sizeof(XENO_MORPH_ROOM_DATA));
 
 
18
    sbptr->dataptr = xmrd;
 
 
19
 
 
 
20
    if (!xmrd)
 
 
21
    {
 
 
22
        RemoveBehaviourStrategy(sbptr);
 
 
23
        return;
 
 
24
    }
 
 
25
 
 
 
26
    xmrd->bhvr_type = I_BehaviourXenoborgMorphRoom;
 
 
27
 
 
 
28
    XENO_MORPH_ROOM_TOOLS_TEMPLATE * xmrtt = (XENO_MORPH_ROOM_TOOLS_TEMPLATE *)bhdata;
 
 
29
 
 
 
30
    xmrd->MainShape = xmrtt->MainShape;
 
 
31
    xmrd->ShutShape = xmrtt->ShutShape;
 
 
32
    xmrd->WallsOutShape = xmrtt->WallsOutShape;
 
 
33
    xmrd->ProbesInShape = xmrtt->ProbesInShape;
 
 
34
 
 
 
35
    MORPHCTRL* morphctrl = malloc(sizeof(MORPHCTRL));
 
 
36
 
 
 
37
    if (!morphctrl)
 
 
38
    {
 
 
39
        RemoveBehaviourStrategy(sbptr);
 
 
40
        return;
 
 
41
    }
 
 
42
 
 
 
43
    MORPHHEADER* morphheader = malloc(sizeof(MORPHHEADER));
 
 
44
 
 
 
45
    if (!morphheader)
 
 
46
    {
 
 
47
        free(morphctrl);
 
 
48
        RemoveBehaviourStrategy(sbptr);
 
 
49
        return;
 
 
50
    }
 
 
51
 
 
 
52
    MORPHFRAME* morphframe = malloc(sizeof(MORPHFRAME));
 
 
53
 
 
 
54
    if (!morphframe)
 
 
55
    {
 
 
56
        free(morphctrl);
 
 
57
        free(morphheader);
 
 
58
        RemoveBehaviourStrategy(sbptr);
 
 
59
        return;
 
 
60
    }
 
 
61
 
 
 
62
    morphframe->mf_shape1 = xmrd->MainShape;
 
 
63
    morphframe->mf_shape2 = xmrd->ShutShape;
 
 
64
 
 
 
65
    morphheader->mph_numframes = 1;
 
 
66
    morphheader->mph_maxframes = ONE_FIXED;
 
 
67
    morphheader->mph_frames = morphframe;
 
 
68
 
 
 
69
    morphctrl->ObMorphCurrFrame = 0;
 
 
70
    morphctrl->ObMorphFlags = 0;
 
 
71
    morphctrl->ObMorphSpeed = 0;
 
 
72
    morphctrl->ObMorphHeader = morphheader;
 
 
73
 
 
 
74
    // Copy the names over
 
 
75
    COPY_NAME (sbptr->SBname, xmrtt->nameID);
 
 
76
    COPY_NAME (xmrd->doorID, xmrtt->doorID);
 
 
77
 
 
 
78
    // Setup module ref
 
 
79
    ConvertModuleNameToPointer(&xmrtt->my_module, MainScene.sm_marray);
 
 
80
    my_mod = xmrtt->my_module.mref_ptr;
 
 
81
 
 
 
82
    assert (my_mod);
 
 
83
 
 
 
84
    my_mod->m_sbptr = sbptr;
 
 
85
    sbptr->moptr = my_mod;
 
 
86
    sbptr->shapeIndex = my_mod->m_mapptr->MapShape;
 
 
87
 
 
 
88
    xmrd->XMR_Mctrl = morphctrl;
 
 
89
    xmrd->XMR_State = XMRS_Idle;
 
 
90
    xmrd->DoorToRoom = 0;
 
 
91
 
 
 
92
    sbptr->morphctrl = xmrd->XMR_Mctrl;
 
 
93
    sbptr->morphctrl->ObMorphCurrFrame = 0;
 
 
94
 
 
 
95
    // set up the animation control
 
 
96
    {
 
 
97
        int item_num = 0;
 
 
98
        int shape_num = my_mod->m_mapptr->MapShape;
 
 
99
        struct shapeheader* shptr = GetShapeData(shape_num);
 
 
100
        TXACTRLBLK **pptxactrlblk = &xmrd->tacb;
 
 
101
 
 
 
102
        for(; item_num < shptr->numitems; item_num ++)
 
 
103
        {
 
 
104
            POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
 
 
105
            assert(poly);
 
 
106
 
 
 
107
            if(poly->PolyFlags & iflag_txanim)
 
 
108
            {
 
 
109
                int num_seq = 0;
 
 
110
                TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
111
 
 
 
112
                if (pnew_txactrlblk)
 
 
113
                {
 
 
114
                    pnew_txactrlblk->tac_flags = 0;
 
 
115
                    pnew_txactrlblk->tac_item = item_num;
 
 
116
                    pnew_txactrlblk->tac_sequence = 0;
 
 
117
                    pnew_txactrlblk->tac_node = 0;
 
 
118
                    pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num);
 
 
119
                    pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num);
 
 
120
 
 
 
121
                    while(pnew_txactrlblk->tac_txarray[num_seq+1])
 
 
122
                        num_seq++;
 
 
123
 
 
 
124
                    /* set the flags in the animation header */
 
 
125
                    // we only ever have one frame of animation per sequence -
 
 
126
                    // nb this can change talk to richard - one sequence with two frames
 
 
127
                    // or mutliple sequences???
 
 
128
 
 
 
129
                    // pnew_txactrlblk->tac_txah.txa_flags |= txa_flag_play;
 
 
130
 
 
 
131
                    /* change the value held in pptxactrlblk
 
 
132
                     which point to the previous structures "next"
 
 
133
                     pointer*/
 
 
134
 
 
 
135
                    *pptxactrlblk = pnew_txactrlblk;
 
 
136
                    pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
137
                }
 
 
138
                else
 
 
139
                {
 
 
140
                    memoryInitialisationFailure = 1;
 
 
141
                }
 
 
142
            }
 
 
143
        }
 
 
144
 
 
 
145
        *pptxactrlblk = NULL;
 
 
146
    }
 
 
147
 
 
 
148
    RequestFadeToBlackLevel = 0;
 
 
149
}
 
 
150
 
 
 
151
void XenoMorphRoomBehaviour (STRATEGYBLOCK * sbptr)
 
 
152
{
 
 
153
    XENO_MORPH_ROOM_DATA * xmrd = (XENO_MORPH_ROOM_DATA *)sbptr->dataptr;
 
 
154
    MORPHCTRL * mctrl = xmrd->XMR_Mctrl;
 
 
155
 
 
 
156
    assert (mctrl);
 
 
157
    assert (mctrl->ObMorphHeader);
 
 
158
    assert (mctrl->ObMorphHeader->mph_frames);
 
 
159
 
 
 
160
    switch (xmrd->XMR_State)
 
 
161
    {
 
 
162
        case XMRS_Idle:
 
 
163
        {
 
 
164
            if (sbptr->moptr->m_dptr)
 
 
165
            {
 
 
166
                if (PlayerStatus.sbptr->containingModule == sbptr->moptr)
 
 
167
                {
 
 
168
                    VECTORCH diff;
 
 
169
                    diff.vx = PlayerStatus.DisplayBlock->ObWorld.vx - sbptr->moptr->m_dptr->ObWorld.vx;
 
 
170
                    diff.vy = PlayerStatus.DisplayBlock->ObWorld.vy - sbptr->moptr->m_dptr->ObWorld.vy;
 
 
171
                    diff.vz = PlayerStatus.DisplayBlock->ObWorld.vz - sbptr->moptr->m_dptr->ObWorld.vz;
 
 
172
 
 
 
173
                    if (diff.vx * diff.vx + diff.vz * diff.vz < 200000)
 
 
174
                        xmrd->XMR_State = XMRS_SafetyChecks;
 
 
175
                }
 
 
176
            }
 
 
177
        }
 
 
178
        break;
 
 
179
        case XMRS_SafetyChecks:
 
 
180
        {
 
 
181
            int can_continue = 1;
 
 
182
            int i;
 
 
183
            // waits to make sure everything is OK before it shuts the walls
 
 
184
 
 
 
185
            if (xmrd->DoorToRoom)
 
 
186
            {
 
 
187
                PROXDOOR_BEHAV_BLOCK * doorbhv = (PROXDOOR_BEHAV_BLOCK*)xmrd->DoorToRoom->dataptr;
 
 
188
 
 
 
189
                doorbhv->door_locked = 1;
 
 
190
 
 
 
191
                if (doorbhv->door_state != I_door_closed)
 
 
192
                    can_continue = 0;
 
 
193
            }
 
 
194
 
 
 
195
            for (i=0; i < NumActiveStBlocks; i++)
 
 
196
            {
 
 
197
                if (ActiveStBlockList[i]->type == I_BehaviourMarine)
 
 
198
                {
 
 
199
                    if (ActiveStBlockList[i]->containingModule == sbptr->moptr)
 
 
200
                    {
 
 
201
                        can_continue = 0;
 
 
202
                        break;
 
 
203
                    }
 
 
204
                }
 
 
205
            }
 
 
206
 
 
 
207
            if (sbptr->moptr->m_dptr)
 
 
208
            {
 
 
209
                if (PlayerStatus.sbptr->containingModule == sbptr->moptr)
 
 
210
                {
 
 
211
                    VECTORCH diff;
 
 
212
                    diff.vx = PlayerStatus.DisplayBlock->ObWorld.vx - sbptr->moptr->m_dptr->ObWorld.vx;
 
 
213
                    diff.vy = PlayerStatus.DisplayBlock->ObWorld.vy - sbptr->moptr->m_dptr->ObWorld.vy;
 
 
214
                    diff.vz = PlayerStatus.DisplayBlock->ObWorld.vz - sbptr->moptr->m_dptr->ObWorld.vz;
 
 
215
 
 
 
216
                    if (diff.vx * diff.vx + diff.vz * diff.vz > 200000)
 
 
217
                        can_continue = 0;
 
 
218
 
 
 
219
                    if(DynamicObjectIsMoving(PlayerStatus.sbptr->DynPtr))
 
 
220
                        can_continue = 0;
 
 
221
                }
 
 
222
                else
 
 
223
                {
 
 
224
                    can_continue = 0;
 
 
225
                }
 
 
226
            }
 
 
227
            else
 
 
228
            {
 
 
229
                    can_continue = 0;
 
 
230
                    xmrd->XMR_State = XMRS_Idle;
 
 
231
            }
 
 
232
 
 
 
233
            if (can_continue)
 
 
234
            {
 
 
235
                // closes in player
 
 
236
                mctrl->ObMorphHeader->mph_frames->mf_shape1 = xmrd->MainShape;
 
 
237
                mctrl->ObMorphHeader->mph_frames->mf_shape2 = xmrd->ShutShape;
 
 
238
 
 
 
239
                mctrl->ObMorphCurrFrame = 0;
 
 
240
                mctrl->ObMorphFlags = mph_flag_play;
 
 
241
                mctrl->ObMorphFlags |= mph_flag_noloop;
 
 
242
                mctrl->ObMorphFlags &= ~mph_flag_reverse;
 
 
243
                mctrl->ObMorphFlags &= ~mph_flag_finished;
 
 
244
                mctrl->ObMorphSpeed = 1 << 18;
 
 
245
 
 
 
246
                xmrd->XMR_State = XMRS_EnclosingPlayer;
 
 
247
            }
 
 
248
        }
 
 
249
        break;
 
 
250
        case XMRS_EnclosingPlayer:
 
 
251
        {
 
 
252
            UpdateMorphing(mctrl);
 
 
253
 
 
 
254
            if(mctrl->ObMorphFlags & mph_flag_finished)        
 
 
255
            {
 
 
256
                mctrl->ObMorphHeader->mph_frames->mf_shape1 = xmrd->ShutShape;
 
 
257
                mctrl->ObMorphHeader->mph_frames->mf_shape2 = xmrd->WallsOutShape;
 
 
258
 
 
 
259
                mctrl->ObMorphCurrFrame = 0;
 
 
260
 
 
 
261
                mctrl->ObMorphFlags = mph_flag_play;
 
 
262
                mctrl->ObMorphFlags |= mph_flag_noloop;
 
 
263
                mctrl->ObMorphFlags &= ~mph_flag_reverse;
 
 
264
                mctrl->ObMorphFlags &= ~mph_flag_finished;
 
 
265
                mctrl->ObMorphSpeed = 1 << 13;
 
 
266
 
 
 
267
                xmrd->XMR_State = XMRS_WallsOut;
 
 
268
            }
 
 
269
        }
 
 
270
        break;
 
 
271
        case XMRS_WallsOut:
 
 
272
        {
 
 
273
            UpdateMorphing(mctrl);
 
 
274
 
 
 
275
            if(mctrl->ObMorphFlags & mph_flag_finished)        
 
 
276
            {
 
 
277
                mctrl->ObMorphHeader->mph_frames->mf_shape1 = xmrd->WallsOutShape;
 
 
278
                mctrl->ObMorphHeader->mph_frames->mf_shape2 = xmrd->ProbesInShape;
 
 
279
 
 
 
280
                mctrl->ObMorphCurrFrame = 0;
 
 
281
 
 
 
282
                mctrl->ObMorphFlags = mph_flag_play;
 
 
283
                mctrl->ObMorphFlags |= mph_flag_noloop;
 
 
284
                mctrl->ObMorphFlags &= ~mph_flag_reverse;
 
 
285
                mctrl->ObMorphFlags &= ~mph_flag_finished;
 
 
286
                mctrl->ObMorphSpeed = 1 << 13;
 
 
287
 
 
 
288
                xmrd->XMR_State = XMRS_ProbesIn;
 
 
289
            }
 
 
290
        }
 
 
291
        break;
 
 
292
        case XMRS_ProbesIn:
 
 
293
        {
 
 
294
            UpdateMorphing(mctrl);
 
 
295
 
 
 
296
            if(mctrl->ObMorphFlags & mph_flag_finished)        
 
 
297
                xmrd->XMR_State = XMRS_FadeToBlack;
 
 
298
        }
 
 
299
        break;
 
 
300
        case XMRS_FadeToBlack:
 
 
301
        {
 
 
302
            RequestFadeToBlackLevel += (NormalFrameTime >> 1);
 
 
303
 
 
 
304
            if (RequestFadeToBlackLevel > (ONE_FIXED))
 
 
305
            {
 
 
306
                RequestFadeToBlackLevel = ONE_FIXED;
 
 
307
                xmrd->timer = 0;
 
 
308
                xmrd->XMR_State = XMRS_Process;
 
 
309
            }
 
 
310
        }
 
 
311
        break;
 
 
312
        case XMRS_Process:
 
 
313
        {
 
 
314
            xmrd->timer += NormalFrameTime;
 
 
315
 
 
 
316
            if (xmrd->timer > (ONE_FIXED << 3))
 
 
317
            {
 
 
318
                if(sbptr->DisplayBlock)
 
 
319
                {
 
 
320
                    struct shapeheader* pis = GetShapeData(xmrd->ProbesInShape);
 
 
321
                    struct shapeheader* ms = GetShapeData(xmrd->MainShape);
 
 
322
 
 
 
323
                    sbptr->DisplayBlock->ObMorphCtrl = 0;
 
 
324
 
 
 
325
                    xmrd->pis_items_str = pis->items;
 
 
326
                    xmrd->pis_sht_str = pis->sh_textures;
 
 
327
 
 
 
328
                    pis->items = ms->items;
 
 
329
                    pis->sh_textures = ms->sh_textures;
 
 
330
                    pis->sh_instruction[4].sh_instr_data = ms->sh_instruction[4].sh_instr_data;
 
 
331
 
 
 
332
                    sbptr->DisplayBlock->ObTxAnimCtrlBlks = xmrd->tacb;
 
 
333
                    sbptr->DisplayBlock->ObShape = xmrd->ProbesInShape;
 
 
334
                    sbptr->DisplayBlock->ShapeData = GetShapeData(xmrd->ProbesInShape);
 
 
335
 
 
 
336
                    // This moves the player to the required location
 
 
337
 
 
 
338
                    PlayerStatus.sbptr->DynPtr->Position = sbptr->DisplayBlock->ObWorld;
 
 
339
                    PlayerStatus.sbptr->DynPtr->Position.vy += 1472;
 
 
340
                    PlayerStatus.sbptr->DynPtr->Position.vx -= 900;
 
 
341
                    PlayerStatus.sbptr->DynPtr->PrevPosition = PlayerStatus.sbptr->DynPtr->Position;
 
 
342
                    PlayerStatus.sbptr->DynPtr->OrientEuler.EulerX = 0;
 
 
343
                    PlayerStatus.sbptr->DynPtr->OrientEuler.EulerY = 1024;
 
 
344
                    PlayerStatus.sbptr->DynPtr->OrientEuler.EulerZ = 0;
 
 
345
                    PlayerStatus.sbptr->DynPtr->PrevOrientEuler = PlayerStatus.sbptr->DynPtr->OrientEuler;
 
 
346
 
 
 
347
                    CreateEulerMatrix (&PlayerStatus.sbptr->DynPtr->OrientEuler, &PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
348
 
 
 
349
                    TransposeMatrixCH(&PlayerStatus.sbptr->DynPtr->OrientMat);
 
 
350
 
 
 
351
                    PlayerStatus.sbptr->DynPtr->PrevOrientMat = PlayerStatus.sbptr->DynPtr->OrientMat;
 
 
352
 
 
 
353
                    xmrd->XMR_State = XMRS_Return;
 
 
354
                }
 
 
355
            }
 
 
356
        }
 
 
357
        break;
 
 
358
        case XMRS_Return:
 
 
359
        {
 
 
360
            RequestFadeToBlackLevel -= (NormalFrameTime >> 1);
 
 
361
 
 
 
362
            if (RequestFadeToBlackLevel <= 0)
 
 
363
            {
 
 
364
                RequestFadeToBlackLevel = 0;
 
 
365
 
 
 
366
                xmrd->timer = 0;
 
 
367
                xmrd->XMR_State = XMRS_ReleasePlayer;
 
 
368
            }
 
 
369
        }
 
 
370
        break;
 
 
371
        case XMRS_ReleasePlayer:
 
 
372
        {
 
 
373
            xmrd->timer += NormalFrameTime;
 
 
374
 
 
 
375
            if (xmrd->timer > (ONE_FIXED << 2))
 
 
376
            {
 
 
377
                sbptr->DisplayBlock->ObShape = xmrd->MainShape;
 
 
378
                sbptr->DisplayBlock->ShapeData = GetShapeData(xmrd->MainShape);
 
 
379
                sbptr->DisplayBlock->ObMorphCtrl = mctrl;
 
 
380
                mctrl->ObMorphHeader->mph_frames->mf_shape1 = xmrd->ProbesInShape;
 
 
381
                mctrl->ObMorphHeader->mph_frames->mf_shape2 = xmrd->MainShape;
 
 
382
                mctrl->ObMorphCurrFrame = 0;
 
 
383
                mctrl->ObMorphFlags = mph_flag_play;
 
 
384
                mctrl->ObMorphFlags |= mph_flag_noloop;
 
 
385
                mctrl->ObMorphFlags &= ~mph_flag_reverse;
 
 
386
                mctrl->ObMorphFlags &= ~mph_flag_finished;
 
 
387
                mctrl->ObMorphSpeed = 1 << 15;
 
 
388
 
 
 
389
                xmrd->XMR_State = XMRS_Finished;
 
 
390
            }
 
 
391
        }
 
 
392
        break;
 
 
393
        case XMRS_Finished:
 
 
394
        {
 
 
395
            if(!(mctrl->ObMorphFlags & mph_flag_finished))        
 
 
396
            {
 
 
397
                UpdateMorphing(mctrl);
 
 
398
            }
 
 
399
            else
 
 
400
            {
 
 
401
                struct shapeheader* pis = GetShapeData(xmrd->ProbesInShape);
 
 
402
                sbptr->DisplayBlock->ObTxAnimCtrlBlks = 0;
 
 
403
                pis->items = xmrd->pis_items_str;
 
 
404
                pis->sh_textures = xmrd->pis_sht_str;
 
 
405
 
 
 
406
                pis->sh_instruction[4].sh_instr_data = xmrd->pis_items_str;
 
 
407
                xmrd->XMR_State = XMRS_Idle;
 
 
408
            }
 
 
409
        }
 
 
410
        break;
 
 
411
        default :
 
 
412
            assert (0 == "Shouldn't be here");
 
 
413
            break;
 
 
414
    }
 
 
415
}