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