1 #include "3dc.h"
2 #include "inline.h"
3 #include "module.h"
4 
5 #include "stratdef.h"
6 #include "gamedef.h"
7 #include "bh_types.h"
8 
9 #include "dynblock.h"
10 
11 #define UseLocalAssert Yes
12 #include "ourasert.h"
13 #include "bh_alien.h"
14 #include "bh_marin.h"
15 #include "bh_xeno.h"
16 #include "bh_corpse.h"
17 #include "bh_debri.h"
18 #include "pldnet.h"
19 #include "maths.h"
20 /*
21 	this attaches runtime and precompiled object
22 	strategyblocks
23 */
24 
25 /*** exported globals *************/
26 
27 int NumActiveStBlocks;
28 STRATEGYBLOCK  *ActiveStBlockList[maxstblocks];
29 
30 
31 /*** static globals ***************/
32 
33 static int NumFreeStBlocks;
34 static STRATEGYBLOCK *FreeStBlockList[maxstblocks];
35 static STRATEGYBLOCK **FreeStBlockListPtr = &FreeStBlockList[maxstblocks-1];
36 STRATEGYBLOCK FreeStBlockData[maxstblocks];
37 static STRATEGYBLOCK  **ActiveStBlockListPtr = &ActiveStBlockList[0];
38 
39 unsigned int IncrementalSBname;
40 
41 /*
42 
43  Support functions for Strategy Blocks
44 
45 */
46 
InitialiseStrategyBlocks(void)47 void InitialiseStrategyBlocks(void)
48 {
49 	STRATEGYBLOCK *FreeBlkPtr = &FreeStBlockData[0];
50 
51 	FreeStBlockListPtr = &FreeStBlockList[maxstblocks-1];
52 
53 	for(NumFreeStBlocks=0; NumFreeStBlocks < maxstblocks; NumFreeStBlocks++)
54 		{
55 			FreeStBlockList[NumFreeStBlocks] = FreeBlkPtr;
56 			FreeBlkPtr->SBflags.destroyed_but_preserved=0;
57 			#if debug
58 			FreeBlkPtr->SBIsValid = 0;
59 			#endif
60 			FreeBlkPtr++;
61 		}
62 
63     /* KJL 17:31:18 11/13/96 - seems like a logical place to initialise dynamics blocks */
64     InitialiseDynamicsBlocks();
65 
66     NumActiveStBlocks = 0;
67     ActiveStBlockListPtr = &ActiveStBlockList[0];
68 
69 	IncrementalSBname=0;
70 }
71 
72 
AllocateStrategyBlock(void)73 STRATEGYBLOCK* AllocateStrategyBlock(void)
74 {
75 	STRATEGYBLOCK *FreeBlkPtr = 0;		/* Default to null ptr */
76 	int *sptr;
77 	int i;
78 
79 	if(NumFreeStBlocks)
80 		{
81 			FreeBlkPtr = *FreeStBlockListPtr--;
82 
83 			NumFreeStBlocks--;					/* One less free block */
84 
85 			/* Clear the block */
86 
87 			sptr = (int *)FreeBlkPtr;
88 			for(i = sizeof(STRATEGYBLOCK)/4; i!=0; i--)
89 				{
90 					*sptr++ = 0;
91 				}
92 		}
93 
94 	return(FreeBlkPtr);
95 }
96 
97 
DeallocateStrategyBlock(STRATEGYBLOCK * sptr)98 void DeallocateStrategyBlock(STRATEGYBLOCK *sptr)
99 {
100 	int a;
101 	/* Reset name */
102 
103 	for(a = 0; a < SB_NAME_LENGTH; a++) {
104 		sptr->SBname[a] = '\0';
105 	}
106 
107 	FreeStBlockListPtr++;
108 
109 	*FreeStBlockListPtr = sptr;
110 
111 	NumFreeStBlocks++;						/* One more free block */
112 }
113 
114 
CreateActiveStrategyBlock(void)115 STRATEGYBLOCK* CreateActiveStrategyBlock(void)
116 {
117 	STRATEGYBLOCK *sb;
118 	sb = AllocateStrategyBlock();
119 
120 	if(sb)
121   	{
122   		#if debug
123   		GLOBALASSERT(sb->SBIsValid == 0);
124   		sb->SBIsValid = 1;
125   		#endif
126 
127   		*ActiveStBlockListPtr++ = sb;
128   		NumActiveStBlocks++;
129   	}
130 
131 	return sb;
132 }
133 
134 
DestroyActiveStrategyBlock(STRATEGYBLOCK * sb)135 int DestroyActiveStrategyBlock(STRATEGYBLOCK* sb)
136 {
137 	int j = -1;
138 	int i;
139 
140 	/* If the block ptr is OK, search the Active Blocks List */
141 
142 	if(sb)
143 	{
144 		for(i = 0; i < NumActiveStBlocks && j!=0; i++)
145 		{
146 
147 			if(ActiveStBlockList[i] == sb)
148 			{
149 				ActiveStBlockList[i] = ActiveStBlockList[NumActiveStBlocks-1];
150 				NumActiveStBlocks--;
151 				ActiveStBlockListPtr--;
152 
153 				if(!sb->SBflags.preserve_until_end_of_level)
154 				{
155 					DeallocateStrategyBlock(sb);		/* Back to Free List */
156 				}
157 				else
158 				{
159 					sb->SBflags.destroyed_but_preserved=1;
160 				}
161 
162 
163 				j = 0;												/* Flag OK */
164 			}
165 		}
166 	}
167 
168 	return(j);
169 }
170 
171 
172 
AttachNewStratBlock(MODULE * moptr,MODULEMAPBLOCK * momptr,DISPLAYBLOCK * dptr)173 STRATEGYBLOCK * AttachNewStratBlock
174 (
175 	MODULE* moptr,
176 	MODULEMAPBLOCK* momptr,
177 	DISPLAYBLOCK* dptr
178 )
179 {
180 	/*oh for a constructor*/
181 	/* fails if any of the above has a
182 		 stratgey block attached*/
183 
184 	STRATEGYBLOCK* sptr;
185 	int i;
186 
187 	GLOBALASSERT(momptr || dptr);
188 
189 	sptr = CreateActiveStrategyBlock();
190 	if (sptr == 0) return 0;
191 
192 	InitialiseSBValues(sptr);
193 
194 	for(i = 0; i < SB_NAME_LENGTH; i++);
195 		{
196 			sptr->SBname[i] = '\0';
197 		}
198 
199 	sptr->SBmomptr = momptr;
200 
201 	if(moptr)
202 		{
203 /*			GLOBALASSERT(!moptr->m_sbptr); HACK*/
204 			moptr->m_sbptr = sptr;
205 			sptr->SBmoptr = moptr;
206 		}
207 
208 	if(dptr)
209 		{
210 			GLOBALASSERT(!dptr->ObStrategyBlock);
211 			dptr->ObStrategyBlock = sptr;
212 			sptr->SBdptr = dptr;
213 		}
214 	else
215 		{
216 			sptr->SBflags.no_displayblock = 1;
217 		}
218 
219 
220 
221 	return(sptr);
222 
223 }
224 
225 
InitialiseSBValues(STRATEGYBLOCK * sptr)226 void InitialiseSBValues(STRATEGYBLOCK* sptr)
227 {
228 	sptr->I_SBtype = I_BehaviourNull;
229 	sptr->SBdataptr = (void *)0x0;
230 
231 	sptr->SBDamageBlock.Health=0;
232 	sptr->SBDamageBlock.Armour=0;
233 	sptr->SBDamageBlock.SB_H_flags.AcidResistant=0;
234 	sptr->SBDamageBlock.SB_H_flags.FireResistant=0;
235 	sptr->SBDamageBlock.SB_H_flags.ElectricResistant=0;
236 	sptr->SBDamageBlock.SB_H_flags.PerfectArmour=0;
237 	sptr->SBDamageBlock.SB_H_flags.ElectricSensitive=0;
238 	sptr->SBDamageBlock.SB_H_flags.Indestructable=0;
239 
240 	sptr->SBflags.please_destroy_me = 0;
241 	sptr->SBflags.no_displayblock = 0;
242 	sptr->SBflags.request_operate = 0;
243 	sptr->SBflags.preserve_until_end_of_level = 0;
244 	sptr->SBflags.destroyed_but_preserved = 0;
245 	sptr->SBflags.not_on_motiontracker = 0;
246 
247 	sptr->integrity = 0;
248 
249 	sptr->maintainVisibility = 0;		  /* patrRWH - function to search thgough the list of active*/
250 	sptr->containingModule = (MODULE *)0; /* patrstrat blocks and return the pointer*/
251 	sptr->shapeIndex = 0;				  /* patr*/
252 
253 	sptr->SBmoptr = (MODULE*)0x0;
254 	sptr->SBmomptr = (MODULEMAPBLOCK*)0x0;
255 	sptr->SBmorphctrl = (MORPHCTRL*)0x0;
256 
257 	sptr->SBdptr=NULL;
258 
259 	sptr->name=0;
260 
261 }
262 
263 
264 /*
265 RWH - function to search thgough the list of active
266 strat blocks and return the pointer
267 */
268 
269 
FindSBWithName(char * id_name)270 STRATEGYBLOCK* FindSBWithName(char* id_name)
271 {
272 	int stratblock = NumActiveStBlocks;
273 	int i;
274 	GLOBALASSERT(stratblock);
275 
276 	if(!id_name)
277 		return NULL;
278 
279 	//If the name is all 0`s I want to return a null pointer - Richard.
280 	for(i=0;i<SB_NAME_LENGTH;i++)
281 	{
282 		if(id_name[i]) break;
283 	}
284 	if(i==SB_NAME_LENGTH)
285 	{
286 		return NULL;
287 	}
288 
289 	while(--stratblock >= 0)
290 		{
291 			STRATEGYBLOCK* sbptr = ActiveStBlockList[stratblock];
292 			GLOBALASSERT(sbptr);
293 
294 			if(sbptr->SBname)
295 				{
296 					if(NAME_ISEQUAL(sbptr->SBname, id_name))
297 					{
298 						return((sbptr));
299 					}
300 				}
301 		}
302 	// we have to return null for lifts - so that
303 	// we know that the lift is outside the env
304 	return(NULL);
305 }
306 
307 
308 static STRATEGYBLOCK SB_Preserved[MAX_PRESERVED_SB];
309 static int Num_SB_Preserved;
310 
311 
InitPreservedSBs()312 void InitPreservedSBs()
313 {
314 	Num_SB_Preserved = 0;
315 }
316 
317 
PreserveStBlocksInModule(MODULE * containing_mod)318 void PreserveStBlocksInModule(MODULE* containing_mod)
319 {
320 	//	this used within level - find objects in module
321 	// all will have sbs
322 
323 	int i;
324 	int max_x, min_x, max_y, min_y, max_z, min_z;
325 
326 	max_x = containing_mod->m_maxx + containing_mod->m_world.vx;
327 	min_x = containing_mod->m_minx + containing_mod->m_world.vx;
328 	max_y = containing_mod->m_maxy + containing_mod->m_world.vy;
329 	min_y = containing_mod->m_miny + containing_mod->m_world.vy;
330 	max_z = containing_mod->m_maxz + containing_mod->m_world.vz;
331 	min_z = containing_mod->m_minz + containing_mod->m_world.vz;
332 
333 	GLOBALASSERT(Num_SB_Preserved == 0);
334 
335 	for(i = 0; i < NumActiveStBlocks && Num_SB_Preserved < MAX_PRESERVED_SB; i++)
336 		{
337 			VECTORCH obj_world;
338 			STRATEGYBLOCK	*sbptr;
339 			DYNAMICSBLOCK	*dynptr;
340 
341 			sbptr = ActiveStBlockList[i];
342 
343 			if(!(dynptr = sbptr->DynPtr))
344 				continue;
345 
346 			obj_world = dynptr->Position;
347 
348 			if(obj_world.vx < max_x)
349 				if(obj_world.vx > min_x)
350 					if(obj_world.vz < max_z)
351 						if(obj_world.vz > min_z)
352 							if(obj_world.vy < max_y)
353 								if(obj_world.vy > min_y)
354 									{
355 										// copy name into somthing
356 										if(sbptr->I_SBtype == I_BehaviourMarinePlayer ||
357 												sbptr->I_SBtype == I_BehaviourMarinePlayer ||
358 												sbptr->I_SBtype == I_BehaviourMarinePlayer)
359 											{
360 												SB_Preserved[Num_SB_Preserved] = *sbptr;
361 
362 												Num_SB_Preserved++;
363 											}
364 									}
365 		}
366 }
367 
368 
SBNeededForNextEnv(STRATEGYBLOCK * sbptr)369 BOOL SBNeededForNextEnv(STRATEGYBLOCK* sbptr)
370 {
371 	int i = 0;
372 
373 	if(Num_SB_Preserved == 0)
374 		return(0);
375 
376 	if (sbptr->I_SBtype!=I_BehaviourMarinePlayer)
377 		if (sbptr->I_SBtype!=I_BehaviourAlienPlayer)
378 			if (sbptr->I_SBtype!=I_BehaviourPredatorPlayer)
379 	 			if (NAME_ISNULL(sbptr->SBname))
380 					return(0);
381 
382 	for(i = 0; i < Num_SB_Preserved; i++)
383 		{
384 			STRATEGYBLOCK	*pres_sbptr;
385 
386 			pres_sbptr = &SB_Preserved[i];
387 
388 			if(NAME_ISEQUAL(pres_sbptr->SBname, sbptr->SBname))
389 				return(1);
390   		}
391 
392 	return(0);
393 }
394 
395 
AddPreservedSBsToActiveList()396 void AddPreservedSBsToActiveList()
397 {
398 	int i;
399 	STRATEGYBLOCK *new_sbptr;
400 
401 	for(i = 0; i < Num_SB_Preserved; i++)
402 		{
403 			new_sbptr =	CreateActiveStrategyBlock();
404 
405 			*new_sbptr = SB_Preserved[i];
406 
407 
408 			if(new_sbptr->I_SBtype == I_BehaviourMarinePlayer ||
409 					new_sbptr->I_SBtype == I_BehaviourMarinePlayer ||
410 					new_sbptr->I_SBtype == I_BehaviourMarinePlayer)
411 
412 				{
413 					DYNAMICSBLOCK *playerDynPtr;
414 
415 					Player->ObStrategyBlock = new_sbptr;
416 
417 				 	playerDynPtr = Player->ObStrategyBlock->DynPtr;
418 					// Need to copy some of the preserved SB info into the appropriate places
419 
420 					Player->ObWorld = playerDynPtr->Position;
421 					Player->ObMat 	= playerDynPtr->OrientMat;
422 					Player->ObEuler = playerDynPtr->OrientEuler;
423 
424 					playerDynPtr->PrevPosition    = playerDynPtr->Position;
425 					playerDynPtr->PrevOrientMat 	= playerDynPtr->OrientMat;
426 					playerDynPtr->PrevOrientEuler = playerDynPtr->OrientEuler;
427 
428 					playerDynPtr->LinVelocity.vx = 0;
429 					playerDynPtr->LinVelocity.vy = 0;
430 					playerDynPtr->LinVelocity.vz = 0;
431 
432 					playerDynPtr->LinImpulse.vx = 0;
433 					playerDynPtr->LinImpulse.vy = 0;
434 					playerDynPtr->LinImpulse.vz = 0;
435 
436 					playerDynPtr->AngVelocity.EulerX = 0;
437 					playerDynPtr->AngVelocity.EulerY = 0;
438 					playerDynPtr->AngVelocity.EulerZ = 0;
439 
440 					playerDynPtr->AngImpulse.EulerX = 0;
441 					playerDynPtr->AngImpulse.EulerY = 0;
442 					playerDynPtr->AngImpulse.EulerZ = 0;
443 
444 				}
445 
446 			// we will almost certainly need
447 			// some clean up here. esp for the
448 			// LIFT_FLOOR_SWITCHES and for objects
449 			// whose shape reference has changed
450 		}
451 }
452 
453 
TeleportPreservedSBsToNewEnvModule(MODULE * new_pos,MODULE * old_pos,int orient_change)454 void TeleportPreservedSBsToNewEnvModule(MODULE *new_pos, MODULE* old_pos, int orient_change)
455 {
456 	int i;
457 	VECTORCH mod_offset;
458 
459 	mod_offset.vx = new_pos->m_world.vx - old_pos->m_world.vx;
460 	mod_offset.vy = new_pos->m_world.vy - old_pos->m_world.vy;
461 	mod_offset.vz = new_pos->m_world.vz - old_pos->m_world.vz;
462 
463 	for(i = 0; i < Num_SB_Preserved; i++)
464 		{
465 			VECTORCH obj_world;
466 			VECTORCH pos_rel;
467 			STRATEGYBLOCK	*sbptr;
468 			DYNAMICSBLOCK	*dynptr;
469 
470 			sbptr = &SB_Preserved[i];
471 
472 			dynptr = sbptr->DynPtr;
473 			GLOBALASSERT(dynptr);
474 
475 			obj_world = sbptr->DynPtr->Position;
476 
477 
478 			{
479 			  // okay we need to find our relative position to the moduke
480 		  	int cos;
481  	  		int sin;
482 				int angle;
483 				MATRIXCH mat;
484 
485 
486 				pos_rel.vx = dynptr->Position.vx - old_pos->m_world.vx;
487 				pos_rel.vy = dynptr->Position.vy - old_pos->m_world.vy;
488 				pos_rel.vz = dynptr->Position.vz - old_pos->m_world.vz;
489 
490 				if(orient_change == 1 || orient_change == -3)
491 					angle = 1024;
492 				else if(orient_change == 2 || orient_change == -2)
493 					angle = 2048;
494 				else if(orient_change == 3 || orient_change == -1)
495 					angle = 3072;
496 				else
497 					angle = 0;
498 
499 		  	cos = GetCos(angle);
500  	  		sin = GetSin(angle);
501 
502 				mat.mat11 = cos;
503 	 	  	mat.mat12 = 0;
504 		  	mat.mat13 = -sin;
505  		  	mat.mat21 = 0;
506  	  		mat.mat22 = 65536;
507  	  		mat.mat23 = 0;
508  	  		mat.mat31 = sin;
509  	  		mat.mat32 = 0;
510  	  		mat.mat33 = cos;
511 
512 				// rotate the relative object about the center of the
513 				// module and rotate the abject about its own y-axis
514 
515 				RotateVector(&pos_rel, &mat);
516 		  	MatrixMultiply(&dynptr->OrientMat,&mat,&dynptr->OrientMat);
517 			 	MatrixToEuler(&dynptr->OrientMat, &dynptr->OrientEuler);
518 			}
519 
520 #if 0
521 			dynptr->Position.vx = mod_offset.vx;
522 			dynptr->Position.vy = mod_offset.vy;
523 			dynptr->Position.vz = mod_offset.vz;
524 
525 			dynptr->PrevPosition.vx = mod_offset.vx;
526 			dynptr->PrevPosition.vy = mod_offset.vy;
527 			dynptr->PrevPosition.vz = mod_offset.vz;
528 #endif
529 
530 			dynptr->Position.vx = pos_rel.vx + new_pos->m_world.vx;
531 			dynptr->Position.vy = pos_rel.vy + new_pos->m_world.vy;
532 			dynptr->Position.vz = pos_rel.vz + new_pos->m_world.vz;
533 
534 			dynptr->PrevPosition.vx = -pos_rel.vx + old_pos->m_world.vx;
535 			dynptr->PrevPosition.vy = -pos_rel.vy + old_pos->m_world.vy;
536 			dynptr->PrevPosition.vz = -pos_rel.vz + old_pos->m_world.vz;
537 
538 		}
539  }
540 
541 
542 
543 
544 // RWH 5/6/97 these next two functions were 1, changed and 2, added
545 // to deal with deallocating stblocks at the end of behaviours
546 // this stops problems with accessing defunct strategy blocks
547 // via collision reports
548 
549 
DestroyAnyStrategyBlock(STRATEGYBLOCK * sbptr)550 void DestroyAnyStrategyBlock(STRATEGYBLOCK *sbptr)
551 {
552 	GLOBALASSERT(sbptr);
553 
554 	sbptr->SBflags.please_destroy_me = 1;
555 }
556 
557 
RemoveDestroyedStrategyBlocks(void)558 void RemoveDestroyedStrategyBlocks(void)
559 {
560 	/*
561 	Go backwards through the strategy block.
562 	This should prevent any strategy blocks from being skipped when they
563 	get shuffled down from the end of the array.
564 	*/
565 	int i = NumActiveStBlocks;
566 
567 	while(i)
568 	{
569 		STRATEGYBLOCK* sbptr = ActiveStBlockList[--i];
570 
571 		if(sbptr->SBflags.please_destroy_me)
572 		{
573 			RemoveBehaviourStrategy(sbptr);
574 		} else {
575 
576 			/* Also... gibb aliens? */
577 			if (sbptr->I_SBtype==I_BehaviourAlien) {
578 
579 				ALIEN_STATUS_BLOCK *alienStatusPointer;
580 				LOCALASSERT(sbptr);
581 				LOCALASSERT(sbptr->DynPtr);
582 
583 				alienStatusPointer=(ALIEN_STATUS_BLOCK *)(sbptr->SBdataptr);
584 
585 				if (alienStatusPointer->GibbFactor>0) {
586 					Extreme_Gibbing(sbptr,alienStatusPointer->HModelController.section_data,alienStatusPointer->GibbFactor);
587 					alienStatusPointer->GibbFactor=0;
588 				} else if (alienStatusPointer->GibbFactor<0) {
589 					KillRandomSections(alienStatusPointer->HModelController.section_data,alienStatusPointer->GibbFactor);
590 					alienStatusPointer->GibbFactor=0;
591 				}
592 
593 			} else if (
594 				(sbptr->I_SBtype==I_BehaviourMarine)
595 				|| (sbptr->I_SBtype==I_BehaviourSeal)
596 				) {
597 
598 				MARINE_STATUS_BLOCK *marineStatusPointer;
599 				LOCALASSERT(sbptr);
600 				LOCALASSERT(sbptr->DynPtr);
601 
602 				marineStatusPointer=(MARINE_STATUS_BLOCK *)(sbptr->SBdataptr);
603 
604 				if (marineStatusPointer->GibbFactor>0) {
605 					Extreme_Gibbing(sbptr,marineStatusPointer->HModelController.section_data,marineStatusPointer->GibbFactor);
606 					marineStatusPointer->GibbFactor=0;
607 				} else if (marineStatusPointer->GibbFactor<0) {
608 					KillRandomSections(marineStatusPointer->HModelController.section_data,-(marineStatusPointer->GibbFactor));
609 					marineStatusPointer->GibbFactor=0;
610 				}
611 			} else if (sbptr->I_SBtype==I_BehaviourPredator) {
612 				PREDATOR_STATUS_BLOCK *predatorStatusPointer;
613 				LOCALASSERT(sbptr);
614 				LOCALASSERT(sbptr->DynPtr);
615 
616 				predatorStatusPointer=(PREDATOR_STATUS_BLOCK *)(sbptr->SBdataptr);
617 
618 				if (predatorStatusPointer->GibbFactor>0) {
619 					Extreme_Gibbing(sbptr,predatorStatusPointer->HModelController.section_data,predatorStatusPointer->GibbFactor);
620 					predatorStatusPointer->GibbFactor=0;
621 				} else if (predatorStatusPointer->GibbFactor<0) {
622 					KillRandomSections(predatorStatusPointer->HModelController.section_data,-(predatorStatusPointer->GibbFactor));
623 					predatorStatusPointer->GibbFactor=0;
624 				}
625 			} else if (sbptr->I_SBtype==I_BehaviourXenoborg) {
626 				XENO_STATUS_BLOCK *xenoStatusPointer;
627 				LOCALASSERT(sbptr);
628 				LOCALASSERT(sbptr->DynPtr);
629 
630 				xenoStatusPointer=(XENO_STATUS_BLOCK *)(sbptr->SBdataptr);
631 
632 				if (xenoStatusPointer->GibbFactor>0) {
633 					Extreme_Gibbing(sbptr,xenoStatusPointer->HModelController.section_data,xenoStatusPointer->GibbFactor);
634 					xenoStatusPointer->GibbFactor=0;
635 				} else if (xenoStatusPointer->GibbFactor<0) {
636 					KillRandomSections(xenoStatusPointer->HModelController.section_data,-(xenoStatusPointer->GibbFactor));
637 					xenoStatusPointer->GibbFactor=0;
638 				}
639 			} else if (sbptr->I_SBtype==I_BehaviourNetCorpse) {
640 
641 				NETCORPSEDATABLOCK *corpseStatusPointer;
642 				LOCALASSERT(sbptr);
643 				LOCALASSERT(sbptr->DynPtr);
644 
645 				corpseStatusPointer=(NETCORPSEDATABLOCK *)(sbptr->SBdataptr);
646 				if(corpseStatusPointer->GibbFactor)
647 				{
648 					/*get a seed for the RNG so that we can send gibbing to other
649 					network players*/
650 					int seed=FastRandom();
651 					SetSeededFastRandom(seed);
652 
653 					if(AvP.Network != I_No_Network)
654 					{
655 						AddNetMsg_Gibbing(sbptr,corpseStatusPointer->GibbFactor,seed);
656 					}
657 
658 					if (corpseStatusPointer->GibbFactor>0) {
659 						Extreme_Gibbing(sbptr,corpseStatusPointer->HModelController.section_data,corpseStatusPointer->GibbFactor);
660 						corpseStatusPointer->GibbFactor=0;
661 					} else if (corpseStatusPointer->GibbFactor<0) {
662 						KillRandomSections(corpseStatusPointer->HModelController.section_data,-(corpseStatusPointer->GibbFactor));
663 						corpseStatusPointer->GibbFactor=0;
664 					}
665 				}
666 			} else if (sbptr->I_SBtype==I_BehaviourHierarchicalFragment) {
667 
668 				HDEBRIS_BEHAV_BLOCK *debrisStatusPointer;
669 				LOCALASSERT(sbptr);
670 				LOCALASSERT(sbptr->DynPtr);
671 
672 				debrisStatusPointer=(HDEBRIS_BEHAV_BLOCK *)(sbptr->SBdataptr);
673 
674 				if (debrisStatusPointer->GibbFactor>0) {
675 					Extreme_Gibbing(sbptr,debrisStatusPointer->HModelController.section_data,debrisStatusPointer->GibbFactor);
676 					debrisStatusPointer->GibbFactor=0;
677 				} else if (debrisStatusPointer->GibbFactor<0) {
678 					KillRandomSections(debrisStatusPointer->HModelController.section_data,-(debrisStatusPointer->GibbFactor));
679 					debrisStatusPointer->GibbFactor=0;
680 				}
681 			}
682 		}
683 	}
684 }
685 
686 
687 
DestroyAllStrategyBlocks(void)688 void DestroyAllStrategyBlocks(void)
689 {
690 	int i = 0;
691 	int a = NumActiveStBlocks;
692 
693 
694 	while(i < a)
695 		{
696 			RemoveBehaviourStrategy(ActiveStBlockList[i++]);
697 		}
698 
699 	//get rid of all the strategyblocks that have been preserved until the end of the level
700 
701 	for(i=0;i<maxstblocks;i++)
702 	{
703 		if(FreeStBlockData[i].SBflags.destroyed_but_preserved)
704 		{
705 	   		FreeStBlockData[i].SBflags.destroyed_but_preserved=0;
706 	   		FreeStBlockData[i].SBflags.preserve_until_end_of_level=0;
707 			DeallocateStrategyBlock(&FreeStBlockData[i]);
708 	   	}
709 	}
710 
711 }
712 
AssignNewSBName(STRATEGYBLOCK * sbPtr)713 void AssignNewSBName(STRATEGYBLOCK *sbPtr) {
714 
715 	IncrementalSBname++;
716 
717 	if(IncrementalSBname>0xffffff)
718 	{
719 		IncrementalSBname=1;
720 	}
721 
722 	*((int *)&sbPtr->SBname[4])=IncrementalSBname;
723 
724 	if(AvP.Network != I_No_Network)
725 	{
726 		//modify name to ensure uniqueness between players
727 		extern DPID AVPDPNetID;
728 		sbPtr->SBname[SB_NAME_LENGTH-1]=+10+PlayerIdInPlayerList(AVPDPNetID); /* Just to make sure... */
729 
730 	}
731 	else
732 	{
733 		sbPtr->SBname[SB_NAME_LENGTH-1]=1; /* Just to make sure... */
734 	}
735 
736 
737 }
738 
GivePlayerCloakAway(void)739 void GivePlayerCloakAway(void) {
740 
741 	PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
742 
743 	playerStatusPtr->cloakPositionGivenAway = 1;
744 	playerStatusPtr->cloakPositionGivenAwayTimer = PLAYERCLOAK_POSTIONGIVENAWAYTIME;
745 }
746