#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;iindex=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;jNumWPLinks;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;jNumModLinks;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;iindex=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;jNumWPLinks;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;jNumModLinks;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;imin; 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;jNumWPLinks;j++) { *(WaypointLink*)data_start=cw->WayLinks[j]; data_start+=sizeof(WaypointLink); } *(int*)data_start=cw->NumModLinks; data_start+=4; for(j=0;jNumModLinks;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;iNumAlienWaypoints;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;jNumWPLinks;j++) { cw->WayLinks[j].index+=NumAlienWaypoints; } } NumAlienWaypoints+=mwc_from->NumAlienWaypoints; //now take ground waypoints from this chunk for(i=0;iNumGroundWaypoints;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;jNumWPLinks;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 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 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 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; }