1 #define DB_LEVEL 3
2 
3 #include "3dc.h"
4 #include "inline.h"
5 #include "module.h"
6 
7 #include "stratdef.h"
8 #include "gamedef.h"
9 #include "bh_types.h"
10 #include "bonusabilities.h"
11 
12 #include "weapons.h"
13 #include "comp_shp.h"
14 #include "inventry.h"
15 #include "triggers.h"
16 
17 #include "dynblock.h"
18 #include "dynamics.h"
19 
20 #define UseLocalAssert Yes
21 
22 #include "ourasert.h"
23 
24 #include "pmove.h"
25 #include "bh_alien.h"
26 #include "bh_gener.h"
27 #include "pvisible.h"
28 #include "bh_pred.h"
29 #include "bh_xeno.h"
30 #include "bh_paq.h"
31 #include "bh_queen.h"
32 #include "bh_marin.h"
33 #include "bh_fhug.h"
34 #include "bh_swdor.h"
35 #include "bh_ldoor.h"
36 #include "bh_plift.h"
37 #include "load_shp.h"
38 #include "bh_weap.h"
39 #include "bh_debri.h"
40 #include "lighting.h"
41 #include "bh_lnksw.h"
42 #include "bh_binsw.h"
43 #include "bh_spcl.h"
44 #include "bh_agun.h"
45 #include "bh_lift.h"
46 #include "bh_ltfx.h"
47 #include "bh_snds.h"
48 #include "bh_mission.h"
49 #include "bh_track.h"
50 #include "bh_fan.h"
51 #include "bh_rubberduck.h"
52 #include "bh_plachier.h"
53 #include "bh_light.h"
54 #include "bh_cable.h"
55 #include "bh_deathvol.h"
56 #include "bh_selfdest.h"
57 #include "bh_dummy.h"
58 #include "bh_pargen.h"
59 #include "bh_videoscreen.h"
60 
61 #include "psnd.h"
62 #include "plat_shp.h"
63 #include "savegame.h"
64 
65 #include "db.h"
66 
67 /* for win95 net game support */
68 #include "pldghost.h"
69 
70 #include "bh_corpse.h"
71 
72 /*
73 	our functions for doing stuff to objects
74   	can be called in two different ways, call the function
75   	that processes the list (ObjectBehaviours) or call
76   	ExecuteBehaviour with the strategyblock
77 */
78 
79 
80 /**** extern globals ****/
81 
82 extern int NormalFrameTime;
83 
84 // Standard Behaviours - note others are in relevent files
85 
86 static void* DoorProxBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr);
87 static void DoorProxBehaveFun(STRATEGYBLOCK* sbptr);
88 static void* SimpleAnimationBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr);
89 static void SimpleAnimBehaveFun(STRATEGYBLOCK* sbptr);
90 static void* InitDatabase(void* bhdata, STRATEGYBLOCK* sbptr);
91 
92 // support functions - others are extened in bh_types.h
93 
94 static int AnythingNearProxDoor(MODULE *doorModulePtr,PROXDOOR_BEHAV_BLOCK *doorbhv);
95 //static void CountToDeallocateTemporaryObject(STRATEGYBLOCK *);
96 
97 /***** extern functions *****/
98 
99 extern void SmokeGeneratorBehaviour(STRATEGYBLOCK *sptr);
100 extern void InitPlayer(STRATEGYBLOCK* sbPtr, int sb_type);
101 extern void AlienFragFun(STRATEGYBLOCK* sptr);
102 extern void SetupSimpleAnimation(int counter, STRATEGYBLOCK *sbPtr);
103 extern void HierarchicalFragmentBehaviour(STRATEGYBLOCK *sptr);
104 
105 extern void Xeno_Enter_PowerUp_State(STRATEGYBLOCK *sbPtr);
106 extern void Xeno_Enter_PowerDown_State(STRATEGYBLOCK *sbPtr);
107 
108 /************************ FUNCTIONS TO FILL OUT SBS ***************/
109 /* essentially these are the old entity type functions ******/
110 
111 /* IMPORTANT IMPORTANT!!!
112 
113 	If you write an allocater for a behaviour that AllocatesMem BESIDES
114 	that for the BehaviourBlock e.g. the simpleanimations generates a
115 	linked list of texture animation control blocks, one for every item
116 	with an animation, THEN YOU MUST ALWAYS WRITE A SPECIFIC DEALLOCATER
117 */
118 
119 
120 static NPC_DATA NpcDataList[I_NPC_End]= {
121 	{
122 		I_NPC_Civilian,
123 		{
124 			20,	/* Health */
125 			0,	/* Armour */
126 			0, /* IsOnFire */
127 			{
128 				0,	/* Acid Resistant */
129 				0,	/* Fire Resistant */
130 				0,	/* Electric Resistant */
131 				0,	/* Perfect Armour */
132 				0,	/* Electric Sensitive */
133 				1,	/* Combustability */
134 				0,	/* Indestructable */
135 			},
136 		},
137 	},
138 	{
139 		I_NPC_FaceHugger,
140 		{
141 			5,	/* Health */
142 			0,	/* Armour */
143 			0, /* IsOnFire */
144 			{
145 				1,	/* Acid Resistant */
146 				0,	/* Fire Resistant */
147 				0,	/* Electric Resistant */
148 				0,	/* Perfect Armour */
149 				1,	/* Electric Sensitive */
150 				3,	/* Combustability */
151 				0,	/* Indestructable */
152 			},
153 		},
154 	},
155 	{
156 		I_NPC_ChestBurster,
157 		{
158 			15,	/* Health */
159 			0,	/* Armour */
160 			0, /* IsOnFire */
161 			{
162 				1,	/* Acid Resistant */
163 				0,	/* Fire Resistant */
164 				0,	/* Electric Resistant */
165 				0,	/* Perfect Armour */
166 				1,	/* Electric Sensitive */
167 				1,	/* Combustability */
168 				0,	/* Indestructable */
169 			},
170 		},
171 	},
172 	{
173 		I_NPC_Alien,
174 		{
175 			30,	/* Health */
176 			5,	/* Armour */
177 			0, /* IsOnFire */
178 			{
179 				1,	/* Acid Resistant */
180 				0,	/* Fire Resistant */
181 				0,	/* Electric Resistant */
182 				1,	/* Perfect Armour */
183 				1,	/* Electric Sensitive */
184 				1,	/* Combustability */
185 				0,	/* Indestructable */
186 			},
187 		},
188 	},
189 	{
190 		I_NPC_Xenoborg,
191 		{
192 			750,/* Health */
193 			120,/* Armour */
194 			0, /* IsOnFire */
195 			{
196 				1,	/* Acid Resistant */
197 				0,	/* Fire Resistant */
198 				0,	/* Electric Resistant */
199 				0,	/* Perfect Armour */
200 				0,	/* Electric Sensitive */
201 				0,	/* Combustability */
202 				0,	/* Indestructable */
203 			},
204 		},
205 	},
206 	{
207 		I_NPC_Marine,
208 		{
209 			25,	/* Health */
210 			8,	/* Armour */
211 			0, /* IsOnFire */
212 			{
213 				0,	/* Acid Resistant */
214 				0,	/* Fire Resistant */
215 				0,	/* Electric Resistant */
216 				0,	/* Perfect Armour */
217 				0,	/* Electric Sensitive */
218 				1,	/* Combustability */
219 				0,	/* Indestructable */
220 			},
221 		},
222 	},
223 	{
224 		I_NPC_PredatorAlien,
225 		{
226 			200,	/* Health */
227 			40,	/* Armour */
228 			0, /* IsOnFire */
229 			{
230 				1,	/* Acid Resistant */
231 				0,	/* Fire Resistant */
232 				0,	/* Electric Resistant */
233 				1,	/* Perfect Armour */
234 				1,	/* Electric Sensitive */
235 				1,	/* Combustability */
236 				0,	/* Indestructable */
237 			},
238 		},
239 	},
240 	{
241 		I_NPC_SFMarine,
242 		{
243 			40,	/* Health */
244 			10,	/* Armour */
245 			0, /* IsOnFire */
246 			{
247 				0,	/* Acid Resistant */
248 				0,	/* Fire Resistant */
249 				0,	/* Electric Resistant */
250 				0,	/* Perfect Armour */
251 				0,	/* Electric Sensitive */
252 				1,	/* Combustability */
253 				0,	/* Indestructable */
254 			},
255 		},
256 	},
257 	{
258 		I_NPC_Predator,
259 		{
260 			450,	/* Health */
261 			200,	/* Armour */
262 			0, /* IsOnFire */
263 			{
264 				0,	/* Acid Resistant */
265 				0,	/* Fire Resistant */
266 				0,	/* Electric Resistant */
267 				0,	/* Perfect Armour */
268 				0,	/* Electric Sensitive */
269 				1,	/* Combustability */
270 				0,	/* Indestructable */
271 			},
272 		},
273 	},
274 	{
275 		I_NPC_PraetorianGuard,
276 		{
277 			150,	/* Health */
278 			60,	/* Armour */
279 			0, /* IsOnFire */
280 			{
281 				1,	/* Acid Resistant */
282 				0,	/* Fire Resistant */
283 				0,	/* Electric Resistant */
284 				1,	/* Perfect Armour */
285 				1,	/* Electric Sensitive */
286 				1,	/* Combustability */
287 				0,	/* Indestructable */
288 			},
289 		},
290 	},
291 	{
292 		I_NPC_AlienQueen,
293 		{
294 			4000,	/* Health */
295 			1000,	/* Armour */
296 			0, /* IsOnFire */
297 			{
298 				1,	/* Acid Resistant */
299 				0,	/* Fire Resistant */
300 				0,	/* Electric Resistant */
301 				1,	/* Perfect Armour */
302 				0,	/* Electric Sensitive */
303 				1,	/* Combustability */
304 				0,	/* Indestructable */
305 			},
306 		},
307 	},
308 	{
309 		I_NPC_DefaultInanimate,
310 		{
311 			10,	/* Health */
312 			2,	/* Armour */
313 			0, /* IsOnFire */
314 			{
315 				1,	/* Acid Resistant */
316 				1,	/* Fire Resistant */
317 				0,	/* Electric Resistant */
318 				1,	/* Perfect Armour */
319 				0,	/* Electric Sensitive */
320 				1,	/* Combustability */
321 				0,	/* Indestructable */
322 			},
323 		},
324 	},
325 	{
326 		I_PC_Alien_Easy,
327 		{
328 			90,	/* Health */
329 			30,	/* Armour (was 6) */
330 			0, /* IsOnFire */
331 			{
332 				1,	/* Acid Resistant */
333 				0,	/* Fire Resistant */
334 				0,	/* Electric Resistant */
335 				0,	/* Perfect Armour */  /* Disabled, CDF 28/7/98 */
336 				1,	/* Electric Sensitive */
337 				1,	/* Combustability */
338 				0,	/* Indestructable */
339 			},
340 		},
341 	},
342 	{
343 		I_PC_Marine_Easy,
344 		{
345 			100,	/* Health */
346 			20,	/* Armour */
347 			0, /* IsOnFire */
348 			{
349 				1,	/* Acid Resistant */
350 				0,	/* Fire Resistant */
351 				0,	/* Electric Resistant */
352 				0,	/* Perfect Armour */
353 				0,	/* Electric Sensitive */
354 				1,	/* Combustability */
355 				0,	/* Indestructable */
356 			},
357 		},
358 	},
359 	{
360 		I_PC_Predator_Easy,
361 		{
362 			450,	/* Health */
363 			0,	/* Armour */
364 			0, /* IsOnFire */
365 			{
366 				1,	/* Acid Resistant */
367 				0,	/* Fire Resistant */
368 				0,	/* Electric Resistant */
369 				0,	/* Perfect Armour */
370 				0,	/* Electric Sensitive */
371 				1,	/* Combustability */
372 				0,	/* Indestructable */
373 			},
374 		},
375 	},
376 	{
377 		I_PC_Alien_Medium,
378 		{
379 			90,	/* Health */
380 			30,	/* Armour (was 6) */
381 			0, /* IsOnFire */
382 			{
383 				1,	/* Acid Resistant */
384 				0,	/* Fire Resistant */
385 				0,	/* Electric Resistant */
386 				0,	/* Perfect Armour */  /* Disabled, CDF 28/7/98 */
387 				1,	/* Electric Sensitive */
388 				1,	/* Combustability */
389 				0,	/* Indestructable */
390 			},
391 		},
392 	},
393 	{
394 		I_PC_Marine_Medium,
395 		{
396 			100,	/* Health */
397 			20,	/* Armour */
398 			0, /* IsOnFire */
399 			{
400 				0,	/* Acid Resistant */
401 				0,	/* Fire Resistant */
402 				0,	/* Electric Resistant */
403 				0,	/* Perfect Armour */
404 				0,	/* Electric Sensitive */
405 				1,	/* Combustability */
406 				0,	/* Indestructable */
407 			},
408 		},
409 	},
410 	{
411 		I_PC_Predator_Medium,
412 		{
413 			450,	/* Health */
414 			0,	/* Armour */
415 			0, /* IsOnFire */
416 			{
417 				0,	/* Acid Resistant */
418 				0,	/* Fire Resistant */
419 				0,	/* Electric Resistant */
420 				0,	/* Perfect Armour */
421 				0,	/* Electric Sensitive */
422 				1,	/* Combustability */
423 				0,	/* Indestructable */
424 			},
425 		},
426 	},
427 	{
428 		I_PC_Alien_Hard,
429 		{
430 			90,	/* Health */
431 			30,	/* Armour (was 6) */
432 			0, /* IsOnFire */
433 			{
434 				1,	/* Acid Resistant */
435 				0,	/* Fire Resistant */
436 				0,	/* Electric Resistant */
437 				0,	/* Perfect Armour */  /* Disabled, CDF 28/7/98 */
438 				1,	/* Electric Sensitive */
439 				1,	/* Combustability */
440 				0,	/* Indestructable */
441 			},
442 		},
443 	},
444 	{
445 		I_PC_Marine_Hard,
446 		{
447 			100,	/* Health */
448 			20,	/* Armour */
449 			0, /* IsOnFire */
450 			{
451 				0,	/* Acid Resistant */
452 				0,	/* Fire Resistant */
453 				0,	/* Electric Resistant */
454 				0,	/* Perfect Armour */
455 				0,	/* Electric Sensitive */
456 				1,	/* Combustability */
457 				0,	/* Indestructable */
458 			},
459 		},
460 	},
461 	{
462 		I_PC_Predator_Hard,
463 		{
464 			450,	/* Health */
465 			0,	/* Armour */
466 			0, /* IsOnFire */
467 			{
468 				0,	/* Acid Resistant */
469 				0,	/* Fire Resistant */
470 				0,	/* Electric Resistant */
471 				0,	/* Perfect Armour */
472 				0,	/* Electric Sensitive */
473 				1,	/* Combustability */
474 				0,	/* Indestructable */
475 			},
476 		},
477 	},
478 	{
479 		I_PC_Alien_Impossible,
480 		{
481 			30,	/* Health */
482 			5,	/* Armour */
483 			0, /* IsOnFire */
484 			{
485 				1,	/* Acid Resistant */
486 				0,	/* Fire Resistant */
487 				0,	/* Electric Resistant */
488 				1,	/* Perfect Armour */
489 				1,	/* Electric Sensitive */
490 				1,	/* Combustability */
491 				0,	/* Indestructable */
492 			},
493 		},
494 	},
495 	{
496 		I_PC_Marine_Impossible,
497 		{
498 			25,	/* Health */
499 			8,	/* Armour */
500 			0, /* IsOnFire */
501 			{
502 				0,	/* Acid Resistant */
503 				0,	/* Fire Resistant */
504 				0,	/* Electric Resistant */
505 				0,	/* Perfect Armour */
506 				0,	/* Electric Sensitive */
507 				1,	/* Combustability */
508 				0,	/* Indestructable */
509 			},
510 		},
511 	},
512 	{
513 		I_PC_Predator_Impossible,
514 		{
515 			450,	/* Health */
516 			200,	/* Armour */
517 			0, /* IsOnFire */
518 			{
519 				0,	/* Acid Resistant */
520 				0,	/* Fire Resistant */
521 				0,	/* Electric Resistant */
522 				0,	/* Perfect Armour */
523 				0,	/* Electric Sensitive */
524 				1,	/* Combustability */
525 				0,	/* Indestructable */
526 			},
527 		},
528 	},
529 	{
530 		I_PC_Alien_MaxStats,
531 		{
532 			180,	/* Health */
533 			30,	/* Armour (was 6) */
534 			0, /* IsOnFire */
535 			{
536 				1,	/* Acid Resistant */
537 				0,	/* Fire Resistant */
538 				0,	/* Electric Resistant */
539 				0,	/* Perfect Armour */  /* Disabled, CDF 28/7/98 */
540 				0,	/* Electric Sensitive */
541 				1,	/* Combustability */
542 				0,	/* Indestructable */
543 			},
544 		},
545 	},
546 	{
547 		I_NPC_SentryGun,
548 		{
549 			50,	/* Health */
550 			50,	/* Armour */
551 			0, /* IsOnFire */
552 			{
553 				0,	/* Acid Resistant */
554 				0,	/* Fire Resistant */
555 				0,	/* Electric Resistant */
556 				0,	/* Perfect Armour */
557 				0,	/* Electric Sensitive */
558 				1,	/* Combustability */
559 				0,	/* Indestructable */
560 			},
561 		},
562 	},
563 	{
564 		I_NPC_Android,
565 		{
566 			40,	/* Health */
567 			8,	/* Armour */
568 			0, /* IsOnFire */
569 			{
570 				0,	/* Acid Resistant */
571 				0,	/* Fire Resistant */
572 				0,	/* Electric Resistant */
573 				0,	/* Perfect Armour */
574 				0,	/* Electric Sensitive */
575 				1,	/* Combustability */
576 				0,	/* Indestructable */
577 			},
578 		},
579 	},
580 };
581 
582 /* Interface Function! */
583 
GetThisNpcData(NPC_TYPES NpcType)584 NPC_DATA *GetThisNpcData(NPC_TYPES NpcType) {
585 int a;
586 
587 for (a=0; a<I_NPC_End; a++) {
588 	if (NpcDataList[a].Type==NpcType) break;
589 }
590 
591 if (a==I_NPC_End) return(NULL);
592 else return(&NpcDataList[a]);
593 
594 }
595 
596 /*----------------------------------------------------------------------
597   Use this function to initialise compiled in objects - redundant in final
598   ----------------------------------------------------------------------*/
599 
600 
AssignRunTimeBehaviours(STRATEGYBLOCK * sbptr)601 void AssignRunTimeBehaviours(STRATEGYBLOCK* sbptr)
602 {
603 	/*
604 	function for assigning behaviours to objects at
605 	runtime. This includes any objects that are going
606 	to be created (grenades) AND compiled in ints such
607     as the player
608 	*/
609 
610 
611 	DISPLAYBLOCK *dptr;
612 
613 	GLOBALASSERT(sbptr);
614 	dptr = sbptr->SBdptr;
615 	GLOBALASSERT(dptr);
616 
617 	dptr->ObShape = I_ShapeCube;
618 
619 	InitPlayer(sbptr, I_BehaviourMarinePlayer);
620 }
621 
622 /*----------------------------------------------------------------------
623   Use this function to initialise binary loaded objects
624   ----------------------------------------------------------------------*/
625 
EnableBehaviourType(STRATEGYBLOCK * sbptr,AVP_BEHAVIOUR_TYPE sb_type,void * bhdata)626 void EnableBehaviourType(STRATEGYBLOCK* sbptr, AVP_BEHAVIOUR_TYPE sb_type, void *bhdata)
627 {
628 
629 	GLOBALASSERT(sbptr);
630 
631 	sbptr->I_SBtype = sb_type;
632 
633 	switch(sb_type)
634 	{
635 		case I_BehaviourAlien:
636       		InitAlienBehaviour(bhdata, sbptr);
637       		break;
638 
639 		case I_BehaviourFaceHugger:
640 			InitFacehuggerBehaviour(bhdata, sbptr);
641 			break;
642 
643 		case I_BehaviourPredator:
644 			InitPredatorBehaviour(bhdata, sbptr);
645 			break;
646 
647 		case I_BehaviourDormantPredator:
648 			InitDormantPredatorBehaviour(bhdata, sbptr);
649 			break;
650 
651 		case I_BehaviourXenoborg:
652 			InitXenoborgBehaviour(bhdata, sbptr);
653 			break;
654 
655 		case I_BehaviourQueenAlien:
656 			InitQueenBehaviour(bhdata, sbptr);
657 			break;
658 
659 		case I_BehaviourPredatorAlien:
660 			GLOBALASSERT(0);
661 			//InitPredAlBehaviour(bhdata, sbptr);
662 			break;
663 
664 		case I_BehaviourMarine:
665 			InitMarineBehaviour(bhdata, sbptr);
666 			break;
667 
668 		case I_BehaviourSeal:
669 			InitSealBehaviour(bhdata, sbptr);
670 			break;
671 
672 		case I_BehaviourProximityDoor:
673 			sbptr->SBdataptr = DoorProxBehaveInit(bhdata, sbptr);
674 			sbptr->SBmoptr->m_flags &= ~m_flag_open;
675 			break;
676 
677 		case I_BehaviourLiftDoor:
678 			sbptr->SBdataptr = LiftDoorBehaveInit(bhdata, sbptr);
679 			break;
680 
681 		case I_BehaviourSwitchDoor:
682 			InitialiseSwitchDoor(bhdata, sbptr);
683 			break;
684 
685 		case I_BehaviourPlatform:
686 			InitialisePlatformLift(bhdata, sbptr);
687 			break;
688 
689 		case I_BehaviourBinarySwitch:
690 			if(sbptr->shapeIndex!=-1)/*Allow for switches that have no shape*/
691 			{
692 				sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
693 			}
694 			sbptr->SBdataptr = BinarySwitchBehaveInit(bhdata, sbptr);
695 			break;
696 
697 		case I_BehaviourLinkSwitch:
698 			if(sbptr->shapeIndex!=-1)/*Allow for switches that have no shape*/
699 			{
700 				sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
701 			}
702 			sbptr->SBdataptr = LinkSwitchBehaveInit(bhdata, sbptr);
703 			break;
704 
705 		case I_BehaviourLift:
706 			sbptr->SBdataptr = LiftBehaveInit(bhdata, sbptr);
707 			break;
708 
709 		case I_BehaviourSimpleAnimation:
710 			sbptr->SBdataptr = SimpleAnimationBehaveInit(bhdata, sbptr);
711 			break;
712 
713 		case I_BehaviourGenerator:
714 			InitGenerator(bhdata, sbptr);
715 			break;
716 
717 		case I_BehaviourAutoGun:
718 			AutoGunBehaveInit(bhdata, sbptr);
719 			break;
720 
721 		case I_BehaviourInanimateObject:
722 			InitInanimateObject(bhdata, sbptr);
723 			break;
724 
725 		case I_BehaviourDatabase:
726 			sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
727 			sbptr->SBdataptr  = InitDatabase(bhdata, sbptr);
728 			break;
729 
730 		case I_BehaviourXenoborgMorphRoom:
731 			sbptr->SBdataptr = InitXenoMorphRoom (bhdata, sbptr);
732 			break;
733 
734 		case I_BehaviourLightFX:
735 		{
736 			sbptr->SBdataptr = LightFXBehaveInit (bhdata, sbptr);
737 			break;
738 		}
739 
740 		case I_BehaviourPlacedSound:
741 		{
742 			sbptr->SBdataptr = SoundBehaveInit (bhdata, sbptr);
743 			break;
744 		}
745 
746 		case I_BehaviourMissionComplete:
747 		{
748 			sbptr->SBdataptr = MissionCompleteBehaveInit (bhdata, sbptr);
749 			break;
750 		}
751 		case I_BehaviourMessage:
752 		{
753 			sbptr->SBdataptr = MessageBehaveInit (bhdata, sbptr);
754 			break;
755 		}
756 		case I_BehaviourTrackObject:
757 		{
758 			sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
759 			sbptr->SBdataptr = TrackObjectBehaveInit(bhdata, sbptr);
760 			break;
761 		}
762 		case I_BehaviourFan:
763 		{
764 			sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
765 			sbptr->SBdataptr = FanBehaveInit(bhdata, sbptr);
766 			break;
767 		}
768 		case I_BehaviourPlacedHierarchy:
769 		{
770 			sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
771 			sbptr->SBdataptr = PlacedHierarchyBehaveInit(bhdata, sbptr);
772 			break;
773 		}
774 
775 		case I_BehaviourPlacedLight:
776 			InitPlacedLight(bhdata, sbptr);
777 			break;
778 
779 		case I_BehaviourVideoScreen:
780 			InitVideoScreen(bhdata, sbptr);
781 			break;
782 
783 		case I_BehaviourPowerCable :
784 			sbptr->SBdataptr = PowerCableBehaveInit(bhdata, sbptr);
785 			break;
786 
787 		case I_BehaviourDeathVolume :
788 			sbptr->SBdataptr = DeathVolumeBehaveInit(bhdata, sbptr);
789 			break;
790 
791 		case I_BehaviourSelfDestruct :
792 			sbptr->SBdataptr = SelfDestructBehaveInit(bhdata, sbptr);
793 			break;
794 
795 		case I_BehaviourParticleGenerator :
796 			sbptr->SBdataptr = ParticleGeneratorBehaveInit(bhdata, sbptr);
797 			break;
798 		default:
799 			break;
800 	}
801 }
802 
803 
804 
805 
806 
807 /****************** DOOR INIT ***************************/
808 
809 
810 /* (these shift values are passed to the open/close prox door fn's,
811 and control the morphing speed) */
812 
813 
DoorProxBehaveInit(void * bhdata,STRATEGYBLOCK * sbptr)814 static void* DoorProxBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
815 {
816 	PROXDOOR_BEHAV_BLOCK *doorbhv;
817 	PROX_DOOR_TOOLS_TEMPLATE *doortt;
818 	MORPHCTRL* morphctrl;
819 	MORPHHEADER* morphheader;
820 	MORPHFRAME* morphframe;
821 	MODULE * my_mod;
822 
823  	GLOBALASSERT(sbptr);
824 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)AllocateMem(sizeof(PROXDOOR_BEHAV_BLOCK));
825 
826 	if(!doorbhv)
827 	{
828 		memoryInitialisationFailure = 1;
829 		return ((void *)NULL);
830 	}
831 
832 	doorbhv->bhvr_type = I_BehaviourProximityDoor;
833 
834 	// Who is doing the deallocation for this - the unloaders
835 	// should CHECK THIS.
836 
837 	doortt = (PROX_DOOR_TOOLS_TEMPLATE*)bhdata;
838 
839 
840 	// Set up a new Morph Control
841 	morphctrl = (MORPHCTRL*)AllocateMem(sizeof(MORPHCTRL));
842 	if(!morphctrl)
843 	{
844 		memoryInitialisationFailure = 1;
845 		return ((void *)NULL);
846 	}
847 	morphheader = (MORPHHEADER*)AllocateMem(sizeof(MORPHHEADER));
848 	if(!morphheader)
849 	{
850 		memoryInitialisationFailure = 1;
851 		return ((void *)NULL);
852 	}
853 	morphframe = (MORPHFRAME*)AllocateMem(sizeof(MORPHFRAME));
854 	if(!morphframe)
855 	{
856 		memoryInitialisationFailure = 1;
857 		return ((void *)NULL);
858 	}
859 
860 	morphframe->mf_shape1 = doortt->shape_open;
861 	morphframe->mf_shape2 = doortt->shape_closed;
862 
863 	morphheader->mph_numframes = 1;
864 	morphheader->mph_maxframes = ONE_FIXED;
865 	morphheader->mph_frames = morphframe;
866 
867 	morphctrl->ObMorphCurrFrame = 0;
868 	morphctrl->ObMorphFlags = 0;
869 	morphctrl->ObMorphSpeed = 0;
870 	morphctrl->ObMorphHeader = morphheader;
871 
872 
873 	// Copy the name over
874 	COPY_NAME (sbptr->SBname, doortt->nameID);
875 
876 
877 	// Setup module ref
878 	{
879 		MREF mref=doortt->my_module;
880 		ConvertModuleNameToPointer (&mref, MainSceneArray[0]->sm_marray);
881 		my_mod = mref.mref_ptr;
882 	}
883 	GLOBALASSERT (my_mod);
884 
885 	my_mod->m_sbptr = sbptr;
886 	sbptr->SBmoptr = my_mod;
887 	sbptr->SBmomptr = my_mod->m_mapptr;
888 	sbptr->SBflags.no_displayblock = 1;
889 
890 
891 	doorbhv->PDmctrl = morphctrl;
892 	doorbhv->lockable_door = doortt->has_lock_target;
893 
894 	doorbhv->door_opening_speed=doortt->door_opening_speed;
895 	doorbhv->door_closing_speed=doortt->door_closing_speed;
896 
897 	if(doortt->has_lock_target)
898 		{
899 			COPY_NAME(doorbhv->target_name, doortt->target_name);
900 		}
901 
902 	sbptr->SBmorphctrl = doorbhv->PDmctrl;
903 	sbptr->SBmorphctrl->ObMorphCurrFrame = 1; /* this should be closed*/
904 
905 	doorbhv->door_state = 	I_door_closed;
906 	CloseDoor(sbptr->SBmorphctrl, DOOR_CLOSEFASTSPEED);
907 
908 	if(sbptr->SBmoptr)
909 		{
910 			sbptr->SBmoptr->m_flags |= m_flag_open;
911 		}
912 	if(sbptr->SBmomptr)
913 		{
914 			sbptr->SBmomptr->MapMorphHeader = sbptr->SBmorphctrl->ObMorphHeader;
915 		}
916 
917 	/*-----------Patrick 9/12/96--------------
918 	 a little addition...
919 	 -----------------------------------------*/
920 	doorbhv->alienTrigger = 0;
921 	doorbhv->marineTrigger = 0;
922 	doorbhv->triggeredByMarine = 0;
923 	doorbhv->alienTimer = 0;
924 	doorbhv->door_locked = doortt->door_is_locked;
925 
926   /* Andy 10/6/97 --------------------------
927    sound stuff...
928   ----------------------------------------*/
929   doorbhv->SoundHandle = SOUND_NOACTIVEINDEX;
930 
931 	{
932 		// Work out the door sound pitch
933 
934 		int maxX,maxY,maxZ,doorSize;
935 
936 		maxX=mainshapelist[morphframe->mf_shape2]->shapemaxx;
937 		maxY=mainshapelist[morphframe->mf_shape2]->shapemaxy;
938 		maxZ=mainshapelist[morphframe->mf_shape2]->shapemaxz;
939 
940 		doorSize = maxX + maxY + maxZ;
941 		if (doorSize < 3000) doorSize = 3000;
942 		else if (doorSize > 8000) doorSize = 8000;
943 
944 		doorSize = (3000 - doorSize) >> 4;
945 
946 		doorbhv->doorType = doorSize;
947 
948 	}
949 
950 	return((void*)doorbhv);
951 }
952 
953 
954 
955 
956 
957 
958 /******************** ANIMATION INIT *************************/
959 
960 
SimpleAnimationBehaveInit(void * bhdata,STRATEGYBLOCK * sbptr)961 static void* SimpleAnimationBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
962 {
963 	/**RWH 10/12/96 ***************************************
964 
965 	Simple Animation intialistation. This will set up an array
966 	of texture control blocks. Each textures controlblock will animate only
967 	one sequence per polygon.
968 
969 	***********************************************************/
970 
971 	SIMPLE_ANIM_BEHAV_BLOCK *sabhv;
972 	int item_num;
973 	TXACTRLBLK **pptxactrlblk;
974 	SIMPLE_ANIM_TOOLS_TEMPLATE * satt = (SIMPLE_ANIM_TOOLS_TEMPLATE *)bhdata;
975 	int shape_num = satt->shape_num;
976 	SHAPEHEADER *shptr = GetShapeData(shape_num);
977 	MODULE * my_mod;
978 
979 
980 	GLOBALASSERT(shptr);
981 	GLOBALASSERT(shptr->numitems > 0);
982 
983 	SetupPolygonFlagAccessForShape(shptr);
984 
985 	sabhv = (SIMPLE_ANIM_BEHAV_BLOCK*)AllocateMem(sizeof(SIMPLE_ANIM_BEHAV_BLOCK));
986 	if(!sabhv)
987 	{
988 		memoryInitialisationFailure = 1;
989 		return ((void *)NULL);
990 	}
991 
992 	sabhv->bhvr_type = I_BehaviourSimpleAnimation;
993 
994 	// Copy the name over
995 	COPY_NAME (sbptr->SBname, satt->nameID);
996 
997 	// Setup module ref
998 
999 	if (*((int *)satt->my_module.mref_name))
1000 	{
1001 		{
1002 			MREF mref=satt->my_module;
1003 			ConvertModuleNameToPointer (&mref, MainSceneArray[0]->sm_marray);
1004 			my_mod = mref.mref_ptr;
1005 		}
1006 		GLOBALASSERT (my_mod);
1007 
1008 		my_mod->m_sbptr = sbptr;
1009 		sbptr->SBmoptr = my_mod;
1010 		sbptr->SBmomptr = my_mod->m_mapptr;
1011 		sbptr->SBflags.no_displayblock = 1;
1012 	}
1013 
1014 
1015 	/* we need to reserve the address of where we
1016 		 are going to place the new animation ctrl block.
1017 
1018 		 this is so that we can call the texture animation builder
1019 		 in the below loop
1020 	*/
1021 
1022 	pptxactrlblk = &sabhv->tacbSimple;
1023 
1024 	/*
1025 	the bhdata is a ptr to the SHAPEHEADER each
1026 	animating polygon has an array of sequences, in
1027 	this case thers is only onr sequence per array
1028 	*/
1029 
1030 	for(item_num = 0; item_num < shptr->numitems; item_num ++)
1031 		{
1032 			POLYHEADER *poly =  (POLYHEADER*)(shptr->items[item_num]);
1033 			LOCALASSERT(poly);
1034 
1035 			if((Request_PolyFlags((void *)poly)) & iflag_txanim)
1036 				{
1037 					TXACTRLBLK *pnew_txactrlblk;
1038 
1039 					pnew_txactrlblk = AllocateMem(sizeof(TXACTRLBLK));
1040 					if (pnew_txactrlblk)
1041 					{
1042  						pnew_txactrlblk->tac_flags = 0;
1043 						pnew_txactrlblk->tac_item = item_num;
1044 						pnew_txactrlblk->tac_sequence = 0;
1045 						pnew_txactrlblk->tac_node = 0;
1046 						pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num);
1047 						pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num);
1048 
1049 						/* set the flags in the animation header */
1050 
1051 						/* KJL 17:00:38 04/04/97 - ChrisF complained about the next line, so
1052 						I've turned it off to see if anything happens. */
1053 						/*pnew_txactrlblk->tac_txah.txa_flags = txa_flag_play; */
1054 
1055 						/* change the value held in pptxactrlblk
1056 						 which point to the previous structures "next"
1057 						 pointer*/
1058 
1059 						*pptxactrlblk = pnew_txactrlblk;
1060 						pptxactrlblk = &pnew_txactrlblk->tac_next;
1061 					}
1062 					else
1063 					{
1064 						memoryInitialisationFailure = 1;
1065 					}
1066 				}
1067 		}
1068 		*pptxactrlblk=0;
1069 
1070 	return((void*)sabhv);
1071 }
1072 
1073 
1074 
InitDatabase(void * bhdata,STRATEGYBLOCK * sbptr)1075 static void* InitDatabase(void* bhdata, STRATEGYBLOCK* sbptr)
1076 {
1077 	DATABASE_BLOCK *db;
1078 	DATABASE_TOOLS_TEMPLATE *dbtt;
1079 
1080 	GLOBALASSERT(sbptr);
1081 	GLOBALASSERT(bhdata);
1082 	dbtt = (DATABASE_TOOLS_TEMPLATE*)bhdata;
1083 
1084 	db = (DATABASE_BLOCK*)AllocateMem(sizeof(DATABASE_BLOCK));
1085 	if(!db)
1086 	{
1087 		memoryInitialisationFailure = 1;
1088 		return ((void *)NULL);
1089 	}
1090 
1091 	db->bhvr_type=I_BehaviourDatabase;
1092 
1093 	db->num = dbtt->num;
1094 
1095 	sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = dbtt->position;
1096 	sbptr->DynPtr->OrientEuler = dbtt->orientation;
1097 	CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat);
1098 	TransposeMatrixCH(&sbptr->DynPtr->OrientMat);
1099 
1100 	sbptr->shapeIndex = dbtt->shape_num;
1101 
1102 	return(void*)db;
1103 }
1104 
1105 
1106 
1107 
1108 
1109 /*********************************************************************
1110 ******************************** ASSIGN SB  Names ********************/
1111 
1112 
AssignAllSBNames()1113 void AssignAllSBNames()
1114 {
1115 
1116 	int stratblock = NumActiveStBlocks;
1117 	GLOBALASSERT(stratblock>=0);
1118 
1119 	while(--stratblock >= 0)
1120 		{
1121 			STRATEGYBLOCK* sbptr = ActiveStBlockList[stratblock];
1122 			GLOBALASSERT(sbptr);
1123 
1124 			switch (sbptr->I_SBtype)
1125 			  {
1126 					case I_BehaviourBinarySwitch:
1127 						{
1128 							BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
1129 							int i;
1130    						bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
1131 							GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
1132 							for (i=0; i<bs_bhv->num_targets; i++)
1133 							{
1134 								bs_bhv->bs_targets[i] = FindSBWithName(bs_bhv->target_names[i].name);
1135 							}
1136 			 				break;
1137 						}
1138 					case I_BehaviourLinkSwitch:
1139 						{
1140 							LINK_SWITCH_BEHAV_BLOCK *ls_bhv;
1141 							int i=0;
1142    							ls_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
1143 							GLOBALASSERT((ls_bhv->bhvr_type == I_BehaviourLinkSwitch));
1144 
1145 							for(i=0;i<ls_bhv->num_linked_switches;i++)
1146 							{
1147 								ls_bhv->lswitch_list[i].bswitch = FindSBWithName(ls_bhv->lswitch_list[i].bs_name);
1148 							}
1149 
1150 							for(i=0;i<ls_bhv->num_targets;i++)
1151 							{
1152 								ls_bhv->ls_targets[i].sbptr=FindSBWithName(ls_bhv->ls_targets[i].name);
1153 							}
1154 
1155 			 				break;
1156 						}
1157 					case I_BehaviourSwitchDoor:
1158 					{
1159 						SWITCH_DOOR_BEHAV_BLOCK *switchDoorBehaviourPtr = (SWITCH_DOOR_BEHAV_BLOCK *)sbptr->SBdataptr;
1160 						if(*((int *)switchDoorBehaviourPtr->linkedDoorName) + *( ((int *)switchDoorBehaviourPtr->linkedDoorName)+1 ) )
1161 							switchDoorBehaviourPtr->linkedDoorPtr = FindSBWithName(switchDoorBehaviourPtr->linkedDoorName);
1162 			 			/* may or may not be linked to another door */
1163 			 			if(switchDoorBehaviourPtr->linkedDoorPtr)
1164 						{
1165 			 				GLOBALASSERT(switchDoorBehaviourPtr->linkedDoorPtr->I_SBtype == I_BehaviourSwitchDoor);
1166 						}
1167 			 			break;
1168 					}
1169 					case I_BehaviourProximityDoor:
1170 						{
1171 							PROXDOOR_BEHAV_BLOCK *doorbhv;
1172 						 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
1173 							GLOBALASSERT((doorbhv->bhvr_type == I_BehaviourProximityDoor));
1174 							if(doorbhv->lockable_door)
1175 								{
1176 								 	doorbhv->door_lock_target = FindSBWithName(doorbhv->target_name);
1177 								}
1178 							break;
1179 						}
1180 					case I_BehaviourLift:
1181 					{
1182 						LIFT_BEHAV_BLOCK *lift_bhv;
1183 						LIFT_STATION *curr_stn;
1184 						lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->SBdataptr;
1185 						GLOBALASSERT((lift_bhv->bhvr_type == I_BehaviourLift));
1186 						curr_stn = &lift_bhv->lift_station;
1187 						GLOBALASSERT(curr_stn);
1188 						curr_stn->lift_call_switch = FindSBWithName(curr_stn->lift_call_switch_name);
1189 						if((*(int*)&curr_stn->lift_floor_switch_name[0]) ||	(*(int*)&curr_stn->lift_floor_switch_name[4]))
1190 							curr_stn->lift_floor_switch = FindSBWithName(curr_stn->lift_floor_switch_name); //lifts with switches that don't teleport,don't know about their floor switches
1191 						curr_stn->lift_door = FindSBWithName(curr_stn->lift_door_name);
1192 
1193 						// find my module pointer
1194 
1195 						{
1196 							STRATEGYBLOCK *my_sb;
1197 							my_sb = FindSBWithName(curr_stn->my_sb_name);
1198 							if(my_sb)
1199 								curr_stn->lift_module = my_sb->SBmoptr;
1200 
1201 						}
1202 
1203 						// find the controlling lift behave block
1204 						lift_bhv->control_sb = FindSBWithName(lift_bhv->control_sb_name);
1205 
1206 						GLOBALASSERT(lift_bhv->control_sb);
1207 
1208 						{
1209 							LIFT_STATION **lift_array;
1210 							LIFT_BEHAV_BLOCK *cont_bhv = lift_bhv->control_sb->SBdataptr;
1211 
1212 							lift_bhv->lift_control = cont_bhv->lift_control;
1213 							lift_array = cont_bhv->lift_control->lift_stations;
1214 
1215 							lift_array[curr_stn->num_floor] = curr_stn;
1216 						}
1217 
1218 						if(curr_stn->starting_station)
1219 						{
1220 							// the door on this floor is open
1221 							// therefore, since we are all perfect
1222 							// i can say
1223 
1224 							GLOBALASSERT(lift_bhv->lift_control->curr_station == -1);
1225 
1226 							lift_bhv->lift_control->curr_station = curr_stn->num_floor;
1227 							if(curr_stn->env == AvP.CurrentEnv)
1228 							{
1229 								if(curr_stn->lift_call_switch)
1230 								{
1231 									// turn on the floor lights
1232 									RequestState(curr_stn->lift_call_switch, 1, 0);
1233 									if((*(int*)&curr_stn->lift_floor_switch_name[0]) ||	(*(int*)&curr_stn->lift_floor_switch_name[4]))
1234 										RequestState(curr_stn->lift_floor_switch, 1, 0);
1235 								}
1236 							}
1237 
1238 
1239 						}
1240 
1241 
1242 
1243 						break;
1244 					}
1245 
1246 					case I_BehaviourXenoborgMorphRoom:
1247 					{
1248 						XENO_MORPH_ROOM_DATA * xmrd = (XENO_MORPH_ROOM_DATA *)sbptr->SBdataptr;
1249 
1250 						GLOBALASSERT (xmrd->bhvr_type == I_BehaviourXenoborgMorphRoom);
1251 
1252 						xmrd->DoorToRoom = FindSBWithName(xmrd->doorID);
1253 						break;
1254 					}
1255 
1256 					default:
1257 						break;
1258 
1259 					case I_BehaviourAlien:
1260 						{
1261 							ALIEN_STATUS_BLOCK *alienStatus = (ALIEN_STATUS_BLOCK *)sbptr->SBdataptr;
1262 							alienStatus->death_target_sbptr = FindSBWithName(alienStatus->death_target_ID);
1263 
1264 			 				break;
1265 						}
1266 					case I_BehaviourMarine:
1267 						{
1268 							MARINE_STATUS_BLOCK *marineStatus = (MARINE_STATUS_BLOCK *)sbptr->SBdataptr;
1269 							marineStatus->death_target_sbptr = FindSBWithName(marineStatus->death_target_ID);
1270 
1271 			 				break;
1272 						}
1273 					case I_BehaviourPredator:
1274 						{
1275 							PREDATOR_STATUS_BLOCK *predatorStatus = (PREDATOR_STATUS_BLOCK *)sbptr->SBdataptr;
1276 							predatorStatus->death_target_sbptr = FindSBWithName(predatorStatus->death_target_ID);
1277 
1278 			 				break;
1279 						}
1280 					case I_BehaviourXenoborg:
1281 						{
1282 							XENO_STATUS_BLOCK *xenoStatus = (XENO_STATUS_BLOCK *)sbptr->SBdataptr;
1283 							xenoStatus->death_target_sbptr = FindSBWithName(xenoStatus->death_target_ID);
1284 
1285 			 				break;
1286 						}
1287 					case I_BehaviourAutoGun:
1288 						{
1289 							AUTOGUN_STATUS_BLOCK *agunStatus = (AUTOGUN_STATUS_BLOCK *)sbptr->SBdataptr;
1290 							agunStatus->death_target_sbptr = FindSBWithName(agunStatus->death_target_ID);
1291 
1292 			 				break;
1293 						}
1294 					case I_BehaviourQueenAlien:
1295 						{
1296 							QUEEN_STATUS_BLOCK *queenStatus = (QUEEN_STATUS_BLOCK *)sbptr->SBdataptr;
1297 							queenStatus->death_target_sbptr = FindSBWithName(queenStatus->death_target_ID);
1298 
1299 			 				break;
1300 						}
1301 					case I_BehaviourFaceHugger:
1302 						{
1303 							FACEHUGGER_STATUS_BLOCK *facehuggerStatus = (FACEHUGGER_STATUS_BLOCK *)sbptr->SBdataptr;
1304 							facehuggerStatus->death_target_sbptr = FindSBWithName(facehuggerStatus->death_target_ID);
1305 
1306 			 				break;
1307 						}
1308 					case I_BehaviourTrackObject:
1309 						{
1310 							int i;
1311 							TRACK_OBJECT_BEHAV_BLOCK *to_bhv = (TRACK_OBJECT_BEHAV_BLOCK *)sbptr->SBdataptr;
1312 							for(i=0;i<to_bhv->num_special_track_points;i++)
1313 							{
1314 								int j;
1315 								SPECIAL_TRACK_POINT* stp=&to_bhv->special_track_points[i];
1316 								for(j=0;j<stp->num_targets;j++)
1317 								{
1318 									stp->targets[j].target_sbptr=FindSBWithName(stp->targets[j].target_name);
1319 								}
1320 							}
1321 
1322 							to_bhv->destruct_target_sbptr=FindSBWithName(to_bhv->destruct_target_ID);
1323 
1324 			 				break;
1325 						}
1326 					case I_BehaviourPlacedHierarchy:
1327 						{
1328 							int i;
1329 							PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK *)sbptr->SBdataptr;
1330 							for(i=0;i<ph_bhv->num_special_track_points;i++)
1331 							{
1332 								int j;
1333 								SPECIAL_TRACK_POINT* stp=&ph_bhv->special_track_points[i];
1334 								for(j=0;j<stp->num_targets;j++)
1335 								{
1336 									stp->targets[j].target_sbptr=FindSBWithName(stp->targets[j].target_name);
1337 								}
1338 							}
1339 
1340 			 				break;
1341 						}
1342 
1343 					case I_BehaviourInanimateObject:
1344 						{
1345 							INANIMATEOBJECT_STATUSBLOCK* objectstatusptr=(INANIMATEOBJECT_STATUSBLOCK*)sbptr->SBdataptr;
1346 							if(objectstatusptr)
1347 							{
1348 								if(objectstatusptr->event_target)
1349 								{
1350 									objectstatusptr->event_target->event_target_sbptr=FindSBWithName(objectstatusptr->event_target->event_target_ID);
1351 								}
1352 							}
1353 							break;
1354 
1355 						}
1356 
1357 					case I_BehaviourPlacedLight:
1358 						{
1359 							PLACED_LIGHT_BEHAV_BLOCK* pl_bhv=(PLACED_LIGHT_BEHAV_BLOCK*)sbptr->SBdataptr;
1360 							if(pl_bhv)
1361 							{
1362 								pl_bhv->destruct_target_sbptr=FindSBWithName(pl_bhv->destruct_target_ID);
1363 
1364 							}
1365 							break;
1366 
1367 						}
1368 					case I_BehaviourVideoScreen:
1369 						{
1370 							VIDEO_SCREEN_BEHAV_BLOCK* videoScreen=(VIDEO_SCREEN_BEHAV_BLOCK*)sbptr->SBdataptr;
1371 							if(videoScreen)
1372 							{
1373 								videoScreen->destruct_target_sbptr=FindSBWithName(videoScreen->destruct_target_ID);
1374 
1375 							}
1376 							break;
1377 
1378 						}
1379 			  }
1380 		}
1381 }
1382 
1383 
1384 /**************************************************************************************/
1385 /******************************* STUFF TO DO BEHAVIOURS *******************************/
1386 
1387 
ObjectBehaviours(void)1388 void ObjectBehaviours(void)
1389 {
1390 	int i;
1391 
1392 #ifdef AVP_DEBUG_VERSION
1393 	for (i=0; i<NumActiveStBlocks; i++)
1394 	{
1395 		if (ActiveStBlockList[i]->SBdptr)
1396 		{
1397 			int j = i+1;
1398 
1399 			for (; j<NumActiveStBlocks; j++)
1400 			{
1401 				if (ActiveStBlockList[i]->SBdptr == ActiveStBlockList[j]->SBdptr)
1402 				{
1403 					GLOBALASSERT (0);
1404 				}
1405 			}
1406 		}
1407 	}
1408 #endif
1409 
1410 	RequestEnvChangeViaLift	= 0;
1411 
1412 	i = 0;
1413 
1414 	while(i < NumActiveStBlocks)
1415 	{
1416 		ExecuteBehaviour(ActiveStBlockList[i++]);
1417   }
1418 
1419 }
1420 
1421 
ExecuteBehaviour(STRATEGYBLOCK * sbptr)1422 void ExecuteBehaviour(STRATEGYBLOCK* sbptr)
1423 {
1424 	GLOBALASSERT(sbptr);
1425 
1426 	switch(sbptr->I_SBtype)
1427 	{
1428 		case I_BehaviourInanimateObject:
1429 			InanimateObjectBehaviour(sbptr);
1430 			break;
1431 
1432 		case I_BehaviourProximityDoor:
1433 			DoorProxBehaveFun(sbptr);
1434 			break;
1435 
1436 		case I_BehaviourBinarySwitch:
1437 			BinarySwitchBehaveFun(sbptr);
1438 			break;
1439 
1440 		case I_BehaviourLiftDoor:
1441 			LiftDoorBehaveFun(sbptr);
1442 			break;
1443 
1444 		case I_BehaviourLift:
1445 			LiftBehaveFun(sbptr);
1446 			break;
1447 
1448     case I_BehaviourGenerator:
1449 			GeneratorBehaviour(sbptr);
1450 			break;
1451 
1452 		case I_BehaviourMarinePlayer:
1453 			PlayerBehaviour(sbptr);
1454 			break;
1455 
1456   	case I_BehaviourAlien:
1457 			AlienBehaviour(sbptr);
1458 			break;
1459 
1460 		case I_BehaviourSwitchDoor:
1461 			SwitchDoorBehaviour(sbptr);
1462 			break;
1463 
1464 		case I_BehaviourLinkSwitch:
1465 			LinkSwitchBehaveFun(sbptr);
1466 			break;
1467 
1468 		case I_BehaviourPlatform:
1469 			PlatformLiftBehaviour(sbptr);
1470 			break;
1471 
1472 		case I_BehaviourSimpleAnimation:
1473 			SimpleAnimBehaveFun(sbptr);
1474 			break;
1475 
1476 		case I_BehaviourAutoGun:
1477 			AutoGunBehaveFun(sbptr);
1478 			break;
1479 
1480 
1481 		case I_BehaviourFragmentationGrenade:
1482 		case I_BehaviourGrenade:
1483 			GrenadeBehaviour(sbptr);
1484 			break;
1485 		case I_BehaviourMolotov:
1486 			MolotovBehaviour(sbptr);
1487 			break;
1488 
1489     case I_BehaviourProximityGrenade:
1490 			ProximityGrenadeBehaviour(sbptr);
1491     	break;
1492 
1493     case I_BehaviourFlareGrenade:
1494 			FlareGrenadeBehaviour(sbptr);
1495     	break;
1496 
1497 		case I_BehaviourClusterGrenade:
1498 			ClusterGrenadeBehaviour(sbptr);
1499 			break;
1500 
1501 		case I_BehaviourFrisbee:
1502 			FrisbeeBehaviour(sbptr);
1503 			break;
1504 
1505 		case I_BehaviourRocket:
1506 			RocketBehaviour(sbptr);
1507 			break;
1508 
1509 		case I_BehaviourPulseGrenade:
1510 			PulseGrenadeBehaviour(sbptr);
1511 			break;
1512 
1513 		case I_BehaviourFaceHugger:
1514 			FacehuggerBehaviour(sbptr);
1515 			break;
1516 
1517 		case I_BehaviourPredator:
1518 			PredatorBehaviour(sbptr);
1519 			break;
1520 
1521 		case I_BehaviourXenoborg:
1522 			XenoborgBehaviour(sbptr);
1523 			break;
1524 
1525 		case I_BehaviourQueenAlien:
1526 			QueenBehaviour(sbptr);
1527 			break;
1528 
1529 		case I_BehaviourPredatorAlien:
1530 			GLOBALASSERT(0);
1531 			//PAQBehaviour(sbptr);
1532 			break;
1533 
1534 		case I_BehaviourMarine:
1535 			MarineBehaviour(sbptr);
1536 			break;
1537 
1538 		case I_BehaviourSeal:
1539 			MarineBehaviour(sbptr);
1540 			break;
1541 
1542 
1543 		case I_BehaviourHierarchicalFragment:
1544 			{
1545 				#if 0
1546 				HDEBRIS_BEHAV_BLOCK *hbbptr=(HDEBRIS_BEHAV_BLOCK *)sbptr->SBdataptr;
1547 				LOCALASSERT(hbbptr);
1548 				if (hbbptr->HModelController.Root_Section->flags&section_sprays_acid) {
1549 					AlienFragFun(sbptr);
1550 				} else {
1551 					OneShotBehaveFun(sbptr);
1552 				}
1553 				#else
1554 				HierarchicalFragmentBehaviour(sbptr);
1555 				#endif
1556 			}
1557 			break;
1558 		case I_BehaviourAlienFragment:
1559 			AlienFragFun(sbptr);
1560 			break;
1561 
1562   	case I_BehaviourFragment:
1563 		case I_BehaviourAutoGunMuzzleFlash:
1564 			OneShotBehaveFun(sbptr);
1565 	  	break;
1566 
1567 		case I_BehaviourOneShotAnim:
1568 			OneShot_Anim_BehaveFun(sbptr);
1569 			break;
1570 
1571 		case I_BehaviourPPPlasmaBolt:
1572 			PPPlasmaBoltBehaviour(sbptr);
1573 			break;
1574 
1575 		case I_BehaviourSpeargunBolt:
1576 			SpeargunBoltBehaviour(sbptr);
1577 			break;
1578 
1579 		case I_BehaviourPredatorEnergyBolt:
1580 			PredatorEnergyBoltBehaviour(sbptr);
1581 			break;
1582 
1583 		case I_BehaviourFrisbeeEnergyBolt:
1584 			FrisbeeEnergyBoltBehaviour(sbptr);
1585 			break;
1586 
1587 		case I_BehaviourXenoborgEnergyBolt:
1588 			XenoborgEnergyBoltBehaviour(sbptr);
1589 			break;
1590 
1591 		case I_BehaviourAlienSpit:
1592 			AlienSpitBehaviour(sbptr);
1593 			break;
1594 
1595 		case I_BehaviourNPCPredatorDisc:
1596 			NPCDiscBehaviour(sbptr);
1597 			break;
1598 
1599 		case I_BehaviourPredatorDisc_SeekTrack:
1600 			DiscBehaviour_SeekTrack(sbptr);
1601 			break;
1602 
1603 		#if 0
1604 		/* KJL 17:07:53 02/24/97 - I've turned these off for now since they
1605 		always seem to cause crashes. */
1606 		case I_BehaviourFlameProjectile:
1607 			FlameProjectileFunction(sbptr);
1608 			break;
1609 		#endif
1610 
1611 		case I_BehaviourDatabase:
1612 			/* KJL 16:30:21 03/13/97 - no behaviour required */
1613 			break;
1614 
1615  		case I_BehaviourNetGhost:
1616 			NetGhostBehaviour(sbptr);
1617 			break;
1618 
1619 		case I_BehaviourSmokeGenerator:
1620 			SmokeGeneratorBehaviour(sbptr);
1621 			break;
1622 
1623 		case I_BehaviourXenoborgMorphRoom:
1624 			XenoMorphRoomBehaviour (sbptr);
1625 			break;
1626 
1627 		case I_BehaviourLightFX:
1628 			LightFXBehaveFun (sbptr);
1629 			break;
1630 
1631 		case I_BehaviourPlacedSound:
1632 		{
1633 			SoundBehaveFun (sbptr);
1634 			break;
1635 		}
1636 		case I_BehaviourTrackObject:
1637 		{
1638 			TrackObjectBehaveFun (sbptr);
1639 			break;
1640 		}
1641 		case I_BehaviourFan:
1642 		{
1643 			FanBehaveFun (sbptr);
1644 			break;
1645 		}
1646 		case I_BehaviourNetCorpse:
1647 		{
1648 			CorpseBehaveFun(sbptr);
1649 			break;
1650 		}
1651 		case I_BehaviourRubberDuck:
1652 		{
1653 			RubberDuckBehaviour(sbptr);
1654 			break;
1655 		}
1656 		case I_BehaviourPlacedHierarchy :
1657 		{
1658 			PlacedHierarchyBehaveFun(sbptr);
1659 			break;
1660 		}
1661 
1662 		case I_BehaviourPlacedLight:
1663 			PlacedLightBehaviour(sbptr);
1664 			break;
1665 
1666 		case I_BehaviourVideoScreen:
1667 			VideoScreenBehaviour(sbptr);
1668 			break;
1669 
1670 		case I_BehaviourPowerCable:
1671 			PowerCableBehaveFun(sbptr);
1672 			break;
1673 
1674 		case I_BehaviourDeathVolume:
1675 			DeathVolumeBehaveFun(sbptr);
1676 			break;
1677 
1678 		case I_BehaviourSelfDestruct:
1679 			SelfDestructBehaveFun(sbptr);
1680 			break;
1681 
1682 		case I_BehaviourGrapplingHook:
1683 			GrapplingHookBehaviour(sbptr);
1684 			break;
1685 
1686 		case I_BehaviourDummy:
1687 			DummyBehaviour(sbptr);
1688 			break;
1689 
1690 		case I_BehaviourParticleGenerator:
1691 			ParticleGeneratorBehaveFun(sbptr);
1692 			break;
1693     default:
1694 			break;
1695 	}
1696 }
1697 
1698 
1699 
1700 
1701 
1702 /********************** OTHER FUNCTIONS **********************/
1703 
1704 
1705 
1706 
1707 
1708 /************************** DOOR FUNCTIONS *************************/
1709 
1710 
1711 
1712 
1713 /*------------Patrick 6/1/97--------------------
1714   I have made some significant modifications to
1715   the proximity door behaviour function, to
1716   facilitate opening and closing by 'far'aliens
1717   ----------------------------------------------*/
1718 
UnlockThisProxdoor(STRATEGYBLOCK * sbptr)1719 void UnlockThisProxdoor(STRATEGYBLOCK* sbptr)
1720 {
1721 	PROXDOOR_BEHAV_BLOCK *doorbhv;
1722 	MORPHCTRL *mctrl;
1723 	DISPLAYBLOCK* dptr;
1724 	MODULE *mptr;
1725 
1726  	GLOBALASSERT(sbptr);
1727 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
1728 	GLOBALASSERT((doorbhv->bhvr_type == I_BehaviourProximityDoor));
1729 	mctrl = doorbhv->PDmctrl;
1730 	GLOBALASSERT(mctrl);
1731 	mptr = sbptr->SBmoptr;
1732 	GLOBALASSERT(mptr);
1733 	dptr = sbptr->SBdptr;
1734 
1735 	/* Unlock door! */
1736 	doorbhv->door_locked = 0;
1737 
1738 }
1739 
DoorProxBehaveFun(STRATEGYBLOCK * sbptr)1740 static void DoorProxBehaveFun(STRATEGYBLOCK* sbptr)
1741 {
1742 	PROXDOOR_BEHAV_BLOCK *doorbhv;
1743 	MORPHCTRL *mctrl;
1744 	DISPLAYBLOCK* dptr;
1745 	MODULE *mptr;
1746 	BOOL open_door = No;
1747 
1748  	GLOBALASSERT(sbptr);
1749 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
1750 	GLOBALASSERT((doorbhv->bhvr_type == I_BehaviourProximityDoor));
1751 	mctrl = doorbhv->PDmctrl;
1752 	GLOBALASSERT(mctrl);
1753 	mptr = sbptr->SBmoptr;
1754 	GLOBALASSERT(mptr);
1755 	dptr = sbptr->SBdptr;
1756 
1757 
1758 	/* update morphing.... */
1759 	UpdateMorphing(mctrl);
1760 
1761 	/*-----------------Patrick 29/4/97-------------------------
1762 	 Little patch for networking: doors should run the
1763 	 AnythingNearProxDoor() test even when they are not visible
1764 	 ----------------------------------------------------------*/
1765 
1766 	if(AvP.Network==I_No_Network)
1767 	{
1768 		/* if door is visible check for proximity of player, aliens, and whatever... */
1769 		if(dptr) open_door = AnythingNearProxDoor(mptr,doorbhv);
1770 	}
1771 	else open_door = AnythingNearProxDoor(mptr,doorbhv);
1772 
1773 
1774 
1775  	/* check for an alien trigger:
1776  	NB Door could be either visible or not when triggered */
1777  	if ((doorbhv->alienTrigger == 1)||((doorbhv->marineTrigger == 1)))
1778 	{
1779 		open_door = Yes;
1780 		if (doorbhv->marineTrigger==1) {
1781 			doorbhv->triggeredByMarine = 1;
1782 		}
1783 		doorbhv->alienTimer = DOOR_FAROPENTIME;
1784 		doorbhv->alienTrigger = 0;
1785 		doorbhv->marineTrigger = 0;
1786 	}
1787 
1788 	if (doorbhv->door_locked)
1789 	{
1790 		open_door = No;
1791 	}
1792 
1793  	switch(doorbhv->door_state)
1794 	{
1795 		case I_door_opening:
1796 		{
1797 			mptr->m_flags |= m_flag_open;
1798 			if(mctrl->ObMorphFlags & mph_flag_finished)
1799 			{
1800 		        if (doorbhv->SoundHandle!=SOUND_NOACTIVEINDEX)
1801 		        {
1802 		          if (doorbhv->triggeredByMarine) {
1803 			          Sound_Play(SID_DOOREND,"dpm",&mptr->m_world,doorbhv->doorType);
1804 				  } else {
1805 			          Sound_Play(SID_DOOREND,"dp",&mptr->m_world,doorbhv->doorType);
1806 				  }
1807 		          Sound_Stop(doorbhv->SoundHandle);
1808 		        }
1809 
1810 				doorbhv->door_state = I_door_open;
1811 			}
1812 			break;
1813 		}
1814 
1815 		case I_door_closing:
1816 		{
1817 			if(open_door)
1818 			{
1819 
1820 				if(dptr)
1821 				{
1822 					OpenDoor(mctrl, doorbhv->door_opening_speed);
1823 					if (doorbhv->SoundHandle==SOUND_NOACTIVEINDEX)
1824 					{
1825 		  		         if (doorbhv->triggeredByMarine) {
1826 		 	 				Sound_Play(SID_DOORSTART,"dpm",&mptr->m_world,doorbhv->doorType);
1827 					 		Sound_Play(SID_DOORMID,"delpm",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1828 						 } else {
1829 		 	 				Sound_Play(SID_DOORSTART,"dp",&mptr->m_world,doorbhv->doorType);
1830 					 		Sound_Play(SID_DOORMID,"delp",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1831 						 }
1832 				 	}
1833 		    }
1834 				else
1835 				{
1836 				  OpenDoor(mctrl, DOOR_OPENFASTSPEED);
1837 				}
1838 
1839 				doorbhv->door_state = I_door_opening;
1840 			}
1841 			else if(mctrl->ObMorphFlags & mph_flag_finished)
1842 			{
1843 		        if (doorbhv->SoundHandle!=SOUND_NOACTIVEINDEX)
1844 		        {
1845 	  		         if (doorbhv->triggeredByMarine) {
1846   				 		Sound_Play(SID_DOOREND,"dpm",&mptr->m_world,doorbhv->doorType);
1847 					 } else {
1848   				 		Sound_Play(SID_DOOREND,"dp",&mptr->m_world,doorbhv->doorType);
1849 					 }
1850 		       		Sound_Stop(doorbhv->SoundHandle);
1851 		        }
1852 
1853 				doorbhv->door_state = I_door_closed;
1854 				mptr->m_flags &= ~m_flag_open;
1855 			}
1856 
1857 			break;
1858 		}
1859 
1860 		case I_door_open:
1861 		{
1862 			mptr->m_flags |= m_flag_open;
1863 			if(!open_door)
1864 			{
1865 
1866  				if(dptr)
1867 				{
1868   		         if (doorbhv->triggeredByMarine) {
1869 			 		Sound_Play(SID_DOORSTART,"dpm",&mptr->m_world,doorbhv->doorType);
1870 			 		Sound_Play(SID_DOORMID,"delpm",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1871 				 } else {
1872 			 		Sound_Play(SID_DOORSTART,"dp",&mptr->m_world,doorbhv->doorType);
1873 			 		Sound_Play(SID_DOORMID,"delp",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1874 				 }
1875 					doorbhv->alienTimer = 0;
1876 					CloseDoor(mctrl,doorbhv->door_closing_speed);
1877 					doorbhv->door_state = I_door_closing;
1878 				}
1879 				else
1880 				{
1881 					doorbhv->alienTimer -= NormalFrameTime;
1882 					if(!(doorbhv->alienTimer>0))
1883 					{
1884 						doorbhv->alienTimer = 0;
1885 						CloseDoor(mctrl, DOOR_CLOSEFASTSPEED);
1886 						doorbhv->door_state = I_door_closing;
1887 					}
1888 				}
1889 			}
1890 
1891 			break;
1892 		}
1893 
1894 		case I_door_closed:
1895 		{
1896 			mptr->m_flags &= ~m_flag_open;
1897 			if(open_door)
1898 			{
1899 		 		if(dptr)
1900 				{
1901 	  		         if (doorbhv->triggeredByMarine) {
1902 						Sound_Play(SID_DOORSTART,"dpm",&mptr->m_world,doorbhv->doorType);
1903 				 		Sound_Play(SID_DOORMID,"delpm",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1904 				 	 } else {
1905 						Sound_Play(SID_DOORSTART,"dp",&mptr->m_world,doorbhv->doorType);
1906 				 		Sound_Play(SID_DOORMID,"delp",&mptr->m_world,&doorbhv->SoundHandle,doorbhv->doorType);
1907 					 }
1908 					OpenDoor(mctrl,doorbhv->door_opening_speed);
1909 				}
1910 				else OpenDoor(mctrl, DOOR_OPENFASTSPEED);
1911 				doorbhv->door_state = I_door_opening;
1912 				mptr->m_flags |= m_flag_open;
1913 			} else {
1914 				doorbhv->triggeredByMarine = 0;
1915 			}
1916 
1917 			break;
1918 		}
1919 
1920 		default:
1921 				LOCALASSERT(1==0);
1922 	}
1923 }
1924 
1925 
OpenDoor(MORPHCTRL * mctrl,int speed)1926 void OpenDoor(MORPHCTRL *mctrl, int speed)
1927 {
1928 	LOCALASSERT(mctrl);
1929 
1930 	mctrl->ObMorphFlags = mph_flag_play;
1931 	mctrl->ObMorphFlags |= mph_flag_noloop;
1932 	mctrl->ObMorphFlags |= mph_flag_reverse;
1933 	mctrl->ObMorphSpeed = speed;
1934 }
1935 
1936 
CloseDoor(MORPHCTRL * mctrl,int speed)1937 void CloseDoor(MORPHCTRL *mctrl, int speed)
1938 {
1939 	LOCALASSERT(mctrl);
1940 
1941 	mctrl->ObMorphFlags = mph_flag_play;
1942 	mctrl->ObMorphFlags |= mph_flag_noloop;
1943 	mctrl->ObMorphFlags &= ~mph_flag_reverse;
1944 	mctrl->ObMorphSpeed =  speed;
1945 }
1946 
1947 /*---------------Patrick 6/1/97-------------------
1948   Sorry, but I can't think of anything better than
1949   searching the	entire sb list for any object that
1950   might trigger a door....
1951   ------------------------------------------------*/
AnythingNearProxDoor(MODULE * doorModulePtr,PROXDOOR_BEHAV_BLOCK * doorbhv)1952 static int AnythingNearProxDoor(MODULE *doorModulePtr,PROXDOOR_BEHAV_BLOCK *doorbhv)
1953 {
1954 	/* KJL 18:06:59 19/02/98 - I've rewritten this check so that it can cope with very tall doors. */
1955 	extern int NumActiveStBlocks;
1956 	extern STRATEGYBLOCK *ActiveStBlockList[];
1957 
1958 	int sbIndex = 0;
1959 	STRATEGYBLOCK *sbPtr;
1960 	DYNAMICSBLOCK *dynPtr;
1961 	DISPLAYBLOCK *dPtr;
1962 	int retval;
1963 
1964 	int maxY;
1965 	int minY;
1966 	int maxX;
1967 	int minX;
1968 	int maxZ;
1969 	int minZ;
1970 
1971 	if (doorModulePtr->m_flags & MODULEFLAG_HORIZONTALDOOR)
1972 	{
1973 		maxY = doorModulePtr->m_world.vy + DOOR_OPENDISTANCE/2;
1974 		minY = doorModulePtr->m_world.vy - DOOR_OPENDISTANCE/2;
1975 		maxX = doorModulePtr->m_world.vx + doorModulePtr->m_maxx + DOOR_OPENDISTANCE/2;
1976 		minX = doorModulePtr->m_world.vx + doorModulePtr->m_minx - DOOR_OPENDISTANCE/2;
1977 		maxZ = doorModulePtr->m_world.vz + doorModulePtr->m_maxz + DOOR_OPENDISTANCE/2;
1978 		minZ = doorModulePtr->m_world.vz + doorModulePtr->m_minz - DOOR_OPENDISTANCE/2;
1979 	}
1980 	else
1981 	{
1982 		maxY = doorModulePtr->m_world.vy + doorModulePtr->m_maxy;
1983 		minY = doorModulePtr->m_world.vy + doorModulePtr->m_miny;
1984 		maxX = doorModulePtr->m_world.vx + DOOR_OPENDISTANCE;
1985 		minX = doorModulePtr->m_world.vx - DOOR_OPENDISTANCE;
1986 		maxZ = doorModulePtr->m_world.vz + DOOR_OPENDISTANCE;
1987 		minZ = doorModulePtr->m_world.vz - DOOR_OPENDISTANCE;
1988 	}
1989 	/* loop thro' the strategy block list...
1990 	looking for triggerable objects (please feel free to add any
1991 	sensible object types) */
1992 	retval=No;
1993 
1994 	while(sbIndex < NumActiveStBlocks)
1995 	{
1996 		sbPtr = ActiveStBlockList[sbIndex++];
1997 		dynPtr = sbPtr->DynPtr;
1998 		dPtr = sbPtr->SBdptr;
1999 
2000 		if(	(dynPtr)&&(dPtr)&&
2001 			((sbPtr->I_SBtype == I_BehaviourAlien)||
2002 			(sbPtr->I_SBtype == I_BehaviourMarinePlayer)||
2003 			(sbPtr->I_SBtype == I_BehaviourPredatorPlayer)||
2004 			(sbPtr->I_SBtype == I_BehaviourAlienPlayer)||
2005 			(sbPtr->I_SBtype == I_BehaviourPredator)||
2006 			(sbPtr->I_SBtype ==	I_BehaviourXenoborg)||
2007 			(sbPtr->I_SBtype ==	I_BehaviourMarine)||
2008 			(sbPtr->I_SBtype ==	I_BehaviourSeal)||
2009 			(sbPtr->I_SBtype ==	I_BehaviourQueenAlien)||
2010 			(sbPtr->I_SBtype ==	I_BehaviourPredatorAlien)||
2011 			(sbPtr->I_SBtype ==	I_BehaviourFaceHugger)||
2012 			(sbPtr->I_SBtype == I_BehaviourGrenade)||
2013 			(sbPtr->I_SBtype == I_BehaviourRocket)||
2014 			(sbPtr->I_SBtype == I_BehaviourFrisbee)||
2015 			(sbPtr->I_SBtype == I_BehaviourPulseGrenade)||
2016 			(sbPtr->I_SBtype == I_BehaviourProximityGrenade)||
2017 			(sbPtr->I_SBtype == I_BehaviourNetGhost)||
2018 //			(sbPtr->I_SBtype == I_BehaviourFlareGrenade)||
2019 			(sbPtr->I_SBtype == I_BehaviourFragmentationGrenade)||
2020 			(sbPtr->I_SBtype == I_BehaviourPredatorDisc_SeekTrack)||
2021 			(sbPtr->I_SBtype == I_BehaviourNetCorpse)||
2022 			(sbPtr->I_SBtype == I_BehaviourHierarchicalFragment)||
2023 			(sbPtr->I_SBtype == I_BehaviourNPCPredatorDisc))
2024 		  )
2025 		{
2026 			if (dynPtr->Position.vy > minY && dynPtr->Position.vy < maxY)
2027 			{
2028 				if (dynPtr->Position.vx > minX && dynPtr->Position.vx < maxX)
2029 				{
2030 					if (dynPtr->Position.vz > minZ && dynPtr->Position.vz < maxZ)
2031 					{
2032 						if ((sbPtr->I_SBtype==I_BehaviourMarine)
2033 							||(sbPtr->I_SBtype==I_BehaviourSeal)) {
2034 							doorbhv->triggeredByMarine = 1;
2035 						}
2036 						retval=Yes;
2037 					}
2038 				}
2039 			}
2040 		}
2041 	}
2042 
2043 	return(retval);
2044 
2045 }
2046 
2047 
2048 
SimpleAnimBehaveFun(STRATEGYBLOCK * sbptr)2049 static void SimpleAnimBehaveFun(STRATEGYBLOCK* sbptr)
2050 {
2051 	/* this just copie the SB taccontrol into the
2052 	   display bloxk if it didnt already have one*/
2053 
2054 	SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv;
2055   	DISPLAYBLOCK* dptr;
2056 
2057 	sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->SBdataptr);
2058 
2059 	GLOBALASSERT(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation);
2060 
2061 	dptr = sbptr->SBdptr;
2062 
2063 	if(dptr)
2064 	{
2065 		if(!dptr->ObTxAnimCtrlBlks)
2066 			{
2067 				dptr->ObTxAnimCtrlBlks = sanimbhv->tacbSimple;
2068 			}
2069 	}
2070 }
2071 
2072 
2073 /********************* SUPPORT  FUNCTION ***********************/
2074 /*
2075 	these set the reqest state in a strategy block
2076 */
2077 
RequestState(STRATEGYBLOCK * sbptr,int message,STRATEGYBLOCK * SBRequester)2078 void RequestState(STRATEGYBLOCK* sbptr, int message, STRATEGYBLOCK * SBRequester)
2079 {
2080 	//lowest bit of message corresponds to old on/off state
2081 	//the rest is extended information ,the interpretation of which depends on the receiving strategy
2082 	BOOL state=message & 1;
2083 	if(!sbptr)
2084 	{
2085 		return;
2086 	}
2087 	//GLOBALASSERT(sbptr);
2088 
2089 	if(sbptr->SBflags.destroyed_but_preserved)
2090 	{
2091 		//target doesn't exist anymore so ignore request.
2092 		return;
2093 	}
2094 
2095 	#if DB_LEVEL >=3
2096 	{
2097 		//add details of request to logfile
2098 		extern int GlobalFrameCounter;
2099 		const char* name1=0;
2100 		const char* name2="ANON";
2101 		if(sbptr) name1=sbptr->name;
2102 		if(SBRequester) name2=SBRequester->name;
2103 		db_logf3(("Frame %d  : %s sent %s message to %s%s",GlobalFrameCounter,name2, state ? "'on'" : "'off'",name1,(message>>1)? " with extra message data" : ""));
2104 	}
2105 	#endif
2106 
2107 
2108 	switch (sbptr->I_SBtype)
2109 	  {
2110 			case I_BehaviourNetCorpse:
2111 				/* Ulp... */
2112 				break;
2113 			case I_BehaviourBinarySwitch:
2114 				{
2115 					// 0 = rest state
2116 					// 1 = unusual state
2117 
2118 					BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
2119 					bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
2120 					GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
2121 
2122 					if(state)
2123 						bs_bhv->request = I_request_on;
2124 					else
2125 						bs_bhv->request = I_request_off;
2126 
2127 					break;
2128 				}
2129 
2130 			case I_BehaviourLinkSwitch:
2131 				{
2132 					LINK_SWITCH_BEHAV_BLOCK *bs_bhv;
2133 
2134 					// 0 = rest state
2135 					// 1 = unusual state
2136 
2137 					bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
2138 					GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourLinkSwitch));
2139 
2140 					if (SBRequester) if (SBRequester->I_SBtype == I_BehaviourBinarySwitch ||
2141 															SBRequester->I_SBtype == I_BehaviourLinkSwitch)
2142 					{
2143 						//if the request has come from one of the linked switches , ignore it
2144 						int i;
2145 						for(i=0;i<bs_bhv->num_linked_switches;i++)
2146 						{
2147 							if(bs_bhv->lswitch_list[i].bswitch==SBRequester)
2148 							{
2149 								break;
2150 							}
2151 						}
2152 						if(i<bs_bhv->num_linked_switches)
2153 						{
2154 							break;
2155 						}
2156 					}
2157 
2158 
2159 					if(state)
2160 						bs_bhv->request = I_request_on;
2161 					else
2162 						bs_bhv->request = I_request_off;
2163 
2164 					break;
2165 				}
2166 
2167 			case I_BehaviourProximityDoor:
2168 				{
2169 					PROXDOOR_BEHAV_BLOCK *door_bhv;
2170 					MORPHCTRL *mctrl;
2171 
2172 					door_bhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2173 					GLOBALASSERT((door_bhv->bhvr_type == I_BehaviourProximityDoor));
2174 					mctrl = door_bhv->PDmctrl;
2175 					GLOBALASSERT(mctrl);
2176 
2177 					//request previously open and closed door.Now it locks or unlocks it.
2178 					if(state == 1)
2179 						{
2180 							door_bhv->door_locked = 0;
2181 						}
2182 					else
2183 						{
2184 							door_bhv->door_locked = 1;
2185 						}
2186 					break;
2187 				}
2188 
2189 			case I_BehaviourLiftDoor:
2190 				{
2191 					LIFT_DOOR_BEHAV_BLOCK *door_bhv;
2192 					door_bhv = (LIFT_DOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2193 					GLOBALASSERT((door_bhv->bhvr_type == I_BehaviourLiftDoor));
2194 
2195 					if(state == 1)
2196 						door_bhv->request_state = I_door_open;
2197 					else
2198 						door_bhv->request_state = I_door_closed;
2199 
2200 					break;
2201 				}
2202 
2203 			case I_BehaviourSwitchDoor:
2204 			{
2205 				SWITCH_DOOR_BEHAV_BLOCK *door_bhv;
2206 				door_bhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2207 				GLOBALASSERT((door_bhv->myBehaviourType == I_BehaviourSwitchDoor));
2208 
2209 				if(state == 1) door_bhv->requestOpen = 1;
2210 				else door_bhv->requestClose = 1;
2211 				break;
2212 			}
2213 
2214 			case I_BehaviourLift:
2215 				{
2216 					LIFT_BEHAV_BLOCK *lift_bhv;
2217 					LIFT_STATION *lift_stn;
2218 			 		GLOBALASSERT(sbptr);
2219 					lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->SBdataptr;
2220 					GLOBALASSERT((lift_bhv->bhvr_type == I_BehaviourLift));
2221 					lift_stn = &lift_bhv->lift_station;
2222 					GLOBALASSERT(lift_stn);
2223 
2224 					if(state == 1)
2225 						lift_stn->called = 1;
2226 					else
2227 						lift_stn->called = 0;
2228 
2229 					break;
2230 				}
2231 
2232 			case I_BehaviourPlatform:
2233 			{
2234 
2235 				((PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbptr->SBdataptr)->Enabled = state;
2236 
2237 				break;
2238 			}
2239 
2240 			case I_BehaviourAutoGun:
2241 			{
2242 				AUTOGUN_STATUS_BLOCK *agunStatusPointer;
2243 				agunStatusPointer = (AUTOGUN_STATUS_BLOCK*)sbptr->SBdataptr;
2244 
2245 				if ((agunStatusPointer->behaviourState==I_inactive)&&(state==1)) {
2246 					agunStatusPointer->behaviourState=I_tracking;
2247 				} else if ((agunStatusPointer->behaviourState==I_tracking)&&(state==0)) {
2248 					agunStatusPointer->behaviourState=I_inactive;
2249 					Sound_Play(SID_SENTRYGUN_SHUTDOWN,"d",&sbptr->DynPtr->Position);
2250 				}
2251 
2252 				break;
2253 			}
2254 
2255 			case I_BehaviourGenerator:
2256 			{
2257 				((GENERATOR_BLOCK*)sbptr->SBdataptr)->Active = state;
2258 				break;
2259 			}
2260 
2261 			case I_BehaviourLightFX:
2262 			{
2263 				LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbptr->SBdataptr;
2264 
2265 				if (lfxbb->type == LFX_Switch)
2266 				{
2267 					switch (lfxbb->current_state)
2268 					{
2269 
2270 						case LFXS_LightOn:
2271 						{
2272 							if(state==0)
2273 							{
2274 								lfxbb->current_state = LFXS_LightFadingDown;
2275 								lfxbb->timer = 0;
2276 							}
2277 							break;
2278 						}
2279 
2280 						case LFXS_LightOff:
2281 						{
2282 							if(state==1)
2283 							{
2284 								lfxbb->current_state = LFXS_LightFadingUp;
2285 								lfxbb->timer = 0;
2286 							}
2287 							break;
2288 						}
2289 
2290 						case LFXS_LightFadingUp:
2291 						{
2292 							if(state==0)
2293 							{
2294 								lfxbb->timer = ONE_FIXED - lfxbb->timer;
2295 								lfxbb->current_state = LFXS_LightFadingDown;
2296 							}
2297 							break;
2298 						}
2299 
2300 						case LFXS_LightFadingDown:
2301 						{
2302 							if(state==1)
2303 							{
2304 								lfxbb->timer = ONE_FIXED - lfxbb->timer;
2305 								lfxbb->current_state = LFXS_LightFadingUp;
2306 							}
2307 							break;
2308 						}
2309 
2310 						default:
2311 						{
2312 							GLOBALASSERT (0 == "Light FX state not supported");
2313 							break;
2314 						}
2315 					}
2316 				}
2317 				else if (lfxbb->type == LFX_FlickySwitch)
2318 				{
2319 					switch (lfxbb->current_state)
2320 					{
2321 
2322 						case LFXS_LightOn:
2323 						{
2324 							if(state==0)
2325 							{
2326 								lfxbb->current_state = LFXS_LightFadingDown;
2327 								lfxbb->timer = 0;
2328 							}
2329 							break;
2330 						}
2331 
2332 						case LFXS_LightOff:
2333 						{
2334 							if(state==1)
2335 							{
2336 								lfxbb->current_state = LFXS_LightFadingUp;
2337 								lfxbb->timer = 0;
2338 							}
2339 							break;
2340 						}
2341 
2342 						case LFXS_LightFadingUp:
2343 						{
2344 							if(state==0)
2345 							{
2346 								lfxbb->multiplier = lfxbb->timer;
2347 								lfxbb->timer = ONE_FIXED - lfxbb->timer;
2348 								lfxbb->current_state = LFXS_LightFadingDown;
2349 							}
2350 							break;
2351 						}
2352 
2353 						case LFXS_LightFadingDown:
2354 						{
2355 							if(state==1)
2356 							{
2357 								lfxbb->timer = ONE_FIXED - lfxbb->timer;
2358 								lfxbb->current_state = LFXS_LightFadingUp;
2359 							}
2360 							break;
2361 						}
2362 
2363 						default:
2364 						{
2365 							GLOBALASSERT (0 == "Light FX state not supported");
2366 							break;
2367 						}
2368 					}
2369 				}
2370 				else if(lfxbb->type==LFX_RandomFlicker)
2371 				{
2372 					switch (lfxbb->current_state)
2373 					{
2374 						case LFXS_Flicking:
2375 						case LFXS_NotFlicking:
2376 							if(state==0)
2377 							{
2378 								//switch light off
2379 								lfxbb->current_state = LFXS_LightOff;
2380 							}
2381 							break;
2382 
2383 						case LFXS_LightOff :
2384 							if(state==1)
2385 							{
2386 								//switch light on
2387 								lfxbb->current_state = LFXS_Flicking;
2388 							}
2389 							break;
2390 						default: ;
2391 					}
2392 				}
2393 
2394 
2395 				break;
2396 			}
2397 			case I_BehaviourMissionComplete:
2398 				{
2399 					SendRequestToMissionStrategy(sbptr,state,message>>1);
2400 
2401 					break;
2402 				}
2403 			case I_BehaviourMessage:
2404 				{
2405 					SendRequestToMessageStrategy(sbptr,state,message>>1);
2406 
2407 					break;
2408 				}
2409 
2410 			case I_BehaviourTrackObject:
2411 				{
2412 
2413 					TRACK_OBJECT_BEHAV_BLOCK *to_bhv;
2414 					to_bhv = (TRACK_OBJECT_BEHAV_BLOCK*)sbptr->SBdataptr;
2415 					GLOBALASSERT((to_bhv->bhvr_type == I_BehaviourTrackObject));
2416 
2417 					if(state)
2418 					{
2419 						switch(message>>1)
2420 						{
2421 							case 0:
2422 								to_bhv->request = track_request_start;
2423 								break;
2424 							case 1:
2425 								to_bhv->request = track_request_startforward;
2426 								break;
2427 							case 2:
2428 								to_bhv->request = track_request_startbackward;
2429 								break;
2430 						}
2431 					}
2432 					else
2433 						to_bhv->request = track_request_stop;
2434 
2435 					break;
2436 				}
2437 
2438 			case I_BehaviourFan:
2439 				{
2440 
2441 					FAN_BEHAV_BLOCK *f_bhv;
2442 					f_bhv = (FAN_BEHAV_BLOCK*)sbptr->SBdataptr;
2443 					GLOBALASSERT((f_bhv->bhvr_type == I_BehaviourFan));
2444 
2445 					if(state)
2446 						f_bhv->state = fan_state_go;
2447 					else
2448 						f_bhv->state = fan_state_stop;
2449 
2450 					break;
2451 				}
2452 
2453 			case I_BehaviourPlacedSound:
2454 				{
2455 					if(state)
2456 						StartPlacedSoundPlaying(sbptr);
2457 					else
2458 						StopPlacedSoundPlaying(sbptr);
2459 					break;
2460 				}
2461 
2462 			case I_BehaviourInanimateObject:
2463 				{
2464 					SendRequestToInanimateObject(sbptr,state,message>>1);
2465 					break;
2466 				}
2467 
2468 			case I_BehaviourPlacedHierarchy :
2469 				{
2470 					SendRequestToPlacedHierarchy(sbptr,state,message>>1);
2471 				}
2472 				break;
2473 
2474 			case I_BehaviourPlacedLight:
2475 				{
2476 					SendRequestToPlacedLight(sbptr,state,message>>1);
2477 
2478 					break;
2479 				}
2480 			case I_BehaviourAlien:
2481 				{
2482 					ALIEN_STATUS_BLOCK *alienStatusPointer;
2483 					alienStatusPointer = (ALIEN_STATUS_BLOCK*)sbptr->SBdataptr;
2484 
2485 					if (alienStatusPointer->BehaviourState==ABS_Dormant) {
2486 						Alien_Awaken(sbptr);
2487 					}
2488 					break;
2489 				}
2490 			case I_BehaviourFaceHugger:
2491 				{
2492 					FACEHUGGER_STATUS_BLOCK *facehuggerStatusPointer;
2493 
2494 					facehuggerStatusPointer = (FACEHUGGER_STATUS_BLOCK *)(sbptr->SBdataptr);
2495 					LOCALASSERT(facehuggerStatusPointer);
2496 
2497 					if (facehuggerStatusPointer->nearBehaviourState==FHNS_Floating) {
2498 						Wake_Hugger(sbptr);
2499 					}
2500 					break;
2501 				}
2502 			case I_BehaviourXenoborg:
2503 				{
2504 					XENO_STATUS_BLOCK *xenoStatusPointer;
2505 					xenoStatusPointer = (XENO_STATUS_BLOCK*)sbptr->SBdataptr;
2506 
2507 					if (state) {
2508 						if (xenoStatusPointer->behaviourState==XS_Inactive) {
2509 							Xeno_Enter_PowerUp_State(sbptr);
2510 						}
2511 					} else {
2512 						if (xenoStatusPointer->behaviourState!=XS_Inactive) {
2513 							Xeno_Enter_PowerDown_State(sbptr);
2514 						}
2515 					}
2516 					break;
2517 				}
2518 
2519 			case I_BehaviourDormantPredator :
2520 				{
2521 					if(state)
2522 					{
2523 						ActivateDormantPredator(sbptr);
2524 					}
2525 					break;
2526 				}
2527 			case I_BehaviourPredator :
2528 				//do nothing
2529 				//can't assert for this one since it might previously have been a dormant predator
2530 				break;
2531 
2532 			case I_BehaviourMarine :
2533 				{
2534 					SendRequestToMarine(sbptr,state,message>>1);
2535 				}
2536 				break;
2537 
2538 			case I_BehaviourDeathVolume:
2539 				{
2540 
2541 					DEATH_VOLUME_BEHAV_BLOCK *dv_bhv;
2542 					dv_bhv = (DEATH_VOLUME_BEHAV_BLOCK*)sbptr->SBdataptr;
2543 					GLOBALASSERT((dv_bhv->bhvr_type == I_BehaviourDeathVolume));
2544 
2545 					dv_bhv->active=state;
2546 
2547 					break;
2548 				}
2549 			case I_BehaviourSelfDestruct:
2550 				{
2551 
2552 					SELF_DESTRUCT_BEHAV_BLOCK *sd_bhv;
2553 					sd_bhv = (SELF_DESTRUCT_BEHAV_BLOCK*)sbptr->SBdataptr;
2554 					GLOBALASSERT((sd_bhv->bhvr_type == I_BehaviourSelfDestruct));
2555 
2556 					sd_bhv->active=state;
2557 
2558 					break;
2559 				}
2560 			case I_BehaviourParticleGenerator:
2561 				{
2562 					SendRequestToParticleGenerator(sbptr,state,message>>1);
2563 
2564 					break;
2565 				}
2566 			default:
2567 			{
2568 				GLOBALASSERT(2<1);
2569 			}
2570 	  }
2571 }
2572 
2573 
GetState(STRATEGYBLOCK * sbptr)2574 BOOL GetState(STRATEGYBLOCK* sbptr)
2575 {
2576 	GLOBALASSERT(sbptr);
2577 
2578 	switch (sbptr->I_SBtype)
2579 	  {
2580 			case I_BehaviourBinarySwitch:
2581 				{
2582 					// 0 = rest state
2583 					// 1 = unusual state
2584 
2585 					BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
2586 					bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
2587 					GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourBinarySwitch));
2588 
2589 					return((BOOL)bs_bhv->state);
2590 
2591 					break;
2592 				}
2593 			case I_BehaviourLinkSwitch:
2594 				{
2595 					// 0 = rest state
2596 					// 1 = unusual state
2597 
2598 					LINK_SWITCH_BEHAV_BLOCK *bs_bhv;
2599 					bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)sbptr->SBdataptr;
2600 					GLOBALASSERT((bs_bhv->bhvr_type == I_BehaviourLinkSwitch));
2601 
2602 					return((BOOL)bs_bhv->state);
2603 
2604 					break;
2605 				}
2606 			case I_BehaviourProximityDoor:
2607 				{
2608 					PROXDOOR_BEHAV_BLOCK *door_bhv;
2609 					door_bhv = (PROXDOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2610 					GLOBALASSERT((door_bhv->bhvr_type == I_BehaviourProximityDoor));
2611 
2612 					// returns true only when fully open
2613 
2614 					if(door_bhv->door_state == I_door_open)
2615 						return((BOOL)1);
2616 					else
2617 						return((BOOL)0);
2618 
2619 					break;
2620 				}
2621 			case I_BehaviourSwitchDoor:
2622 				{
2623 					/* returns true if fully open (DO NOT CHANGE THIS) */
2624 					SWITCH_DOOR_BEHAV_BLOCK *door_bhv;
2625 					door_bhv = (SWITCH_DOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2626 					GLOBALASSERT(door_bhv->myBehaviourType == I_BehaviourSwitchDoor);
2627 
2628 					if(door_bhv->doorState == I_door_open) return((BOOL)1);
2629 					else return((BOOL)0);
2630 					break;
2631 				}
2632 			case I_BehaviourLiftDoor:
2633 				{
2634 					LIFT_DOOR_BEHAV_BLOCK *door_bhv;
2635 					door_bhv = (LIFT_DOOR_BEHAV_BLOCK*)sbptr->SBdataptr;
2636 					GLOBALASSERT((door_bhv->bhvr_type == I_BehaviourLiftDoor));
2637 
2638 					// returns true only when fully open so that the lift
2639 					// dosn't start to move when we can still see out
2640 
2641 					if(door_bhv->door_state == I_door_closed)
2642 						return((BOOL)0);
2643 					else
2644 						return((BOOL)1);
2645 
2646 					break;
2647 				}
2648 			case I_BehaviourLift:
2649 				{
2650 					LIFT_BEHAV_BLOCK *lift_bhv;
2651 					LIFT_STATION *lift_stn;
2652 			 		GLOBALASSERT(sbptr);
2653 					lift_bhv = (LIFT_BEHAV_BLOCK*)sbptr->SBdataptr;
2654 					GLOBALASSERT((lift_bhv->bhvr_type == I_BehaviourLift));
2655 					lift_stn = &lift_bhv->lift_station;
2656 					GLOBALASSERT(lift_stn);
2657 
2658 					return(lift_stn->called);
2659 
2660 					break;
2661 				}
2662 			default:
2663 				GLOBALASSERT(2<1);
2664 	  }
2665 
2666 	return((BOOL)0);
2667 }
2668 
2669 
2670 
2671 
MakeObject(AVP_BEHAVIOUR_TYPE bhvr,VECTORCH * positionPtr)2672 DISPLAYBLOCK *MakeObject(AVP_BEHAVIOUR_TYPE bhvr, VECTORCH *positionPtr)
2673 {
2674   // This function creates the specified object, fully
2675   // initialized, WITHOUT a modulemapblock into which
2676   // we can collapse it again if required, and a valid
2677   // strategyblock,
2678 
2679 	extern int NumActiveBlocks;
2680 
2681   DISPLAYBLOCK *dptr;
2682   STRATEGYBLOCK *sptr;
2683   MODULEMAPBLOCK *mmbptr;
2684   MODULE m_temp;
2685   //TXACTRLBLK *taPtr;
2686 
2687   if (NumActiveBlocks >= maxobjects) return (DISPLAYBLOCK *)NULL;
2688   if (NumActiveStBlocks >= maxstblocks) return (DISPLAYBLOCK *)NULL;
2689 
2690   // 1. Set up shape data BEFORE making the displayblock,
2691   // since "AllocateModuleObject()" will fill in shapeheader
2692   // information and extent data
2693 
2694   mmbptr = &TempModuleMap;
2695 
2696   switch (bhvr)
2697   {
2698     case I_BehaviourAutoGunMuzzleFlash:
2699 		{
2700 			CreateShapeInstance(mmbptr,"Sntrymuz");
2701 			break;
2702 		}
2703 
2704 		case I_BehaviourRocket:
2705 		{
2706 			CreateShapeInstance(mmbptr,"missile");
2707 		    break;
2708 		}
2709 
2710 		case I_BehaviourFrisbee:
2711 		case I_BehaviourNPCPredatorDisc:
2712 		case I_BehaviourPredatorDisc_SeekTrack:
2713 		{
2714 			//CreateShapeInstance(mmbptr,"disk@hnpcpredator");
2715 			CreateShapeInstance(mmbptr,"Shell");
2716 		    break;
2717 		}
2718 
2719 		case I_BehaviourPulseGrenade: /* need a new shape */
2720 		case I_BehaviourGrenade:
2721 		{
2722 			CreateShapeInstance(mmbptr,"Shell");
2723 			break;
2724 		}
2725 		case I_BehaviourFragmentationGrenade:
2726 		{
2727 			CreateShapeInstance(mmbptr,"Frag");
2728 			break;
2729 		}
2730 		case I_BehaviourClusterGrenade:
2731 		{
2732 			CreateShapeInstance(mmbptr,"Cluster");
2733 			break;
2734 		}
2735 		case I_BehaviourProximityGrenade:
2736 		{
2737 			CreateShapeInstance(mmbptr,"Proxmine");
2738 			break;
2739 		}
2740 
2741 
2742 		case I_BehaviourFlareGrenade:
2743 		{
2744 			CreateShapeInstance(mmbptr,"Flare");
2745 			break;
2746 		}
2747 
2748 		case I_BehaviourSpeargunBolt:
2749 		{
2750 			CreateShapeInstance(mmbptr,"spear");
2751 			break;
2752 		}
2753 		case I_BehaviourPPPlasmaBolt:
2754 		case I_BehaviourFrisbeeEnergyBolt:
2755 		case I_BehaviourPredatorEnergyBolt:
2756 		case I_BehaviourXenoborgEnergyBolt:
2757 		{
2758 			//uses special effect instead of a shape
2759     		mmbptr->MapShape = 0;
2760 			mmbptr->MapType = MapType_Default;
2761 //			CreateShapeInstance(mmbptr,"Plasbolt");
2762 			CreateShapeInstance(mmbptr,"Shell");
2763 
2764 			break;
2765 		}
2766 		case I_BehaviourAlienSpit:
2767 		{
2768 			CreateShapeInstance(mmbptr,"Spit");
2769 			break;
2770 		}
2771 
2772     case I_BehaviourTest:
2773     default:
2774 		{
2775       // Don't call this function for undefined types
2776       GLOBALASSERT (1 == 0);
2777 			break;
2778     }
2779 	}
2780 
2781   // And allocate the modulemapblock object
2782 
2783 	m_temp.m_numlights = 0;
2784 	m_temp.m_lightarray = NULL;
2785   m_temp.m_mapptr = mmbptr;
2786   m_temp.m_sbptr = (STRATEGYBLOCK*)NULL;
2787   AllocateModuleObject(&m_temp);
2788 
2789   dptr = m_temp.m_dptr;
2790 
2791 	if (dptr == 0) return(DISPLAYBLOCK*)NULL;
2792 
2793   dptr->ObMyModule = NULL;     /* Module that created us */
2794 	dptr->ObWorld = *positionPtr;
2795 
2796  	sptr = AttachNewStratBlock((MODULE*)NULL, mmbptr, dptr);
2797 
2798   if (sptr == 0) return(DISPLAYBLOCK*)NULL;
2799 
2800   // 2. NOW set up the strategyblock-specific fields for
2801   // the new displayblock. We won't go through the "AttachNew
2802   // StrategyBlock" and "AssignRunTimeBehaviours" pair, since
2803   // the first switches on ObShape and the second on bhvr;
2804   // but, in this case, there isn't a particular connection
2805   // between them.
2806 
2807   sptr->I_SBtype = bhvr;
2808 
2809   switch (bhvr)
2810   {
2811     case I_BehaviourAutoGunMuzzleFlash:
2812     // but soon it will be an animated sequence
2813 		{
2814 			sptr->SBdataptr = (ONE_SHOT_BEHAV_BLOCK *) AllocateMem(sizeof(ONE_SHOT_BEHAV_BLOCK ));
2815 
2816    		if (sptr->SBdataptr == 0)
2817 			{
2818 				// Failed to allocate a strategy block data pointer
2819 				RemoveBehaviourStrategy(sptr);
2820 				return (DISPLAYBLOCK*)NULL;
2821 			}
2822 
2823 			((ONE_SHOT_BEHAV_BLOCK * ) sptr->SBdataptr)->counter = ONE_FIXED/10;
2824 
2825 			/* KJL 17:23:22 11/26/96 - here's a little something to give a random orientation */
2826 			{
2827 				EULER orientation;
2828 				orientation.EulerX = 0;
2829 				orientation.EulerY = 0;
2830 				orientation.EulerZ = FastRandom()&4095;
2831 
2832 				CreateEulerMatrix(&orientation, &dptr->ObMat);
2833 				TransposeMatrixCH(&dptr->ObMat);
2834 			}
2835 
2836 			AddLightingEffectToObject(dptr,LFX_MUZZLEFLASH);
2837 
2838 			break;
2839 		}
2840 
2841 
2842 		case I_BehaviourFrisbee:
2843 		case I_BehaviourRocket:
2844 		case I_BehaviourPulseGrenade:
2845 		case I_BehaviourGrenade:
2846 		case I_BehaviourFlareGrenade:
2847 		case I_BehaviourFragmentationGrenade:
2848 		case I_BehaviourClusterGrenade:
2849 		case I_BehaviourProximityGrenade:
2850 		case I_BehaviourSpeargunBolt:
2851 		case I_BehaviourPPPlasmaBolt:
2852 		case I_BehaviourFrisbeeEnergyBolt:
2853 		case I_BehaviourPredatorEnergyBolt:
2854 		case I_BehaviourXenoborgEnergyBolt:
2855 		case I_BehaviourAlienSpit:
2856 		case I_BehaviourNPCPredatorDisc:
2857 		case I_BehaviourPredatorDisc_SeekTrack:
2858 		{
2859 		  AssignNewSBName(sptr);
2860 		  break;
2861 		}
2862 
2863     case I_BehaviourTest:
2864       break;
2865 
2866     default:
2867 
2868       // Don't call this function for undefined
2869       // types
2870 
2871       GLOBALASSERT (1 == 0);
2872 			break;
2873   }
2874   return dptr;
2875 }
2876 
2877 
2878 // this is seperate so that it can be called during env changes
RemoveBehaviourStrategy(STRATEGYBLOCK * sbptr)2879 void RemoveBehaviourStrategy(STRATEGYBLOCK* sbptr)
2880 {
2881 	GLOBALASSERT(sbptr);
2882 
2883 	/* Andy 16/8/97  - Updated to cope with partially allocated strategy blocks
2884 										 We need to check that each allocation has been completed before
2885 										  trying to deallocate */
2886 
2887 	/* CDF 12/11/96 - Destroys ANY strategyblock. *
2888 	* Please maintain...                         */
2889 
2890 	// this is to check for the sb destroy flag
2891 	// only destroy sbs if DoNotRemoveSB = 0
2892 	// and the destroy flag is set
2893 
2894 	// first check to see if we need the SB in the next env
2895 	// if we do we need to preserve the contents
2896 
2897 	if(SBNeededForNextEnv(sbptr))
2898 	{
2899 		//we take a copy and preserve everything except our
2900 		//ActiveStBlockList copy
2901 
2902 		DestroyActiveStrategyBlock(sbptr);
2903 		return;
2904 	}
2905 
2906 	// this notifies the game flow system that an object has been destroyed
2907 
2908 
2909 	switch(sbptr->I_SBtype)
2910 	{
2911 		case I_BehaviourProximityDoor:
2912 		{
2913 			{
2914 				/* patrick 7/7/97: remove sound handle, if we have one*/
2915 				PROXDOOR_BEHAV_BLOCK *doorbhv = (PROXDOOR_BEHAV_BLOCK *)(sbptr->SBdataptr);
2916 				if(doorbhv && doorbhv->SoundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(doorbhv->SoundHandle);
2917 			}
2918 			// 	Deallocater for the doors hack
2919 			if (sbptr->SBmorphctrl &&
2920 					sbptr->SBmorphctrl->ObMorphHeader &&
2921 					sbptr->SBmorphctrl->ObMorphHeader->mph_frames)
2922 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader->mph_frames);
2923 
2924 			if (sbptr->SBmorphctrl &&
2925 					sbptr->SBmorphctrl->ObMorphHeader)
2926 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader);
2927 
2928 			if (sbptr->SBmorphctrl)
2929 				DeallocateMem( sbptr->SBmorphctrl);
2930 
2931 			break;
2932 		}
2933 		case I_BehaviourLiftDoor:
2934 		{
2935 			// 	Deallocater for the doors hack
2936 			{
2937 				/* patrick 7/7/97: remove sound handle, if we have one*/
2938 				LIFT_DOOR_BEHAV_BLOCK *doorbhv = (LIFT_DOOR_BEHAV_BLOCK *)(sbptr->SBdataptr);
2939 				if(doorbhv && doorbhv->SoundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(doorbhv->SoundHandle);
2940 			}
2941 
2942 			if (sbptr->SBmorphctrl &&
2943 					sbptr->SBmorphctrl->ObMorphHeader &&
2944 					sbptr->SBmorphctrl->ObMorphHeader->mph_frames)
2945 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader->mph_frames);
2946 
2947 			if (sbptr->SBmorphctrl &&
2948 					sbptr->SBmorphctrl->ObMorphHeader)
2949 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader);
2950 
2951 			if (sbptr->SBmorphctrl)
2952 				DeallocateMem( sbptr->SBmorphctrl);
2953 
2954 			break;
2955 		}
2956 		case I_BehaviourSwitchDoor:
2957 		{
2958 			{
2959 				/* patrick 7/7/97: remove sound handle, if we have one*/
2960 				SWITCH_DOOR_BEHAV_BLOCK *doorbhv = (SWITCH_DOOR_BEHAV_BLOCK *)(sbptr->SBdataptr);
2961 				if(doorbhv && doorbhv->SoundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(doorbhv->SoundHandle);
2962 			}
2963 
2964 			if (sbptr->SBmorphctrl &&
2965 					sbptr->SBmorphctrl->ObMorphHeader &&
2966 					sbptr->SBmorphctrl->ObMorphHeader->mph_frames)
2967 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader->mph_frames);
2968 
2969 			if (sbptr->SBmorphctrl &&
2970 					sbptr->SBmorphctrl->ObMorphHeader)
2971 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader);
2972 
2973 			if (sbptr->SBmorphctrl)
2974 				DeallocateMem( sbptr->SBmorphctrl);
2975 
2976 			break;
2977 		}
2978 		case I_BehaviourSimpleAnimation:
2979 		{
2980 
2981 			SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv;
2982 			TXACTRLBLK *txactrl;
2983 			TXACTRLBLK *txactrl_next;
2984 
2985 			sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->SBdataptr);
2986 			if (sanimbhv)
2987 			{
2988 				GLOBALASSERT(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation);
2989 
2990 				txactrl_next = sanimbhv->tacbSimple;
2991 				while(txactrl_next)
2992 				{
2993 					txactrl = txactrl_next;
2994 					txactrl_next = txactrl->tac_next;
2995 					DeallocateMem((void*)txactrl);
2996 				}
2997 			}
2998 			break;
2999 		}
3000 		case I_BehaviourBinarySwitch:
3001 		{
3002 			BINARY_SWITCH_BEHAV_BLOCK *bs_bhv;
3003 			TXACTRLBLK *txactrl;
3004 			TXACTRLBLK *txactrl_next;
3005 
3006    		bs_bhv = (BINARY_SWITCH_BEHAV_BLOCK*)(sbptr->SBdataptr);
3007 			if (bs_bhv)
3008 			{
3009 				GLOBALASSERT(bs_bhv->bhvr_type == I_BehaviourBinarySwitch);
3010 
3011 			 	/* Andy 20/8/97: remove sound handle, if we have one*/
3012 			 	if(bs_bhv->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(bs_bhv->soundHandle);
3013 
3014 				if(bs_bhv->bs_track)
3015 				{
3016 					Reset_Track(bs_bhv->bs_track);
3017 				}
3018 
3019 				txactrl_next = bs_bhv->bs_tac;
3020 				while(txactrl_next)
3021 				{
3022 					txactrl = txactrl_next;
3023 					txactrl_next = txactrl->tac_next;
3024 					DeallocateMem((void*)txactrl);
3025 				}
3026 				if (bs_bhv->target_names) DeallocateMem ((void *)bs_bhv->target_names);
3027 				if (bs_bhv->bs_targets) DeallocateMem ((void *)bs_bhv->bs_targets);
3028 				if (bs_bhv->request_messages) DeallocateMem ((void *)bs_bhv->request_messages);
3029 
3030 			}
3031 			break;
3032 	 	}
3033 		case I_BehaviourLinkSwitch:
3034 		{
3035 			LINK_SWITCH_BEHAV_BLOCK *bs_bhv;
3036 			TXACTRLBLK *txactrl;
3037 			TXACTRLBLK *txactrl_next;
3038 
3039    			bs_bhv = (LINK_SWITCH_BEHAV_BLOCK*)(sbptr->SBdataptr);
3040 			if (bs_bhv)
3041 			{
3042 				GLOBALASSERT(bs_bhv->bhvr_type == I_BehaviourLinkSwitch);
3043 
3044 			 	/* Andy 20/8/97: remove sound handle, if we have one*/
3045 			 	if(bs_bhv->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(bs_bhv->soundHandle);
3046 
3047 				if(bs_bhv->ls_track)
3048 				{
3049 					Reset_Track(bs_bhv->ls_track);
3050 				}
3051 
3052 
3053 				txactrl_next = bs_bhv->ls_tac;
3054 				while(txactrl_next)
3055 				{
3056 					txactrl = txactrl_next;
3057 					txactrl_next = txactrl->tac_next;
3058 					DeallocateMem((void*)txactrl);
3059 				}
3060 
3061 
3062 				if (bs_bhv->ls_targets) DeallocateMem ((void *)bs_bhv->ls_targets);
3063 				if (bs_bhv->lswitch_list) DeallocateMem ((void *)bs_bhv->lswitch_list);
3064 			}
3065 			break;
3066 		}
3067 		case I_BehaviourLift:
3068 		{
3069 			LIFT_BEHAV_BLOCK *lift_bhv;
3070    		lift_bhv = (LIFT_BEHAV_BLOCK*)(sbptr->SBdataptr);
3071 
3072 			if (lift_bhv)
3073 			{
3074 				GLOBALASSERT(lift_bhv->bhvr_type == I_BehaviourLift);
3075 
3076 				/* patrick 7/7//97*/
3077 				if(lift_bhv->lift_control)
3078 				{
3079 					if(lift_bhv->lift_control->SoundHandle!=SOUND_NOACTIVEINDEX)
3080 					Sound_Stop(lift_bhv->lift_control->SoundHandle);
3081 				}
3082 
3083 				if(lift_bhv->controller)
3084 				{
3085 					if (lift_bhv->lift_control && lift_bhv->lift_control->lift_stations)
3086 						DeallocateMem(lift_bhv->lift_control->lift_stations);
3087 					if (lift_bhv->lift_control)
3088 						DeallocateMem(lift_bhv->lift_control);
3089 				}
3090 			}
3091 			break;
3092 		}
3093 		case I_BehaviourAutoGun:
3094 		{
3095 			AUTOGUN_STATUS_BLOCK *ag_bhv;
3096 
3097  			ag_bhv = (AUTOGUN_STATUS_BLOCK*)(sbptr->SBdataptr);
3098 			if (ag_bhv)
3099 			{
3100 				/* patrick 7/7/97*/
3101 				if(ag_bhv->soundHandle!=SOUND_NOACTIVEINDEX)
3102 				{
3103 					Sound_Stop(ag_bhv->soundHandle);
3104 				}
3105 				Dispel_HModel(&ag_bhv->HModelController);
3106 
3107 			}
3108 			break;
3109 		}
3110 		case I_BehaviourAlien:
3111 			{
3112 				ALIEN_STATUS_BLOCK *asb;
3113 				asb=(ALIEN_STATUS_BLOCK *)(sbptr->SBdataptr);
3114 				Dispel_HModel(&asb->HModelController);
3115 			}
3116 			break;
3117 		case I_BehaviourGenerator:
3118 		{
3119 			break;
3120 		}
3121 
3122 		case I_BehaviourMarine:
3123 		case I_BehaviourSeal:
3124 		{
3125 			MARINE_STATUS_BLOCK *marineStatusPointer;
3126 			marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbptr->SBdataptr);
3127 			if(marineStatusPointer)
3128 			{
3129 				Dispel_HModel(&marineStatusPointer->HModelController);
3130 
3131 				if(marineStatusPointer->myGunFlash) DestroyActiveObject(marineStatusPointer->myGunFlash);
3132 				if(marineStatusPointer->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(marineStatusPointer->soundHandle);
3133 			}
3134 			break;
3135 		}
3136 		case I_BehaviourDummy:
3137 		{
3138 			DUMMY_STATUS_BLOCK *dummyStatusPointer;
3139 			dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbptr->SBdataptr);
3140 			if(dummyStatusPointer)
3141 			{
3142 				Dispel_HModel(&dummyStatusPointer->HModelController);
3143 			}
3144 			break;
3145 		}
3146 		case I_BehaviourPredatorDisc_SeekTrack:
3147 		{
3148 		  	PC_PRED_DISC_BEHAV_BLOCK *bblk;
3149 			bblk = (PC_PRED_DISC_BEHAV_BLOCK *)(sbptr->SBdataptr);
3150 			if(bblk)
3151 			{
3152 				if (bblk->soundHandle!=SOUND_NOACTIVEINDEX) {
3153 					Sound_Stop(bblk->soundHandle);
3154 				}
3155 
3156 				Dispel_HModel(&bblk->HModelController);
3157 
3158 			}
3159 			break;
3160 		}
3161 		case I_BehaviourPredatorEnergyBolt:
3162 		case I_BehaviourFrisbeeEnergyBolt:
3163 		{
3164 		  	CASTER_BOLT_BEHAV_BLOCK *bblk;
3165 			bblk = (CASTER_BOLT_BEHAV_BLOCK *)(sbptr->SBdataptr);
3166 			if(bblk)
3167 			{
3168 				if (bblk->soundHandle!=SOUND_NOACTIVEINDEX) {
3169 					Sound_Stop(bblk->soundHandle);
3170 				}
3171 			}
3172 			break;
3173 		}
3174 		case I_BehaviourFrisbee:
3175 		{
3176 		  	FRISBEE_BEHAV_BLOCK *fblk;
3177 			fblk = (FRISBEE_BEHAV_BLOCK *)(sbptr->SBdataptr);
3178 			if(fblk)
3179 			{
3180 				if (fblk->soundHandle!=SOUND_NOACTIVEINDEX) {
3181 					Sound_Stop(fblk->soundHandle);
3182 				}
3183 
3184 				Dispel_HModel(&fblk->HModelController);
3185 
3186 			}
3187 			break;
3188 		}
3189 
3190 		case I_BehaviourFaceHugger:
3191 		{
3192 			FACEHUGGER_STATUS_BLOCK *fhugStatusPointer;
3193 			fhugStatusPointer = (FACEHUGGER_STATUS_BLOCK *)(sbptr->SBdataptr);
3194 			if(fhugStatusPointer)
3195 			{
3196 				if(fhugStatusPointer->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(fhugStatusPointer->soundHandle);
3197 			}
3198 			Dispel_HModel(&fhugStatusPointer->HModelController);
3199 			break;
3200 		}
3201 
3202 		case I_BehaviourXenoborg:
3203 		{
3204 			/* need to get rid of the animations...*/
3205 			XENO_STATUS_BLOCK *xenoStatus;
3206 
3207 			xenoStatus = (XENO_STATUS_BLOCK*)(sbptr->SBdataptr);
3208 			if(xenoStatus)
3209 			{
3210 				Dispel_HModel(&xenoStatus->HModelController);
3211 				/* Zounds! */
3212 				if(xenoStatus->soundHandle1!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->soundHandle1);
3213 				if(xenoStatus->soundHandle2!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->soundHandle2);
3214 				if(xenoStatus->head_whirr!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->head_whirr);
3215 				if(xenoStatus->left_arm_whirr!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->left_arm_whirr);
3216 				if(xenoStatus->right_arm_whirr!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->right_arm_whirr);
3217 				if(xenoStatus->torso_whirr!=SOUND_NOACTIVEINDEX) Sound_Stop(xenoStatus->torso_whirr);
3218 
3219 			}
3220 			break;
3221 		}
3222 		case I_BehaviourPredator:
3223 		{
3224 			PREDATOR_STATUS_BLOCK *predatorStatusPointer;
3225 			predatorStatusPointer = (PREDATOR_STATUS_BLOCK *)(sbptr->SBdataptr);
3226 			if(predatorStatusPointer)
3227 			{
3228 				Dispel_HModel(&predatorStatusPointer->HModelController);
3229 
3230 				if(predatorStatusPointer->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(predatorStatusPointer->soundHandle);
3231 			}
3232 			break;
3233 		}
3234 		case I_BehaviourQueenAlien:
3235 		{
3236 			QUEEN_STATUS_BLOCK *queenStatusPointer;
3237 			queenStatusPointer = (QUEEN_STATUS_BLOCK *)(sbptr->SBdataptr);
3238 			if(queenStatusPointer)
3239 			{
3240 				Dispel_HModel(&queenStatusPointer->HModelController);
3241 			}
3242 			//stop any sound the queen is making
3243 			if(queenStatusPointer->soundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(queenStatusPointer->soundHandle);
3244 
3245 			break;
3246 		}
3247 		case I_BehaviourNetGhost:
3248 		{
3249 			{
3250 				NETGHOSTDATABLOCK *ghostData;
3251 				ghostData = (NETGHOSTDATABLOCK *)(sbptr->SBdataptr);
3252 				if(ghostData)
3253 				{
3254 					if(ghostData->myGunFlash) DestroyActiveObject(ghostData->myGunFlash);
3255 					if(ghostData->SoundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle);
3256 					if(ghostData->SoundHandle2!=SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle2);
3257 					if(ghostData->SoundHandle3!=SOUND_NOACTIVEINDEX) Sound_Stop(ghostData->SoundHandle3);
3258 					Dispel_HModel(&ghostData->HModelController);
3259 				}
3260 			}
3261 			break;
3262 		}
3263 
3264 		case I_BehaviourXenoborgMorphRoom:
3265 		{
3266 			XENO_MORPH_ROOM_DATA * xmrd = (XENO_MORPH_ROOM_DATA *)sbptr->SBdataptr;
3267 
3268 			if (sbptr->SBmorphctrl &&
3269 					sbptr->SBmorphctrl->ObMorphHeader &&
3270 					sbptr->SBmorphctrl->ObMorphHeader->mph_frames)
3271 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader->mph_frames);
3272 
3273 			if (sbptr->SBmorphctrl &&
3274 					sbptr->SBmorphctrl->ObMorphHeader)
3275 				DeallocateMem( sbptr->SBmorphctrl->ObMorphHeader);
3276 
3277 			if (sbptr->SBmorphctrl)
3278 				DeallocateMem( sbptr->SBmorphctrl);
3279 
3280 			if (xmrd)
3281 			{
3282 				if (xmrd->tacb)
3283 				{
3284 					TXACTRLBLK *txactrl;
3285 					TXACTRLBLK *txactrl_next;
3286 
3287 					txactrl_next = xmrd->tacb;
3288 
3289 					while(txactrl_next)
3290 					{
3291 						txactrl = txactrl_next;
3292 						txactrl_next = txactrl->tac_next;
3293 						DeallocateMem((void*)txactrl);
3294 					}
3295 				}
3296 			}
3297 			break;
3298 		}
3299 		case I_BehaviourInanimateObject :
3300 		{
3301 			INANIMATEOBJECT_STATUSBLOCK* objectstatusptr=(INANIMATEOBJECT_STATUSBLOCK*)sbptr->SBdataptr;
3302 			TXACTRLBLK *txactrl;
3303 			TXACTRLBLK *txactrl_next;
3304 
3305 
3306 			if (objectstatusptr)
3307 			{
3308 				if(objectstatusptr->event_target)
3309 				{
3310 					DeallocateMem(objectstatusptr->event_target);
3311 				}
3312 
3313 				if(!objectstatusptr->inan_tac) break;
3314 				txactrl_next = objectstatusptr->inan_tac;
3315 
3316 				while(txactrl_next)
3317 				{
3318 					txactrl = txactrl_next;
3319 					txactrl_next = txactrl->tac_next;
3320 					DeallocateMem((void*)txactrl);
3321 				}
3322 			}
3323 			break;
3324 		}
3325 		case I_BehaviourVideoScreen :
3326 		{
3327 			VIDEO_SCREEN_BEHAV_BLOCK* videoScreen=(VIDEO_SCREEN_BEHAV_BLOCK*)sbptr->SBdataptr;
3328 			TXACTRLBLK *txactrl;
3329 			TXACTRLBLK *txactrl_next;
3330 
3331 
3332 			if (videoScreen)
3333 			{
3334 
3335 				if(!videoScreen->inan_tac) break;
3336 				txactrl_next = videoScreen->inan_tac;
3337 
3338 				while(txactrl_next)
3339 				{
3340 					txactrl = txactrl_next;
3341 					txactrl_next = txactrl->tac_next;
3342 					DeallocateMem((void*)txactrl);
3343 				}
3344 			}
3345 			break;
3346 		}
3347 
3348 		case I_BehaviourPlacedLight :
3349 		{
3350 			PLACED_LIGHT_BEHAV_BLOCK* pl_bhv=(PLACED_LIGHT_BEHAV_BLOCK*)sbptr->SBdataptr;
3351 			TXACTRLBLK *txactrl;
3352 			TXACTRLBLK *txactrl_next;
3353 
3354 			if (pl_bhv)
3355 			{
3356 				if(sbptr->SBdptr)
3357 				{
3358 					//set num lights to zero so it doesn't attempt to deallocate the light
3359 					sbptr->SBdptr->ObNumLights=0;
3360 				}
3361 				//reset vaules in lightblock
3362 				pl_bhv->light->LightBright=pl_bhv->light->LightBrightStore;
3363 				pl_bhv->light->RedScale=pl_bhv->colour_red;
3364 				pl_bhv->light->GreenScale=pl_bhv->colour_green;
3365 				pl_bhv->light->BlueScale=pl_bhv->colour_blue;
3366 
3367 				if(!pl_bhv->inan_tac) break;
3368 				txactrl_next = pl_bhv->inan_tac;
3369 
3370 				while(txactrl_next)
3371 				{
3372 					txactrl = txactrl_next;
3373 					txactrl_next = txactrl->tac_next;
3374 					DeallocateMem((void*)txactrl);
3375 				}
3376 			}
3377 			break;
3378 		}
3379 		case I_BehaviourHierarchicalFragment:
3380 			{
3381 				HDEBRIS_BEHAV_BLOCK *hdbblk=(HDEBRIS_BEHAV_BLOCK *)sbptr->SBdataptr;
3382 
3383 				Dispel_HModel(&hdbblk->HModelController);
3384 			}
3385 			break;
3386 
3387 		case I_BehaviourPlacedSound:
3388 		{
3389 			SoundBehaveDestroy (sbptr);
3390 			break;
3391 		}
3392 
3393 		case I_BehaviourMissionComplete:
3394 		{
3395 			MISSION_COMPLETE_BEHAV_BLOCK *mc_bhv;
3396 			mc_bhv = (MISSION_COMPLETE_BEHAV_BLOCK*)sbptr->SBdataptr;
3397 			if(mc_bhv)
3398 			{
3399 				GLOBALASSERT((mc_bhv->bhvr_type == I_BehaviourMissionComplete));
3400 				ResetMission(mc_bhv->mission_objective_ptr);
3401 
3402 			}
3403 			break;
3404 		}
3405 
3406 		case I_BehaviourTrackObject:
3407 		{
3408 			TRACK_OBJECT_BEHAV_BLOCK *to_bhv;
3409 			TXACTRLBLK *txactrl;
3410 			TXACTRLBLK *txactrl_next;
3411 
3412    			to_bhv = (TRACK_OBJECT_BEHAV_BLOCK*)(sbptr->SBdataptr);
3413 			if (to_bhv)
3414 			{
3415 				GLOBALASSERT(to_bhv->bhvr_type == I_BehaviourTrackObject);
3416 
3417 				if(to_bhv->to_track)
3418 				{
3419 					Reset_Track(to_bhv->to_track);
3420 				}
3421 
3422 				txactrl_next = to_bhv->to_tac;
3423 				while(txactrl_next)
3424 				{
3425 					txactrl = txactrl_next;
3426 					txactrl_next = txactrl->tac_next;
3427 					DeallocateMem((void*)txactrl);
3428 				}
3429 			}
3430 			break;
3431 		case I_BehaviourPlacedHierarchy:
3432 		{
3433 			PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv;
3434 
3435    			ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)(sbptr->SBdataptr);
3436 			if (ph_bhv)
3437 			{
3438 				GLOBALASSERT(ph_bhv->bhvr_type == I_BehaviourPlacedHierarchy);
3439 				DeletePlacedHierarchy(ph_bhv);
3440 			}
3441 			break;
3442 		}
3443 		case I_BehaviourNetCorpse:
3444 		{
3445 			{
3446 				NETCORPSEDATABLOCK *corpseData;
3447 				corpseData = (NETCORPSEDATABLOCK *)(sbptr->SBdataptr);
3448 				if(corpseData)
3449 				{
3450 					if(corpseData->SoundHandle!=SOUND_NOACTIVEINDEX) Sound_Stop(corpseData->SoundHandle);
3451 					Dispel_HModel(&corpseData->HModelController);
3452 				}
3453 			}
3454 			break;
3455 		}
3456 
3457 		case I_BehaviourLightFX :
3458 		{
3459 			LIGHT_FX_BEHAV_BLOCK * lfxbb;
3460 			TXACTRLBLK *txactrl;
3461 			TXACTRLBLK *txactrl_next;
3462 
3463 			lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbptr->SBdataptr;
3464 			if(lfxbb)
3465 			{
3466 				txactrl_next = lfxbb->anim_control;
3467 				while(txactrl_next)
3468 				{
3469 					txactrl = txactrl_next;
3470 					txactrl_next = txactrl->tac_next;
3471 					DeallocateMem((void*)txactrl);
3472 				}
3473 			}
3474 			break;
3475 
3476 		}
3477 
3478 		case I_BehaviourFan :
3479 		{
3480 			FAN_BEHAV_BLOCK* f_bhv=(FAN_BEHAV_BLOCK*)sbptr->SBdataptr;
3481 			if(f_bhv->track)
3482 			{
3483 				Reset_Track(f_bhv->track);
3484 			}
3485 			break;
3486 
3487 
3488 		}
3489 		case I_BehaviourSpeargunBolt:
3490 		{
3491 			SPEAR_BEHAV_BLOCK *sbblk=(SPEAR_BEHAV_BLOCK *)sbptr->SBdataptr;
3492 
3493 			if (sbblk->SpearThroughFragment) {
3494 				/* There's a hierarchy to dispel. */
3495 				Dispel_HModel(&sbblk->HierarchicalFragment);
3496 			}
3497 			break;
3498 		}
3499 		case I_BehaviourPlatform :
3500 		{
3501 			PLATFORMLIFT_BEHAVIOUR_BLOCK* pl_bhv=(PLATFORMLIFT_BEHAVIOUR_BLOCK*)sbptr->SBdataptr;
3502 			if(pl_bhv->sound)
3503 			{
3504 				Stop_Track_Sound(pl_bhv->sound);
3505 			}
3506 			if(pl_bhv->start_sound)
3507 			{
3508 				Stop_Track_Sound(pl_bhv->start_sound);
3509 			}
3510 			if(pl_bhv->end_sound)
3511 			{
3512 				Stop_Track_Sound(pl_bhv->end_sound);
3513 			}
3514 			break;
3515 		}
3516 		case I_BehaviourParticleGenerator :
3517 		{
3518 			PARTICLE_GENERATOR_BEHAV_BLOCK* pargen=(PARTICLE_GENERATOR_BEHAV_BLOCK*)sbptr->SBdataptr;
3519 			if(pargen->sound)
3520 			{
3521 				Stop_Track_Sound(pargen->sound);
3522 			}
3523 			break;
3524 		}
3525 
3526 	 	}
3527 		default:
3528 		{
3529 			break;
3530 		}
3531 	}
3532 
3533 
3534 	/* destroy the behaviour block BUT not if I am the player	*/
3535 
3536 	if((sbptr->I_SBtype != I_BehaviourMarinePlayer)&&(sbptr->I_SBtype != I_BehaviourAlienPlayer)&&(sbptr->I_SBtype != I_BehaviourPredatorPlayer))
3537 	{
3538 		/* patrick: 23/7/97 I am adding a test for SBdataptr before deallocating it- */
3539 		if(sbptr->SBdataptr)
3540 		{
3541 			DeallocateMem(sbptr->SBdataptr);
3542 			#if debug
3543 			//I dont do a full initialisation with debug because
3544 			//we dont want to hide switch on Behaviour type bugs
3545 			// I just do this to trap the bastard
3546 			sbptr->SBdataptr = NULL;
3547 			#endif
3548 		}
3549 	}
3550 
3551 	/* remove DYNBLOCK and DisplayBlock*/
3552 	if (sbptr->SBdptr)
3553 	{
3554 		DestroyActiveObject(sbptr->SBdptr);
3555 	}
3556 	if (sbptr->DynPtr)
3557 	{
3558 		DeallocateDynamicsBlock(sbptr->DynPtr);
3559 	}
3560 
3561 	#if !debug
3562 	// ull SB init
3563 	if(!sbptr->SBflags.preserve_until_end_of_level)
3564 	{
3565 		InitialiseSBValues(sbptr);
3566 	}
3567 	#endif
3568 	/* Finally remove the StrategyBlock*/
3569 	DestroyActiveStrategyBlock(sbptr);
3570 }
3571 
3572 
3573 
3574 
3575 /*--------------------**
3576 ** Loading and Saving **
3577 **--------------------*/
3578 typedef struct prox_door_save_block
3579 {
3580 	SAVE_BLOCK_STRATEGY_HEADER header;
3581 
3582 	int door_state;
3583 	BOOL door_locked;
3584 
3585 	//from the morph control
3586 	int ObMorphCurrFrame;
3587 	int ObMorphFlags;
3588 	int ObMorphSpeed;
3589 
3590 	BOOL triggeredByMarine;
3591 
3592 }PROX_DOOR_SAVE_BLOCK;
3593 
LoadStrategy_ProxDoor(SAVE_BLOCK_STRATEGY_HEADER * header)3594 void LoadStrategy_ProxDoor(SAVE_BLOCK_STRATEGY_HEADER* header)
3595 {
3596 	STRATEGYBLOCK* sbPtr;
3597 	PROXDOOR_BEHAV_BLOCK *doorbhv;
3598 	PROX_DOOR_SAVE_BLOCK* block = (PROX_DOOR_SAVE_BLOCK*) header;
3599 
3600 	if(header->size!=sizeof(*block)) return;
3601 
3602 	//find the existing strategy block
3603 	sbPtr = FindSBWithName(block->header.SBname);
3604 	if(!sbPtr) return;
3605 
3606 	//make sure the strategy found is of the right type
3607 	if(sbPtr->I_SBtype != I_BehaviourProximityDoor) return;
3608 
3609 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbPtr->SBdataptr;
3610 
3611 	doorbhv->door_state = block->door_state;
3612 	doorbhv->door_locked = block->door_locked;
3613 	doorbhv->triggeredByMarine = block->triggeredByMarine;
3614 	doorbhv->PDmctrl->ObMorphCurrFrame = block->ObMorphCurrFrame;
3615 	doorbhv->PDmctrl->ObMorphFlags = block->ObMorphFlags;
3616 	doorbhv->PDmctrl->ObMorphSpeed = block->ObMorphSpeed;
3617 
3618 
3619 	Load_SoundState(&doorbhv->SoundHandle);
3620 
3621 }
3622 
SaveStrategy_ProxDoor(STRATEGYBLOCK * sbPtr)3623 void SaveStrategy_ProxDoor(STRATEGYBLOCK* sbPtr)
3624 {
3625 	PROX_DOOR_SAVE_BLOCK *block;
3626 	PROXDOOR_BEHAV_BLOCK *doorbhv ;
3627 	doorbhv = (PROXDOOR_BEHAV_BLOCK*)sbPtr->SBdataptr;
3628 
3629 	GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
3630 
3631 
3632 	block->door_state = doorbhv->door_state;
3633 	block->door_locked = doorbhv->door_locked;
3634 	block->triggeredByMarine = doorbhv->triggeredByMarine;
3635 	block->ObMorphCurrFrame = doorbhv->PDmctrl->ObMorphCurrFrame;
3636 	block->ObMorphFlags = doorbhv->PDmctrl->ObMorphFlags;
3637 	block->ObMorphSpeed = doorbhv->PDmctrl->ObMorphSpeed;
3638 
3639 	Save_SoundState(&doorbhv->SoundHandle);
3640 }
3641 
3642 
3643 /*---------------------------**
3644 ** End of loading and saving **
3645 **---------------------------*/
3646