avp/3dc/win95/wpchunk.cpp
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

575 lines
12 KiB
C++

#include "wpchunk.hpp"
//macro for helping to force inclusion of chunks when using libraries
FORCE_CHUNK_INCLUDE_IMPLEMENT(wpchunk)
ChunkWaypoint::ChunkWaypoint()
{
index=-1;
NumWPLinks=0;
WayLinks=0;
NumModLinks=0;
ModLinks=0;
flags=0;
spare2=0;
}
ChunkWaypoint::~ChunkWaypoint()
{
if(WayLinks) delete [] WayLinks;
if(ModLinks) delete [] ModLinks;
}
ModuleLink::~ModuleLink()
{
if(module_name) delete module_name;
}
RIF_IMPLEMENT_DYNCREATE("WAYPOINT",Module_Waypoint_Chunk)
#if UseOldChunkLoader
Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
:Chunk(parent,"WAYPOINT")
{
NumWaypoints=*(int*)data;
data+=4;
if(NumWaypoints)
Waypoints=new ChunkWaypoint[NumWaypoints];
else
Waypoints=0;
for(int i=0;i<NumWaypoints;i++)
{
ChunkWaypoint* cw=&Waypoints[i];
cw->index=i;
cw->min=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
cw->max=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
cw->centre=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
cw->flags=*(int*)data;
data+=4;
cw->spare2=*(int*)data;
data+=4;
cw->NumWPLinks=*(int*)data;
data+=4;
if(cw->NumWPLinks)
cw->WayLinks=new WaypointLink[cw->NumWPLinks];
else
cw->WayLinks=0;
for(int j=0;j<cw->NumWPLinks;j++)
{
cw->WayLinks[j]=*(WaypointLink*)data;
data+=sizeof(WaypointLink);
}
cw->NumModLinks=*(int*)data;
data+=4;
if(cw->NumModLinks)
cw->ModLinks=new ModuleLink[cw->NumModLinks];
else
cw->ModLinks=0;
for(j=0;j<cw->NumModLinks;j++)
{
ModuleLink* ml=&cw->ModLinks[j];
ml->module_name=new char[strlen(data)+1];
strcpy(ml->module_name,data);
data+=(strlen(data)+4)&~3;
ml->flags=*(int*)data;
data+=4;
}
}
spare1=*(int*)data;
data+=4;
spare2=*(int*)data;
data+=4;
}
#else
Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
:Chunk(parent,"WAYPOINT")
{
NumWaypoints=*(int*)data;
data+=4;
NumGroundWaypoints=0;
NumAlienWaypoints=0;
AlienWaypoints=0;
GroundWaypoints=0;
if(NumWaypoints)
Waypoints=new ChunkWaypoint[NumWaypoints];
else
Waypoints=0;
if(NumWaypoints)
{
int first_ground_waypoint=-1;
for(int i=0;i<NumWaypoints;i++)
{
ChunkWaypoint* cw=&Waypoints[i];
cw->index=i;
cw->min=*(ChunkVectorInt*)data;
data+=sizeof(ChunkVectorInt);
cw->max=*(ChunkVectorInt*)data;
data+=sizeof(ChunkVectorInt);
cw->centre=*(ChunkVectorInt*)data;
data+=sizeof(ChunkVectorInt);
cw->flags=*(int*)data;
data+=4;
cw->spare2=*(int*)data;
data+=4;
cw->NumWPLinks=*(int*)data;
data+=4;
if(cw->NumWPLinks)
cw->WayLinks=new WaypointLink[cw->NumWPLinks];
else
cw->WayLinks=0;
for(int j=0;j<cw->NumWPLinks;j++)
{
cw->WayLinks[j]=*(WaypointLink*)data;
data+=sizeof(WaypointLink);
}
cw->NumModLinks=*(int*)data;
data+=4;
if(cw->NumModLinks)
cw->ModLinks=new ModuleLink[cw->NumModLinks];
else
cw->ModLinks=0;
for(j=0;j<cw->NumModLinks;j++)
{
ModuleLink* ml=&cw->ModLinks[j];
ml->module_name=new char[strlen(data)+1];
strcpy(ml->module_name,data);
data+=(strlen(data)+4)&~3;
ml->flags=*(int*)data;
data+=4;
}
if(cw->flags & WaypointFlag_FirstGroundWaypoint)
{
first_ground_waypoint=i;
cw->flags &=~WaypointFlag_FirstGroundWaypoint;
}
}
if(first_ground_waypoint>=0)
{
GroundWaypoints=&Waypoints[first_ground_waypoint];
NumGroundWaypoints=NumWaypoints-first_ground_waypoint;
}
NumAlienWaypoints=NumWaypoints-NumGroundWaypoints;
if(NumAlienWaypoints)
{
AlienWaypoints=&Waypoints[0];
}
}
spare1=*(int*)data;
data+=4;
spare2=*(int*)data;
data+=4;
}
#endif
Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent)
:Chunk(parent,"WAYPOINT")
{
NumWaypoints=0;
Waypoints=0;
NumAlienWaypoints=0;
AlienWaypoints=0;
NumGroundWaypoints=0;
GroundWaypoints=0;
spare1=0;
spare2=0;
}
Module_Waypoint_Chunk::~Module_Waypoint_Chunk()
{
if(Waypoints)
delete [] Waypoints;
}
size_t Module_Waypoint_Chunk::size_chunk()
{
chunk_size=16;
for(int i=0;i<NumWaypoints;i++)
{
chunk_size+=16+3*sizeof(ChunkVectorInt);
chunk_size+=sizeof(WaypointLink)*Waypoints[i].NumWPLinks;
for(int j=0;j<Waypoints[i].NumModLinks;j++)
{
chunk_size+=4;
chunk_size+=(strlen(Waypoints[i].ModLinks[j].module_name)+4)&~3;
}
}
return chunk_size;
}
void Module_Waypoint_Chunk::fill_data_block(char* data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
*(int*)data_start=NumWaypoints;
data_start+=4;
for(int i=0;i<NumWaypoints;i++)
{
ChunkWaypoint* cw=&Waypoints[i];
*(ChunkVectorInt*)data_start=cw->min;
data_start+=sizeof(ChunkVectorInt);
*(ChunkVectorInt*)data_start=cw->max;
data_start+=sizeof(ChunkVectorInt);
*(ChunkVectorInt*)data_start=cw->centre;
data_start+=sizeof(ChunkVectorInt);
if(i==NumAlienWaypoints)
{
//mark start of marine waypoints
*(int*)data_start=cw->flags | WaypointFlag_FirstGroundWaypoint;
}
else
{
*(int*)data_start=cw->flags;
}
data_start+=4;
*(int*)data_start=cw->spare2;
data_start+=4;
*(int*)data_start=cw->NumWPLinks;
data_start+=4;
for(int j=0;j<cw->NumWPLinks;j++)
{
*(WaypointLink*)data_start=cw->WayLinks[j];
data_start+=sizeof(WaypointLink);
}
*(int*)data_start=cw->NumModLinks;
data_start+=4;
for(j=0;j<cw->NumModLinks;j++)
{
ModuleLink* ml=&cw->ModLinks[j];
strcpy(data_start,ml->module_name);
data_start+=(strlen(ml->module_name)+4)&~3;
*(int*)data_start=ml->flags;
data_start+=4;
}
}
}
void Module_Waypoint_Chunk::TransferWaypointData(Module_Waypoint_Chunk* mwc_from)
{
if(!mwc_from)return;
if(!mwc_from->NumWaypoints)return;
if(mwc_from==this)return;
if(mwc_from->NumWaypoints)
{
ChunkWaypoint* new_wp=new ChunkWaypoint[NumWaypoints+mwc_from->NumWaypoints];
//first take alien waypoints from this chunk
for(int i=0;i<NumAlienWaypoints;i++)
{
new_wp[i]=AlienWaypoints[i];
//set pointers to zero so the memory doesn't get deallocated when the old
//waypoint array is deleted
AlienWaypoints[i].WayLinks=0;
AlienWaypoints[i].ModLinks=0;
}
//copy alien waypoints from other chunk
for(i=0;i<mwc_from->NumAlienWaypoints;i++)
{
ChunkWaypoint* cw=&new_wp[i+NumAlienWaypoints];
*cw=mwc_from->AlienWaypoints[i];
//set pointers to zero so the memory doesn't get deallocated when the old
//waypoint chunk is deleted
mwc_from->AlienWaypoints[i].WayLinks=0;
mwc_from->AlienWaypoints[i].ModLinks=0;
//adjust the indeces
cw->index+=NumAlienWaypoints;
for(int j=0;j<cw->NumWPLinks;j++)
{
cw->WayLinks[j].index+=NumAlienWaypoints;
}
}
NumAlienWaypoints+=mwc_from->NumAlienWaypoints;
//now take ground waypoints from this chunk
for(i=0;i<NumGroundWaypoints;i++)
{
new_wp[NumAlienWaypoints+i]=GroundWaypoints[i];
//set pointers to zero so the memory doesn't get deallocated when the old
//waypoint array is deleted
GroundWaypoints[i].WayLinks=0;
GroundWaypoints[i].ModLinks=0;
}
//copy ground waypoints from other chunk
for(i=0;i<mwc_from->NumGroundWaypoints;i++)
{
ChunkWaypoint* cw=&new_wp[i+NumAlienWaypoints+NumGroundWaypoints];
*cw=mwc_from->GroundWaypoints[i];
//set pointers to zero so the memory doesn't get deallocated when the old
//waypoint chunk is deleted
mwc_from->GroundWaypoints[i].WayLinks=0;
mwc_from->GroundWaypoints[i].ModLinks=0;
//adjust the indeces
cw->index+=NumGroundWaypoints;
for(int j=0;j<cw->NumWPLinks;j++)
{
cw->WayLinks[j].index+=NumGroundWaypoints;
}
}
NumGroundWaypoints+=mwc_from->NumGroundWaypoints;
NumWaypoints+=mwc_from->NumWaypoints;
//replace pointer to waypoints
delete [] Waypoints;
Waypoints=new_wp;
}
if(NumAlienWaypoints)
AlienWaypoints=&Waypoints[0];
else
AlienWaypoints=0;
if(NumGroundWaypoints)
GroundWaypoints=&Waypoints[NumAlienWaypoints];
else
GroundWaypoints=0;
delete mwc_from;
}
///////////////////////////////////////////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("AIMODMAS",AI_Module_Master_Chunk)
AI_Module_Master_Chunk::AI_Module_Master_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"AIMODMAS")
{
}
AI_Module_Master_Chunk::AI_Module_Master_Chunk(Object_Module_Data_Chunk* parent)
:Chunk(parent,"AIMODMAS")
{
}
size_t AI_Module_Master_Chunk::size_chunk()
{
chunk_size=12;
return chunk_size;
}
void AI_Module_Master_Chunk::fill_data_block(char* data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
}
AI_Module_Slave_Chunk* AddModuleSlaveChunk(Object_Chunk* oc,Object_Chunk* master)
{
Object_Module_Data_Chunk* omdc=0;
omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
if(!omdc)
omdc=new Object_Module_Data_Chunk(oc);
Chunk* child_chunk=omdc->lookup_single_child("AIMODSLA");
if(child_chunk)
delete child_chunk;
return new AI_Module_Slave_Chunk(omdc,master);
}
void AI_Module_Master_Chunk::AddModule(Object_Chunk* oc)
{
if(ModuleList.contains(oc)) return;
if(oc==get_my_object_chunk()) return;
Object_Module_Data_Chunk* omdc=0;
omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
if(omdc)
{
List<Chunk*> chlist;
omdc->lookup_child("AIMODMAS",chlist);
if(chlist.size())
{
//if the module being added is a master , add all its slaves as well
AI_Module_Master_Chunk* ammc=(AI_Module_Master_Chunk*)chlist.first_entry();
for(LIF<Object_Chunk*> oblif(&ammc->ModuleList);!oblif.done();oblif.next())
{
if(!ModuleList.contains(oblif()) && oblif()!=get_my_object_chunk())
{
ModuleList.add_entry(oblif());
//create new slave chunks for the modules being added
AddModuleSlaveChunk(oblif(),get_my_object_chunk());
}
}
delete ammc;
}
}
//add this module
ModuleList.add_entry(oc);
AddModuleSlaveChunk(oc,get_my_object_chunk());
//see if there are any waypoints to copy
if(omdc)
{
Module_Waypoint_Chunk* mwc_from=(Module_Waypoint_Chunk*)omdc->lookup_single_child("WAYPOINT");
if(mwc_from)
{
Module_Waypoint_Chunk* mwc_to=0;
mwc_to=(Module_Waypoint_Chunk*)parent->lookup_single_child("WAYPOINT");
if(!mwc_to)
mwc_to=new Module_Waypoint_Chunk(parent);
mwc_to->TransferWaypointData(mwc_from);
}
}
}
Object_Chunk* AI_Module_Master_Chunk::get_my_object_chunk()
{
return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;
}
///////////////////////////////////////////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("AIMODSLA",AI_Module_Slave_Chunk)
#if UseOldChunkLoader
AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Object_Module_Data_Chunk* parent,const char* data,size_t)
:Chunk(parent,"AIMODSLA")
{
MasterModule=0;
MasterModuleName=new char[strlen(data)+1];
strcpy(MasterModuleName,data);
MasterModuleIndex=0;
}
#else
AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"AIMODSLA")
{
MasterModule=0;
MasterModuleIndex=*(int*)data;
}
#endif
AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Object_Module_Data_Chunk* parent,Object_Chunk* _MasterModule)
:Chunk(parent,"AIMODSLA")
{
MasterModule=_MasterModule;
MasterModuleIndex=MasterModule->object_data.index_num;
}
AI_Module_Slave_Chunk::~AI_Module_Slave_Chunk()
{
#if UseOldChunkLoader
delete [] MasterModuleName;
#endif
}
size_t AI_Module_Slave_Chunk::size_chunk()
{
chunk_size=16;
return chunk_size;
}
void AI_Module_Slave_Chunk::fill_data_block(char* data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
*((int *) data_start) = MasterModuleIndex;
data_start += 4;
}
void AI_Module_Slave_Chunk::post_input_processing()
{
#if !UseOldChunkLoader
File_Chunk* fc=(File_Chunk*)GetRootChunk();
if(!strcmp(fc->identifier,"REBINFF2"))
{
Object_Chunk* oc=fc->get_object_by_index(MasterModuleIndex);
if(oc)
{
Object_Module_Data_Chunk* omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
if(!omdc)
{
return;
}
List<Chunk*> chlist;
omdc->lookup_child("AIMODMAS",chlist);
if(!chlist.size())
{
//master module doesn't have a master module chunk
return;
}
AI_Module_Master_Chunk* ammc=(AI_Module_Master_Chunk*)chlist.first_entry();
ammc->ModuleList.add_entry(get_my_object_chunk());
MasterModule=oc;
return;
}
}
#endif
}
Object_Chunk* AI_Module_Slave_Chunk::get_my_object_chunk()
{
return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;
}