4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "system.h"
 
 
2
#include "stratdef.h"
 
 
3
#include "bh_types.h"
 
 
4
#include "linkswitch.h"
 
 
5
#include "pldghost.h"
 
 
6
#include "binaryswitch.h"
 
 
7
#include <assert.h>
 
 
8
#include <stdlib.h>
 
 
9
#include <stdio.h>
 
 
10
 
 
 
11
extern int RealFrameTime;
 
 
12
 
 
 
13
static int check_link_switch_states (LINK_SWITCH_BEHAV_BLOCK * lsbb)
 
 
14
{
 
 
15
    int i=0;
 
 
16
    LSWITCH_ITEM * lsi = lsbb->lswitch_list;
 
 
17
 
 
 
18
//    printf("Checking link states\n");
 
 
19
 
 
 
20
    if (!lsbb->state)
 
 
21
        return 0;
 
 
22
 
 
 
23
//    printf("Link switch OK\n");
 
 
24
 
 
 
25
    while (i < lsbb->num_linked_switches)
 
 
26
    {
 
 
27
        switch(lsi[i].bswitch->type)
 
 
28
        {
 
 
29
            case I_BehaviourBinarySwitch:
 
 
30
            {
 
 
31
                BINARY_SWITCH_BEHAV_BLOCK * bsbb = ((BINARY_SWITCH_BEHAV_BLOCK *)lsi[i].bswitch->dataptr);
 
 
32
 
 
 
33
                // if it's off return No
 
 
34
                if (!bsbb->state)
 
 
35
                    return 0;
 
 
36
    //            printf("Switch %d OK\n", i);
 
 
37
            }
 
 
38
            break;
 
 
39
            case I_BehaviourLinkSwitch:
 
 
40
            {
 
 
41
                LINK_SWITCH_BEHAV_BLOCK * linked_lsbb = ((LINK_SWITCH_BEHAV_BLOCK *)lsi[i].bswitch->dataptr);
 
 
42
 
 
 
43
                // if the system state is off return No
 
 
44
                if (!linked_lsbb->system_state)
 
 
45
                    return 0;
 
 
46
            }
 
 
47
            break;
 
 
48
            default:
 
 
49
            {
 
 
50
                assert(0=="Switch should only have links to link switches and binary switches");
 
 
51
            }
 
 
52
        }
 
 
53
        i++;
 
 
54
    }
 
 
55
 
 
 
56
//    printf("Link switchs activated\n");
 
 
57
 
 
 
58
return 1;
 
 
59
}
 
 
60
 
 
 
61
void LinkSwitchBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
 
 
62
{
 
 
63
     assert(sbptr);
 
 
64
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = malloc(sizeof(LINK_SWITCH_BEHAV_BLOCK));
 
 
65
 
 
 
66
    if(!ls_bhv)
 
 
67
    {
 
 
68
        RemoveBehaviourStrategy(sbptr);
 
 
69
        return;
 
 
70
    }
 
 
71
 
 
 
72
    sbptr->dataptr = ls_bhv;
 
 
73
    ls_bhv->bhvr_type = I_BehaviourLinkSwitch;
 
 
74
 
 
 
75
    // from loaders
 
 
76
    // 1 rest_state - on or off
 
 
77
    // 2 mode
 
 
78
    // 3 timer switch - time for reset
 
 
79
    // 4 security clerance to operate
 
 
80
    // 5 copy the target name
 
 
81
 
 
 
82
    LINK_SWITCH_TOOLS_TEMPLATE *ls_tt = (LINK_SWITCH_TOOLS_TEMPLATE*)bhdata;
 
 
83
 
 
 
84
    COPY_NAME(sbptr->SBname, ls_tt->nameID);
 
 
85
 
 
 
86
    if (ls_tt->mode == I_lswitch_SELFDESTRUCT)
 
 
87
    {
 
 
88
        ls_bhv->ls_mode = I_lswitch_timer;
 
 
89
        ls_bhv->IS_SELF_DESTRUCT = 1;
 
 
90
    }
 
 
91
    else
 
 
92
    {
 
 
93
        ls_bhv->ls_mode = ls_tt->mode;
 
 
94
        ls_bhv->IS_SELF_DESTRUCT = 0;
 
 
95
    }
 
 
96
 
 
 
97
    ls_bhv->num_targets = ls_tt->num_targets;
 
 
98
 
 
 
99
    if(ls_bhv->num_targets)
 
 
100
    {
 
 
101
        ls_bhv->ls_targets = malloc(sizeof(LINK_SWITCH_TARGET) * ls_tt->num_targets);
 
 
102
 
 
 
103
        if (!ls_bhv->ls_targets)
 
 
104
        {
 
 
105
            RemoveBehaviourStrategy(sbptr);
 
 
106
            return;
 
 
107
        }
 
 
108
    }
 
 
109
    else
 
 
110
    {
 
 
111
        ls_bhv->ls_targets = NULL;
 
 
112
    }
 
 
113
 
 
 
114
    {
 
 
115
        int i;
 
 
116
        for (i=0; i<ls_tt->num_targets; i++)
 
 
117
        {
 
 
118
            ls_bhv->ls_targets[i] = ls_tt->targets[i];
 
 
119
            ls_bhv->ls_targets[i].sbptr = 0;
 
 
120
        }
 
 
121
    }
 
 
122
 
 
 
123
    ls_bhv->time_for_reset = ls_tt->time_for_reset;
 
 
124
    ls_bhv->security_clerance = ls_tt->security_clearance;
 
 
125
    ls_bhv->switch_flags = ls_tt->switch_flags;
 
 
126
    ls_bhv->trigger_volume_min = ls_tt->trigger_volume_min;    
 
 
127
    ls_bhv->trigger_volume_max = ls_tt->trigger_volume_max;    
 
 
128
    ls_bhv->switch_always_on = ls_tt->switch_always_on;
 
 
129
    ls_bhv->switch_off_message_same = ls_tt->switch_off_message_same;    
 
 
130
    ls_bhv->switch_off_message_none = ls_tt->switch_off_message_none;    
 
 
131
 
 
 
132
    // set up the animation control
 
 
133
    if(sbptr->shapeIndex != -1)
 
 
134
    {
 
 
135
        sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
136
 
 
 
137
        if(NULL == sbptr->DynPtr)
 
 
138
        {
 
 
139
            RemoveBehaviourStrategy(sbptr);
 
 
140
            return;
 
 
141
        }
 
 
142
        else
 
 
143
        {
 
 
144
            sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = ls_tt->position;
 
 
145
            sbptr->DynPtr->OrientEuler = ls_tt->orientation;
 
 
146
            CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat);
 
 
147
            TransposeMatrixCH(&sbptr->DynPtr->OrientMat);    
 
 
148
            sbptr->containingModule = ModuleFromPosition(&sbptr->DynPtr->Position, NULL);
 
 
149
 
 
 
150
            if(NULL == sbptr->containingModule)
 
 
151
            {
 
 
152
                printf("no contaning module for link switch\n");
 
 
153
                RemoveBehaviourStrategy(sbptr);
 
 
154
                return;
 
 
155
            }
 
 
156
 
 
 
157
            sbptr->maintainVisibility = 1;
 
 
158
        }
 
 
159
 
 
 
160
        int item_num = 0;
 
 
161
        struct shapeheader* shptr = mainshapelist[sbptr->shapeIndex];
 
 
162
        TXACTRLBLK **pptxactrlblk = &ls_bhv->ls_tac;
 
 
163
 
 
 
164
        for(; item_num < shptr->numitems; item_num++)
 
 
165
        {
 
 
166
            POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
 
 
167
            assert(poly);
 
 
168
 
 
 
169
            if(poly->PolyFlags  & iflag_txanim)
 
 
170
            {
 
 
171
                int num_seq = 0;
 
 
172
                TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
173
 
 
 
174
                if (pnew_txactrlblk)
 
 
175
                {
 
 
176
                    pnew_txactrlblk->tac_flags = 0;
 
 
177
                    pnew_txactrlblk->tac_item = item_num;
 
 
178
                    pnew_txactrlblk->tac_sequence = ls_tt->rest_state;
 
 
179
                    pnew_txactrlblk->tac_node = 0;
 
 
180
                    pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(sbptr->shapeIndex, item_num);
 
 
181
                    pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, sbptr->shapeIndex);
 
 
182
 
 
 
183
                    while(pnew_txactrlblk->tac_txarray[num_seq+1])
 
 
184
                        num_seq++;
 
 
185
 
 
 
186
                    // Assert does not work at this point so
 
 
187
                    assert(num_seq == 2);
 
 
188
 
 
 
189
                    /* set the flags in the animation header */
 
 
190
                    // we only ever have one frame of animation per sequence -
 
 
191
                    // nb this can change talk to richard - one sequence with two frames
 
 
192
                    // or mutliple sequences???
 
 
193
 
 
 
194
                    //Now two sequences with an arbitrary number of frames - Richard
 
 
195
 
 
 
196
                    pnew_txactrlblk->tac_txah.txa_flags |= txa_flag_play;
 
 
197
 
 
 
198
                    /* change the value held in pptxactrlblk
 
 
199
                     which point to the previous structures "next"
 
 
200
                     pointer*/
 
 
201
 
 
 
202
                    *pptxactrlblk = pnew_txactrlblk;
 
 
203
                    pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
204
                }
 
 
205
                else
 
 
206
                {
 
 
207
                    memoryInitialisationFailure = 1;
 
 
208
                }
 
 
209
            }
 
 
210
        }
 
 
211
        *pptxactrlblk = 0;
 
 
212
    }
 
 
213
    else
 
 
214
    {
 
 
215
        //no shape - so there won't be any animation
 
 
216
        ls_bhv->ls_tac = 0;
 
 
217
    }
 
 
218
 
 
 
219
    ls_bhv->ls_dtype = linkswitch_no_display;
 
 
220
 
 
 
221
    if (ls_bhv->ls_tac)
 
 
222
        ls_bhv->ls_dtype = linkswitch_animate_me;
 
 
223
 
 
 
224
    ls_bhv->ls_track = ls_tt->track;
 
 
225
 
 
 
226
    if (ls_bhv->ls_track)
 
 
227
    {
 
 
228
        ls_bhv->ls_track->sbptr = sbptr;
 
 
229
 
 
 
230
        if (ls_bhv->ls_dtype == linkswitch_animate_me)
 
 
231
            ls_bhv->ls_dtype = linkswitch_animate_and_move_me;
 
 
232
        else
 
 
233
            ls_bhv->ls_dtype = linkswitch_move_me;
 
 
234
    }
 
 
235
 
 
 
236
    // fill in the rest ourselves
 
 
237
 
 
 
238
    ls_bhv->request = 0;
 
 
239
    ls_bhv->state = ls_tt->rest_state;
 
 
240
    ls_bhv->timer = 0;    
 
 
241
    ls_bhv->system_state = 0;
 
 
242
    ls_bhv->soundHandle = SOUND_NOACTIVEINDEX;
 
 
243
    ls_bhv->num_linked_switches = ls_tt->num_linked_switches;
 
 
244
 
 
 
245
    if(ls_tt->num_linked_switches)
 
 
246
    {
 
 
247
        ls_bhv->lswitch_list = malloc(sizeof(LSWITCH_ITEM) * ls_bhv->num_linked_switches);
 
 
248
 
 
 
249
        if (NULL == ls_bhv->lswitch_list)
 
 
250
        {
 
 
251
            RemoveBehaviourStrategy(sbptr);
 
 
252
            return;
 
 
253
        }
 
 
254
        else
 
 
255
        {
 
 
256
            int i;
 
 
257
            for (i=0; i < ls_tt->num_linked_switches; i++)
 
 
258
            {
 
 
259
                COPY_NAME (ls_bhv->lswitch_list[i].bs_name, ls_tt->switchIDs[i].name);
 
 
260
            }
 
 
261
        }
 
 
262
    }
 
 
263
    else
 
 
264
    {
 
 
265
        ls_bhv->lswitch_list = NULL;
 
 
266
    }
 
 
267
 
 
 
268
    if(ls_bhv->state)
 
 
269
    {
 
 
270
        ls_bhv->timer = ls_bhv->time_for_reset;    
 
 
271
 
 
 
272
        if(ls_bhv->ls_track)
 
 
273
        {
 
 
274
            //set the track to the end position
 
 
275
            ls_bhv->ls_track->current_section = (ls_bhv->ls_track->num_sections-1);
 
 
276
            ls_bhv->ls_track->timer = ls_bhv->ls_track->sections[ls_bhv->ls_track->current_section].time_for_section;
 
 
277
            ls_bhv->ls_track->playing = 1;
 
 
278
            Update_Track_Position(ls_bhv->ls_track);
 
 
279
        }
 
 
280
    }
 
 
281
 
 
 
282
    ls_bhv->TimeUntilNetSynchAllowed = 0;
 
 
283
}
 
 
284
 
 
 
285
void LinkSwitchBehaveFun(STRATEGYBLOCK* sbptr)
 
 
286
{
 
 
287
     assert(sbptr);
 
 
288
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->dataptr;
 
 
289
    assert((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
290
    DISPLAYBLOCK* dptr = sbptr->DisplayBlock;
 
 
291
 
 
 
292
    /****** 
 
 
293
        What I need to do - check to see if we have
 
 
294
        a request - requests have different effects depending on 
 
 
295
        the mode - so we have to switch on the mode
 
 
296
    *****/
 
 
297
 
 
 
298
    switch(ls_bhv->ls_dtype)
 
 
299
    {
 
 
300
        case linkswitch_animate_me:
 
 
301
        case linkswitch_animate_and_move_me:
 
 
302
            if(dptr)
 
 
303
                dptr->ObTxAnimCtrlBlks = ls_bhv->ls_tac;
 
 
304
        default:
 
 
305
        break;
 
 
306
    }
 
 
307
 
 
 
308
    if (!ReturnPlayerSecurityClearance(ls_bhv->security_clerance) && ls_bhv->security_clerance)
 
 
309
    {
 
 
310
        ls_bhv->request = I_no_request;
 
 
311
        return;
 
 
312
    }
 
 
313
 
 
 
314
    if(ls_bhv->switch_flags && SwitchFlag_UseTriggerVolume)
 
 
315
    {
 
 
316
        /*See if switch has been set off*/
 
 
317
        int i;
 
 
318
        for (i=0; i < NumActiveStBlocks; i++)
 
 
319
        {
 
 
320
            int needToTest = 0;
 
 
321
            STRATEGYBLOCK *sbPtr = ActiveStBlockList[i];
 
 
322
 
 
 
323
            if (sbPtr->DynPtr)
 
 
324
            {
 
 
325
                if (sbPtr->DisplayBlock == PlayerStatus.DisplayBlock)
 
 
326
                {
 
 
327
                    needToTest = 1;
 
 
328
                }
 
 
329
                else if (sbPtr->type == I_BehaviourNetGhost)
 
 
330
                {
 
 
331
                    NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
332
 
 
 
333
                    switch(ghostData->type)
 
 
334
                    {
 
 
335
                        case I_BehaviourMarinePlayer:
 
 
336
                        case I_BehaviourAlienPlayer:
 
 
337
                        case I_BehaviourPredatorPlayer:
 
 
338
                            needToTest = 1;
 
 
339
                        default:
 
 
340
                        break;
 
 
341
                    }
 
 
342
                }
 
 
343
            }
 
 
344
 
 
 
345
            if(needToTest&&
 
 
346
                sbPtr->DynPtr->Position.vx > ls_bhv->trigger_volume_min.vx &&    
 
 
347
                sbPtr->DynPtr->Position.vx < ls_bhv->trigger_volume_max.vx &&
 
 
348
                sbPtr->DynPtr->Position.vy > ls_bhv->trigger_volume_min.vy &&
 
 
349
                sbPtr->DynPtr->Position.vy < ls_bhv->trigger_volume_max.vy &&
 
 
350
                sbPtr->DynPtr->Position.vz > ls_bhv->trigger_volume_min.vz &&
 
 
351
                sbPtr->DynPtr->Position.vz < ls_bhv->trigger_volume_max.vz)
 
 
352
            {
 
 
353
                ls_bhv->request=I_request_on;
 
 
354
                    break;
 
 
355
            }
 
 
356
        }
 
 
357
    }
 
 
358
 
 
 
359
    if (ls_bhv->request == I_request_on)
 
 
360
    {
 
 
361
        if (ls_bhv->triggered_last)
 
 
362
            ls_bhv->request = I_no_request;
 
 
363
        else
 
 
364
            ls_bhv->triggered_last = 1;
 
 
365
    }
 
 
366
    else
 
 
367
    {
 
 
368
        ls_bhv->triggered_last = 0;
 
 
369
    }
 
 
370
 
 
 
371
    if(ls_bhv->switch_always_on)
 
 
372
    {
 
 
373
        ls_bhv->request = I_no_request;
 
 
374
        ls_bhv->state = 1;
 
 
375
    }
 
 
376
 
 
 
377
    if(SinglePlayer != AvP.PlayMode)
 
 
378
    {
 
 
379
        /*
 
 
380
        Every time a switch is updated there is a time delay of 5 seconds before the
 
 
381
        switch can next be changed by the host sending synch messages.
 
 
382
        This prevents the host machine from resetting a switch before it learns that
 
 
383
        it has been pressed
 
 
384
        */
 
 
385
 
 
 
386
        if(ls_bhv->request == I_no_request)
 
 
387
        {
 
 
388
            ls_bhv->TimeUntilNetSynchAllowed-=RealFrameTime;
 
 
389
 
 
 
390
            if(ls_bhv->TimeUntilNetSynchAllowed < 0)
 
 
391
                ls_bhv->TimeUntilNetSynchAllowed = 0;
 
 
392
        }
 
 
393
        else
 
 
394
        {
 
 
395
            ls_bhv->TimeUntilNetSynchAllowed = 5 * ONE_FIXED;
 
 
396
        }
 
 
397
    }
 
 
398
 
 
 
399
        switch(ls_bhv->ls_mode)
 
 
400
        {
 
 
401
                case I_lswitch_timer:
 
 
402
                {
 
 
403
 
 
 
404
                    if(ls_bhv->request == I_request_on && !ls_bhv->state) 
 
 
405
                    {
 
 
406
                         ls_bhv->timer = ls_bhv->time_for_reset;
 
 
407
 
 
 
408
                        switch(ls_bhv->ls_dtype)
 
 
409
                        {
 
 
410
                            case binswitch_move_me:
 
 
411
                            case binswitch_animate_and_move_me:
 
 
412
                            {
 
 
413
                                // moving switch
 
 
414
                                ls_bhv->new_state = 1;
 
 
415
                                ls_bhv->new_request = -1;
 
 
416
                                ls_bhv->ls_track->reverse=0;
 
 
417
                                Start_Track_Playing(ls_bhv->ls_track);
 
 
418
                                ls_bhv->mode_store = ls_bhv->ls_mode;
 
 
419
                                ls_bhv->ls_mode = I_lswitch_moving;
 
 
420
                            }
 
 
421
                            break;
 
 
422
                            default:
 
 
423
                                ls_bhv->state = 1;
 
 
424
                        }
 
 
425
 
 
 
426
                        if(ls_bhv->ls_tac)
 
 
427
                        {
 
 
428
                            ls_bhv->ls_tac->tac_sequence = 1;
 
 
429
                            ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
 
 
430
                        }
 
 
431
                    }
 
 
432
                    else if(ls_bhv->timer > 0)
 
 
433
                    {
 
 
434
                         ls_bhv->timer -= NormalFrameTime;
 
 
435
 
 
 
436
                        if(ls_bhv->timer <= 0)
 
 
437
                        {
 
 
438
                            ls_bhv->state = 0;
 
 
439
 
 
 
440
                            switch(ls_bhv->ls_dtype)
 
 
441
                            {
 
 
442
                                case binswitch_move_me:
 
 
443
                                case binswitch_animate_and_move_me:
 
 
444
                                {
 
 
445
                                    // moving switch
 
 
446
                                    ls_bhv->new_state = 0;
 
 
447
                                    ls_bhv->new_request = -1;
 
 
448
                                    ls_bhv->ls_track->reverse=1;
 
 
449
                                    Start_Track_Playing(ls_bhv->ls_track);
 
 
450
                                    ls_bhv->mode_store = ls_bhv->ls_mode;
 
 
451
                                    ls_bhv->ls_mode = I_lswitch_moving;
 
 
452
                                }
 
 
453
                                default:
 
 
454
                                break;
 
 
455
                            }
 
 
456
 
 
 
457
                            if(ls_bhv->ls_tac)
 
 
458
                            {
 
 
459
                                ls_bhv->ls_tac->tac_sequence = 0;
 
 
460
                                ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
 
 
461
                            }
 
 
462
                        }
 
 
463
                    }
 
 
464
                }
 
 
465
                break;                
 
 
466
                case I_lswitch_toggle:
 
 
467
                {
 
 
468
                    // if it's off and no request then we can return
 
 
469
 
 
 
470
                    if (!ls_bhv->state && (ls_bhv->request == I_no_request))
 
 
471
                            return;
 
 
472
 
 
 
473
                    /* change the state and request the new state in the target */
 
 
474
 
 
 
475
                    if(ls_bhv->request != I_no_request)
 
 
476
                    {
 
 
477
                        switch(ls_bhv->ls_dtype)
 
 
478
                        {
 
 
479
                            case binswitch_move_me:
 
 
480
                            case binswitch_animate_and_move_me:
 
 
481
                            {
 
 
482
                                // moving switch
 
 
483
                                ls_bhv->new_state = !ls_bhv->state;
 
 
484
                                ls_bhv->new_request = -1;
 
 
485
                                ls_bhv->mode_store = ls_bhv->ls_mode;
 
 
486
                                ls_bhv->ls_mode = I_lswitch_moving;
 
 
487
                                ls_bhv->ls_track->reverse=ls_bhv->state;
 
 
488
                                Start_Track_Playing(ls_bhv->ls_track);
 
 
489
                            }
 
 
490
                            break;
 
 
491
                            default:
 
 
492
                                ls_bhv->state = !ls_bhv->state;
 
 
493
                        }
 
 
494
 
 
 
495
                        if(ls_bhv->ls_tac)
 
 
496
                        {
 
 
497
                            ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
 
 
498
                            ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
 
 
499
                        }
 
 
500
                    }
 
 
501
                }
 
 
502
                break;                
 
 
503
                case I_lswitch_wait:
 
 
504
                {
 
 
505
                    if (!ls_bhv->state)
 
 
506
                    {
 
 
507
                        switch(ls_bhv->request)
 
 
508
                        {
 
 
509
                            case I_no_request:
 
 
510
                                return; // if it's off and no request then we can return
 
 
511
                            case I_request_on:
 
 
512
                            {
 
 
513
                                switch(ls_bhv->ls_dtype)
 
 
514
                                {
 
 
515
                                    case binswitch_move_me:
 
 
516
                                    case binswitch_animate_and_move_me:
 
 
517
                                    {
 
 
518
 
 
 
519
                                        // moving switch
 
 
520
                                        ls_bhv->new_state = 1;
 
 
521
                                        ls_bhv->new_request = -1;
 
 
522
                                        ls_bhv->ls_track->reverse = 0;
 
 
523
                                        Start_Track_Playing(ls_bhv->ls_track);
 
 
524
                                        ls_bhv->mode_store = ls_bhv->ls_mode;
 
 
525
                                        ls_bhv->ls_mode = I_lswitch_moving;
 
 
526
                                    }
 
 
527
                                    break;
 
 
528
                                    default:
 
 
529
                                        ls_bhv->state = 1;
 
 
530
                                }
 
 
531
                            }
 
 
532
                            default:
 
 
533
                            break;
 
 
534
                        }
 
 
535
                    }
 
 
536
                    else
 
 
537
                    {
 
 
538
                        if (ls_bhv->request == I_request_off)
 
 
539
                        {
 
 
540
                            switch(ls_bhv->ls_dtype)
 
 
541
                            {
 
 
542
                                case binswitch_move_me:
 
 
543
                                case binswitch_animate_and_move_me:
 
 
544
                                {
 
 
545
                                    // moving switch
 
 
546
                                    ls_bhv->new_state = 0;
 
 
547
                                    ls_bhv->new_request = -1;
 
 
548
                                    ls_bhv->ls_track->reverse = 1;
 
 
549
                                    Start_Track_Playing(ls_bhv->ls_track);
 
 
550
                                    ls_bhv->mode_store = ls_bhv->ls_mode;
 
 
551
                                    ls_bhv->ls_mode = I_lswitch_moving;
 
 
552
                                }
 
 
553
                                break;
 
 
554
                                default:
 
 
555
                                    ls_bhv->state = 0;
 
 
556
                            }
 
 
557
                        }
 
 
558
                    }
 
 
559
 
 
 
560
                    if(ls_bhv->ls_tac)
 
 
561
                    {
 
 
562
                        ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
 
 
563
                        ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
 
 
564
                    }
 
 
565
                }
 
 
566
                break;
 
 
567
                case I_lswitch_moving:
 
 
568
                {
 
 
569
                    //printf("moving\n");
 
 
570
                    Update_Track_Position(ls_bhv->ls_track);
 
 
571
 
 
 
572
                    if (!ls_bhv->ls_track->playing)
 
 
573
                    {
 
 
574
                        ls_bhv->ls_mode = ls_bhv->mode_store;
 
 
575
                        ls_bhv->state = ls_bhv->new_state;
 
 
576
 
 
 
577
                        if(ls_bhv->ls_tac)
 
 
578
                        {
 
 
579
                            ls_bhv->ls_tac->tac_sequence = ls_bhv->state ? 1 : 0;
 
 
580
                            ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbptr->shapeIndex));
 
 
581
                        }
 
 
582
                    }
 
 
583
                }
 
 
584
                break;
 
 
585
            default:
 
 
586
                assert(2<1);
 
 
587
        }
 
 
588
 
 
 
589
    ls_bhv->request = I_no_request;
 
 
590
 
 
 
591
    //check to see if the system state has changed
 
 
592
 
 
 
593
    if (ls_bhv->system_state)
 
 
594
    {
 
 
595
        if (!check_link_switch_states(ls_bhv))
 
 
596
        {
 
 
597
            ls_bhv->system_state = 0;
 
 
598
 
 
 
599
            //link switch system state is turning off
 
 
600
            if(!ls_bhv->switch_off_message_none)
 
 
601
            {
 
 
602
                int i;
 
 
603
                for(i=0; i < ls_bhv->num_targets; i++)
 
 
604
                    RequestState(ls_bhv->ls_targets[i].sbptr,ls_bhv->ls_targets[i].request_message^(!ls_bhv->switch_off_message_same), sbptr);
 
 
605
            }
 
 
606
        }
 
 
607
    }
 
 
608
    else
 
 
609
    {
 
 
610
        if (check_link_switch_states(ls_bhv))
 
 
611
        {
 
 
612
            int i;
 
 
613
            ls_bhv->system_state = 1;
 
 
614
            //link switch system state is turning on
 
 
615
            for(i=0; i < ls_bhv->num_targets; i++)
 
 
616
                RequestState(ls_bhv->ls_targets[i].sbptr,ls_bhv->ls_targets[i].request_message, sbptr);
 
 
617
        }
 
 
618
    }
 
 
619
}
 
 
620
 
 
 
621
#define LINKSWITCHSYNCH_ON     0
 
 
622
#define LINKSWITCHSYNCH_OFF     1
 
 
623
#define LINKSWITCHSYNCH_IGNORE 2
 
 
624
 
 
 
625
int LinkSwitchGetSynchData(STRATEGYBLOCK* sbPtr)
 
 
626
{
 
 
627
     assert(sbPtr);
 
 
628
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
629
    assert((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
630
 
 
 
631
    //don't try to synch moving switches
 
 
632
    if(ls_bhv->ls_mode == I_lswitch_moving)
 
 
633
        return LINKSWITCHSYNCH_IGNORE;
 
 
634
 
 
 
635
return ((ls_bhv->state) ? LINKSWITCHSYNCH_ON : LINKSWITCHSYNCH_OFF);
 
 
636
}
 
 
637
 
 
 
638
void LinkSwitchSetSynchData(STRATEGYBLOCK* sbPtr,int status)
 
 
639
{
 
 
640
     assert(sbPtr);
 
 
641
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
642
    assert((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
 
 
643
 
 
 
644
    if(ls_bhv->TimeUntilNetSynchAllowed > 0)
 
 
645
    {
 
 
646
        //ignore this attempt to synch the switch
 
 
647
        return;
 
 
648
    }
 
 
649
 
 
 
650
    //don't try to synch moving switches
 
 
651
    if(ls_bhv->ls_mode == I_lswitch_moving)
 
 
652
        return;
 
 
653
 
 
 
654
    switch(status)
 
 
655
    {
 
 
656
        case LINKSWITCHSYNCH_ON :
 
 
657
            if(!ls_bhv->state)
 
 
658
                RequestState(sbPtr,1,0); //this switch should be on
 
 
659
        break;
 
 
660
        case LINKSWITCHSYNCH_OFF :
 
 
661
            if(ls_bhv->state)
 
 
662
                RequestState(sbPtr,0,0); //this switch should be off
 
 
663
    }
 
 
664
}
 
 
665
 
 
 
666
/*--------------------**
 
 
667
** Loading and Saving **
 
 
668
**--------------------*/
 
 
669
#include "savegame.h"
 
 
670
typedef struct link_switch_save_block
 
 
671
{
 
 
672
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
673
 
 
 
674
    BINARY_SWITCH_REQUEST_STATE request;
 
 
675
    int system_state;
 
 
676
    int state;
 
 
677
 
 
 
678
    LSWITCH_MODE ls_mode;
 
 
679
    int timer;
 
 
680
    int new_state;
 
 
681
    int new_request;
 
 
682
    LSWITCH_MODE mode_store;
 
 
683
    int triggered_last;
 
 
684
    int txanim_sequence;
 
 
685
 
 
 
686
} LINK_SWITCH_SAVE_BLOCK;
 
 
687
 
 
 
688
//defines for load/save macros
 
 
689
#define SAVELOAD_BLOCK block
 
 
690
#define SAVELOAD_BEHAV ls_bhv
 
 
691
 
 
 
692
void LoadStrategy_LinkSwitch(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
693
{
 
 
694
    LINK_SWITCH_SAVE_BLOCK* block = (LINK_SWITCH_SAVE_BLOCK*) header; 
 
 
695
 
 
 
696
    //check the size of the save block
 
 
697
    if(header->size != sizeof(*block))
 
 
698
        return;
 
 
699
 
 
 
700
    //find the existing strategy block
 
 
701
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
702
 
 
 
703
    if(!sbPtr)
 
 
704
        return;
 
 
705
 
 
 
706
    //make sure the strategy found is of the right type
 
 
707
    if(sbPtr->type != I_BehaviourLinkSwitch)
 
 
708
        return;
 
 
709
 
 
 
710
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
711
 
 
 
712
    //start copying stuff
 
 
713
 
 
 
714
    COPYELEMENT_LOAD(request)
 
 
715
    COPYELEMENT_LOAD(system_state)
 
 
716
    COPYELEMENT_LOAD(state)
 
 
717
    COPYELEMENT_LOAD(ls_mode)
 
 
718
    COPYELEMENT_LOAD(timer)
 
 
719
    COPYELEMENT_LOAD(new_state)
 
 
720
    COPYELEMENT_LOAD(new_request)
 
 
721
    COPYELEMENT_LOAD(mode_store)
 
 
722
    COPYELEMENT_LOAD(triggered_last)
 
 
723
 
 
 
724
    //set the texture animation sequence
 
 
725
    if(ls_bhv->ls_tac)
 
 
726
    {
 
 
727
        ls_bhv->ls_tac->tac_sequence = block->txanim_sequence;
 
 
728
        ls_bhv->ls_tac->tac_txah_s = GetTxAnimHeaderFromShape(ls_bhv->ls_tac, (sbPtr->shapeIndex));
 
 
729
    }
 
 
730
 
 
 
731
    //load the track position , if the switch has one
 
 
732
    if(ls_bhv->ls_track)
 
 
733
    {
 
 
734
        SAVE_BLOCK_HEADER* track_header = GetNextBlockIfOfType(SaveBlock_Track);
 
 
735
 
 
 
736
        if(track_header)
 
 
737
            LoadTrackPosition(track_header,ls_bhv->ls_track);
 
 
738
    }
 
 
739
}
 
 
740
 
 
 
741
void SaveStrategy_LinkSwitch(STRATEGYBLOCK* sbPtr)
 
 
742
{
 
 
743
    LINK_SWITCH_SAVE_BLOCK *block;
 
 
744
    LINK_SWITCH_BEHAV_BLOCK *ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
745
 
 
 
746
    GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
 
 
747
 
 
 
748
    //start copying stuff
 
 
749
    COPYELEMENT_SAVE(request)
 
 
750
    COPYELEMENT_SAVE(system_state)
 
 
751
    COPYELEMENT_SAVE(state)
 
 
752
    COPYELEMENT_SAVE(ls_mode)
 
 
753
    COPYELEMENT_SAVE(timer)
 
 
754
    COPYELEMENT_SAVE(new_state)
 
 
755
    COPYELEMENT_SAVE(new_request)
 
 
756
    COPYELEMENT_SAVE(mode_store)
 
 
757
    COPYELEMENT_SAVE(triggered_last)
 
 
758
 
 
 
759
    //get the animation sequence
 
 
760
    if(ls_bhv->ls_tac)
 
 
761
        block->txanim_sequence = ls_bhv->ls_tac->tac_sequence;
 
 
762
    else
 
 
763
        block->txanim_sequence = 0;
 
 
764
 
 
 
765
    //save the track position , if the switch has one
 
 
766
 
 
 
767
    if(ls_bhv->ls_track)
 
 
768
        SaveTrackPosition(ls_bhv->ls_track);
 
 
769
}