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§ion_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