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