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