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