4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "bh_types.h"
 
 
5
#include "bh_light.h"
 
 
6
#include "pldghost.h"
 
 
7
#include "particle.h"
 
 
8
#include "userprofile.h"
 
 
9
#include "debris.h"
 
 
10
#include <assert.h>
 
 
11
#include <stdlib.h>
 
 
12
 
 
 
13
static void SetTextureAnimationSequence(int shapeindex,TXACTRLBLK* tac,int sequence)
 
 
14
{
 
 
15
    while(tac)
 
 
16
    {
 
 
17
        tac->tac_sequence = sequence;
 
 
18
        tac->tac_txah_s = GetTxAnimHeaderFromShape(tac, shapeindex);
 
 
19
        tac = tac->tac_next;
 
 
20
    }
 
 
21
}
 
 
22
 
 
 
23
static void UpdatePlacedLightState(PLACED_LIGHT_BEHAV_BLOCK* pl_bhv)
 
 
24
{
 
 
25
    int done = 0;
 
 
26
 
 
 
27
    do
 
 
28
    {
 
 
29
        switch(pl_bhv->state)
 
 
30
        {
 
 
31
            case Light_State_Standard:
 
 
32
            case Light_State_Flicker:
 
 
33
            case Light_State_Broken:
 
 
34
                done = 1;
 
 
35
            break;
 
 
36
            case Light_State_StrobeUp :
 
 
37
                if(pl_bhv->timer >= pl_bhv->fade_up_time)
 
 
38
                {
 
 
39
                    pl_bhv->timer -= pl_bhv->fade_up_time;
 
 
40
                    pl_bhv->state = Light_State_StrobeUpDelay;
 
 
41
                }
 
 
42
                else
 
 
43
                {
 
 
44
                    done = 1;
 
 
45
                }
 
 
46
            break;
 
 
47
            case Light_State_StrobeUpDelay:
 
 
48
                if(pl_bhv->timer >= pl_bhv->up_time)
 
 
49
                {
 
 
50
                    pl_bhv->timer -= pl_bhv->up_time;
 
 
51
                    pl_bhv->state = Light_State_StrobeDown;
 
 
52
                }
 
 
53
                else
 
 
54
                {
 
 
55
                    done = 1;
 
 
56
                }
 
 
57
            break;
 
 
58
            case Light_State_StrobeDown:
 
 
59
                if(pl_bhv->timer >= pl_bhv->fade_down_time)
 
 
60
                {
 
 
61
                    pl_bhv->timer -= pl_bhv->fade_down_time;
 
 
62
                    pl_bhv->state = Light_State_StrobeDownDelay;
 
 
63
                }
 
 
64
                else
 
 
65
                {
 
 
66
                    done = 1;
 
 
67
                }
 
 
68
            break;
 
 
69
            case Light_State_StrobeDownDelay:
 
 
70
                if(pl_bhv->timer >= pl_bhv->down_time)
 
 
71
                {
 
 
72
                    pl_bhv->timer -= pl_bhv->down_time;
 
 
73
                    pl_bhv->state = Light_State_StrobeUp;
 
 
74
                }
 
 
75
                else
 
 
76
                {
 
 
77
                    done = 1;
 
 
78
                }
 
 
79
            break;
 
 
80
             default :
 
 
81
                assert(1==0);
 
 
82
                done = 1;
 
 
83
         }
 
 
84
 
 
 
85
    } while(!done);
 
 
86
 
 
 
87
    switch(pl_bhv->on_off_state)
 
 
88
    {
 
 
89
        case Light_OnOff_On:
 
 
90
        case Light_OnOff_Off:
 
 
91
        break;
 
 
92
        case Light_OnOff_FadeOn:
 
 
93
            if(pl_bhv->on_off_timer >= pl_bhv->fade_up_time)
 
 
94
            {
 
 
95
                pl_bhv->on_off_timer = 0;
 
 
96
 
 
 
97
                if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
98
                {
 
 
99
                    pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
100
                }
 
 
101
                else
 
 
102
                {
 
 
103
                    pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
104
                    pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
105
                    pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
106
                }
 
 
107
                pl_bhv->on_off_state = Light_OnOff_On;
 
 
108
            }
 
 
109
        break;
 
 
110
        case Light_OnOff_FadeOff:
 
 
111
            if(pl_bhv->on_off_timer>= pl_bhv->fade_down_time)
 
 
112
            {
 
 
113
                pl_bhv->on_off_timer = 0;
 
 
114
 
 
 
115
                if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
116
                {
 
 
117
                    pl_bhv->light->LightBright = 0;
 
 
118
                }
 
 
119
                else
 
 
120
                {
 
 
121
                    pl_bhv->light->RedScale = pl_bhv->colour_red+pl_bhv->colour_diff_red;
 
 
122
                    pl_bhv->light->GreenScale = pl_bhv->colour_green+pl_bhv->colour_diff_green;
 
 
123
                    pl_bhv->light->BlueScale = pl_bhv->colour_blue+pl_bhv->colour_diff_blue;
 
 
124
                }
 
 
125
                pl_bhv->on_off_state = Light_OnOff_Off;
 
 
126
            }
 
 
127
        break;
 
 
128
        case Light_OnOff_Flicker:
 
 
129
            if(pl_bhv->on_off_timer > 2 * ONE_FIXED)
 
 
130
            {
 
 
131
                pl_bhv->on_off_timer = 0;
 
 
132
                pl_bhv->on_off_state = Light_OnOff_On;
 
 
133
                pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
134
            }
 
 
135
        break;
 
 
136
        default:
 
 
137
            assert(1==0);
 
 
138
    }
 
 
139
}
 
 
140
 
 
 
141
 
 
 
142
void InitPlacedLight(void* bhdata, STRATEGYBLOCK *sbPtr)
 
 
143
{
 
 
144
    TOOLS_DATA_PLACEDLIGHT *toolsData = (TOOLS_DATA_PLACEDLIGHT *)bhdata;
 
 
145
 
 
 
146
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = malloc(sizeof(PLACED_LIGHT_BEHAV_BLOCK));
 
 
147
 
 
 
148
    if(!pl_bhv)
 
 
149
    {
 
 
150
        RemoveBehaviourStrategy(sbPtr);
 
 
151
        return;
 
 
152
    }
 
 
153
 
 
 
154
    pl_bhv->bhvr_type = I_BehaviourPlacedLight;
 
 
155
 
 
 
156
    sbPtr->dataptr = pl_bhv;
 
 
157
    sbPtr->maintainVisibility = 1;
 
 
158
 
 
 
159
    {
 
 
160
        const NPC_DATA *NpcData = &NpcDataList[I_NPC_DefaultInanimate];
 
 
161
        sbPtr->DamageBlock = NpcData->StartingStats;
 
 
162
        sbPtr->DamageBlock.Health = NpcData->StartingStats.Health << ONE_FIXED_SHIFT;
 
 
163
        sbPtr->DamageBlock.Armour = NpcData->StartingStats.Armour << ONE_FIXED_SHIFT;
 
 
164
    }
 
 
165
 
 
 
166
    pl_bhv->destruct_target_request = toolsData->destruct_target_request;
 
 
167
{
 
 
168
    int i;
 
 
169
    for(i=0; i < SB_NAME_LENGTH; i++)
 
 
170
        pl_bhv->destruct_target_ID[i] = toolsData->destruct_target_ID[i];
 
 
171
}
 
 
172
 
 
 
173
    pl_bhv->destruct_target_sbptr = 0;
 
 
174
    pl_bhv->sequence = toolsData->sequence;
 
 
175
    pl_bhv->colour_red = toolsData->colour_red;
 
 
176
    pl_bhv->colour_green = toolsData->colour_green;
 
 
177
    pl_bhv->colour_blue = toolsData->colour_blue;
 
 
178
    pl_bhv->colour_diff_red = toolsData->colour_diff_red;
 
 
179
    pl_bhv->colour_diff_green = toolsData->colour_diff_green;
 
 
180
    pl_bhv->colour_diff_blue = toolsData->colour_diff_blue;
 
 
181
    pl_bhv->fade_up_time = toolsData->fade_up_time;
 
 
182
    pl_bhv->fade_down_time = toolsData->fade_down_time;
 
 
183
    pl_bhv->up_time = toolsData->up_time;
 
 
184
    pl_bhv->down_time = toolsData->down_time;
 
 
185
    pl_bhv->timer = toolsData->timer;
 
 
186
    pl_bhv->flicker_timer = 0;
 
 
187
    pl_bhv->type = toolsData->type;
 
 
188
    pl_bhv->on_off_type = toolsData->on_off_type;
 
 
189
    pl_bhv->state = toolsData->state;
 
 
190
    pl_bhv->on_off_state = toolsData->on_off_state;
 
 
191
    pl_bhv->swap_colour_and_brightness_alterations = toolsData->swap_colour_and_brightness_alterations;
 
 
192
    pl_bhv->on_off_timer = 0;
 
 
193
    pl_bhv->has_broken_sequence = 1;
 
 
194
    pl_bhv->has_corona = 0;
 
 
195
 
 
 
196
    sbPtr->DamageBlock.Health *= toolsData->integrity;
 
 
197
    sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
 
 
198
 
 
 
199
    if(!sbPtr->DynPtr)
 
 
200
    {
 
 
201
        RemoveBehaviourStrategy(sbPtr);
 
 
202
        return;
 
 
203
    }
 
 
204
 
 
 
205
    sbPtr->DynPtr->Mass = 1;
 
 
206
 
 
 
207
    if(!toolsData->static_light)
 
 
208
    {
 
 
209
        sbPtr->DynPtr->Friction = 1;
 
 
210
        sbPtr->DynPtr->Elasticity = 16384;
 
 
211
        sbPtr->DynPtr->IsStatic = 0;
 
 
212
        sbPtr->DynPtr->IsInanimate = 1;
 
 
213
    }
 
 
214
    //sbPtr->DynPtr->IsStatic = 0;
 
 
215
    //sbPtr->DynPtr->GravityOn = 0;
 
 
216
    //sbPtr->DynPtr->DynamicsType = DYN_TYPE_NO_COLLISIONS;
 
 
217
 
 
 
218
    sbPtr->DynPtr->Mass = toolsData->mass;
 
 
219
 
 
 
220
    if(!UserProfile.GameOptions.AllLightsDestructable)
 
 
221
        sbPtr->DamageBlock.Indestructable = (toolsData->integrity > 20);
 
 
222
 
 
 
223
    /*check to see if object is animated.*/
 
 
224
    /*also check for corona flag at the same time*/
 
 
225
    {
 
 
226
        int item_num = 0;
 
 
227
        struct shapeheader* shptr = mainshapelist[sbPtr->shapeIndex];
 
 
228
        TXACTRLBLK **pptxactrlblk = &pl_bhv->inan_tac;
 
 
229
 
 
 
230
        for(; item_num < shptr->numitems; item_num ++)
 
 
231
        {
 
 
232
            POLYHEADER *poly =  (POLYHEADER*)(shptr->items[item_num]);
 
 
233
            assert(poly);
 
 
234
 
 
 
235
            if(poly->PolyFlags & iflag_txanim)
 
 
236
            {
 
 
237
                TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
238
 
 
 
239
                if(pnew_txactrlblk)
 
 
240
                {
 
 
241
                    pnew_txactrlblk->tac_flags = 0;                                        
 
 
242
                    pnew_txactrlblk->tac_item = item_num;                                        
 
 
243
                    pnew_txactrlblk->tac_sequence = 0;                                        
 
 
244
                    pnew_txactrlblk->tac_node = 0;                                        
 
 
245
                    pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(sbPtr->shapeIndex, item_num);                                        
 
 
246
                    pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, sbPtr->shapeIndex);
 
 
247
                    *pptxactrlblk = pnew_txactrlblk;
 
 
248
                    pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
249
 
 
 
250
                    {
 
 
251
                        //see how many sequences there are
 
 
252
                        int num_seq = 0;
 
 
253
                        while(pnew_txactrlblk->tac_txarray[num_seq + 1])
 
 
254
                            num_seq++;
 
 
255
 
 
 
256
                        if(num_seq < 3 )
 
 
257
                            pl_bhv->has_broken_sequence = 0;
 
 
258
 
 
 
259
                        assert(num_seq >= 2);
 
 
260
                    }
 
 
261
                }
 
 
262
                else
 
 
263
                {
 
 
264
                    *pptxactrlblk = NULL; 
 
 
265
                }
 
 
266
            }
 
 
267
 
 
 
268
            if(poly->PolyFlags & iflag_light_corona)
 
 
269
            {
 
 
270
                int* vertexptr = &poly->Poly1stPt;
 
 
271
                int num_verts = 0;
 
 
272
 
 
 
273
                pl_bhv->has_corona = 1;
 
 
274
                pl_bhv->corona_location.vx = pl_bhv->corona_location.vy = pl_bhv->corona_location.vz = 0;
 
 
275
 
 
 
276
                //take the average of all the points in the polygon
 
 
277
                while(*vertexptr != -1)
 
 
278
                {
 
 
279
                    num_verts++;
 
 
280
 
 
 
281
                    VECTORCH *v1 = (VECTORCH*)&shptr->points[0][(*vertexptr)*3];
 
 
282
                    pl_bhv->corona_location.vx += v1->vx;
 
 
283
                    pl_bhv->corona_location.vy += v1->vy;
 
 
284
                    pl_bhv->corona_location.vz += v1->vz;
 
 
285
 
 
 
286
                    vertexptr++;
 
 
287
                }
 
 
288
                pl_bhv->corona_location.vx /= num_verts;
 
 
289
                pl_bhv->corona_location.vy /= num_verts;
 
 
290
                pl_bhv->corona_location.vz /= num_verts;
 
 
291
            }
 
 
292
            if(poly->PolyFlags & iflag_transparent)
 
 
293
            poly->PolyFlags |= iflag_glowing;
 
 
294
        }
 
 
295
 
 
 
296
        *pptxactrlblk = 0;
 
 
297
 
 
 
298
        pl_bhv->light = toolsData->light;
 
 
299
        assert(pl_bhv->light);
 
 
300
 
 
 
301
        pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
302
        pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
303
        pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
304
 
 
 
305
        {
 
 
306
            pl_bhv->light->LightBright = ONE_FIXED * 8;
 
 
307
            pl_bhv->light->LightRange = 10000;
 
 
308
            pl_bhv->light->LightBrightStore = ONE_FIXED * 8;
 
 
309
        }
 
 
310
    }
 
 
311
 
 
 
312
    if(!pl_bhv->inan_tac)
 
 
313
        pl_bhv->has_broken_sequence = 0;
 
 
314
 
 
 
315
    SetTextureAnimationSequence(sbPtr->shapeIndex, pl_bhv->inan_tac, pl_bhv->sequence);
 
 
316
 
 
 
317
    {
 
 
318
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
319
 
 
 
320
        dynPtr->PrevPosition = dynPtr->Position = toolsData->position;
 
 
321
        dynPtr->OrientEuler = toolsData->orientation;
 
 
322
        CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
 
 
323
        TransposeMatrixCH(&dynPtr->OrientMat);      
 
 
324
        sbPtr->containingModule = ModuleFromPosition(&sbPtr->DynPtr->Position, NULL);
 
 
325
 
 
 
326
        if (NULL == sbPtr->containingModule)
 
 
327
        {
 
 
328
            //printf("no containing module for placed light\n");
 
 
329
            RemoveBehaviourStrategy(sbPtr);
 
 
330
            return;
 
 
331
        }
 
 
332
    }
 
 
333
 
 
 
334
    if(SinglePlayer != AvP.PlayMode)
 
 
335
    {
 
 
336
        //If playing a network game with predestroyed lights , get rid of this light
 
 
337
        if(netGameData.preDestroyLights && !sbPtr->DamageBlock.Indestructable)
 
 
338
            KillLightForRespawn(sbPtr);
 
 
339
    }
 
 
340
 
 
 
341
    {
 
 
342
    int i;
 
 
343
    for(i=0; i < SB_NAME_LENGTH; i++)
 
 
344
        sbPtr->SBname[i] = toolsData->nameID[i];
 
 
345
    }
 
 
346
 
 
 
347
    UpdatePlacedLightState(pl_bhv);
 
 
348
 
 
 
349
    /* these must be initialised for respawning objects in multiplayer game */
 
 
350
    pl_bhv->startingHealth = sbPtr->DamageBlock.Health;
 
 
351
    pl_bhv->startingArmour = sbPtr->DamageBlock.Armour;
 
 
352
}
 
 
353
 
 
 
354
static void UpdatePlacedLightColour(PLACED_LIGHT_BEHAV_BLOCK* pl_bhv)
 
 
355
{
 
 
356
    int mult;
 
 
357
    assert(pl_bhv);
 
 
358
 
 
 
359
    //first alter colour for stobing lights
 
 
360
    switch(pl_bhv->state)    
 
 
361
    {
 
 
362
        case Light_State_Broken:
 
 
363
            break;
 
 
364
        case Light_State_Standard:
 
 
365
            if(pl_bhv->on_off_state != Light_OnOff_Off)
 
 
366
            {
 
 
367
                pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
368
                pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
369
                pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
370
            }
 
 
371
        break;
 
 
372
        case Light_State_StrobeUpDelay:
 
 
373
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
374
            {
 
 
375
                pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
376
                pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
377
                pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
378
            }
 
 
379
            else
 
 
380
            {
 
 
381
                pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
382
            }
 
 
383
        break;
 
 
384
        case Light_State_StrobeDownDelay:
 
 
385
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
386
            {
 
 
387
                pl_bhv->light->RedScale = pl_bhv->colour_red+pl_bhv->colour_diff_red;
 
 
388
                pl_bhv->light->GreenScale = pl_bhv->colour_green+pl_bhv->colour_diff_green;
 
 
389
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+pl_bhv->colour_diff_blue;
 
 
390
            }
 
 
391
            else
 
 
392
            {
 
 
393
                pl_bhv->light->LightBright = 0;
 
 
394
            }
 
 
395
        break;
 
 
396
        case Light_State_StrobeUp:
 
 
397
            mult = DIV_FIXED(pl_bhv->fade_up_time-pl_bhv->timer,pl_bhv->fade_up_time);
 
 
398
 
 
 
399
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
400
            {
 
 
401
                pl_bhv->light->RedScale = pl_bhv->colour_red+MUL_FIXED(pl_bhv->colour_diff_red,mult);
 
 
402
                pl_bhv->light->GreenScale = pl_bhv->colour_green+MUL_FIXED(pl_bhv->colour_diff_green,mult);
 
 
403
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+MUL_FIXED(pl_bhv->colour_diff_blue,mult);
 
 
404
            }
 
 
405
            else
 
 
406
            {
 
 
407
                mult = ONE_FIXED - mult;
 
 
408
                pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore, mult);
 
 
409
            }
 
 
410
        break;
 
 
411
        case Light_State_StrobeDown:
 
 
412
            mult = DIV_FIXED(pl_bhv->timer,pl_bhv->fade_down_time);
 
 
413
 
 
 
414
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
415
            {
 
 
416
                pl_bhv->light->RedScale = pl_bhv->colour_red+MUL_FIXED(pl_bhv->colour_diff_red,mult);
 
 
417
                pl_bhv->light->GreenScale = pl_bhv->colour_green+MUL_FIXED(pl_bhv->colour_diff_green,mult);
 
 
418
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+MUL_FIXED(pl_bhv->colour_diff_blue,mult);
 
 
419
            }
 
 
420
            else
 
 
421
            {
 
 
422
                mult = ONE_FIXED - mult;
 
 
423
                pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore,mult);
 
 
424
            }
 
 
425
        break;
 
 
426
        case Light_State_Flicker:
 
 
427
            if(pl_bhv->on_off_state == Light_OnOff_On)
 
 
428
            {
 
 
429
                if(pl_bhv->flicker_timer >= 1750)
 
 
430
                {
 
 
431
                    mult = FastRandom() & 0xffff;
 
 
432
 
 
 
433
                    if (!((mult % 24 ) >> 3))
 
 
434
                        mult |= 0xa000;
 
 
435
                    else
 
 
436
                        mult &=~ 0xf000;
 
 
437
 
 
 
438
                    pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore, mult);
 
 
439
                }
 
 
440
            }
 
 
441
        break;
 
 
442
        default:
 
 
443
            assert(1==0);
 
 
444
    }
 
 
445
 
 
 
446
    //now alter brightness for switching on/off
 
 
447
    switch(pl_bhv->on_off_state)
 
 
448
    {
 
 
449
        case Light_OnOff_Off:
 
 
450
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
451
            {
 
 
452
                pl_bhv->light->LightBright = 0;
 
 
453
            }
 
 
454
            else
 
 
455
            {
 
 
456
                pl_bhv->light->RedScale = pl_bhv->colour_red+pl_bhv->colour_diff_red;
 
 
457
                pl_bhv->light->GreenScale = pl_bhv->colour_green+pl_bhv->colour_diff_green;
 
 
458
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+pl_bhv->colour_diff_blue;
 
 
459
            }
 
 
460
        break;
 
 
461
        case Light_OnOff_On:
 
 
462
            if(pl_bhv->state != Light_State_Flicker)
 
 
463
            {
 
 
464
                if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
465
                {
 
 
466
                    pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
467
                }
 
 
468
                else
 
 
469
                {
 
 
470
                    pl_bhv->light->RedScale = pl_bhv->colour_red;
 
 
471
                    pl_bhv->light->GreenScale = pl_bhv->colour_green;
 
 
472
                    pl_bhv->light->BlueScale = pl_bhv->colour_blue;
 
 
473
                }
 
 
474
            }
 
 
475
        break;
 
 
476
        case Light_OnOff_FadeOn:
 
 
477
            mult = DIV_FIXED(pl_bhv->on_off_timer,pl_bhv->fade_up_time);
 
 
478
 
 
 
479
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
480
            {
 
 
481
                pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore,mult);
 
 
482
            }
 
 
483
            else
 
 
484
            {
 
 
485
                mult = ONE_FIXED - mult;
 
 
486
                pl_bhv->light->RedScale = pl_bhv->colour_red+MUL_FIXED(pl_bhv->colour_diff_red,mult);
 
 
487
                pl_bhv->light->GreenScale = pl_bhv->colour_green+MUL_FIXED(pl_bhv->colour_diff_green,mult);
 
 
488
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+MUL_FIXED(pl_bhv->colour_diff_blue,mult);
 
 
489
            }
 
 
490
        break;
 
 
491
        case Light_OnOff_FadeOff:
 
 
492
            mult = DIV_FIXED(pl_bhv->fade_down_time-pl_bhv->on_off_timer,pl_bhv->fade_down_time);
 
 
493
 
 
 
494
            if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
495
            {
 
 
496
                pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore,mult);
 
 
497
            }
 
 
498
            else
 
 
499
            {
 
 
500
                mult = ONE_FIXED - mult;
 
 
501
                pl_bhv->light->RedScale = pl_bhv->colour_red+MUL_FIXED(pl_bhv->colour_diff_red,mult);
 
 
502
                pl_bhv->light->GreenScale = pl_bhv->colour_green+MUL_FIXED(pl_bhv->colour_diff_green,mult);
 
 
503
                pl_bhv->light->BlueScale = pl_bhv->colour_blue+MUL_FIXED(pl_bhv->colour_diff_blue,mult);
 
 
504
            }
 
 
505
        break;
 
 
506
        case Light_OnOff_Flicker:
 
 
507
            if(pl_bhv->flicker_timer >= 3500)
 
 
508
            {
 
 
509
                mult = FastRandom() & 0xffff;
 
 
510
 
 
 
511
                if (!((mult % 24 ) >> 3))
 
 
512
                    mult |= 0xa000;
 
 
513
                else
 
 
514
                    mult &=~ 0xf000;
 
 
515
 
 
 
516
                pl_bhv->light->LightBright = MUL_FIXED(pl_bhv->light->LightBrightStore,mult);
 
 
517
            }
 
 
518
        break;
 
 
519
        default:
 
 
520
            assert(1==0);
 
 
521
    }
 
 
522
}
 
 
523
 
 
 
524
void KillLightForRespawn(STRATEGYBLOCK *sbPtr)
 
 
525
{
 
 
526
    /* make the light invisible, and remove it from visibility management */
 
 
527
    sbPtr->maintainVisibility = 0;
 
 
528
 
 
 
529
    DestroyActiveObject(&sbPtr->DisplayBlock);
 
 
530
}
 
 
531
 
 
 
532
void PlacedLightBehaviour(STRATEGYBLOCK *sbPtr)
 
 
533
{
 
 
534
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
535
    assert(pl_bhv);
 
 
536
 
 
 
537
    if(pl_bhv->inan_tac)
 
 
538
    {
 
 
539
        DISPLAYBLOCK* dptr = sbPtr->DisplayBlock;
 
 
540
 
 
 
541
        /*deal with texture animation*/
 
 
542
        if(dptr && !dptr->ObTxAnimCtrlBlks)
 
 
543
            dptr->ObTxAnimCtrlBlks = pl_bhv->inan_tac;
 
 
544
    }
 
 
545
 
 
 
546
    //if the light is broken , don't do anything else
 
 
547
    if(pl_bhv->state == Light_State_Broken)
 
 
548
        return;
 
 
549
 
 
 
550
    //update timer if necessary
 
 
551
    if(pl_bhv->on_off_state != Light_OnOff_Off && pl_bhv->on_off_state != Light_OnOff_On)
 
 
552
    {
 
 
553
        pl_bhv->on_off_timer += NormalFrameTime;
 
 
554
        pl_bhv->flicker_timer %= 3500;
 
 
555
        pl_bhv->flicker_timer += NormalFrameTime;
 
 
556
    }
 
 
557
    else
 
 
558
    {
 
 
559
        switch(pl_bhv->state)
 
 
560
        {
 
 
561
            case Light_State_StrobeUp:
 
 
562
            case Light_State_StrobeDown:
 
 
563
            case Light_State_StrobeUpDelay:
 
 
564
            case Light_State_StrobeDownDelay:
 
 
565
                pl_bhv->timer += NormalFrameTime;
 
 
566
            break;
 
 
567
            case Light_State_Flicker:
 
 
568
                pl_bhv->flicker_timer %= 1750;
 
 
569
                pl_bhv->flicker_timer += NormalFrameTime;
 
 
570
            default:
 
 
571
            break;
 
 
572
        }
 
 
573
    }
 
 
574
 
 
 
575
    UpdatePlacedLightState(pl_bhv);
 
 
576
 
 
 
577
    if(sbPtr->DisplayBlock)
 
 
578
        UpdatePlacedLightColour(pl_bhv);
 
 
579
}
 
 
580
 
 
 
581
void MakePlacedLightNear(STRATEGYBLOCK *sbPtr)
 
 
582
{
 
 
583
    DISPLAYBLOCK *dPtr = CreateActiveObject();
 
 
584
 
 
 
585
    if(NULL != dPtr)
 
 
586
    {
 
 
587
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
588
        PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = (PLACED_LIGHT_BEHAV_BLOCK*) sbPtr->dataptr;
 
 
589
        LIGHTBLOCK *lptr_array = pl_bhv->light;
 
 
590
 
 
 
591
        dPtr->ObShape = sbPtr->shapeIndex;
 
 
592
        dPtr->ShapeData = mainshapelist[sbPtr->shapeIndex];
 
 
593
 
 
 
594
        /*
 
 
595
            Module lights
 
 
596
 
 
 
597
            There is an option for a pointer to an array of lights in a module
 
 
598
            structure. These lights are transferred to the display block and
 
 
599
            flagged as "LFlag_WasNotAllocated" so that "DeallocateLightBlock()"
 
 
600
            knows to ignore them.
 
 
601
 
 
 
602
            The number of lights in the array is "m_numlights" and the pointer
 
 
603
            is called "m_lightarray".
 
 
604
 
 
 
605
            The addition of non-allocated does not need to be a module specific
 
 
606
            option.
 
 
607
 
 
 
608
            Non-allocated lights can co-exist peacefully with the other lights.
 
 
609
        */
 
 
610
 
 
 
611
        /* Make sure the light is flagged correctly */
 
 
612
 
 
 
613
        lptr_array->LightFlags |= LFlag_WasNotAllocated;
 
 
614
 
 
 
615
        AddLightBlock(dPtr, lptr_array);
 
 
616
 
 
 
617
        sbPtr->DisplayBlock = dPtr;
 
 
618
        dPtr->ObStrategyBlock = sbPtr;
 
 
619
 
 
 
620
        dPtr->ObWorld = dynPtr->Position;
 
 
621
        dPtr->ObEuler = dynPtr->OrientEuler;
 
 
622
        dPtr->ObMat = dynPtr->OrientMat;
 
 
623
 
 
 
624
        dPtr->extent.min_x = -10;
 
 
625
        dPtr->extent.max_x = 10;
 
 
626
        dPtr->extent.min_z = -10;
 
 
627
        dPtr->extent.max_z = 10;
 
 
628
        dPtr->extent.min_y = 10;
 
 
629
        dPtr->extent.max_y = 10;
 
 
630
        dPtr->extent.radius = 200;
 
 
631
 
 
 
632
        dPtr->ObFlags3 |= ObFlag3_NoLightDot; //so light will light itself
 
 
633
        UpdatePlacedLightColour(pl_bhv);
 
 
634
    }
 
 
635
}
 
 
636
 
 
 
637
void RespawnLight(STRATEGYBLOCK *sbPtr)
 
 
638
{
 
 
639
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
640
 
 
 
641
    if(netGameData.preDestroyLights)
 
 
642
        return; //don't restore lights for this type of net game
 
 
643
 
 
 
644
    if(pl_bhv->state == Light_State_Broken)
 
 
645
    {
 
 
646
        sbPtr->maintainVisibility = 1;
 
 
647
 
 
 
648
        /* must respawn health too... */    
 
 
649
        sbPtr->DamageBlock.Health = pl_bhv->startingHealth;
 
 
650
        sbPtr->DamageBlock.Armour = pl_bhv->startingArmour;
 
 
651
 
 
 
652
        //reactivate the light
 
 
653
        pl_bhv->sequence = 1;
 
 
654
        pl_bhv->light->LightBright = pl_bhv->light->LightBrightStore;
 
 
655
        pl_bhv->on_off_state = Light_OnOff_On;
 
 
656
 
 
 
657
        switch(pl_bhv->type)
 
 
658
        {
 
 
659
            case Light_Type_Standard:
 
 
660
                pl_bhv->state = Light_State_Standard;
 
 
661
            break;
 
 
662
            case Light_Type_Strobe:
 
 
663
                pl_bhv->state = Light_State_StrobeUpDelay;
 
 
664
            break;
 
 
665
            case Light_Type_Flicker:
 
 
666
                pl_bhv->state = Light_State_Flicker;
 
 
667
        }
 
 
668
 
 
 
669
        //need to use the on animation sequence again
 
 
670
        SetTextureAnimationSequence(sbPtr->shapeIndex, pl_bhv->inan_tac, pl_bhv->sequence);
 
 
671
 
 
 
672
        UpdatePlacedLightState(pl_bhv);
 
 
673
    }
 
 
674
}
 
 
675
 
 
 
676
/* this global flag is used to distinguish between messages from the host, and locally caused damage */
 
 
677
extern int InanimateDamageFromNetHost;
 
 
678
 
 
 
679
void PlacedLightIsDamaged(STRATEGYBLOCK *sbPtr, const DAMAGE_PROFILE *damage, int multiple)
 
 
680
{
 
 
681
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
682
    assert(pl_bhv);
 
 
683
 
 
 
684
    if(pl_bhv->state == Light_State_Broken)
 
 
685
    {
 
 
686
        if (!sbPtr->DamageBlock.Indestructable && !pl_bhv->has_broken_sequence)
 
 
687
        {
 
 
688
            if(SinglePlayer == AvP.PlayMode)
 
 
689
                sbPtr->please_destroy_me = 1;
 
 
690
            else
 
 
691
                KillLightForRespawn(sbPtr);
 
 
692
        }
 
 
693
        return;
 
 
694
    }
 
 
695
 
 
 
696
    if((NetworkPeer == AvP.PlayMode) && !InanimateDamageFromNetHost)
 
 
697
    {
 
 
698
        //add light damaged net message
 
 
699
        AddNetMsg_InanimateObjectDamaged(sbPtr, damage, multiple);
 
 
700
        return;
 
 
701
    }
 
 
702
 
 
 
703
    if(sbPtr->DamageBlock.Health <= 0) 
 
 
704
    {
 
 
705
        if(NetworkHost == AvP.PlayMode)
 
 
706
        {
 
 
707
            AddNetMsg_InanimateObjectDestroyed(sbPtr);
 
 
708
            return;
 
 
709
        }
 
 
710
 
 
 
711
        //change to broken sequence if it exists.
 
 
712
        //otherwise destroy light 
 
 
713
        pl_bhv->state = Light_State_Broken;
 
 
714
        pl_bhv->on_off_state = Light_OnOff_Off;
 
 
715
        pl_bhv->sequence = 2;
 
 
716
        pl_bhv->light->LightBright = 0;
 
 
717
 
 
 
718
        //notify target of destruction
 
 
719
        if(pl_bhv->destruct_target_sbptr)
 
 
720
            RequestState(pl_bhv->destruct_target_sbptr, pl_bhv->destruct_target_request, 0);
 
 
721
 
 
 
722
        /* KJL 17:08:44 10/07/98 - Make some sparks */
 
 
723
        if (sbPtr->DisplayBlock)
 
 
724
            MakeSprayOfSparks(&sbPtr->DisplayBlock->ObMat, &sbPtr->DisplayBlock->ObWorld);
 
 
725
 
 
 
726
        if(pl_bhv->has_broken_sequence)
 
 
727
        {
 
 
728
            SetTextureAnimationSequence(sbPtr->shapeIndex, pl_bhv->inan_tac, pl_bhv->sequence);
 
 
729
        }
 
 
730
        else
 
 
731
        {
 
 
732
            MakeFragments(sbPtr); // Actually only sound
 
 
733
 
 
 
734
            if(SinglePlayer == AvP.PlayMode)
 
 
735
                sbPtr->please_destroy_me = 1;
 
 
736
            else
 
 
737
                KillLightForRespawn(sbPtr);
 
 
738
        }
 
 
739
    }
 
 
740
}
 
 
741
 
 
 
742
#define LightRequest_AdjustIntegrity 0x00000001
 
 
743
#define LightRequest_AdjustType_Standard 0x00000002
 
 
744
#define LightRequest_AdjustType_Strobe 0x00000004
 
 
745
#define LightRequest_AdjustType_Flicker 0x00000008
 
 
746
#define LightRequest_SwapUpAndDown 0x00000010
 
 
747
 
 
 
748
void SendRequestToPlacedLight(STRATEGYBLOCK* sbptr, int state, int extended_data)
 
 
749
{
 
 
750
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbptr->dataptr;
 
 
751
    assert(pl_bhv);
 
 
752
 
 
 
753
    if(pl_bhv->state == Light_State_Broken)
 
 
754
        return;
 
 
755
 
 
 
756
    if(extended_data)
 
 
757
    {
 
 
758
        if(extended_data & LightRequest_AdjustIntegrity)
 
 
759
        {
 
 
760
            if(state)
 
 
761
            {
 
 
762
                int new_integrity = (extended_data >> 7) & 0xff;
 
 
763
                sbptr->DamageBlock.Indestructable = (new_integrity > 20);
 
 
764
 
 
 
765
                if(!new_integrity)
 
 
766
                {
 
 
767
                    sbptr->DamageBlock.Health = 0;
 
 
768
                    PlacedLightIsDamaged(sbptr, &damage_profiles[CERTAINDEATH], ONE_FIXED);
 
 
769
                }
 
 
770
                else
 
 
771
                    sbptr->DamageBlock.Health = (10 << ONE_FIXED_SHIFT) * new_integrity;    
 
 
772
            }
 
 
773
        }
 
 
774
 
 
 
775
        if(state)
 
 
776
        {
 
 
777
            if(extended_data & (LightRequest_AdjustType_Standard | LightRequest_AdjustType_Flicker))
 
 
778
            {
 
 
779
                /* changing state, try to preserve strobe timer */
 
 
780
                switch(pl_bhv->state)
 
 
781
                {
 
 
782
                    /* lack of break's intended */
 
 
783
                    case Light_State_StrobeUpDelay:
 
 
784
                        pl_bhv->timer += pl_bhv->fade_up_time;
 
 
785
 
 
 
786
                    case Light_State_StrobeUp:
 
 
787
                        pl_bhv->timer += pl_bhv->down_time;
 
 
788
 
 
 
789
                    case Light_State_StrobeDownDelay:
 
 
790
                        pl_bhv->timer += pl_bhv->fade_down_time;
 
 
791
                    default:
 
 
792
                    break;
 
 
793
                }
 
 
794
            }
 
 
795
 
 
 
796
            if(extended_data & LightRequest_AdjustType_Standard)
 
 
797
            {
 
 
798
                pl_bhv->type = Light_Type_Standard;
 
 
799
                pl_bhv->state = Light_State_Standard;
 
 
800
            }
 
 
801
 
 
 
802
            if(extended_data & LightRequest_AdjustType_Flicker)
 
 
803
            {
 
 
804
                 pl_bhv->type = Light_Type_Flicker;
 
 
805
                  pl_bhv->state = Light_State_Flicker;
 
 
806
            }
 
 
807
 
 
 
808
            if(extended_data & LightRequest_AdjustType_Strobe)
 
 
809
            {
 
 
810
                if(pl_bhv->type != Light_Type_Strobe)
 
 
811
                {
 
 
812
                    pl_bhv->type = Light_Type_Strobe;
 
 
813
                    pl_bhv->state = Light_State_StrobeDown;
 
 
814
                }
 
 
815
            }
 
 
816
 
 
 
817
            if(extended_data & LightRequest_SwapUpAndDown)
 
 
818
            {
 
 
819
                //swap the up and down colours for the light
 
 
820
                int temp_red = pl_bhv->colour_red;    
 
 
821
                int temp_green = pl_bhv->colour_green;    
 
 
822
                int temp_blue = pl_bhv->colour_blue;    
 
 
823
 
 
 
824
                pl_bhv->colour_red += pl_bhv->colour_diff_red;
 
 
825
                pl_bhv->colour_green += pl_bhv->colour_diff_green;
 
 
826
                pl_bhv->colour_blue += pl_bhv->colour_diff_blue;
 
 
827
 
 
 
828
                pl_bhv->colour_diff_red = temp_red-pl_bhv->colour_red;
 
 
829
                pl_bhv->colour_diff_blue = temp_blue-pl_bhv->colour_blue;
 
 
830
                pl_bhv->colour_diff_green = temp_green-pl_bhv->colour_green;
 
 
831
            }
 
 
832
        }
 
 
833
    }
 
 
834
    else
 
 
835
    {
 
 
836
        if(state) //switch light on
 
 
837
        {
 
 
838
            if(pl_bhv->on_off_state != Light_OnOff_On)
 
 
839
            {
 
 
840
                switch(pl_bhv->on_off_type)
 
 
841
                {
 
 
842
                    case Light_OnOff_Type_Fade:
 
 
843
                    {
 
 
844
                        switch(pl_bhv->on_off_state)
 
 
845
                        {
 
 
846
                            case Light_OnOff_FadeOn:
 
 
847
                                break;
 
 
848
 
 
 
849
                            case Light_OnOff_FadeOff:
 
 
850
                            {
 
 
851
                                //reverse direction of fade
 
 
852
                                int mult = ONE_FIXED-DIV_FIXED(pl_bhv->on_off_timer,pl_bhv->fade_down_time);
 
 
853
                                pl_bhv->on_off_timer = MUL_FIXED(mult,pl_bhv->fade_up_time);
 
 
854
                                pl_bhv->on_off_state = Light_OnOff_FadeOn;
 
 
855
                            }
 
 
856
                            break;
 
 
857
                            case Light_OnOff_Off:
 
 
858
                            {
 
 
859
                                //start to fade up
 
 
860
                                pl_bhv->on_off_timer = 0;
 
 
861
                                pl_bhv->on_off_state = Light_OnOff_FadeOn;
 
 
862
                            }
 
 
863
                            break;
 
 
864
                            default:
 
 
865
                            {
 
 
866
                                assert(0);
 
 
867
                            }
 
 
868
                        }
 
 
869
                    }
 
 
870
                    break;
 
 
871
                    case Light_OnOff_Type_Standard:
 
 
872
                        pl_bhv->on_off_state = Light_OnOff_On;
 
 
873
                    break;
 
 
874
                    case Light_OnOff_Type_Flicker:
 
 
875
                        if(pl_bhv->on_off_state != Light_OnOff_Flicker)
 
 
876
                        {
 
 
877
                            pl_bhv->on_off_state = Light_OnOff_Flicker;
 
 
878
                            pl_bhv->on_off_timer = 0;
 
 
879
 
 
 
880
                            //light is flickering on , so play the flickering on sound
 
 
881
                            Sound_Play(SID_LIGHT_FLICKER_ON, "d", &sbptr->DynPtr->Position);
 
 
882
                        }
 
 
883
                    break;
 
 
884
                    default :
 
 
885
                        assert(1==0);
 
 
886
                        break;
 
 
887
                }
 
 
888
            }
 
 
889
        }
 
 
890
        else //switch the light off 
 
 
891
        {
 
 
892
            if(pl_bhv->on_off_state != Light_OnOff_Off)
 
 
893
            {
 
 
894
                switch(pl_bhv->on_off_type)
 
 
895
                {
 
 
896
                    case Light_OnOff_Type_Fade:
 
 
897
                    {
 
 
898
                        switch(pl_bhv->on_off_state)
 
 
899
                        {
 
 
900
                            case Light_OnOff_On:
 
 
901
                                //start to fade down
 
 
902
                                pl_bhv->on_off_timer = 0;
 
 
903
                                pl_bhv->on_off_state = Light_OnOff_FadeOff;
 
 
904
                            break;
 
 
905
                            case Light_OnOff_FadeOn:
 
 
906
                            //reverse direction of fade
 
 
907
                            {
 
 
908
                                int mult = ONE_FIXED-DIV_FIXED(pl_bhv->on_off_timer,pl_bhv->fade_up_time);
 
 
909
                                pl_bhv->on_off_timer = MUL_FIXED(mult,pl_bhv->fade_down_time);
 
 
910
                                pl_bhv->on_off_state = Light_OnOff_FadeOff;
 
 
911
                            }
 
 
912
                            break;
 
 
913
                            case Light_OnOff_FadeOff:
 
 
914
                                break;
 
 
915
                            default:
 
 
916
                            {
 
 
917
                                assert(0);
 
 
918
                            }
 
 
919
                        }
 
 
920
                    }
 
 
921
                    break;
 
 
922
                    case Light_OnOff_Type_Standard:
 
 
923
                    case Light_OnOff_Type_Flicker:
 
 
924
                    {
 
 
925
                        pl_bhv->on_off_state = Light_OnOff_Off;
 
 
926
 
 
 
927
                        if(!pl_bhv->swap_colour_and_brightness_alterations)
 
 
928
                        {
 
 
929
                            pl_bhv->light->LightBright = 0;
 
 
930
                        }
 
 
931
                        else
 
 
932
                        {
 
 
933
                            pl_bhv->light->RedScale = pl_bhv->colour_red+pl_bhv->colour_diff_red;
 
 
934
                            pl_bhv->light->GreenScale = pl_bhv->colour_green+pl_bhv->colour_diff_green;
 
 
935
                            pl_bhv->light->BlueScale = pl_bhv->colour_blue+pl_bhv->colour_diff_blue;
 
 
936
                        }
 
 
937
                    }
 
 
938
                    break;
 
 
939
                    default:
 
 
940
                        assert(1==0);
 
 
941
                        break;
 
 
942
                }
 
 
943
            }
 
 
944
        }
 
 
945
    }
 
 
946
 
 
 
947
    pl_bhv->sequence = (pl_bhv->on_off_state != Light_OnOff_Off);
 
 
948
 
 
 
949
    SetTextureAnimationSequence(sbptr->shapeIndex, pl_bhv->inan_tac, pl_bhv->sequence);
 
 
950
}
 
 
951
 
 
 
952
/*--------------------**
 
 
953
** Loading and Saving **
 
 
954
**--------------------*/
 
 
955
#include "savegame.h"
 
 
956
 
 
 
957
typedef struct placed_light_save_block
 
 
958
{
 
 
959
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
960
 
 
 
961
    LIGHT_TYPE type;
 
 
962
    LIGHT_STATE state;
 
 
963
    LIGHT_ON_OFF_STATE on_off_state;
 
 
964
    int sequence;    //texture animation sequence
 
 
965
    int colour_red;  //colour for fade up state
 
 
966
    int colour_green;
 
 
967
    int colour_blue;
 
 
968
    int colour_diff_red;  //difference from up colour to down colour
 
 
969
    int colour_diff_green;
 
 
970
    int colour_diff_blue;
 
 
971
    int timer;
 
 
972
    int on_off_timer;
 
 
973
    int flicker_timer;
 
 
974
 
 
 
975
    //strategyblock stuff
 
 
976
    DAMAGEBLOCK DamageBlock;
 
 
977
 
 
 
978
} PLACED_LIGHT_SAVE_BLOCK;
 
 
979
 
 
 
980
//defines for load/save macros
 
 
981
#define SAVELOAD_BLOCK block
 
 
982
#define SAVELOAD_BEHAV pl_bhv
 
 
983
 
 
 
984
void LoadStrategy_PlacedLight(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
985
{
 
 
986
    PLACED_LIGHT_SAVE_BLOCK* block = (PLACED_LIGHT_SAVE_BLOCK*) header; 
 
 
987
 
 
 
988
    //check the size of the save block
 
 
989
    if(header->size != sizeof(*block))
 
 
990
        return;
 
 
991
 
 
 
992
    //find the existing strategy block
 
 
993
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
994
 
 
 
995
    if(!sbPtr)
 
 
996
        return;
 
 
997
 
 
 
998
    //make sure the strategy found is of the right type
 
 
999
    if(sbPtr->type != I_BehaviourPlacedLight)
 
 
1000
        return;
 
 
1001
 
 
 
1002
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
1003
 
 
 
1004
    //start copying stuff
 
 
1005
 
 
 
1006
    COPYELEMENT_LOAD(type);
 
 
1007
    COPYELEMENT_LOAD(state);
 
 
1008
       COPYELEMENT_LOAD(on_off_state);
 
 
1009
    COPYELEMENT_LOAD(sequence);    //texture animation sequence
 
 
1010
    COPYELEMENT_LOAD(colour_red);  //colour for fade up state
 
 
1011
    COPYELEMENT_LOAD(colour_green);
 
 
1012
    COPYELEMENT_LOAD(colour_blue);
 
 
1013
    COPYELEMENT_LOAD(colour_diff_red);  //difference from up colour to down colour
 
 
1014
    COPYELEMENT_LOAD(colour_diff_green);
 
 
1015
    COPYELEMENT_LOAD(colour_diff_blue);
 
 
1016
    COPYELEMENT_LOAD(timer);
 
 
1017
    COPYELEMENT_LOAD(on_off_timer);
 
 
1018
    COPYELEMENT_LOAD(flicker_timer);
 
 
1019
 
 
 
1020
    sbPtr->DamageBlock = block->DamageBlock;
 
 
1021
 
 
 
1022
    SetTextureAnimationSequence(sbPtr->shapeIndex, pl_bhv->inan_tac, pl_bhv->sequence);
 
 
1023
    UpdatePlacedLightColour(pl_bhv);
 
 
1024
}
 
 
1025
 
 
 
1026
void SaveStrategy_PlacedLight(STRATEGYBLOCK* sbPtr)
 
 
1027
{
 
 
1028
    PLACED_LIGHT_SAVE_BLOCK *block;
 
 
1029
    PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
1030
 
 
 
1031
    GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
 
 
1032
 
 
 
1033
    //start copying stuff
 
 
1034
    COPYELEMENT_SAVE(type);
 
 
1035
    COPYELEMENT_SAVE(state);
 
 
1036
       COPYELEMENT_SAVE(on_off_state);
 
 
1037
    COPYELEMENT_SAVE(sequence);    //texture animation sequence
 
 
1038
    COPYELEMENT_SAVE(colour_red);  //colour for fade up state
 
 
1039
    COPYELEMENT_SAVE(colour_green);
 
 
1040
    COPYELEMENT_SAVE(colour_blue);
 
 
1041
    COPYELEMENT_SAVE(colour_diff_red);  //difference from up colour to down colour
 
 
1042
    COPYELEMENT_SAVE(colour_diff_green);
 
 
1043
    COPYELEMENT_SAVE(colour_diff_blue);
 
 
1044
    COPYELEMENT_SAVE(timer);
 
 
1045
    COPYELEMENT_SAVE(on_off_timer);
 
 
1046
    COPYELEMENT_SAVE(flicker_timer);
 
 
1047
 
 
 
1048
    block->DamageBlock = sbPtr->DamageBlock;
 
 
1049
}