avp/3dc/MODULE.C
Rebellion Developments 218ca90543 Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from:
https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code

All text files were converted to Unix format.
2019-08-19 05:45:17 +02:00

1131 lines
19 KiB
C

#include "3dc.h"
#include "inline.h"
#include "module.h"
#include "stratdef.h"
#include "bh_types.h"
#include "pvisible.h"
#include "pfarlocs.h"
#include "avpview.h"
#include "ourasert.h"
#include "pldghost.h"
#if SupportModules
/* imported externs */
extern SCENE Global_Scene;
extern int NumActiveBlocks;
extern DISPLAYBLOCK *ActiveBlockList[];
extern DISPLAYBLOCK *dptr_last;
extern unsigned char KeyASCII;
/**** Protos ****/
void FindVisibleModules(VMODULE *vptr,int flag);
/**** Statics ****/
static MODULE **Global_ModuleArrayPtr;
void AllNewModuleHandler(void)
{
{
int i;
SCENEMODULE *smptr;
smptr = Global_ModulePtr[Global_Scene];
Global_ModuleArrayPtr = smptr->sm_marray;
for(i = 0; i < ModuleArraySize; i++)
{
ModuleCurrVisArray[i] = 0;
}
}
/* handle dynamic module objects */
{
int numberOfObjects = NumActiveBlocks;
while (numberOfObjects--)
{
DISPLAYBLOCK* objectPtr = ActiveBlockList[numberOfObjects];
if(objectPtr->ObFlags3 & ObFlag3_DynamicModuleObject)
{
STRATEGYBLOCK *sbPtr = objectPtr->ObStrategyBlock;
sbPtr->containingModule = (ModuleFromPosition(&(objectPtr->ObWorld), sbPtr->containingModule));
if (sbPtr->containingModule)
if (ModuleIsPhysical(sbPtr->containingModule))
{
ModuleCurrVisArray[sbPtr->containingModule->m_index] = 1;
if(sbPtr->containingModule->m_vmptr) FindVisibleModules(sbPtr->containingModule->m_vmptr,1);
}
}
}
}
/*If this is an network game , and this machine is the ai server , then need to check if
there are any aliens near to other players*/
if(AvP.Network!=I_No_Network && AvP.NetworkAIServer)
{
/* go through the strategy blocks looking for players*/
int sbIndex;
for(sbIndex=0;sbIndex<NumActiveStBlocks;sbIndex++)
{
STRATEGYBLOCK *playerSbPtr = ActiveStBlockList[sbIndex];
NETGHOSTDATABLOCK *ghostData;
if(playerSbPtr->I_SBtype!=I_BehaviourNetGhost) continue;
ghostData = (NETGHOSTDATABLOCK *)playerSbPtr->SBdataptr;
if(ghostData->type==I_BehaviourAlienPlayer ||
ghostData->type==I_BehaviourMarinePlayer ||
ghostData->type==I_BehaviourPredatorPlayer)
{
int sbIndex2;
//found one of the players
if(!playerSbPtr->containingModule) continue;
/*now search through the strategy blocks , to see if any aliens are
visible from the player's location*/
for(sbIndex2=0;sbIndex2<NumActiveStBlocks;sbIndex2++)
{
STRATEGYBLOCK *alienSbPtr = ActiveStBlockList[sbIndex2];
/*Is it an alien?*/
if(alienSbPtr->I_SBtype!=I_BehaviourAlien) continue;
if(!alienSbPtr->containingModule) continue;
if(IsModuleVisibleFromModule(playerSbPtr->containingModule,alienSbPtr->containingModule))
{
/*The player can see the alien , so link in all modules that the
player can see*/
if (ModuleIsPhysical(playerSbPtr->containingModule))
{
ModuleCurrVisArray[playerSbPtr->containingModule->m_index] = 1;
if(playerSbPtr->containingModule->m_vmptr) FindVisibleModules(playerSbPtr->containingModule->m_vmptr,1);
}
/*Since all modules visible by this player have now been linked , don't need
to check for any more aliens for this player*/
break;
}
}
}
}
}
/* handle player visibilities */
{
extern MODULE * playerPherModule;
playerPherModule = (ModuleFromPosition(&(Global_VDB_Ptr->VDB_World), playerPherModule));
if(!playerPherModule)
{
playerPherModule = (ModuleFromPosition(&(Player->ObWorld), playerPherModule));
}
if (playerPherModule)
{
ModuleCurrVisArray[playerPherModule->m_index] = 2;
if(playerPherModule->m_vmptr) FindVisibleModules(playerPherModule->m_vmptr,2);
}
}
/* handle AIMODULE visibility stuff */
{
int i;
for(i = 0; i < ModuleArraySize; i++)
{
if (ModuleCurrVisArray[i] == 2)
{
AIMODULE *aiModulePtr = Global_ModuleArrayPtr[i]->m_aimodule;
if (aiModulePtr)
{
MODULE **modulelistPtr = aiModulePtr->m_module_ptrs;
while(*modulelistPtr)
{
int index = (*modulelistPtr)->m_index;
if (!ModuleCurrVisArray[index]) ModuleCurrVisArray[index]=1;
modulelistPtr++;
}
}
}
}
}
/* update active block list */
{
int i;
for(i = 0; i < ModuleArraySize; i++)
{
MODULE *mptr = Global_ModuleArrayPtr[i];
if(ModuleCurrVisArray[i])
{
if(mptr->m_dptr == 0 && ((mptr->m_flags & m_flag_dormant) == 0))
{
AllocateModuleObject(mptr);
}
}
else
{
if(mptr->m_dptr) DeallocateModuleObject(mptr);
}
}
}
/* call Patrick's code */
DoObjectVisibilities();
}
void FindVisibleModules(VMODULE *vptr,int flag)
{
while(vptr->vmod_type != vmtype_term)
{
MODULE *mptr;
/* Add this module to the visible array */
if(vptr->vmod_mref.mref_ptr)
{
mptr = vptr->vmod_mref.mref_ptr;
ModuleCurrVisArray[mptr->m_index] = flag;
}
/* VMODULE instructions */
switch(vptr->vmod_instr)
{
case vmodi_null:
vptr++;
break;
case vmodi_bra_vc:
/* If the door/viewport is closed... */
/* Branch to this vptr */
/* else vptr++; */
if(mptr)
{
if(mptr->m_flags & m_flag_open) vptr++;
else vptr = vptr->vmod_data.vmodidata_ptr;
}
break;
}
}
}
int ThisObjectIsInAModuleVisibleFromCurrentlyVisibleModules(STRATEGYBLOCK *sbPtr)
{
VMODULE *vPtr;
GLOBALASSERT(sbPtr);
GLOBALASSERT(sbPtr->containingModule);
vPtr = sbPtr->containingModule->m_vmptr;
GLOBALASSERT(vPtr);
if(ModuleCurrVisArray[sbPtr->containingModule->m_index] == 2)
{
return 1;
}
while(vPtr->vmod_type != vmtype_term)
{
MODULE *mptr;
/* consider this module */
if(vPtr->vmod_mref.mref_ptr)
{
mptr = vPtr->vmod_mref.mref_ptr;
if(ModuleCurrVisArray[mptr->m_index] == 2)
{
if(vPtr->vmod_instr==vmodi_bra_vc)
{
if(mptr->m_flags & m_flag_open) return 1;
}
else
{
return 1;
}
}
}
/* VMODULE instructions */
switch(vPtr->vmod_instr)
{
case vmodi_null:
vPtr++;
break;
case vmodi_bra_vc:
/* If the door/viewport is closed... */
/* Branch to this vPtr */
/* else vPtr++; */
if(mptr)
{
if(mptr->m_flags & m_flag_open) vPtr++;
else vPtr = vPtr->vmod_data.vmodidata_ptr;
}
break;
}
}
return 0;
}
void ModuleFunctions(MODULE *mptr, MFUNCTION mf)
{
switch(mf)
{
case mfun_null:
break;
}
}
void AllocateModuleObject(MODULE *mptr)
{
DISPLAYBLOCK *dptr;
MODULEMAPBLOCK *mapblockptr;
STRATEGYBLOCK *sb = 0;
#if SupportMorphing
MORPHCTRL *mc;
#endif
dptr_last = 0;
mptr->m_dptr = 0;
if(mptr == 0) return; /* Whoops! */
if(mptr->m_mapptr == 0) return; /* Not all modules have maps */
dptr = CreateActiveObject();
if(dptr) {
/* Tell the module we exist */
mptr->m_dptr = dptr;
/* Tell the object who its module is */
dptr->ObMyModule = mptr;
/* Get the strategy block, if it exists */
if(mptr->m_sbptr) sb = mptr->m_sbptr;
/* If there is a STRATEGYBLOCK, tell it we exist */
if(sb) {
dptr->ObStrategyBlock = sb;
sb->SBdptr = dptr;
}
/* Read the map */
mapblockptr = mptr->m_mapptr;
dptr->ObShape = mapblockptr->MapShape;
CopyLocation(&mapblockptr->MapWorld, &dptr->ObWorld);
CopyEuler(&mapblockptr->MapEuler, &dptr->ObEuler);
dptr->ObFlags = mapblockptr->MapFlags;
dptr->ObFlags2 = mapblockptr->MapFlags2;
dptr->ObFlags3 = mapblockptr->MapFlags3;
#if SupportMorphing
/* If there is a strategy block, see if it has a MORPHCTRL structure */
if(sb) {
if(sb->SBmorphctrl) {
/* Pass MORPHCTRL to dptr */
dptr->ObMorphCtrl = sb->SBmorphctrl;
/* Copy the morph pointer from the map to the dptr */
mc = dptr->ObMorphCtrl;
mc->ObMorphHeader = mapblockptr->MapMorphHeader;
/* OLD TEST - These values are now set elsewhere */
#if 0
if(mc->ObMorphHeader) {
mc->ObMorphCurrFrame = 0;
mc->ObMorphFlags = mph_flag_play/* | mph_flag_noloop | mph_flag_reverse*/;
mc->ObMorphSpeed = ONE_FIXED;
}
#endif
}
}
#endif /* Support Morphing */
#if InterfaceEngine
dbptr->o_chunk = mapblockptr->o_chunk;
#endif
dptr->ObLightType = LightType_PerVertex;
dptr->ObFlags |= ObFlag_MultLSrc;
if(mapblockptr->MapVDBData)
MapSetVDB(dptr, mapblockptr->MapVDBData);
dptr->ObLightType = mapblockptr->MapLightType;
MapBlockInit(dptr);
/* KJL 14:15:34 04/19/97 - their used to be lots of maths here
to calculate orientation, but in AvP all modules are aligned to
the world space axes... */
{
extern MATRIXCH IdentityMatrix;
dptr->ObMat = IdentityMatrix;
}
/*
Module lights
There is an option for a pointer to an array of lights in a module
structure. These lights are transferred to the display block and
flagged as "LFlag_WasNotAllocated" so that "DeallocateLightBlock()"
knows to ignore them.
The number of lights in the array is "m_numlights" and the pointer
is called "m_lightarray".
The addition of non-allocated does not need to be a module specific
option.
Non-allocated lights can co-exist peacefully with the other lights.
*/
if(mptr->m_numlights && mptr->m_lightarray) {
LIGHTBLOCK *lptr_array = mptr->m_lightarray;
int i;
for(i = mptr->m_numlights; i!=0; i--) {
/* Make sure the light is flagged correctly */
lptr_array->LightFlags |= LFlag_WasNotAllocated;
/* Add the light */
AddLightBlock(dptr, lptr_array);
/* Next light from the array */
lptr_array++;
}
}
/*
As with shared points, extra item data for prelighting is also
copied from the module to the display block.
WARNING:
Allocation and deallocation of this pointer is the responsibility
of the user!
*/
dptr->ObEIDPtr = mptr->m_extraitemdata;
/* Added Name to DISPLAYBLOCK */
#if SupportWindows95
dptr->name = mptr->name;
#endif
MapPostProcessing(dptr);
ModuleObjectJustAllocated(mptr); /* Project Function */
/* Bug Fix */
if (dptr->ObStrategyBlock) {
STRATEGYBLOCK *sbptr=dptr->ObStrategyBlock;
if (sbptr->I_SBtype==I_BehaviourSimpleAnimation) {
SIMPLE_ANIM_BEHAV_BLOCK *sanimbhv;
sanimbhv = (SIMPLE_ANIM_BEHAV_BLOCK*)(sbptr->SBdataptr);
GLOBALASSERT(sanimbhv->bhvr_type == I_BehaviourSimpleAnimation);
GLOBALASSERT (dptr == sbptr->SBdptr);
if(!dptr->ObTxAnimCtrlBlks) {
dptr->ObTxAnimCtrlBlks = sanimbhv->tacbSimple;
}
}
}
}
dptr_last = dptr;
}
void DeallocateModuleObject(MODULE *mptr)
{
DISPLAYBLOCK *dptr;
STRATEGYBLOCK *sb;
if(mptr->m_dptr) {
ModuleObjectAboutToBeDeallocated(mptr); /* Project Function */
dptr = mptr->m_dptr;
DestroyActiveObject(dptr);
/* Clear module reference to dptr */
mptr->m_dptr = 0;
/* If there is a STRATEGYBLOCK, clear that reference too */
if(mptr->m_sbptr) {
sb = mptr->m_sbptr;
sb->SBdptr = 0;
}
}
}
/*
The Module Preprocessor
Pass the array of pointers to modules.
This function creates module indices and converts names into pointers.
*/
/*
temp patch to match current chunk
loader configuration
*/
void PreprocessAllModules(void)
{
SCENEMODULE **sm_array_ptr;
SCENEMODULE *sm_ptr;
if(Global_ModulePtr == 0) return;
sm_array_ptr = Global_ModulePtr;
while(*sm_array_ptr)
{
sm_ptr = *sm_array_ptr;
PreprocessModuleArray(sm_ptr->sm_marray);
sm_array_ptr++;
}
}
/*
A special function to deallocate the module visibility arrays
*/
void DeallocateModuleVisArrays(void)
{
if(ModuleCurrVisArray) {
DeallocateMem(ModuleCurrVisArray);
ModuleCurrVisArray = 0;
}
}
/*
Allocate the two arrays used to keep track of module visibility from
frame to frame. The function uses the global scene variable to access the
appropriate SCENEMODULE and find out how many modules are present. It also
deallocates the previous arrays if they exist.
*/
int GetModuleVisArrays(void)
{
SCENEMODULE *sm_ptr;
MODULE **m_array_ptr;
MODULE *m_ptr;
int index, i;
if(Global_ModulePtr == 0) return No;
DeallocateModuleVisArrays();
sm_ptr = Global_ModulePtr[Global_Scene];
m_array_ptr = sm_ptr->sm_marray;
index = smallint;
while(*m_array_ptr) {
m_ptr = *m_array_ptr++;
if(m_ptr->m_index > index) index = m_ptr->m_index;
}
ModuleArraySize = index + 1;
ModuleCurrVisArray = AllocateMem(ModuleArraySize);
if(ModuleCurrVisArray)
{
for(i = 0; i < ModuleArraySize; i++)
{
ModuleCurrVisArray[i] = 0;
}
#if 0
textprint("visibility arrays ok, size %d\n", ModuleArraySize);
#endif
return Yes;
}
else return No;
}
#define ppma_print No
#if 1
void PreprocessModuleArray(MODULE **m_array_ptr)
{
MODULE **m_array = m_array_ptr;
MODULE *m_ptr;
int index;
#if ppma_print
textprint("PreprocessModuleArray %u\n", m_array_ptr);
#endif
index = 0;
while(*m_array) {
/* Get the module pointer */
m_ptr = *m_array;
/* Assign the module an index */
m_ptr->m_index = index++;
#if ppma_print
textprint("\nModule %u, ", m_ptr);
PrintName(&m_ptr->m_name);
textprint(", index %d\n", m_ptr->m_index);
textprint(" (vptr = ");
PrintName(&m_ptr->m_vptr.mref_name);
textprint(")\n");
#endif
/* Convert module references from names to pointers */
if(!(m_ptr->m_flags & m_flag_gotptrs)) {
#if 0
/* Vertical Pointer */
ConvertModuleNameToPointer(&m_ptr->m_vptr, m_array_ptr);
/* Extent Pointer */
ConvertModuleNameToPointer(&m_ptr->m_ext, m_array_ptr);
/* Function Pointer */
ConvertModuleNameToPointer(&m_ptr->m_funref, m_array_ptr);
// Hack by John to make the m_link pointers work
if (m_ptr->m_link_ptrs)
{
MREF * m_link_ptr = m_ptr->m_link_ptrs;
while (m_link_ptr->mref_ptr)
{
ConvertModuleNameToPointer(m_link_ptr++, m_array_ptr);
}
}
#endif
/* VMODULE Array */
if(m_ptr->m_vmptr) {
/* Convert VMODIDATA names to pointers */
PreprocessVMODIDATA(m_ptr->m_vmptr);
/* Convert MREF names to pointers */
/*
v_ptr = m_ptr->m_vmptr;
while(v_ptr->vmod_type != vmtype_term) {
ConvertModuleNameToPointer(&v_ptr->vmod_mref, m_array_ptr);
v_ptr++;
}
*/
}
/* Tell the module that its names are now pointers */
m_ptr->m_flags |= m_flag_gotptrs;
}
/* Calculate module extents */
//I'll set the extents and world position in the loaders -Richard.
//GetModuleMapData(m_ptr);
/* Next module array entry */
m_array++;
}
/*WaitForReturn();*/
}
#else
#endif
/*
VMODIDATA is the data associated with VMODI, the VMODULE instruction. Some
of the data items are names which need to be converted to pointers.
*/
void PreprocessVMODIDATA(VMODULE *v_ptr)
{
VMODULE *v_array_ptr = v_ptr;
while(v_ptr->vmod_type != vmtype_term) {
if(!(v_ptr->vmod_flags & vm_flag_gotptrs)) {
switch(v_ptr->vmod_instr) {
case vmodi_null:
break;
case vmodi_bra_vc:
ConvertVModuleNameToPointer(&v_ptr->vmod_data, v_array_ptr);
break;
}
v_ptr->vmod_flags |= vm_flag_gotptrs;
}
v_ptr++;
}
}
/*
Convert MREF name to MREF pointer
*/
#define cmntp_print No
void ConvertModuleNameToPointer(MREF *mref_ptr, MODULE **m_array_ptr)
{
MODULE *m_ptr;
int StillSearching;
#if cmntp_print
textprint("ConvertModuleNameToPointer\n");
#endif
/* Set "null" names to null pointers */
if(CompareName((char *)&mref_ptr->mref_name, "null")) {
#if cmntp_print
textprint("making ptr null\n");
#endif
mref_ptr->mref_ptr = 0;
return;
}
/* Search for the module with the same name */
#if cmntp_print
textprint("Searching for name...\n");
#endif
StillSearching = Yes;
while(*m_array_ptr && StillSearching) {
m_ptr = *m_array_ptr;
if(CompareName((char *)&mref_ptr->mref_name, (char *)&m_ptr->m_name)) {
#if cmntp_print
textprint(" found name ");
PrintName(&m_ptr->m_name);
textprint(", ptr %u\n", m_ptr);
#endif
mref_ptr->mref_ptr = m_ptr;
StillSearching = No;
}
m_array_ptr++;
}
/* If the name was not found, make this a null pointer */
if(StillSearching) mref_ptr->mref_ptr = 0;
}
/*
Convert VMODIDATA.vmodidata_label names to VMODIDATA.vmodidata_ptr
*/
#define cvmntp_print No
void ConvertVModuleNameToPointer(VMODIDATA *vmodidata_ptr, VMODULE *v_array_ptr)
{
int StillSearching;
#if cvmntp_print
textprint("ConvertVModuleNameToPointer\n");
#endif
/* Set "null" names to null pointers */
if(CompareName((char *)&vmodidata_ptr->vmodidata_label, "null")) {
#if cvmntp_print
textprint(" making vmodidata_ptr null\n");
#endif
vmodidata_ptr->vmodidata_ptr = 0;
return;
}
/* Search for the VMODULE with the same name */
#if cvmntp_print
textprint(" Searching for name...\n");
#endif
StillSearching = Yes;
while((v_array_ptr->vmod_type != vmtype_term) && StillSearching) {
if(CompareName((char *)&vmodidata_ptr->vmodidata_label, (char *)&v_array_ptr->vmod_name)) {
#if cmntp_print
textprint(" found name ");
PrintName(&v_array_ptr->vmod_name);
textprint(", ptr %u\n", v_array_ptr);
#endif
vmodidata_ptr->vmodidata_ptr = v_array_ptr;
StillSearching = No;
}
v_array_ptr++;
}
/* If the name was not found, make this a null pointer */
if(StillSearching)
{
if(v_array_ptr->vmod_type == vmtype_term)
{
vmodidata_ptr->vmodidata_ptr = v_array_ptr;
}
else
{
vmodidata_ptr->vmodidata_ptr = 0;
}
}
}
int CompareName(char *name1, char *name2)
{
int i;
for(i = 4; i!=0; i--) {
if(*name1++ != *name2++) return No;
}
return Yes;
}
void PrintName(char *name)
{
char m_name[5];
m_name[0] = name[0];
m_name[1] = name[1];
m_name[2] = name[2];
m_name[3] = name[3];
m_name[4] = 0;
textprint(m_name);
}
int IsModuleVisibleFromModule(MODULE *source, MODULE *target) {
VMODULE *vptr;
MODULE *mptr;
int gotit;
vptr=source->m_vmptr;
gotit=0;
if ((source==NULL)||(target==NULL)) return(0);
if (source==target) return(1);
while(! ((vptr->vmod_type == vmtype_term)||(gotit)) ) {
/* Add this module to the visible array */
if(vptr->vmod_mref.mref_ptr) {
mptr = vptr->vmod_mref.mref_ptr;
if (mptr==target) gotit=1;
}
/* VMODULE instructions */
switch(vptr->vmod_instr) {
case vmodi_null:
vptr++;
break;
case vmodi_bra_vc:
/* NYD */
/* If the door/viewport is closed... */
/* Branch to this vptr */
if(mptr)
{
if(mptr->m_flags & m_flag_open)
vptr++;
else
vptr = vptr->vmod_data.vmodidata_ptr;
}
/* else vptr++; */
break;
}
}
return(gotit);
}
int IsAIModuleVisibleFromAIModule(AIMODULE *source,AIMODULE *target) {
if ((source==NULL)||(target==NULL)) return(0);
if (source==target) return(1);
{
MODULE **targetModulelistPtr;
MODULE **sourceModulelistPtr = source->m_module_ptrs;
while(*sourceModulelistPtr) {
targetModulelistPtr=target->m_module_ptrs;
while(*targetModulelistPtr) {
if (IsModuleVisibleFromModule(*sourceModulelistPtr,*targetModulelistPtr)) {
return(1);
}
targetModulelistPtr++;
}
sourceModulelistPtr++;
}
}
return(0);
}
#endif