4b825dc642cb6eb9a060e54bf8d69288fbee4904ebd360ec63ec976c05699f3180e866b3f69e5472
 
 
1
#include "wpchunk.hpp"
 
 
2
#include <cstring>
 
 
3
 
 
 
4
ChunkWaypoint::ChunkWaypoint()
 
 
5
{
 
 
6
    index = -1;
 
 
7
    NumWPLinks = 0;
 
 
8
    WayLinks = 0;
 
 
9
    NumModLinks = 0;
 
 
10
    ModLinks = 0;
 
 
11
    flags = 0;
 
 
12
    spare2 = 0;
 
 
13
}
 
 
14
 
 
 
15
ChunkWaypoint::~ChunkWaypoint()
 
 
16
{
 
 
17
    if(WayLinks)
 
 
18
        delete [] WayLinks;
 
 
19
 
 
 
20
    if(ModLinks)
 
 
21
        delete [] ModLinks;
 
 
22
}
 
 
23
 
 
 
24
RIF_IMPLEMENT_DYNCREATE("WAYPOINT", Module_Waypoint_Chunk)
 
 
25
 
 
 
26
Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize) :Chunk(parent,"WAYPOINT")
 
 
27
{
 
 
28
    NumWaypoints = *(int*)data;
 
 
29
    data += sizeof(int);
 
 
30
 
 
 
31
    NumGroundWaypoints = 0;
 
 
32
    NumAlienWaypoints = 0;
 
 
33
    AlienWaypoints = 0;
 
 
34
    GroundWaypoints = 0;
 
 
35
 
 
 
36
    if(NumWaypoints)
 
 
37
           Waypoints = new ChunkWaypoint[NumWaypoints];
 
 
38
    else
 
 
39
        Waypoints = 0;
 
 
40
 
 
 
41
    if(NumWaypoints)
 
 
42
    {
 
 
43
        int first_ground_waypoint = -1;
 
 
44
 
 
 
45
        for(int i=0; i < NumWaypoints; i++)
 
 
46
        {
 
 
47
            int j;
 
 
48
 
 
 
49
            ChunkWaypoint* cw = &Waypoints[i];
 
 
50
            cw->index = i;
 
 
51
 
 
 
52
            cw->min = *(ChunkVectorInt*)data;
 
 
53
            data += sizeof(ChunkVectorInt);    
 
 
54
            cw->max = *(ChunkVectorInt*)data;
 
 
55
            data += sizeof(ChunkVectorInt);    
 
 
56
            cw->centre = *(ChunkVectorInt*)data;
 
 
57
            data += sizeof(ChunkVectorInt);    
 
 
58
 
 
 
59
            cw->flags = *(int *)data;
 
 
60
            data += sizeof(int);    
 
 
61
            cw->spare2 = *(int *)data;
 
 
62
            data += sizeof(int);    
 
 
63
 
 
 
64
            cw->NumWPLinks = *(int *)data;
 
 
65
            data += sizeof(int);
 
 
66
 
 
 
67
            if(cw->NumWPLinks)
 
 
68
                cw->WayLinks = new WaypointLink[cw->NumWPLinks];
 
 
69
            else
 
 
70
                cw->WayLinks = 0;
 
 
71
 
 
 
72
            for(j=0; j < cw->NumWPLinks; j++)
 
 
73
            {
 
 
74
                cw->WayLinks[j] = *(WaypointLink*)data;
 
 
75
                data += sizeof(WaypointLink);
 
 
76
            }
 
 
77
 
 
 
78
            cw->NumModLinks = *(int *)data;
 
 
79
            data += sizeof(int);
 
 
80
 
 
 
81
            if(cw->NumModLinks)
 
 
82
                cw->ModLinks = new ModuleLink[cw->NumModLinks];
 
 
83
            else
 
 
84
                cw->ModLinks = 0;
 
 
85
 
 
 
86
            for(j=0; j < cw->NumModLinks; j++)
 
 
87
            {
 
 
88
                ModuleLink* ml = &cw->ModLinks[j];
 
 
89
                ml->module_name = data;
 
 
90
                data += (strlen(data)+4)&~3;
 
 
91
                ml->flags = *(int *)data;
 
 
92
                data += 4;
 
 
93
            }
 
 
94
 
 
 
95
            if(cw->flags & WaypointFlag_FirstGroundWaypoint)
 
 
96
            {
 
 
97
                first_ground_waypoint = i;
 
 
98
                cw->flags &= ~WaypointFlag_FirstGroundWaypoint;
 
 
99
            }
 
 
100
        }
 
 
101
 
 
 
102
        if(first_ground_waypoint >= 0)
 
 
103
        {
 
 
104
            GroundWaypoints = &Waypoints[first_ground_waypoint];
 
 
105
            NumGroundWaypoints = NumWaypoints-first_ground_waypoint;
 
 
106
        }
 
 
107
 
 
 
108
        NumAlienWaypoints = NumWaypoints-NumGroundWaypoints;
 
 
109
 
 
 
110
        if(NumAlienWaypoints)
 
 
111
            AlienWaypoints = &Waypoints[0];
 
 
112
    }
 
 
113
 
 
 
114
    spare1 = *(int *)data;
 
 
115
    data += sizeof(int);
 
 
116
    spare2 = *(int *)data;
 
 
117
    data += sizeof(int);
 
 
118
}
 
 
119
 
 
 
120
Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent) :Chunk(parent,"WAYPOINT")
 
 
121
{
 
 
122
    NumWaypoints = 0;
 
 
123
    Waypoints = 0;
 
 
124
    NumAlienWaypoints = 0;
 
 
125
    AlienWaypoints = 0;
 
 
126
    NumGroundWaypoints = 0;
 
 
127
    GroundWaypoints = 0;
 
 
128
    spare1 = 0;
 
 
129
    spare2 = 0;    
 
 
130
}
 
 
131
 
 
 
132
Module_Waypoint_Chunk::~Module_Waypoint_Chunk()
 
 
133
{
 
 
134
    if(Waypoints)
 
 
135
        delete [] Waypoints;
 
 
136
}
 
 
137
 
 
 
138
size_t Module_Waypoint_Chunk::size_chunk()
 
 
139
{
 
 
140
    chunk_size = 16;
 
 
141
 
 
 
142
    for(int i=0; i < NumWaypoints; i++)
 
 
143
    {
 
 
144
        chunk_size += 16+3*sizeof(ChunkVectorInt);
 
 
145
        chunk_size += sizeof(WaypointLink)*Waypoints[i].NumWPLinks;
 
 
146
 
 
 
147
        for(int j=0; j < Waypoints[i].NumModLinks; j++)
 
 
148
        {
 
 
149
            chunk_size += 4;
 
 
150
            chunk_size += (Waypoints[i].ModLinks[j].module_name.size() + 4)&~3;
 
 
151
        }
 
 
152
    }
 
 
153
 
 
 
154
return chunk_size;
 
 
155
}
 
 
156
 
 
 
157
void Module_Waypoint_Chunk::fill_data_block(char* data_start)
 
 
158
{
 
 
159
    strncpy (data_start, identifier, 8);
 
 
160
    data_start += 8;
 
 
161
    *((int *) data_start) = chunk_size;
 
 
162
    data_start += sizeof(int);
 
 
163
 
 
 
164
    *(int *)data_start = NumWaypoints;
 
 
165
    data_start += sizeof(int);
 
 
166
 
 
 
167
    for(int i=0; i < NumWaypoints; i++)
 
 
168
    {
 
 
169
        int j;
 
 
170
 
 
 
171
        ChunkWaypoint* cw = &Waypoints[i];
 
 
172
 
 
 
173
        *(ChunkVectorInt*)data_start = cw->min;
 
 
174
        data_start += sizeof(ChunkVectorInt);
 
 
175
        *(ChunkVectorInt*)data_start = cw->max;
 
 
176
        data_start += sizeof(ChunkVectorInt);
 
 
177
        *(ChunkVectorInt*)data_start = cw->centre;
 
 
178
        data_start += sizeof(ChunkVectorInt);
 
 
179
 
 
 
180
        if(i == NumAlienWaypoints)
 
 
181
        {
 
 
182
            //mark start of marine waypoints
 
 
183
            *(int *)data_start = cw->flags | WaypointFlag_FirstGroundWaypoint;
 
 
184
        }
 
 
185
        else
 
 
186
        {
 
 
187
            *(int *)data_start = cw->flags;
 
 
188
        }
 
 
189
 
 
 
190
        data_start += sizeof(int);
 
 
191
 
 
 
192
        *(int *)data_start = cw->spare2;
 
 
193
        data_start += sizeof(int);
 
 
194
 
 
 
195
        *(int *)data_start = cw->NumWPLinks;
 
 
196
        data_start += sizeof(int);
 
 
197
 
 
 
198
        for(j=0; j < cw->NumWPLinks; j++)
 
 
199
        {
 
 
200
            *(WaypointLink*)data_start = cw->WayLinks[j];
 
 
201
            data_start += sizeof(WaypointLink);
 
 
202
        }
 
 
203
 
 
 
204
        *(int *)data_start = cw->NumModLinks;
 
 
205
        data_start += sizeof(int);
 
 
206
 
 
 
207
        for(j=0; j < cw->NumModLinks; j++)
 
 
208
        {
 
 
209
            ModuleLink* ml = &cw->ModLinks[j];
 
 
210
            strcpy(data_start, ml->module_name.c_str());
 
 
211
            data_start += (ml->module_name.size() + 4)&~3;
 
 
212
            *(int*)data_start = ml->flags;
 
 
213
            data_start += 4;
 
 
214
        }
 
 
215
    }
 
 
216
}
 
 
217
 
 
 
218
void Module_Waypoint_Chunk::TransferWaypointData(Module_Waypoint_Chunk* mwc_from)
 
 
219
{
 
 
220
    if(!mwc_from)
 
 
221
        return;    
 
 
222
 
 
 
223
    if(!mwc_from->NumWaypoints)
 
 
224
        return;
 
 
225
 
 
 
226
    if(mwc_from == this)
 
 
227
        return;
 
 
228
 
 
 
229
    if(mwc_from->NumWaypoints)
 
 
230
    {
 
 
231
        int i;
 
 
232
 
 
 
233
        ChunkWaypoint* new_wp = new ChunkWaypoint[NumWaypoints+mwc_from->NumWaypoints];
 
 
234
        //first take alien waypoints from this chunk
 
 
235
 
 
 
236
        for(i=0; i < NumAlienWaypoints; i++)
 
 
237
        {
 
 
238
            new_wp[i] = AlienWaypoints[i];
 
 
239
            //set pointers to zero so the memory doesn't get deallocated when the old
 
 
240
            //waypoint array is deleted
 
 
241
            AlienWaypoints[i].WayLinks = 0;
 
 
242
            AlienWaypoints[i].ModLinks = 0;
 
 
243
        }
 
 
244
 
 
 
245
        //copy alien waypoints from other chunk
 
 
246
 
 
 
247
        for(i=0; i < mwc_from->NumAlienWaypoints; i++)
 
 
248
        {
 
 
249
            ChunkWaypoint* cw = &new_wp[i+NumAlienWaypoints];
 
 
250
            *cw = mwc_from->AlienWaypoints[i];
 
 
251
            //set pointers to zero so the memory doesn't get deallocated when the old
 
 
252
            //waypoint chunk is deleted
 
 
253
            mwc_from->AlienWaypoints[i].WayLinks = 0;
 
 
254
            mwc_from->AlienWaypoints[i].ModLinks = 0;
 
 
255
 
 
 
256
            //adjust the indeces
 
 
257
            cw->index += NumAlienWaypoints;
 
 
258
 
 
 
259
            for(int j=0; j < cw->NumWPLinks; j++)
 
 
260
                cw->WayLinks[j].index += NumAlienWaypoints;
 
 
261
         }
 
 
262
 
 
 
263
        NumAlienWaypoints += mwc_from->NumAlienWaypoints;
 
 
264
 
 
 
265
        //now take ground waypoints from this chunk
 
 
266
        for(i=0; i < NumGroundWaypoints; i++)
 
 
267
        {
 
 
268
            new_wp[NumAlienWaypoints+i] = GroundWaypoints[i];
 
 
269
            //set pointers to zero so the memory doesn't get deallocated when the old
 
 
270
            //waypoint array is deleted
 
 
271
            GroundWaypoints[i].WayLinks = 0;
 
 
272
            GroundWaypoints[i].ModLinks = 0;
 
 
273
        }
 
 
274
 
 
 
275
        //copy ground waypoints from other chunk
 
 
276
 
 
 
277
        for(i=0; i < mwc_from->NumGroundWaypoints; i++)
 
 
278
        {
 
 
279
            ChunkWaypoint* cw = &new_wp[i+NumAlienWaypoints+NumGroundWaypoints];
 
 
280
            *cw=mwc_from->GroundWaypoints[i];
 
 
281
            //set pointers to zero so the memory doesn't get deallocated when the old
 
 
282
            //waypoint chunk is deleted
 
 
283
            mwc_from->GroundWaypoints[i].WayLinks = 0;
 
 
284
            mwc_from->GroundWaypoints[i].ModLinks = 0;
 
 
285
 
 
 
286
            //adjust the indeces
 
 
287
            cw->index += NumGroundWaypoints;
 
 
288
 
 
 
289
            for(int j=0; j < cw->NumWPLinks; j++)
 
 
290
                cw->WayLinks[j].index += NumGroundWaypoints;
 
 
291
         }
 
 
292
 
 
 
293
        NumGroundWaypoints += mwc_from->NumGroundWaypoints;
 
 
294
        NumWaypoints += mwc_from->NumWaypoints;
 
 
295
        //replace pointer to waypoints
 
 
296
        delete [] Waypoints;
 
 
297
        Waypoints = new_wp;
 
 
298
    }
 
 
299
 
 
 
300
    if(NumAlienWaypoints)
 
 
301
        AlienWaypoints = &Waypoints[0];
 
 
302
    else
 
 
303
        AlienWaypoints = 0;
 
 
304
 
 
 
305
    if(NumGroundWaypoints)
 
 
306
        GroundWaypoints = &Waypoints[NumAlienWaypoints];
 
 
307
    else
 
 
308
        GroundWaypoints = 0;
 
 
309
 
 
 
310
    delete mwc_from;    
 
 
311
}
 
 
312
 
 
 
313
RIF_IMPLEMENT_DYNCREATE("AIMODMAS", AI_Module_Master_Chunk)
 
 
314
 
 
 
315
void AI_Module_Master_Chunk::fill_data_block(char* data_start)
 
 
316
{
 
 
317
    strncpy (data_start, identifier, 8);
 
 
318
    data_start += 8;
 
 
319
    *((int *) data_start) = chunk_size;
 
 
320
    data_start += sizeof(int);
 
 
321
}
 
 
322
 
 
 
323
AI_Module_Slave_Chunk* AddModuleSlaveChunk(Object_Chunk* oc,Object_Chunk* master)
 
 
324
{
 
 
325
    Object_Module_Data_Chunk* omdc = 0;
 
 
326
    omdc = (Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
 
 
327
 
 
 
328
    if(!omdc)
 
 
329
        omdc = new Object_Module_Data_Chunk(oc);
 
 
330
 
 
 
331
    Chunk* child_chunk = omdc->lookup_single_child("AIMODSLA");
 
 
332
 
 
 
333
    if(child_chunk)
 
 
334
        delete child_chunk;
 
 
335
 
 
 
336
return new AI_Module_Slave_Chunk(omdc, master);
 
 
337
}
 
 
338
 
 
 
339
void AI_Module_Master_Chunk::AddModule(Object_Chunk* oc)
 
 
340
{
 
 
341
 
 
 
342
std::list<Object_Chunk *>::iterator it = ModuleList.begin();
 
 
343
 
 
 
344
    for (; it != ModuleList.end(); it++)
 
 
345
    {
 
 
346
        if ( *it == oc )
 
 
347
            return;
 
 
348
    }
 
 
349
 
 
 
350
    if(oc == get_my_object_chunk())
 
 
351
        return;
 
 
352
 
 
 
353
    Object_Module_Data_Chunk* omdc = (Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
 
 
354
 
 
 
355
    if(omdc)
 
 
356
    {
 
 
357
        std::list<Chunk*> chlist;
 
 
358
        omdc->lookup_child("AIMODMAS", chlist);
 
 
359
 
 
 
360
        if(chlist.size())
 
 
361
        {
 
 
362
            //if the module being added is a master , add all its slaves as well
 
 
363
            AI_Module_Master_Chunk* ammc = (AI_Module_Master_Chunk*)chlist.front();
 
 
364
 
 
 
365
            std::list<Object_Chunk *>::iterator oblif = ammc->ModuleList.begin();
 
 
366
 
 
 
367
            for (; oblif != ammc->ModuleList.end(); oblif++)
 
 
368
            {
 
 
369
                std::list<Object_Chunk *>::iterator it = ModuleList.begin();
 
 
370
                int contains = 0;
 
 
371
 
 
 
372
                for(; it != ModuleList.end(); it++)
 
 
373
                {
 
 
374
                    if ( *it == *oblif)
 
 
375
                    {
 
 
376
                        contains = 1;
 
 
377
                        break;
 
 
378
                    }
 
 
379
                }
 
 
380
 
 
 
381
                if(!contains && *oblif != get_my_object_chunk())
 
 
382
                {
 
 
383
                    ModuleList.push_back(*oblif);
 
 
384
                    //create new slave chunks for the modules being added
 
 
385
                    AddModuleSlaveChunk( *oblif, get_my_object_chunk());
 
 
386
                }
 
 
387
            }
 
 
388
 
 
 
389
        delete ammc;
 
 
390
        }
 
 
391
    }
 
 
392
 
 
 
393
    ModuleList.push_back(oc);
 
 
394
    AddModuleSlaveChunk(oc,get_my_object_chunk());
 
 
395
 
 
 
396
    //see if there are any waypoints to copy
 
 
397
    if(omdc)
 
 
398
    {
 
 
399
        Module_Waypoint_Chunk* mwc_from = (Module_Waypoint_Chunk*)omdc->lookup_single_child("WAYPOINT");
 
 
400
 
 
 
401
        if(mwc_from)
 
 
402
        {
 
 
403
            Module_Waypoint_Chunk* mwc_to = (Module_Waypoint_Chunk*)parent->lookup_single_child("WAYPOINT");
 
 
404
 
 
 
405
            if(!mwc_to)
 
 
406
                mwc_to = new Module_Waypoint_Chunk(parent);
 
 
407
 
 
 
408
            mwc_to->TransferWaypointData(mwc_from);
 
 
409
        }
 
 
410
    }
 
 
411
}
 
 
412
 
 
 
413
Object_Chunk* AI_Module_Master_Chunk::get_my_object_chunk()
 
 
414
{
 
 
415
    return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;    
 
 
416
}
 
 
417
 
 
 
418
RIF_IMPLEMENT_DYNCREATE("AIMODSLA", AI_Module_Slave_Chunk)
 
 
419
 
 
 
420
AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Chunk_With_Children* parent,const char* data,size_t)
 
 
421
:Chunk(parent,"AIMODSLA")
 
 
422
{
 
 
423
    MasterModule = 0;
 
 
424
    MasterModuleIndex = *(int*)data;
 
 
425
}
 
 
426
 
 
 
427
AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Object_Module_Data_Chunk* parent,Object_Chunk* _MasterModule)
 
 
428
:Chunk(parent,"AIMODSLA")
 
 
429
{
 
 
430
    MasterModule = _MasterModule;
 
 
431
    MasterModuleIndex = MasterModule->object_data.index_num;
 
 
432
}
 
 
433
 
 
 
434
void AI_Module_Slave_Chunk::fill_data_block(char* data_start)
 
 
435
{
 
 
436
    strncpy (data_start, identifier, 8);
 
 
437
    data_start += 8;
 
 
438
    *((int *) data_start) = chunk_size;
 
 
439
    data_start += sizeof(int);
 
 
440
    *((int *) data_start) = MasterModuleIndex;
 
 
441
    data_start += sizeof(int);
 
 
442
}
 
 
443
 
 
 
444
void AI_Module_Slave_Chunk::post_input_processing()
 
 
445
{
 
 
446
    File_Chunk* fc = (File_Chunk*)GetRootChunk();
 
 
447
 
 
 
448
    if(!strcmp(fc->identifier, "REBINFF2"))
 
 
449
    {
 
 
450
        Object_Chunk* oc = fc->get_object_by_index(MasterModuleIndex);
 
 
451
 
 
 
452
        if(oc)
 
 
453
        {
 
 
454
            Object_Module_Data_Chunk* omdc = (Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
 
 
455
 
 
 
456
            if(!omdc)
 
 
457
                return;
 
 
458
 
 
 
459
            std::list<Chunk*> chlist;
 
 
460
            omdc->lookup_child("AIMODMAS", chlist);
 
 
461
 
 
 
462
            if(!chlist.size())
 
 
463
            {
 
 
464
                //master module doesn't have a master module chunk
 
 
465
                return;
 
 
466
            }
 
 
467
 
 
 
468
            AI_Module_Master_Chunk* ammc = (AI_Module_Master_Chunk*)chlist.front();
 
 
469
            ammc->ModuleList.push_back(get_my_object_chunk());
 
 
470
            MasterModule = oc;
 
 
471
        }
 
 
472
    }
 
 
473
}
 
 
474
 
 
 
475
Object_Chunk* AI_Module_Slave_Chunk::get_my_object_chunk()
 
 
476
{
 
 
477
    return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;    
 
 
478
}