| | 1 | #include "system.h" |
| | 2 | #include "prototyp.h" |
| | 3 | #include "stratdef.h" |
| | 4 | #include "bh_types.h" |
| | 5 | #include <assert.h> |
| | 6 | #include "pldghost.h" |
| | 7 | #include "pfarlocs.h" |
| | 8 | #include <stdlib.h> |
| | 9 | #include <stdio.h> |
| | 10 | |
| | 11 | SCENEMODULE MainScene; |
| | 12 | |
| | 13 | const MATRIXCH IdentityMatrix = |
| | 14 | { |
| | 15 | ONE_FIXED, 0, 0, |
| | 16 | 0, ONE_FIXED, 0, |
| | 17 | 0, 0, ONE_FIXED |
| | 18 | }; |
| | 19 | |
| | 20 | extern int ModuleArraySize; |
| | 21 | extern int NumActiveBlocks; |
| | 22 | extern DISPLAYBLOCK *ActiveBlockList[]; |
| | 23 | extern int render_sky; |
| | 24 | |
| | 25 | static void FindVisibleModules(VMODULE *vptr, int flag) |
| | 26 | { |
| | 27 | while(!vptr->end_module) |
| | 28 | { |
| | 29 | MODULE *mptr = NULL; |
| | 30 | |
| | 31 | /* Add this module to the visible array */ |
| | 32 | if(vptr->vmod_mref.mref_ptr) |
| | 33 | { |
| | 34 | mptr = vptr->vmod_mref.mref_ptr; |
| | 35 | ModuleCurrVisArray[mptr->m_index] = flag; |
| | 36 | } |
| | 37 | |
| | 38 | /* VMODULE instructions */ |
| | 39 | switch(vptr->vmod_instr) |
| | 40 | { |
| | 41 | case vmodi_null: |
| | 42 | vptr++; |
| | 43 | break; |
| | 44 | case vmodi_bra_vc: |
| | 45 | /* If the door/viewport is closed... */ |
| | 46 | /* Branch to this vptr */ |
| | 47 | /* else vptr++; */ |
| | 48 | if(mptr) |
| | 49 | { |
| | 50 | if(mptr->m_flags & m_flag_open) |
| | 51 | vptr++; |
| | 52 | else |
| | 53 | vptr = vptr->vmod_data.vmodidata_ptr; |
| | 54 | } |
| | 55 | } |
| | 56 | } |
| | 57 | } |
| | 58 | |
| | 59 | DISPLAYBLOCK * AllocateNewObject(const int shapeIndex) |
| | 60 | { |
| | 61 | DISPLAYBLOCK *dptr = CreateActiveObject(); |
| | 62 | |
| | 63 | if(dptr) |
| | 64 | { |
| | 65 | dptr->ObShape = shapeIndex; |
| | 66 | struct shapeheader* sptr = mainshapelist[shapeIndex]; |
| | 67 | |
| | 68 | dptr->ShapeData = sptr; |
| | 69 | dptr->extent.radius = sptr->shaperadius; |
| | 70 | dptr->extent.max_x = sptr->shapemaxx; |
| | 71 | dptr->extent.min_x = sptr->shapeminx; |
| | 72 | dptr->extent.max_y = sptr->shapemaxy; |
| | 73 | dptr->extent.min_y = sptr->shapeminy; |
| | 74 | dptr->extent.max_z = sptr->shapemaxz; |
| | 75 | dptr->extent.min_z = sptr->shapeminz; |
| | 76 | dptr->ObMat = IdentityMatrix; |
| | 77 | } |
| | 78 | |
| | 79 | return dptr; |
| | 80 | } |
| | 81 | |
| | 82 | static void AllocateModuleObject(MODULE *mptr) |
| | 83 | { |
| | 84 | DISPLAYBLOCK *dptr = CreateActiveObject(); |
| | 85 | |
| | 86 | if(dptr) |
| | 87 | { |
| | 88 | mptr->m_dptr = dptr; |
| | 89 | dptr->Module = mptr; |
| | 90 | |
| | 91 | if(mptr->m_sbptr) |
| | 92 | { |
| | 93 | dptr->ObStrategyBlock = mptr->m_sbptr; |
| | 94 | mptr->m_sbptr->DisplayBlock = dptr; |
| | 95 | |
| | 96 | if(mptr->m_sbptr->morphctrl) |
| | 97 | dptr->ObMorphCtrl = mptr->m_sbptr->morphctrl; |
| | 98 | } |
| | 99 | |
| | 100 | MODULEMAPBLOCK *mapblockptr = mptr->m_mapptr; |
| | 101 | |
| | 102 | dptr->ObShape = mapblockptr->MapShape; |
| | 103 | dptr->ObWorld = mapblockptr->MapWorld; |
| | 104 | dptr->ObEuler = mapblockptr->MapEuler; |
| | 105 | dptr->ObFlags = mapblockptr->MapFlags; |
| | 106 | dptr->ObFlags2 = mapblockptr->MapFlags2; |
| | 107 | dptr->ObFlags3 = mapblockptr->MapFlags3; |
| | 108 | |
| | 109 | struct shapeheader* sptr = mainshapelist[dptr->ObShape]; |
| | 110 | dptr->ShapeData = sptr; |
| | 111 | |
| | 112 | dptr->extent.radius = sptr->shaperadius; |
| | 113 | dptr->extent.max_x = sptr->shapemaxx; |
| | 114 | dptr->extent.min_x = sptr->shapeminx; |
| | 115 | dptr->extent.max_y = sptr->shapemaxy; |
| | 116 | dptr->extent.min_y = sptr->shapeminy; |
| | 117 | dptr->extent.max_z = sptr->shapemaxz; |
| | 118 | dptr->extent.min_z = sptr->shapeminz; |
| | 119 | |
| | 120 | /* |
| | 121 | KJL 14:15:34 04/19/97 - their used to be lots of maths here |
| | 122 | to calculate orientation, but in AvP all modules are aligned to |
| | 123 | the world space axes... |
| | 124 | */ |
| | 125 | |
| | 126 | dptr->ObMat = IdentityMatrix; |
| | 127 | |
| | 128 | /* |
| | 129 | |
| | 130 | Module lights |
| | 131 | |
| | 132 | There is an option for a pointer to an array of lights in a module |
| | 133 | structure. These lights are transferred to the display block and |
| | 134 | flagged as "LFlag_WasNotAllocated" so that "DeallocateLightBlock()" |
| | 135 | knows to ignore them. |
| | 136 | |
| | 137 | The number of lights in the array is "m_numlights" and the pointer |
| | 138 | is called "m_lightarray". |
| | 139 | |
| | 140 | The addition of non-allocated does not need to be a module specific |
| | 141 | option. |
| | 142 | |
| | 143 | Non-allocated lights can co-exist peacefully with the other lights. |
| | 144 | |
| | 145 | */ |
| | 146 | |
| | 147 | if(mptr->m_numlights && mptr->m_lightarray) |
| | 148 | { |
| | 149 | LIGHTBLOCK *lptr_array = mptr->m_lightarray; |
| | 150 | int i; |
| | 151 | |
| | 152 | for(i = mptr->m_numlights; i; i--) |
| | 153 | { |
| | 154 | /* Make sure the light is flagged correctly */ |
| | 155 | |
| | 156 | lptr_array->LightFlags |= LFlag_WasNotAllocated; |
| | 157 | |
| | 158 | AddLightBlock(dptr, lptr_array); |
| | 159 | |
| | 160 | /* Next light from the array */ |
| | 161 | |
| | 162 | lptr_array++; |
| | 163 | } |
| | 164 | } |
| | 165 | |
| | 166 | /* Bug Fix */ // for what?? |
| | 167 | /* |
| | 168 | if (dptr->ObStrategyBlock) |
| | 169 | { |
| | 170 | STRATEGYBLOCK *sbptr = dptr->ObStrategyBlock; |
| | 171 | |
| | 172 | if (sbptr->type == I_BehaviourSimpleAnimation) |
| | 173 | { |
| | 174 | SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->dataptr); |
| | 175 | |
| | 176 | assert(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation); |
| | 177 | assert (dptr == sbptr->DisplayBlock); |
| | 178 | |
| | 179 | if(!dptr->ObTxAnimCtrlBlks) |
| | 180 | dptr->ObTxAnimCtrlBlks = sanimbhv->tacbSimple; |
| | 181 | } |
| | 182 | } |
| | 183 | */ |
| | 184 | } |
| | 185 | } |
| | 186 | |
| | 187 | int IsModuleVisibleFromModule(MODULE *source, MODULE *target) |
| | 188 | { |
| | 189 | if ((source == NULL) || (target == NULL)) |
| | 190 | return 0; |
| | 191 | else if (source == target) |
| | 192 | return 1; |
| | 193 | else |
| | 194 | { |
| | 195 | VMODULE *vptr = source->m_vmptr; |
| | 196 | |
| | 197 | while(!vptr->end_module) |
| | 198 | { |
| | 199 | /* Add this module to the visible array */ |
| | 200 | MODULE *mptr = NULL; |
| | 201 | |
| | 202 | if(vptr->vmod_mref.mref_ptr) |
| | 203 | { |
| | 204 | mptr = vptr->vmod_mref.mref_ptr; |
| | 205 | |
| | 206 | if (mptr == target) |
| | 207 | return 1; |
| | 208 | } |
| | 209 | |
| | 210 | /* VMODULE instructions */ |
| | 211 | |
| | 212 | switch(vptr->vmod_instr) |
| | 213 | { |
| | 214 | case vmodi_null: |
| | 215 | vptr++; |
| | 216 | break; |
| | 217 | case vmodi_bra_vc: |
| | 218 | |
| | 219 | /* NYD */ |
| | 220 | |
| | 221 | /* If the door/viewport is closed... */ |
| | 222 | |
| | 223 | /* Branch to this vptr */ |
| | 224 | |
| | 225 | if(mptr) |
| | 226 | { |
| | 227 | if(mptr->m_flags & m_flag_open) |
| | 228 | vptr++; |
| | 229 | else |
| | 230 | vptr = vptr->vmod_data.vmodidata_ptr; |
| | 231 | } |
| | 232 | |
| | 233 | /* else vptr++; */ |
| | 234 | } |
| | 235 | } |
| | 236 | |
| | 237 | return 0; |
| | 238 | } |
| | 239 | } |
| | 240 | |
| | 241 | |
| | 242 | void ModuleHandler() |
| | 243 | { |
| | 244 | int i; |
| | 245 | |
| | 246 | for(i=0; i < ModuleArraySize; i++) |
| | 247 | ModuleCurrVisArray[i] = 0; |
| | 248 | |
| | 249 | /* handle dynamic module objects */ |
| | 250 | { |
| | 251 | int numberOfObjects = NumActiveBlocks; |
| | 252 | |
| | 253 | while (numberOfObjects--) |
| | 254 | { |
| | 255 | DISPLAYBLOCK* objectPtr = ActiveBlockList[numberOfObjects]; |
| | 256 | |
| | 257 | if(objectPtr->ObFlags3 & ObFlag3_DynamicModuleObject) |
| | 258 | { |
| | 259 | STRATEGYBLOCK *sbPtr = objectPtr->ObStrategyBlock; |
| | 260 | |
| | 261 | sbPtr->containingModule = ModuleFromPosition(&objectPtr->ObWorld, sbPtr->containingModule); |
| | 262 | |
| | 263 | if (sbPtr->containingModule && ModuleIsPhysical(sbPtr->containingModule)) |
| | 264 | { |
| | 265 | ModuleCurrVisArray[sbPtr->containingModule->m_index] = 1; |
| | 266 | |
| | 267 | if(sbPtr->containingModule->m_vmptr) |
| | 268 | FindVisibleModules(sbPtr->containingModule->m_vmptr, 1); |
| | 269 | } |
| | 270 | } |
| | 271 | } |
| | 272 | } |
| | 273 | |
| | 274 | /*If this is an network game , and this machine is the ai server , then need to check if |
| | 275 | there are any aliens near to other players*/ |
| | 276 | |
| | 277 | if(NetworkHost == AvP.PlayMode) |
| | 278 | { |
| | 279 | /* go through the strategy blocks looking for players*/ |
| | 280 | int sbIndex; |
| | 281 | for(sbIndex = 0; sbIndex < NumActiveStBlocks; sbIndex++) |
| | 282 | { |
| | 283 | STRATEGYBLOCK *playerSbPtr = ActiveStBlockList[sbIndex]; |
| | 284 | |
| | 285 | if(playerSbPtr->type != I_BehaviourNetGhost) |
| | 286 | continue; |
| | 287 | |
| | 288 | NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)playerSbPtr->dataptr; |
| | 289 | |
| | 290 | switch(ghostData->type) |
| | 291 | { |
| | 292 | case I_BehaviourAlienPlayer: |
| | 293 | case I_BehaviourMarinePlayer: |
| | 294 | case I_BehaviourPredatorPlayer: |
| | 295 | { |
| | 296 | int sbIndex2 = 0; |
| | 297 | //found one of the players |
| | 298 | if(!playerSbPtr->containingModule) |
| | 299 | continue; |
| | 300 | |
| | 301 | /*now search through the strategy blocks , to see if any aliens are |
| | 302 | visible from the player's location*/ |
| | 303 | |
| | 304 | for(; sbIndex2 < NumActiveStBlocks; sbIndex2++) |
| | 305 | { |
| | 306 | STRATEGYBLOCK *alienSbPtr = ActiveStBlockList[sbIndex2]; |
| | 307 | /*Is it an alien?*/ |
| | 308 | if(alienSbPtr->type != I_BehaviourAlien) |
| | 309 | continue; |
| | 310 | |
| | 311 | if(!alienSbPtr->containingModule) |
| | 312 | continue; |
| | 313 | |
| | 314 | if(IsModuleVisibleFromModule(playerSbPtr->containingModule, alienSbPtr->containingModule)) |
| | 315 | { |
| | 316 | /*The player can see the alien , so link in all modules that the player can see*/ |
| | 317 | |
| | 318 | if (ModuleIsPhysical(playerSbPtr->containingModule)) |
| | 319 | { |
| | 320 | ModuleCurrVisArray[playerSbPtr->containingModule->m_index] = 1; |
| | 321 | |
| | 322 | if(playerSbPtr->containingModule->m_vmptr) |
| | 323 | FindVisibleModules(playerSbPtr->containingModule->m_vmptr, 1); |
| | 324 | } |
| | 325 | |
| | 326 | /* Since all modules visible by this player have now been linked, |
| | 327 | don't need to check for any more aliens for this player */ |
| | 328 | break; |
| | 329 | } |
| | 330 | } |
| | 331 | } |
| | 332 | default: |
| | 333 | break; |
| | 334 | } |
| | 335 | } |
| | 336 | } |
| | 337 | |
| | 338 | ModuleCurrVisArray[PlayerStatus.sbptr->containingModule->m_index] = 2; |
| | 339 | |
| | 340 | if(PlayerStatus.sbptr->containingModule->m_vmptr) |
| | 341 | FindVisibleModules(PlayerStatus.sbptr->containingModule->m_vmptr, 2); |
| | 342 | |
| | 343 | for(i=0; i < ModuleArraySize; i++) |
| | 344 | { |
| | 345 | /* handle AIMODULE visibility stuff */ |
| | 346 | |
| | 347 | if (ModuleCurrVisArray[i] == 2) |
| | 348 | { |
| | 349 | AIMODULE *aiModulePtr = MainScene.sm_marray[i]->m_aimodule; |
| | 350 | |
| | 351 | if (aiModulePtr) |
| | 352 | { |
| | 353 | MODULE **modulelistPtr = aiModulePtr->m_module_ptrs; |
| | 354 | |
| | 355 | while(*modulelistPtr) |
| | 356 | { |
| | 357 | int index = (*modulelistPtr)->m_index; |
| | 358 | |
| | 359 | if (!ModuleCurrVisArray[index]) |
| | 360 | ModuleCurrVisArray[index] = 1; |
| | 361 | |
| | 362 | modulelistPtr++; |
| | 363 | } |
| | 364 | } |
| | 365 | } |
| | 366 | } |
| | 367 | |
| | 368 | render_sky = 0; |
| | 369 | |
| | 370 | for(i=0; i < ModuleArraySize; i++) |
| | 371 | { |
| | 372 | MODULE *mptr = MainScene.sm_marray[i]; |
| | 373 | |
| | 374 | if(ModuleCurrVisArray[i]) |
| | 375 | { |
| | 376 | /* mptr->m_mapptr Not all modules have maps */ |
| | 377 | |
| | 378 | if(!mptr->m_dptr && !(mptr->m_flags & m_flag_dormant) && mptr->m_mapptr) |
| | 379 | { |
| | 380 | AllocateModuleObject(mptr); |
| | 381 | } |
| | 382 | |
| | 383 | if((mptr->m_flags & MODULEFLAG_SKY) && (2 == ModuleCurrVisArray[mptr->m_index])) |
| | 384 | render_sky = 1; |
| | 385 | } |
| | 386 | else if(mptr->m_dptr) |
| | 387 | { |
| | 388 | DestroyActiveObject(&mptr->m_dptr); |
| | 389 | |
| | 390 | if(mptr->m_sbptr) |
| | 391 | mptr->m_sbptr->DisplayBlock = NULL; |
| | 392 | } |
| | 393 | } |
| | 394 | } |
| | 395 | |
| | 396 | int ThisObjectIsInAModuleVisibleFromCurrentlyVisibleModules(STRATEGYBLOCK *sbPtr) |
| | 397 | { |
| | 398 | assert(sbPtr); |
| | 399 | assert(sbPtr->containingModule); |
| | 400 | |
| | 401 | VMODULE *vPtr = sbPtr->containingModule->m_vmptr; |
| | 402 | assert(vPtr); |
| | 403 | |
| | 404 | if(ModuleCurrVisArray[sbPtr->containingModule->m_index] == 2) |
| | 405 | return 1; |
| | 406 | |
| | 407 | while(!vPtr->end_module) |
| | 408 | { |
| | 409 | MODULE *mptr = NULL; |
| | 410 | |
| | 411 | /* consider this module */ |
| | 412 | if(vPtr->vmod_mref.mref_ptr) |
| | 413 | { |
| | 414 | mptr = vPtr->vmod_mref.mref_ptr; |
| | 415 | |
| | 416 | if(ModuleCurrVisArray[mptr->m_index] == 2) |
| | 417 | { |
| | 418 | if(vPtr->vmod_instr == vmodi_bra_vc) |
| | 419 | { |
| | 420 | if (mptr->m_flags & m_flag_open) |
| | 421 | return 1; |
| | 422 | } |
| | 423 | else |
| | 424 | return 1; |
| | 425 | } |
| | 426 | } |
| | 427 | |
| | 428 | /* VMODULE instructions */ |
| | 429 | switch(vPtr->vmod_instr) |
| | 430 | { |
| | 431 | case vmodi_null: |
| | 432 | vPtr++; |
| | 433 | break; |
| | 434 | case vmodi_bra_vc: |
| | 435 | /* If the door/viewport is closed... */ |
| | 436 | /* Branch to this vPtr */ |
| | 437 | /* else vPtr++; */ |
| | 438 | if(mptr) |
| | 439 | { |
| | 440 | if(mptr->m_flags & m_flag_open) |
| | 441 | vPtr++; |
| | 442 | else |
| | 443 | vPtr = vPtr->vmod_data.vmodidata_ptr; |
| | 444 | } |
| | 445 | } |
| | 446 | } |
| | 447 | |
| | 448 | return 0; |
| | 449 | } |
| | 450 | |
| | 451 | int CompareName(char *name1, char *name2) |
| | 452 | { |
| | 453 | int i = 4; |
| | 454 | |
| | 455 | for(; i; i--) |
| | 456 | { |
| | 457 | if(*name1++ != *name2++) |
| | 458 | return 0; |
| | 459 | } |
| | 460 | |
| | 461 | return 1; |
| | 462 | } |
| | 463 | |
| | 464 | void PrintName(char *name) |
| | 465 | { |
| | 466 | char m_name[5]; |
| | 467 | |
| | 468 | m_name[0] = name[0]; |
| | 469 | m_name[1] = name[1]; |
| | 470 | m_name[2] = name[2]; |
| | 471 | m_name[3] = name[3]; |
| | 472 | m_name[4] = '\0'; |
| | 473 | printf("%s",m_name); |
| | 474 | } |
| | 475 | |
| | 476 | // Convert VMODIDATA.vmodidata_label names to VMODIDATA.vmodidata_ptr |
| | 477 | |
| | 478 | void ConvertVModuleNameToPointer(VMODIDATA *vmodidata_ptr, VMODULE *v_array_ptr) |
| | 479 | { |
| | 480 | int StillSearching = 1; |
| | 481 | |
| | 482 | /* Set "null" names to null pointers */ |
| | 483 | |
| | 484 | if(CompareName((char *)&vmodidata_ptr->vmodidata_label, "null")) |
| | 485 | { |
| | 486 | vmodidata_ptr->vmodidata_ptr = 0; |
| | 487 | return; |
| | 488 | } |
| | 489 | |
| | 490 | /* Search for the VMODULE with the same name */ |
| | 491 | |
| | 492 | while(!v_array_ptr->end_module && StillSearching) |
| | 493 | { |
| | 494 | if(CompareName((char *)&vmodidata_ptr->vmodidata_label, (char *)&v_array_ptr->vmod_name)) |
| | 495 | { |
| | 496 | /* |
| | 497 | printf(" found name "); |
| | 498 | PrintName(&v_array_ptr->vmod_name); |
| | 499 | printf(", ptr %u\n", v_array_ptr); |
| | 500 | */ |
| | 501 | |
| | 502 | vmodidata_ptr->vmodidata_ptr = v_array_ptr; |
| | 503 | StillSearching = 0; |
| | 504 | } |
| | 505 | |
| | 506 | v_array_ptr++; |
| | 507 | } |
| | 508 | |
| | 509 | /* If the name was not found, make this a null pointer */ |
| | 510 | |
| | 511 | if(StillSearching) |
| | 512 | { |
| | 513 | if(v_array_ptr->end_module) |
| | 514 | vmodidata_ptr->vmodidata_ptr = v_array_ptr; |
| | 515 | else |
| | 516 | vmodidata_ptr->vmodidata_ptr = NULL; |
| | 517 | } |
| | 518 | } |
| | 519 | |
| | 520 | /* |
| | 521 | |
| | 522 | VMODIDATA is the data associated with VMODI, the VMODULE instruction. Some |
| | 523 | of the data items are names which need to be converted to pointers. |
| | 524 | |
| | 525 | */ |
| | 526 | |
| | 527 | void PreprocessVMODIDATA(VMODULE *v_ptr) |
| | 528 | { |
| | 529 | VMODULE *v_array_ptr = v_ptr; |
| | 530 | |
| | 531 | while(!v_ptr->end_module) |
| | 532 | { |
| | 533 | if(!(v_ptr->vmod_flags & vm_flag_gotptrs)) |
| | 534 | { |
| | 535 | switch(v_ptr->vmod_instr) |
| | 536 | { |
| | 537 | case vmodi_null: |
| | 538 | break; |
| | 539 | case vmodi_bra_vc: |
| | 540 | ConvertVModuleNameToPointer(&v_ptr->vmod_data, v_array_ptr); |
| | 541 | } |
| | 542 | |
| | 543 | v_ptr->vmod_flags |= vm_flag_gotptrs; |
| | 544 | } |
| | 545 | |
| | 546 | v_ptr++; |
| | 547 | } |
| | 548 | } |
| | 549 | |
| | 550 | // Convert MREF name to MREF pointer |
| | 551 | |
| | 552 | void ConvertModuleNameToPointer(MREF *mref_ptr, MODULE **m_array_ptr) |
| | 553 | { |
| | 554 | int StillSearching = 1; |
| | 555 | |
| | 556 | /* Set "null" names to null pointers */ |
| | 557 | |
| | 558 | if(CompareName((char *)&mref_ptr->mref_name, "null")) |
| | 559 | { |
| | 560 | mref_ptr->mref_ptr = 0; |
| | 561 | return; |
| | 562 | } |
| | 563 | |
| | 564 | /* Search for the module with the same name */ |
| | 565 | |
| | 566 | while(*m_array_ptr && StillSearching) |
| | 567 | { |
| | 568 | MODULE *m_ptr = *m_array_ptr; |
| | 569 | |
| | 570 | if(CompareName((char *)&mref_ptr->mref_name, (char *)&m_ptr->m_name)) |
| | 571 | { |
| | 572 | /* |
| | 573 | printf(" found name "); |
| | 574 | PrintName(&m_ptr->m_name); |
| | 575 | printf(", ptr %u\n", m_ptr); |
| | 576 | */ |
| | 577 | |
| | 578 | mref_ptr->mref_ptr = m_ptr; |
| | 579 | StillSearching = 0; |
| | 580 | } |
| | 581 | |
| | 582 | m_array_ptr++; |
| | 583 | } |
| | 584 | |
| | 585 | /* If the name was not found, make this a null pointer */ |
| | 586 | |
| | 587 | if(StillSearching) |
| | 588 | mref_ptr->mref_ptr = 0; |
| | 589 | } |
| | 590 | |
| | 591 | /* |
| | 592 | The Module Preprocessor |
| | 593 | |
| | 594 | Pass the array of pointers to modules. |
| | 595 | This function creates module indices and converts names into pointers. |
| | 596 | */ |
| | 597 | |
| | 598 | void PreprocessModuleArray() |
| | 599 | { |
| | 600 | MODULE **m_array_ptr = MainScene.sm_marray; |
| | 601 | MODULE **m_array = m_array_ptr; |
| | 602 | ModuleArraySize = 0; |
| | 603 | |
| | 604 | //printf("PreprocessModuleArray %u\n", m_array_ptr); |
| | 605 | |
| | 606 | while(*m_array) |
| | 607 | { |
| | 608 | /* Get the module pointer */ |
| | 609 | |
| | 610 | MODULE *m_ptr = *m_array; |
| | 611 | |
| | 612 | m_ptr->m_index = ModuleArraySize++; |
| | 613 | |
| | 614 | /* |
| | 615 | printf("\nModule %u, ", m_ptr); |
| | 616 | PrintName(&m_ptr->m_name); |
| | 617 | printf(", index %d\n", m_ptr->m_index); |
| | 618 | printf(" (vptr = "); |
| | 619 | PrintName(&m_ptr->m_vptr.mref_name); |
| | 620 | printf(")\n"); |
| | 621 | */ |
| | 622 | |
| | 623 | /* Convert module references from names to pointers */ |
| | 624 | |
| | 625 | if(!(m_ptr->m_flags & m_flag_gotptrs)) |
| | 626 | { |
| | 627 | if(m_ptr->m_vmptr) |
| | 628 | { |
| | 629 | /* Convert VMODIDATA names to pointers */ |
| | 630 | |
| | 631 | PreprocessVMODIDATA(m_ptr->m_vmptr); |
| | 632 | |
| | 633 | /* Convert MREF names to pointers */ |
| | 634 | /* |
| | 635 | v_ptr = m_ptr->m_vmptr; |
| | 636 | |
| | 637 | while(!v_ptr->end_module) |
| | 638 | { |
| | 639 | ConvertModuleNameToPointer(&v_ptr->vmod_mref, m_array_ptr); |
| | 640 | v_ptr++; |
| | 641 | } |
| | 642 | */ |
| | 643 | } |
| | 644 | |
| | 645 | /* Tell the module that its names are now pointers */ |
| | 646 | |
| | 647 | m_ptr->m_flags |= m_flag_gotptrs; |
| | 648 | } |
| | 649 | |
| | 650 | /* Next module array entry */ |
| | 651 | |
| | 652 | m_array++; |
| | 653 | } |
| | 654 | |
| | 655 | ModuleCurrVisArray = malloc(ModuleArraySize); |
| | 656 | |
| | 657 | if (NULL == ModuleCurrVisArray) |
| | 658 | { |
| | 659 | printf("GetModuleVisArrays() failed\n"); |
| | 660 | } |
| | 661 | else |
| | 662 | { |
| | 663 | int i; |
| | 664 | for(i = 0; i < ModuleArraySize; i++) |
| | 665 | ModuleCurrVisArray[i] = 0; |
| | 666 | } |
| | 667 | |
| | 668 | //printf("visibility arrays ok, size %d\n", ModuleArraySize); |
| | 669 | } |
| | 670 | |
| | 671 | int IsAIModuleVisibleFromAIModule(AIMODULE *source, AIMODULE *target) |
| | 672 | { |
| | 673 | if ((source == NULL) || (target == NULL)) |
| | 674 | return 0; |
| | 675 | else if (source == target) |
| | 676 | return 1; |
| | 677 | else |
| | 678 | { |
| | 679 | MODULE **sourceModulelistPtr = source->m_module_ptrs; |
| | 680 | |
| | 681 | while(*sourceModulelistPtr) |
| | 682 | { |
| | 683 | MODULE **targetModulelistPtr = target->m_module_ptrs; |
| | 684 | |
| | 685 | while(*targetModulelistPtr) |
| | 686 | { |
| | 687 | if (IsModuleVisibleFromModule(*sourceModulelistPtr,*targetModulelistPtr)) |
| | 688 | return 1; |
| | 689 | |
| | 690 | targetModulelistPtr++; |
| | 691 | } |
| | 692 | |
| | 693 | sourceModulelistPtr++; |
| | 694 | } |
| | 695 | |
| | 696 | return 0; |
| | 697 | } |
| | 698 | } |
| | 699 | |
| | 700 | void DeallocateModules() |
| | 701 | { |
| | 702 | MODULE ** m_arrayPtr = MainScene.sm_marray; |
| | 703 | int i = 0; |
| | 704 | |
| | 705 | while (*m_arrayPtr) |
| | 706 | { |
| | 707 | MODULE * this_mod = *m_arrayPtr++; |
| | 708 | |
| | 709 | if(this_mod->m_mapptr) |
| | 710 | free(this_mod->m_mapptr); |
| | 711 | |
| | 712 | if(this_mod->name) |
| | 713 | free(this_mod->name); |
| | 714 | |
| | 715 | if(this_mod->m_vmptr) |
| | 716 | free(this_mod->m_vmptr); |
| | 717 | |
| | 718 | if(this_mod->m_lightarray) |
| | 719 | free(this_mod->m_lightarray); |
| | 720 | } |
| | 721 | |
| | 722 | if(MainScene.sm_module) |
| | 723 | free(MainScene.sm_module); |
| | 724 | |
| | 725 | if(MainScene.sm_marray) |
| | 726 | free(MainScene.sm_marray); |
| | 727 | |
| | 728 | MainScene.sm_module = NULL; |
| | 729 | MainScene.sm_marray = NULL; |
| | 730 | |
| | 731 | for(i=0; i < AIModuleArraySize; i++) |
| | 732 | { |
| | 733 | AIMODULE* aim = &AIModuleArray[i]; |
| | 734 | |
| | 735 | if(aim->m_link_ptrs) |
| | 736 | free(aim->m_link_ptrs); |
| | 737 | |
| | 738 | if(aim->m_module_ptrs) |
| | 739 | free(aim->m_module_ptrs); |
| | 740 | |
| | 741 | if(aim->m_waypoints) |
| | 742 | { |
| | 743 | WAYPOINT_HEADER* wh = aim->m_waypoints; |
| | 744 | int j = 0; |
| | 745 | |
| | 746 | for(; j < wh->num_waypoints; j++) |
| | 747 | { |
| | 748 | WAYPOINT_VOLUME* wv = &wh->first_waypoint[j]; |
| | 749 | |
| | 750 | if(wv->first_link) |
| | 751 | free(wv->first_link); |
| | 752 | } |
| | 753 | |
| | 754 | if(wh->first_waypoint) |
| | 755 | free(wh->first_waypoint); |
| | 756 | |
| | 757 | free(wh); |
| | 758 | } |
| | 759 | } |
| | 760 | |
| | 761 | free(AIModuleArray); |
| | 762 | AIModuleArray = NULL; |
| | 763 | |
| | 764 | free(ModuleCurrVisArray); |
| | 765 | ModuleCurrVisArray = NULL; |
| | 766 | } |