4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "system.h"
 
 
2
#include "stratdef.h"
 
 
3
#include "weapons.h"
 
 
4
#include "platformlift.h"
 
 
5
#include "pldghost.h"
 
 
6
#include "bh_types.h"
 
 
7
#include <stdlib.h>
 
 
8
#include <assert.h>
 
 
9
 
 
 
10
static void SquashingSomething_for_sure(DYNAMICSBLOCK *dynPtr)
 
 
11
{
 
 
12
    struct collisionreport *nextReport = dynPtr->CollisionReportPtr;
 
 
13
 
 
 
14
    while(nextReport)
 
 
15
    {
 
 
16
        STRATEGYBLOCK *sbPtr = nextReport->ObstacleSBPtr;
 
 
17
 
 
 
18
        if(NULL != sbPtr)
 
 
19
        {
 
 
20
            sbPtr->DamageBlock.Indestructable = 0;
 
 
21
            CauseDamageToObject(sbPtr, &damage_profiles[FALLINGDAMAGE], (100*NormalFrameTime), NULL);
 
 
22
        }
 
 
23
 
 
 
24
        nextReport = nextReport->NextCollisionReportPtr;
 
 
25
    }
 
 
26
}
 
 
27
 
 
 
28
static void SquashingSomething(DYNAMICSBLOCK *dynPtr)
 
 
29
{
 
 
30
    struct collisionreport *nextReport = dynPtr->CollisionReportPtr;
 
 
31
 
 
 
32
    /* walk the collision report list, looking for collisions against objects */
 
 
33
    while(nextReport)
 
 
34
    {
 
 
35
        STRATEGYBLOCK *sbPtr = nextReport->ObstacleSBPtr;
 
 
36
 
 
 
37
        if(NULL != sbPtr)
 
 
38
        {
 
 
39
            if(nextReport->ObstacleNormal.vy < -46340)
 
 
40
            {
 
 
41
                /* squish! */
 
 
42
                sbPtr->DamageBlock.Indestructable = 0;
 
 
43
                CauseDamageToObject(sbPtr, &damage_profiles[FALLINGDAMAGE], (100*NormalFrameTime), NULL);
 
 
44
            }
 
 
45
            else if (nextReport->ObstacleNormal.vy > 46340)
 
 
46
            {
 
 
47
                DYNAMICSBLOCK *objDynPtr = sbPtr->DynPtr;
 
 
48
 
 
 
49
                if (objDynPtr && (objDynPtr->LinImpulse.vy < PLATFORMLIFT_SPEED))
 
 
50
                    objDynPtr->LinImpulse.vy += PLATFORMLIFT_SPEED;
 
 
51
            }
 
 
52
        }
 
 
53
 
 
 
54
        nextReport = nextReport->NextCollisionReportPtr;
 
 
55
    } 
 
 
56
}
 
 
57
 
 
 
58
static int PlayerIsNearOtherTerminal(STRATEGYBLOCK *sbPtr)
 
 
59
{
 
 
60
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
61
    assert(platformliftdata->state == PLBS_AtRest);
 
 
62
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
63
 
 
 
64
    int averageHeight = (platformliftdata->upHeight + platformliftdata->downHeight)/2;
 
 
65
 
 
 
66
    if(dynPtr->Position.vy > averageHeight)
 
 
67
    {
 
 
68
        if (PlayerStatus.sbptr->DynPtr->Position.vy < averageHeight)
 
 
69
            return 1;
 
 
70
    }
 
 
71
    else if (PlayerStatus.sbptr->DynPtr->Position.vy > averageHeight)
 
 
72
    {
 
 
73
        return 1;
 
 
74
    }
 
 
75
 
 
 
76
return 0;
 
 
77
}
 
 
78
 
 
 
79
static int ActivatedByPlayer(DYNAMICSBLOCK *dynPtr)
 
 
80
{
 
 
81
        struct collisionreport *nextReport = dynPtr->CollisionReportPtr;
 
 
82
 
 
 
83
        /* walk the collision report list, looking for collisions against objects */
 
 
84
        while(nextReport)
 
 
85
        {
 
 
86
        //printf("collision with %p\n",nextReport->ObstacleSBPtr);
 
 
87
        if(nextReport->ObstacleSBPtr == PlayerStatus.sbptr)
 
 
88
            return 1;
 
 
89
 
 
 
90
        nextReport = nextReport->NextCollisionReportPtr;
 
 
91
        }
 
 
92
 
 
 
93
return 0;
 
 
94
}
 
 
95
 
 
 
96
static int PLiftIsNearerUpThanDown(STRATEGYBLOCK *sbPtr)
 
 
97
{
 
 
98
    assert(sbPtr);
 
 
99
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
100
    assert(sbPtr->DynPtr);
 
 
101
 
 
 
102
    int upDist = sbPtr->DynPtr->Position.vy - platformliftdata->upHeight;
 
 
103
    int downDist = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy;
 
 
104
 
 
 
105
return (upDist < downDist);
 
 
106
}
 
 
107
 
 
 
108
/* returns 1 if the player or a remote player is within 5 m of the other end of the lift track...*/
 
 
109
static int NetPlayerAtOtherTerminal(STRATEGYBLOCK *sbPtr)
 
 
110
{
 
 
111
    int sbIndex = 0;
 
 
112
    VECTORCH otherTerminal;
 
 
113
 
 
 
114
    assert(sbPtr);
 
 
115
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
116
    assert(platformliftdata);
 
 
117
    assert(platformliftdata->state == PLBS_AtRest);
 
 
118
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
119
    assert(dynPtr);
 
 
120
 
 
 
121
    if(PLiftIsNearerUpThanDown(sbPtr))
 
 
122
    {
 
 
123
        otherTerminal = dynPtr->Position;
 
 
124
        otherTerminal.vy = platformliftdata->downHeight;
 
 
125
    }
 
 
126
    else
 
 
127
    {
 
 
128
        otherTerminal = dynPtr->Position;
 
 
129
        otherTerminal.vy = platformliftdata->upHeight;    
 
 
130
    }
 
 
131
 
 
 
132
    while(sbIndex < NumActiveStBlocks)
 
 
133
    {
 
 
134
        STRATEGYBLOCK *sbPtr = ActiveStBlockList[sbIndex++];
 
 
135
 
 
 
136
        if(sbPtr->type == I_BehaviourNetGhost)
 
 
137
        {
 
 
138
            NETGHOSTDATABLOCK *ghostData =     ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
139
            assert(ghostData);
 
 
140
 
 
 
141
            switch(ghostData->type)
 
 
142
            {
 
 
143
                case I_BehaviourMarinePlayer:
 
 
144
                case I_BehaviourAlienPlayer:
 
 
145
                case I_BehaviourPredatorPlayer:
 
 
146
                {
 
 
147
                    /* remote player */
 
 
148
                    assert(sbPtr->DynPtr);
 
 
149
                    if(VectorDistance(&(sbPtr->DynPtr->Position),&(otherTerminal)) < 5000)
 
 
150
                        return 1;
 
 
151
                }
 
 
152
                default:
 
 
153
                break;
 
 
154
            }
 
 
155
        }
 
 
156
        else if(sbPtr == PlayerStatus.sbptr)
 
 
157
        {
 
 
158
            /* local player */
 
 
159
            assert(sbPtr->DynPtr);
 
 
160
            if(VectorDistance(&sbPtr->DynPtr->Position, &otherTerminal) < 5000)
 
 
161
                return 1;
 
 
162
        }
 
 
163
    }
 
 
164
return 0;
 
 
165
}
 
 
166
 
 
 
167
static void StopPlatformLift(STRATEGYBLOCK *sbPtr)
 
 
168
{
 
 
169
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
170
 
 
 
171
    sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vy = sbPtr->DynPtr->Displacement.vz = 0;
 
 
172
    platformliftdata->state = PLBS_AtRest;
 
 
173
 
 
 
174
    /* just to stop drift... */
 
 
175
    /*
 
 
176
    if(PLiftIsNearerUpThanDown(sbPtr))
 
 
177
        sbPtr->DynPtr->Position.vy = platformliftdata->upHeight;
 
 
178
    else
 
 
179
        sbPtr->DynPtr->Position.vy = platformliftdata->downHeight;
 
 
180
    */
 
 
181
 
 
 
182
    platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES;
 
 
183
 
 
 
184
    //stop sound if the lift has any
 
 
185
    if(platformliftdata->sound)
 
 
186
        Stop_Track_Sound(platformliftdata->sound);
 
 
187
 
 
 
188
    //start end sound if lift has any
 
 
189
    if(platformliftdata->end_sound)
 
 
190
        Start_Track_Sound(platformliftdata->end_sound,&sbPtr->DynPtr->Position);
 
 
191
 
 
 
192
    if (platformliftdata->OneUse)
 
 
193
        platformliftdata->Enabled = 0;
 
 
194
}
 
 
195
 
 
 
196
static void SendPlatformLiftUp(STRATEGYBLOCK *sbPtr)
 
 
197
{
 
 
198
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
199
 
 
 
200
    platformliftdata->state = PLBS_GoingUp;
 
 
201
    sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vz = 0;
 
 
202
    platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES;
 
 
203
 
 
 
204
    sbPtr->DynPtr->Displacement.vy = -MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime);
 
 
205
    {
 
 
206
        int d = platformliftdata->upHeight - sbPtr->DynPtr->Position.vy;
 
 
207
 
 
 
208
         if (d > sbPtr->DynPtr->Displacement.vy)
 
 
209
             sbPtr->DynPtr->Displacement.vy = d;
 
 
210
    }
 
 
211
}
 
 
212
 
 
 
213
static void SendPlatformLiftDown(STRATEGYBLOCK *sbPtr)
 
 
214
{
 
 
215
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
216
 
 
 
217
    platformliftdata->state = PLBS_GoingDown;
 
 
218
    sbPtr->DynPtr->Displacement.vx = sbPtr->DynPtr->Displacement.vz = 0;
 
 
219
    platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES;
 
 
220
 
 
 
221
    sbPtr->DynPtr->Displacement.vy = MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime);
 
 
222
 
 
 
223
    int d = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy;
 
 
224
 
 
 
225
    if (d < sbPtr->DynPtr->Displacement.vy)
 
 
226
        sbPtr->DynPtr->Displacement.vy = d;
 
 
227
}
 
 
228
 
 
 
229
static int LiftDoorClosed(STRATEGYBLOCK *sbPtr)
 
 
230
{
 
 
231
    int i;
 
 
232
    for(i = 0; i < NumActiveStBlocks; i++)
 
 
233
    {
 
 
234
        STRATEGYBLOCK *candidate = ActiveStBlockList[i];
 
 
235
 
 
 
236
        if((NULL != candidate->DisplayBlock) && (I_BehaviourProximityDoor== candidate->type))
 
 
237
        {
 
 
238
            #define DOOR_OPENDISTANCE  (3000)
 
 
239
            PROXDOOR_BEHAV_BLOCK *doorbhv = (PROXDOOR_BEHAV_BLOCK*)candidate->dataptr;
 
 
240
            MODULE *mptr = candidate->moptr;
 
 
241
            int maxY = mptr->m_world.vy + mptr->m_maxy;
 
 
242
            int minY = mptr->m_world.vy + mptr->m_miny;
 
 
243
            int maxX = mptr->m_world.vx + DOOR_OPENDISTANCE;
 
 
244
            int minX = mptr->m_world.vx - DOOR_OPENDISTANCE;
 
 
245
            int maxZ = mptr->m_world.vz + DOOR_OPENDISTANCE;
 
 
246
            int minZ = mptr->m_world.vz - DOOR_OPENDISTANCE;
 
 
247
 
 
 
248
            DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
249
 
 
 
250
            if ((dynPtr->Position.vy > minY && dynPtr->Position.vy < maxY)
 
 
251
            &&
 
 
252
            (dynPtr->Position.vx > minX && dynPtr->Position.vx < maxX)
 
 
253
            &&
 
 
254
            (dynPtr->Position.vz > minZ && dynPtr->Position.vz < maxZ))
 
 
255
            {
 
 
256
                return (I_door_closed == doorbhv->door_state);
 
 
257
            }
 
 
258
        }
 
 
259
    }
 
 
260
 
 
 
261
return 1;
 
 
262
}
 
 
263
 
 
 
264
/*------------------------------Patrick 2/4/97-----------------------------------
 
 
265
  State change functions: these are alos used by network message processing fns
 
 
266
  --------------------------------------------------------------------------------*/
 
 
267
void ActivatePlatformLift(STRATEGYBLOCK *sbPtr)
 
 
268
{
 
 
269
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
270
    assert(platformliftdata);
 
 
271
 
 
 
272
    platformliftdata->state = PLBS_Activating;
 
 
273
    platformliftdata->activationDelayTimer = PLATFORMLIFT_ACTIVATIONTIME;
 
 
274
    platformliftdata->netMsgCount = PLATFORMLIFT_NUMNETMESSAGES;
 
 
275
}
 
 
276
 
 
 
277
void PlatformLiftBehaviour(STRATEGYBLOCK *sbPtr)
 
 
278
{
 
 
279
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
280
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
281
 
 
 
282
    switch(platformliftdata->state)
 
 
283
    {
 
 
284
        case PLBS_AtRest:
 
 
285
        {
 
 
286
            switch(AvP.PlayMode)
 
 
287
            {
 
 
288
                case NetworkHost:
 
 
289
                {
 
 
290
                    if(platformliftdata->Enabled)
 
 
291
                    {
 
 
292
                        if(NetPlayerAtOtherTerminal(sbPtr))
 
 
293
                        {
 
 
294
                            ActivatePlatformLift(sbPtr);
 
 
295
                        }
 
 
296
                        else if(sbPtr->DisplayBlock)
 
 
297
                        {
 
 
298
                            /* check for activation by this player*/
 
 
299
                            if(ActivatedByPlayer(dynPtr))
 
 
300
                                ActivatePlatformLift(sbPtr);
 
 
301
                        }
 
 
302
                    }
 
 
303
                }
 
 
304
                break;
 
 
305
                case NetworkPeer:
 
 
306
                {
 
 
307
                    if(ActivatedByPlayer(dynPtr))
 
 
308
                        AddNetMsg_RequestPlatformLiftActivate(sbPtr);
 
 
309
                }
 
 
310
                break;
 
 
311
                default:
 
 
312
                {
 
 
313
                    /* single player */
 
 
314
                    if (platformliftdata->Enabled && (NULL != sbPtr->DisplayBlock))
 
 
315
                    {
 
 
316
                        /* check for activation */
 
 
317
                        if(ActivatedByPlayer(dynPtr) || PlayerIsNearOtherTerminal(sbPtr))
 
 
318
                        {
 
 
319
                            ActivatePlatformLift(sbPtr);
 
 
320
                        }
 
 
321
                    }
 
 
322
                }
 
 
323
            }
 
 
324
            //printf("Platform state: at rest\n");
 
 
325
        }
 
 
326
        break;
 
 
327
        case PLBS_Activating:
 
 
328
        {
 
 
329
            if(NetworkPeer != AvP.PlayMode)
 
 
330
            {
 
 
331
if(LiftDoorClosed(sbPtr))
 
 
332
                if(platformliftdata->activationDelayTimer > 0)
 
 
333
                    platformliftdata->activationDelayTimer -= NormalFrameTime;
 
 
334
 
 
 
335
                if(platformliftdata->activationDelayTimer <= 0)
 
 
336
                {
 
 
337
                    //play start sound if the lift has any
 
 
338
                    if(platformliftdata->start_sound)
 
 
339
                        Start_Track_Sound(platformliftdata->start_sound,&sbPtr->DynPtr->Position);
 
 
340
 
 
 
341
                    platformliftdata->activationDelayTimer = 0;
 
 
342
 
 
 
343
                    if(dynPtr->Position.vy > ((platformliftdata->upHeight+platformliftdata->downHeight) / 2))
 
 
344
                        SendPlatformLiftUp(sbPtr);
 
 
345
                    else
 
 
346
                        SendPlatformLiftDown(sbPtr);
 
 
347
                }
 
 
348
            }
 
 
349
            //printf("Platform state: activating\n");
 
 
350
            //printf("Platform timer: %d\n",platformliftdata->activationDelayTimer);
 
 
351
        }
 
 
352
        break;    
 
 
353
        case PLBS_GoingUp:
 
 
354
        {
 
 
355
            if(dynPtr->Position.vy <= platformliftdata->upHeight)
 
 
356
            {
 
 
357
                StopPlatformLift(sbPtr);
 
 
358
            }
 
 
359
            else
 
 
360
            {
 
 
361
                sbPtr->DynPtr->Displacement.vy = -MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime);
 
 
362
 
 
 
363
                {
 
 
364
                    int d = platformliftdata->upHeight - sbPtr->DynPtr->Position.vy;
 
 
365
 
 
 
366
                     if (d > sbPtr->DynPtr->Displacement.vy)
 
 
367
                         sbPtr->DynPtr->Displacement.vy = d;
 
 
368
                }
 
 
369
 
 
 
370
                if(dynPtr->Position.vy == dynPtr->PrevPosition.vy)
 
 
371
                {
 
 
372
                    if(NetworkPeer != AvP.PlayMode)
 
 
373
                        SquashingSomething_for_sure(dynPtr);
 
 
374
                }
 
 
375
            }
 
 
376
 
 
 
377
            //printf("Platform state: going up\n");
 
 
378
        }
 
 
379
        break; 
 
 
380
        case PLBS_GoingDown:
 
 
381
        {
 
 
382
            if(dynPtr->Position.vy >= platformliftdata->downHeight)
 
 
383
            {
 
 
384
                StopPlatformLift(sbPtr);
 
 
385
            }
 
 
386
            else 
 
 
387
            {
 
 
388
                sbPtr->DynPtr->Displacement.vy = MUL_FIXED(PLATFORMLIFT_SPEED, NormalFrameTime);
 
 
389
 
 
 
390
                {
 
 
391
                    int d = platformliftdata->downHeight - sbPtr->DynPtr->Position.vy;
 
 
392
 
 
 
393
                     if (d < sbPtr->DynPtr->Displacement.vy)
 
 
394
                         sbPtr->DynPtr->Displacement.vy = d;
 
 
395
                }
 
 
396
 
 
 
397
                if(NetworkPeer != AvP.PlayMode)
 
 
398
                    SquashingSomething(dynPtr);
 
 
399
            }
 
 
400
            //printf("Platform state: going down\n");
 
 
401
        }
 
 
402
        break; 
 
 
403
        default:
 
 
404
        assert(1==0);
 
 
405
    }
 
 
406
 
 
 
407
    //update sound
 
 
408
    switch(platformliftdata->state)
 
 
409
    {
 
 
410
        case PLBS_GoingUp:
 
 
411
        case PLBS_GoingDown:
 
 
412
        {
 
 
413
            int mainSoundShouldBePlaying = 1;
 
 
414
            MovePlatformLift(sbPtr);
 
 
415
 
 
 
416
            //the main sound should be started if there is no start sound , or the start sound has
 
 
417
            //almost finished
 
 
418
            if(platformliftdata->start_sound && platformliftdata->start_sound->playing)
 
 
419
            {
 
 
420
                Update_Track_Sound(platformliftdata->start_sound,&dynPtr->Position);
 
 
421
                mainSoundShouldBePlaying = 0;
 
 
422
            }
 
 
423
 
 
 
424
            if(platformliftdata->sound)
 
 
425
            {
 
 
426
                if(platformliftdata->sound->playing)
 
 
427
                {
 
 
428
                    Update_Track_Sound(platformliftdata->sound, &dynPtr->Position);
 
 
429
                }
 
 
430
                else if(mainSoundShouldBePlaying)
 
 
431
                {
 
 
432
                    Start_Track_Sound(platformliftdata->sound, &sbPtr->DynPtr->Position);
 
 
433
                }
 
 
434
            }
 
 
435
        }
 
 
436
        default:
 
 
437
        break;
 
 
438
    }
 
 
439
 
 
 
440
    //printf("Platform pos: %d / %d / %d\n",platformliftdata->upHeight,dynPtr->Position.vy,platformliftdata->downHeight);
 
 
441
 
 
 
442
    /* send state messages in net game */
 
 
443
    if(NetworkHost == AvP.PlayMode)
 
 
444
    {
 
 
445
        if(platformliftdata->netMsgCount > 0)
 
 
446
        {
 
 
447
            /* don't send at rest messages: peers detect end of movement locally. */
 
 
448
            if(platformliftdata->state != PLBS_AtRest) 
 
 
449
                AddNetMsg_PlatformLiftState(sbPtr);
 
 
450
 
 
 
451
            platformliftdata->netMsgCount--;
 
 
452
        }
 
 
453
    }
 
 
454
}
 
 
455
 
 
 
456
void InitialisePlatformLift(void* bhdata, STRATEGYBLOCK *sbPtr)
 
 
457
{
 
 
458
    PLATFORMLIFT_TOOLS_TEMPLATE *toolsData = (PLATFORMLIFT_TOOLS_TEMPLATE *)bhdata;
 
 
459
 
 
 
460
    /* create, initialise and attach a data block */
 
 
461
    PLATFORMLIFT_BEHAVIOUR_BLOCK* platformliftdata = malloc(sizeof(PLATFORMLIFT_BEHAVIOUR_BLOCK));
 
 
462
    DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
463
 
 
 
464
    if((NULL == platformliftdata) || (NULL == dynPtr))
 
 
465
    {
 
 
466
        RemoveBehaviourStrategy(sbPtr);
 
 
467
        return;
 
 
468
    }
 
 
469
 
 
 
470
    sbPtr->dataptr = platformliftdata; 
 
 
471
    platformliftdata->homePosition = toolsData->position;
 
 
472
    platformliftdata->activationDelayTimer = 0;
 
 
473
    platformliftdata->state = PLBS_AtRest;
 
 
474
    platformliftdata->netMsgCount = 0;
 
 
475
 
 
 
476
    if(toolsData->travel < 0)
 
 
477
    {
 
 
478
        platformliftdata->upHeight = platformliftdata->homePosition.vy + toolsData->travel;
 
 
479
        platformliftdata->downHeight = platformliftdata->homePosition.vy;
 
 
480
    }
 
 
481
    else
 
 
482
    {
 
 
483
        platformliftdata->upHeight = platformliftdata->homePosition.vy;
 
 
484
        platformliftdata->downHeight = platformliftdata->homePosition.vy + toolsData->travel;
 
 
485
    }
 
 
486
 
 
 
487
    assert(platformliftdata->upHeight < platformliftdata->downHeight);
 
 
488
 
 
 
489
    platformliftdata->sound = toolsData->sound;
 
 
490
    platformliftdata->start_sound = toolsData->start_sound;
 
 
491
    platformliftdata->end_sound = toolsData->end_sound;
 
 
492
    platformliftdata->Enabled = toolsData->Enabled;
 
 
493
    platformliftdata->OneUse = toolsData->OneUse;
 
 
494
 
 
 
495
    dynPtr->GravityOn = 0;
 
 
496
    //dynPtr->StopOnCollision = 1;
 
 
497
    dynPtr->IsStatic = 0;
 
 
498
    dynPtr->OnlyCollideWithObjects = 1;
 
 
499
    dynPtr->UseDisplacement = 1;
 
 
500
    dynPtr->PrevPosition = dynPtr->Position = toolsData->position;
 
 
501
    dynPtr->LinVelocity.vx = dynPtr->LinVelocity.vy = dynPtr->LinVelocity.vz = 0;
 
 
502
    dynPtr->OrientEuler = toolsData->orientation;
 
 
503
    CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
504
    TransposeMatrixCH(&dynPtr->OrientMat);      
 
 
505
 
 
 
506
    {
 
 
507
    int i;
 
 
508
    for(i=0; i < SB_NAME_LENGTH; i++)
 
 
509
        sbPtr->SBname[i] = toolsData->nameID[i];
 
 
510
    }
 
 
511
 
 
 
512
    sbPtr->maintainVisibility = 1;
 
 
513
    sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL);
 
 
514
 
 
 
515
    if(NULL == sbPtr->containingModule)
 
 
516
    {
 
 
517
        //printf("no valid containing module for platforlift\n");
 
 
518
        RemoveBehaviourStrategy(sbPtr);
 
 
519
    }
 
 
520
}
 
 
521
 
 
 
522
void NetworkPeerChangePlatformLiftState(STRATEGYBLOCK* sbPtr,PLATFORMLIFT_STATES new_state)
 
 
523
{
 
 
524
    assert(sbPtr);
 
 
525
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK *)sbPtr->dataptr;
 
 
526
    assert(platformliftdata);
 
 
527
    assert(sbPtr->DynPtr);
 
 
528
 
 
 
529
    //check to see if this is a new state , and change any sound playing as necessary
 
 
530
 
 
 
531
    switch(new_state)
 
 
532
    {
 
 
533
        case PLBS_Activating:
 
 
534
            /*
 
 
535
            ignore this state change , since only the host does anything while the lift is
 
 
536
            activating , and this will prevent the lift from stopping at the ends correctly
 
 
537
            */
 
 
538
        return;
 
 
539
        case PLBS_GoingUp:
 
 
540
        case PLBS_GoingDown:
 
 
541
            switch(platformliftdata->state)
 
 
542
            {
 
 
543
                case PLBS_GoingUp:
 
 
544
                case PLBS_GoingDown:
 
 
545
                break;
 
 
546
                default:
 
 
547
                {
 
 
548
                    //platform lift has started moving
 
 
549
                    if(platformliftdata->start_sound)
 
 
550
                        Start_Track_Sound(platformliftdata->start_sound,&sbPtr->DynPtr->Position);
 
 
551
                }
 
 
552
            }
 
 
553
        default:
 
 
554
        break;
 
 
555
    }
 
 
556
 
 
 
557
    platformliftdata->state = new_state;
 
 
558
}
 
 
559
 
 
 
560
/*--------------------**
 
 
561
** Loading and Saving **
 
 
562
**--------------------*/
 
 
563
#include "savegame.h"
 
 
564
typedef struct platform_lift_save_block
 
 
565
{
 
 
566
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
567
 
 
 
568
    DYNAMICSBLOCK dynamics;
 
 
569
 
 
 
570
    int activationDelayTimer;
 
 
571
    PLATFORMLIFT_STATES    state;
 
 
572
 
 
 
573
    int Enabled; 
 
 
574
    int OneUse; //if set ,lift becomes disabled after changing position once
 
 
575
 
 
 
576
} PLATFORM_LIFT_SAVE_BLOCK;
 
 
577
 
 
 
578
//defines for load/save macros
 
 
579
#define SAVELOAD_BLOCK block
 
 
580
#define SAVELOAD_BEHAV platformliftdata
 
 
581
 
 
 
582
void LoadStrategy_PlatformLift(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
583
{
 
 
584
    PLATFORM_LIFT_SAVE_BLOCK* block = (PLATFORM_LIFT_SAVE_BLOCK*) header; 
 
 
585
 
 
 
586
    //check the size of the save block
 
 
587
    if(header->size != sizeof(*block))
 
 
588
        return;
 
 
589
 
 
 
590
    //find the existing strategy block
 
 
591
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
592
 
 
 
593
    if(!sbPtr)
 
 
594
        return;
 
 
595
 
 
 
596
    //make sure the strategy found is of the right type
 
 
597
    if(sbPtr->type != I_BehaviourPlatform)
 
 
598
        return;
 
 
599
 
 
 
600
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbPtr->dataptr;
 
 
601
 
 
 
602
    //start copying stuff
 
 
603
 
 
 
604
    COPYELEMENT_LOAD(activationDelayTimer)
 
 
605
    COPYELEMENT_LOAD(state)
 
 
606
    COPYELEMENT_LOAD(Enabled)
 
 
607
    COPYELEMENT_LOAD(OneUse)
 
 
608
 
 
 
609
    *sbPtr->DynPtr = block->dynamics;
 
 
610
}
 
 
611
 
 
 
612
void SaveStrategy_PlatformLift(STRATEGYBLOCK* sbPtr)
 
 
613
{
 
 
614
    PLATFORM_LIFT_SAVE_BLOCK *block;
 
 
615
    PLATFORMLIFT_BEHAVIOUR_BLOCK *platformliftdata = (PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbPtr->dataptr;
 
 
616
 
 
 
617
    GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
 
 
618
 
 
 
619
    COPYELEMENT_SAVE(activationDelayTimer)
 
 
620
    COPYELEMENT_SAVE(state)
 
 
621
    COPYELEMENT_SAVE(Enabled)
 
 
622
    COPYELEMENT_SAVE(OneUse)
 
 
623
 
 
 
624
    block->dynamics = *sbPtr->DynPtr;
 
 
625
    block->dynamics.CollisionReportPtr = 0;
 
 
626
}