4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "bh_types.h"
 
 
5
#include "dynamics.h"
 
 
6
#include "placedhierarchy.h"
 
 
7
#include <assert.h>
 
 
8
#include <stdlib.h>
 
 
9
 
 
 
10
SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char *);
 
 
11
 
 
 
12
void PlacedHierarchyBehaveInit(void* bhdata, STRATEGYBLOCK* sbptr)
 
 
13
{
 
 
14
    assert(sbptr);
 
 
15
    assert(bhdata);
 
 
16
 
 
 
17
    PLACED_HIERARCHY_BEHAV_BLOCK* ph_bhv = malloc(sizeof(PLACED_HIERARCHY_BEHAV_BLOCK));
 
 
18
    sbptr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
19
    sbptr->dataptr = ph_bhv;
 
 
20
    sbptr->containingModule = ModuleFromPosition(&sbptr->DynPtr->Position, NULL);
 
 
21
 
 
 
22
    if(!ph_bhv || !sbptr->DynPtr || (NULL == sbptr->containingModule))
 
 
23
    {
 
 
24
        RemoveBehaviourStrategy(sbptr);
 
 
25
        return;
 
 
26
    }
 
 
27
 
 
 
28
    sbptr->maintainVisibility = 1;
 
 
29
    ph_bhv->bhvr_type = I_BehaviourPlacedHierarchy;
 
 
30
 
 
 
31
    PLACED_HIERARCHY_TOOLS_TEMPLATE* ph_tt = (PLACED_HIERARCHY_TOOLS_TEMPLATE*)bhdata;
 
 
32
 
 
 
33
    COPY_NAME(sbptr->SBname, ph_tt->nameID);
 
 
34
 
 
 
35
    sbptr->DynPtr->Position = sbptr->DynPtr->PrevPosition = ph_tt->position;
 
 
36
    sbptr->DynPtr->OrientEuler = ph_tt->orientation;
 
 
37
    CreateEulerMatrix(&sbptr->DynPtr->OrientEuler, &sbptr->DynPtr->OrientMat);
 
 
38
    TransposeMatrixCH(&sbptr->DynPtr->OrientMat);
 
 
39
 
 
 
40
    ph_bhv->num_sequences = ph_tt->num_sequences;
 
 
41
    ph_bhv->sequences = ph_tt->sequences;
 
 
42
    ph_bhv->num_sounds = ph_tt->num_sounds;
 
 
43
    ph_bhv->sounds = ph_tt->sounds;
 
 
44
    ph_bhv->num_special_track_points = ph_tt->num_special_track_points;
 
 
45
    ph_bhv->special_track_points = ph_tt->special_track_points;
 
 
46
 
 
 
47
      SECTION *root_section = GetNamedHierarchyFromLibrary(ph_tt->file_name, ph_tt->hier_name);
 
 
48
    assert(root_section);
 
 
49
    Create_HModel(&ph_bhv->HModelController, root_section);
 
 
50
 
 
 
51
    ph_bhv->current_seq = ph_tt->first_sequence;
 
 
52
   
InitHModelSequence(&ph_bhv->HModelController,ph_bhv->current_seq->sequence_no,ph_bhv->current_seq->sub_sequence_no,ph_bhv->current_seq->
;time);
 
 
53
    ph_bhv->HModelController.Playing = ph_tt->playing;
 
 
54
    ph_bhv->HModelController.Looped = ph_bhv->current_seq->loop;
 
 
55
 
 
 
56
    //find the hierarchy section that sound should be produced from
 
 
57
    SECTION_DATA* sound_section_data =  GetThisSectionData(ph_bhv->HModelController.section_data,"SoundSource");
 
 
58
 
 
 
59
    if(!sound_section_data)
 
 
60
    {
 
 
61
        //if there isn't a SoundSource object , sound can come from the root section
 
 
62
        sound_section_data = ph_bhv->HModelController.section_data;
 
 
63
    }
 
 
64
 
 
 
65
    ph_bhv->sound_location = &sound_section_data->World_Offset;
 
 
66
}
 
 
67
 
 
 
68
void MakePlacedHierarchyNear(STRATEGYBLOCK* sbptr)
 
 
69
{
 
 
70
    DYNAMICSBLOCK *dynPtr = sbptr->DynPtr;
 
 
71
    PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)(sbptr->dataptr);    
 
 
72
 
 
 
73
    assert(dynPtr);
 
 
74
 
 
 
75
    DISPLAYBLOCK *dPtr = CreateActiveObject();
 
 
76
 
 
 
77
    if(dPtr == NULL)
 
 
78
        return; /* cannot create displayblock, so leave object "far" */
 
 
79
 
 
 
80
    sbptr->DisplayBlock = dPtr;
 
 
81
    dPtr->ObStrategyBlock = sbptr;
 
 
82
 
 
 
83
    /* also need to initialise positional information in the new display
 
 
84
    block from the existing dynamics block: this necessary because this 
 
 
85
    function is (usually) called between the dynamics and rendering systems
 
 
86
    so it is not initialised by the dynamics system the first time it is
 
 
87
    drawn. */
 
 
88
    dPtr->ObWorld = dynPtr->Position;
 
 
89
    dPtr->ObEuler = dynPtr->OrientEuler;
 
 
90
    dPtr->ObMat = dynPtr->OrientMat;
 
 
91
 
 
 
92
    dPtr->HModelControlBlock = &ph_bhv->HModelController;
 
 
93
    ProveHModel(dPtr->HModelControlBlock,dPtr);
 
 
94
}
 
 
95
 
 
 
96
void PlacedHierarchyBehaveFun(STRATEGYBLOCK* sbptr)
 
 
97
{
 
 
98
    assert(sbptr);
 
 
99
    PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv =(PLACED_HIERARCHY_BEHAV_BLOCK*) sbptr->dataptr;
 
 
100
    assert((ph_bhv->bhvr_type) == I_BehaviourPlacedHierarchy);
 
 
101
 
 
 
102
    if(sbptr->DisplayBlock)
 
 
103
        ProveHModel(&ph_bhv->HModelController, sbptr->DisplayBlock);
 
 
104
    else
 
 
105
        ProveHModel_Far(&ph_bhv->HModelController,sbptr);
 
 
106
 
 
 
107
    //update sound
 
 
108
    if(ph_bhv->HModelController.Playing && ph_bhv->current_seq)
 
 
109
    {
 
 
110
        int i;
 
 
111
        int timer = ph_bhv->HModelController.sequence_timer;
 
 
112
        int keyframe_flags = ph_bhv->HModelController.keyframe_flags;
 
 
113
 
 
 
114
        if(keyframe_flags)
 
 
115
        {
 
 
116
            for(i = 0; i < ph_bhv->num_special_track_points; i++)
 
 
117
            {
 
 
118
                if(keyframe_flags & ph_bhv->special_track_points[i].track_point_no)
 
 
119
                {
 
 
120
                    SPECIAL_TRACK_POINT* stp = &ph_bhv->special_track_points[i];
 
 
121
                    int j = 0;
 
 
122
                    for(; j < stp->num_targets; j++)
 
 
123
                    {
 
 
124
                        TRACK_POINT_TARGET* tpt = &stp->targets[j];
 
 
125
                         RequestState(tpt->target_sbptr,tpt->request,0);
 
 
126
                    }
 
 
127
                }    
 
 
128
            }
 
 
129
        }
 
 
130
 
 
 
131
        for(i=0; i < ph_bhv->current_seq->num_sound_times; i++)
 
 
132
        {
 
 
133
            PLACED_HIERARCHY_SOUND_TIMES* s_time = &ph_bhv->current_seq->sound_times[i];
 
 
134
 
 
 
135
            if(s_time->sound)
 
 
136
            {
 
 
137
                PLACED_HIERARCHY_SOUND* sound = s_time->sound;
 
 
138
                //not much point in continuing if the sound wasn't loaded anyway
 
 
139
 
 
 
140
                if(SID_NOSOUND != sound->sound_number)
 
 
141
                {
 
 
142
                    if(timer >= s_time->start_time && timer < s_time->end_time)
 
 
143
                    {
 
 
144
                        //start sound if not already playing
 
 
145
                        if(!sound->playing)
 
 
146
                        {
 
 
147
                            int dist = VectorDistance(&PlayerStatus.DisplayBlock->ObWorld, ph_bhv->sound_location);
 
 
148
 
 
 
149
                            if(dist <= sound->outer_range) //make sure sound is in range
 
 
150
                            {
 
 
151
                                SOUND3DDATA s3d;
 
 
152
                                s3d.position = *ph_bhv->sound_location;
 
 
153
                                s3d.inner_range = sound->inner_range;
 
 
154
                                s3d.outer_range = sound->outer_range;
 
 
155
                                s3d.velocity.vx = 0;
 
 
156
                                s3d.velocity.vy = 0;
 
 
157
                                s3d.velocity.vz = 0;
 
 
158
 
 
 
159
                                if(s_time->sound->loop)
 
 
160
            Sound_Play ((SOUNDINDEX)sound->sound_number, "nvpel", &s3d,sound->max_volume,sound->pitch,&sound->activ_no);
 
 
161
                                else
 
 
162
            Sound_Play ((SOUNDINDEX)sound->sound_number, "nvpe", &s3d,sound->max_volume,sound->pitch,&sound->activ_no);
 
 
163
 
 
 
164
                            }
 
 
165
                            sound->playing = 1;
 
 
166
                        }
 
 
167
                        else //otherwise update its position
 
 
168
                        {
 
 
169
                            int dist = VectorDistance(&PlayerStatus.DisplayBlock->ObWorld, ph_bhv->sound_location);
 
 
170
 
 
 
171
                            if(sound->activ_no != SOUND_NOACTIVEINDEX)
 
 
172
                            {
 
 
173
                                if(dist <= sound->outer_range)
 
 
174
                                {
 
 
175
                                    SOUND3DDATA s3d;
 
 
176
                                    s3d.position = *ph_bhv->sound_location;
 
 
177
                                    s3d.inner_range = sound->inner_range;
 
 
178
                                    s3d.outer_range = sound->outer_range;
 
 
179
                                    s3d.velocity.vx = 0;
 
 
180
                                    s3d.velocity.vy = 0;
 
 
181
                                    s3d.velocity.vz = 0;
 
 
182
                                    Sound_UpdateNew3d (sound->activ_no, &s3d);
 
 
183
                                }
 
 
184
                                else
 
 
185
                                {
 
 
186
                                    Sound_Stop(sound->activ_no);
 
 
187
                                }
 
 
188
                            }
 
 
189
                            else
 
 
190
                            {
 
 
191
                                if(dist <= sound->outer_range && sound->loop)
 
 
192
                                {
 
 
193
                                    SOUND3DDATA s3d;
 
 
194
                                    s3d.position = *ph_bhv->sound_location;
 
 
195
                                    s3d.inner_range = sound->inner_range;
 
 
196
                                    s3d.outer_range = sound->outer_range;
 
 
197
                                    s3d.velocity.vx = 0;
 
 
198
                                    s3d.velocity.vy = 0;
 
 
199
                                    s3d.velocity.vz = 0;
 
 
200
        Sound_Play ((SOUNDINDEX)sound->sound_number, "nvpel", &s3d,sound->max_volume,sound->pitch,&sound->activ_no);
 
 
201
                                }
 
 
202
                            }
 
 
203
                        }
 
 
204
                    }
 
 
205
                    else
 
 
206
                    {
 
 
207
                        //stop sound
 
 
208
                        if(sound->activ_no != SOUND_NOACTIVEINDEX)
 
 
209
                            Sound_Stop(sound->activ_no);
 
 
210
 
 
 
211
                        sound->playing = 0;
 
 
212
                    }
 
 
213
                }
 
 
214
            }
 
 
215
        }
 
 
216
    }
 
 
217
}
 
 
218
 
 
 
219
void DeletePlacedHierarchy(PLACED_HIERARCHY_BEHAV_BLOCK* ph_bhv)
 
 
220
{
 
 
221
    int i=0;
 
 
222
 
 
 
223
    if(!ph_bhv)
 
 
224
        return;
 
 
225
 
 
 
226
    for(; i < ph_bhv->num_sounds; i++)
 
 
227
    {
 
 
228
        if(ph_bhv->sounds[i].activ_no != SOUND_NOACTIVEINDEX)
 
 
229
            Sound_Stop(ph_bhv->sounds[i].activ_no);
 
 
230
    }
 
 
231
 
 
 
232
    Dispel_HModel(&ph_bhv->HModelController);
 
 
233
}
 
 
234
 
 
 
235
void PlacedHierarchyStopSequence(PLACED_HIERARCHY_BEHAV_BLOCK* ph_bhv)
 
 
236
{
 
 
237
    int i=0;
 
 
238
    //stop hierarchy from playing
 
 
239
    ph_bhv->HModelController.Playing=0;
 
 
240
 
 
 
241
    //and stop all the sounds
 
 
242
    for(; i < ph_bhv->num_sounds; i++)
 
 
243
    {
 
 
244
        if(ph_bhv->sounds[i].activ_no != SOUND_NOACTIVEINDEX)
 
 
245
            Sound_Stop(ph_bhv->sounds[i].activ_no);
 
 
246
 
 
 
247
        ph_bhv->sounds[i].playing = 0;
 
 
248
    }
 
 
249
}
 
 
250
 
 
 
251
void SendRequestToPlacedHierarchy(STRATEGYBLOCK* sbptr, int state,int extended_data)
 
 
252
{
 
 
253
    assert(sbptr);
 
 
254
    assert(sbptr->dataptr);
 
 
255
    PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)sbptr->dataptr;
 
 
256
    assert((ph_bhv->bhvr_type == I_BehaviourPlacedHierarchy));
 
 
257
 
 
 
258
    int seq_num = (extended_data>>7) & 0xff;
 
 
259
 
 
 
260
    if(state)
 
 
261
    {
 
 
262
        PLACED_HIERARCHY_SEQUENCE* new_sequence;
 
 
263
        assert(seq_num < ph_bhv->num_sequences);
 
 
264
 
 
 
265
        new_sequence = &ph_bhv->sequences[seq_num];
 
 
266
 
 
 
267
        assert(new_sequence->sequence_no != -1);
 
 
268
 
 
 
269
        if(new_sequence == ph_bhv->current_seq)
 
 
270
        {
 
 
271
            //restart the current sequence
 
 
272
            ph_bhv->HModelController.Playing = 1;
 
 
273
        }
 
 
274
        else
 
 
275
        {
 
 
276
            //stop the current sequence
 
 
277
            PlacedHierarchyStopSequence(ph_bhv);
 
 
278
            //start the new sequence
 
 
279
            ph_bhv->current_seq = new_sequence;
 
 
280
           
InitHModelSequence(&ph_bhv->HModelController,ph_bhv->current_seq->sequence_no,ph_bhv->current_seq->sub_sequence_no,ph_bhv->current_seq->
;time);
 
 
281
            ph_bhv->HModelController.Playing = 1;
 
 
282
            ph_bhv->HModelController.Looped = ph_bhv->current_seq->loop;
 
 
283
        }
 
 
284
    }
 
 
285
    else
 
 
286
    {
 
 
287
        PlacedHierarchyStopSequence(ph_bhv);
 
 
288
    }
 
 
289
}
 
 
290
 
 
 
291
#include "savegame.h"
 
 
292
 
 
 
293
void LoadStrategy_PlacedHierarchy(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
294
{
 
 
295
    int i;
 
 
296
    char * buffer = (char*) header;
 
 
297
 
 
 
298
    buffer += sizeof(*header);
 
 
299
 
 
 
300
    //find the existing strategy block
 
 
301
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
302
    if(!sbPtr)
 
 
303
        return;
 
 
304
 
 
 
305
    //make sure the strategy found is of the right type
 
 
306
    if(sbPtr->type != I_BehaviourPlacedHierarchy)
 
 
307
        return;
 
 
308
 
 
 
309
    PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
310
 
 
 
311
    {
 
 
312
        int sequence_index = *(int*) buffer;
 
 
313
        buffer += sizeof(int);
 
 
314
 
 
 
315
        if(sequence_index >= 0 && sequence_index < ph_bhv->num_sequences)
 
 
316
        {
 
 
317
            ph_bhv->current_seq = &ph_bhv->sequences[sequence_index];
 
 
318
        }
 
 
319
    }
 
 
320
 
 
 
321
    {
 
 
322
        int loaded_num_sounds = *(int*) buffer;
 
 
323
        buffer +=sizeof(int);
 
 
324
 
 
 
325
        for(i=0; i < loaded_num_sounds && i<ph_bhv->num_sounds; i++)
 
 
326
        {
 
 
327
            int playing = *(int*)buffer;
 
 
328
            buffer += sizeof(int);
 
 
329
 
 
 
330
            ph_bhv->sounds[i].playing = playing;
 
 
331
        }
 
 
332
    }
 
 
333
 
 
 
334
    //load the hierarchy
 
 
335
    {
 
 
336
        SAVE_BLOCK_HEADER* hier_header = GetNextBlockIfOfType(SaveBlock_Hierarchy);
 
 
337
 
 
 
338
        if(hier_header)
 
 
339
            LoadHierarchy(hier_header,&ph_bhv->HModelController);
 
 
340
    }
 
 
341
 
 
 
342
    for(i=0; i < ph_bhv->num_sounds; i++)
 
 
343
        Load_SoundState(&ph_bhv->sounds[i].activ_no);
 
 
344
}
 
 
345
 
 
 
346
void SaveStrategy_PlacedHierarchy(STRATEGYBLOCK* sbPtr)
 
 
347
{
 
 
348
    int i;
 
 
349
 
 
 
350
    PLACED_HIERARCHY_BEHAV_BLOCK *ph_bhv = (PLACED_HIERARCHY_BEHAV_BLOCK*)sbPtr->dataptr;
 
 
351
 
 
 
352
    //determine memory required
 
 
353
    unsigned int size = sizeof(SAVE_BLOCK_STRATEGY_HEADER)+(2*sizeof(int))+(sizeof(int)*ph_bhv->num_sounds);
 
 
354
 
 
 
355
    SAVE_BLOCK_STRATEGY_HEADER* header = (SAVE_BLOCK_STRATEGY_HEADER*) GetPointerForSaveBlock(size);
 
 
356
    char* buffer = (char*) header;
 
 
357
    buffer += sizeof(*header);
 
 
358
 
 
 
359
    //fill in the header
 
 
360
    header->type = SaveBlock_Strategy;
 
 
361
    header->size = size;
 
 
362
    header->bhvr_type = I_BehaviourPlacedHierarchy;
 
 
363
    COPY_NAME(header->SBname,sbPtr->SBname);
 
 
364
 
 
 
365
    {
 
 
366
        int sequence_index = ph_bhv->current_seq-ph_bhv->sequences;
 
 
367
        *(int*)buffer = sequence_index;
 
 
368
        buffer += sizeof(int);
 
 
369
    }
 
 
370
 
 
 
371
    *(int*)buffer = ph_bhv->num_sounds;
 
 
372
    buffer += sizeof(int);
 
 
373
 
 
 
374
    for(i=0; i < ph_bhv->num_sounds; i++)
 
 
375
    {
 
 
376
        int playing = ph_bhv->sounds[i].playing;
 
 
377
        *(int*)buffer = playing;
 
 
378
        buffer += sizeof(int);
 
 
379
    }
 
 
380
 
 
 
381
    //save the hierarchy
 
 
382
    SaveHierarchy(&ph_bhv->HModelController);
 
 
383
 
 
 
384
    for(i=0; i < ph_bhv->num_sounds; i++)
 
 
385
        Save_SoundState(&ph_bhv->sounds[i].activ_no);
 
 
386
}