~ubuntu-branches/ubuntu/lucid/warzone2100/lucid

« back to all changes in this revision

Viewing changes to src/effects.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger, Paul Wise, Christoph Egger
  • Date: 2009-06-29 17:12:52 UTC
  • mfrom: (1.1.11 upstream) (2.1.7 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090629171252-5ddnlfg3zfchrega
Tags: 2.2.1+dfsg1-1
[ Paul Wise ]
* New upstream release (Closes: #534962)
* Adjust the flex build-depends to take account of the conflict
  with all the versions of flex 2.5.34 (LP: #372872)
* Make the -music Recommends more strict, 2.1 music doesn't work
  with 2.2.
* Upstream moved the downloads to sourceforge, update the watch file
* Bump Standards-Version, no changes needed
* Drop use of dh_desktop since it no longer does anything
* Recommend the new warzone2100-video package, version 2.2 or similar
* Mention the warzone2100 crash reports in the -dbg package description

[ Christoph Egger ]
* Replace CC-2.0 graphic from cybersphinx, create a new tarball
* Add myself to uploaders

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
        This file is part of Warzone 2100.
3
3
        Copyright (C) 1999-2004  Eidos Interactive
4
 
        Copyright (C) 2005-2007  Warzone Resurrection Project
 
4
        Copyright (C) 2005-2009  Warzone Resurrection Project
5
5
 
6
6
        Warzone 2100 is free software; you can redistribute it and/or modify
7
7
        it under the terms of the GNU General Public License as published by
39
39
#include "lib/framework/frameresource.h"
40
40
#include "lib/framework/input.h"
41
41
#include "lib/framework/tagfile.h"
42
 
#include "lib/framework/math-help.h"
 
42
#include "lib/framework/math_ext.h"
43
43
 
44
44
#include "lib/ivis_common/ivisdef.h" //ivis matrix code
45
45
#include "lib/ivis_common/piedef.h" //ivis matrix code
 
46
#include "lib/framework/fixedpoint.h"
46
47
#include "lib/ivis_common/piepalette.h"
47
48
#include "lib/ivis_common/piestate.h"
48
49
#include "lib/ivis_opengl/piematrix.h"
96
97
#define SET_CYCLIC(x)                   ((x->control) = (UBYTE)(x->control | EFFECT_CYCLIC))
97
98
#define SET_SCALED(x)                   ((x->control) = (UBYTE)(x->control | EFFECT_SCALED))
98
99
#define SET_LIT(x)                              ((x->control) = (UBYTE)(x->control | EFFECT_LIT))
99
 
#define SET_LITABS(x)                   ((x.control) = (UBYTE)(x.control | EFFECT_LIT))
100
100
 
101
101
#define MINIMUM_IMPACT_VELOCITY         (16)
102
102
#define NORMAL_SMOKE_LIFESPAN           (6000 + rand()%3000)
182
182
static  UDWORD  skipped,skippedEffects,letThrough;
183
183
static  UDWORD  auxVar; // dirty filthy hack - don't look for what this does.... //FIXME
184
184
static  UDWORD  auxVarSec; // dirty filthy hack - don't look for what this does.... //FIXME
185
 
static  UDWORD  aeCalls;
186
185
static  UDWORD  specifiedSize;
187
186
static  UDWORD  ellSpec;
188
187
 
213
212
static void     renderBloodEffect               ( EFFECT *psEffect );
214
213
static void     renderDestructionEffect ( EFFECT *psEffect );
215
214
static void renderFirework                      ( EFFECT *psEffect );
 
215
 
216
216
static void positionEffect(EFFECT *psEffect);
217
217
/* There is no render destruction effect! */
218
218
 
228
228
static void     effectSetupFire                 ( EFFECT *psEffect );
229
229
static void     effectSetUpSatLaser             ( EFFECT *psEffect );
230
230
static void effectSetUpFirework         ( EFFECT *psEffect );
231
 
#ifdef DEBUG
232
 
static BOOL     validatePie( EFFECT_GROUP group, iIMDShape *pie );
233
 
#endif
234
231
static void effectStructureUpdates(void);
235
232
static void effectDroidUpdates(void);
 
233
static UDWORD effectGetNumFrames(EFFECT *psEffect);
 
234
 
236
235
 
237
236
static void positionEffect(EFFECT *psEffect)
238
237
{
260
259
 
261
260
static void killEffect(EFFECT *e)
262
261
{
 
262
        if (e->group == EFFECT_FIRE)
 
263
        {
 
264
                const int posX = map_coord(e->position.x);
 
265
                const int posY = map_coord(e->position.z);
 
266
                MAPTILE *psTile = mapTile(posX, posY);
 
267
 
 
268
                ASSERT(psTile, "Fire effect on non-existing tile (%d, %d)", posX, posY);
 
269
                if (psTile)
 
270
                {
 
271
                        psTile->tileInfoBits &= ~BITS_ON_FIRE;  // clear fire bit
 
272
                }
 
273
        }
263
274
        effectStatus[e-asEffectsList] = ES_INACTIVE;
264
275
        e->control = (UBYTE) 0;
265
276
}
266
277
 
267
 
// ----------------------------------------------------------------------------------------
268
278
static BOOL     essentialEffect(EFFECT_GROUP group, EFFECT_TYPE type)
269
279
{
270
280
        switch(group)
281
291
                {
282
292
                        return(true);
283
293
                }
284
 
                else
285
 
                {
286
 
                        return(false);
287
 
                }
288
294
        default:
289
295
                return(false);
290
 
                break;
291
296
        }
292
297
}
293
298
 
301
306
                return(true);
302
307
        default:
303
308
                return(false);
304
 
                break;
305
309
        }
306
310
}
307
311
 
308
 
// ----------------------------------------------------------------------------------------
309
 
/*      Simply sets the free pointer to the start - actually this isn't necessary
 
312
/**     Simply sets the free pointer to the start - actually this isn't necessary
310
313
        as it will work just fine anyway. This WOULD be necessary were we to change
311
314
        the system so that it seeks FREE slots rather than the oldest one. This is because
312
315
        different effects last for different times and the oldest effect may have
314
317
*/
315
318
void    initEffectsSystem( void )
316
319
{
317
 
UDWORD  i;
318
 
EFFECT  *psEffect;
319
 
 
 
320
        UDWORD  i;
 
321
        EFFECT  *psEffect;
320
322
 
321
323
        /* Set position to first */
322
324
        freeEffect = 0;
334
336
        {
335
337
                /* Get a pointer - just cos our macro requires it, speeds not an issue here */
336
338
                psEffect = &asEffectsList[i];
337
 
                /* Clear all the control bits */
338
 
                psEffect->control = (UBYTE)0;
 
339
                // clear the fire bit
 
340
                killEffect(psEffect);
 
341
                // Clear out the whole array
 
342
                memset(psEffect, 0x0, sizeof(EFFECT));
339
343
                /* All effects are initially inactive */
340
344
                effectStatus[i] = ES_INACTIVE;
341
345
        }
342
346
}
343
347
 
344
 
// ----------------------------------------------------------------------------------------
345
348
void    effectSetLandLightSpec(LAND_LIGHT_SPEC spec)
346
349
{
347
350
        ellSpec = spec;
348
351
}
349
 
// ----------------------------------------------------------------------------------------
 
352
 
350
353
void    effectSetSize(UDWORD size)
351
354
{
352
355
        specifiedSize = size;
353
356
}
354
 
// ----------------------------------------------------------------------------------------
 
357
 
355
358
void    addMultiEffect(Vector3i *basePos, Vector3i *scatter, EFFECT_GROUP group,
356
359
                                           EFFECT_TYPE type,BOOL specified, iIMDShape *imd, UDWORD number, BOOL lit, UDWORD size)
357
360
{
358
 
UDWORD  i;
359
 
Vector3i scatPos;
360
 
 
 
361
        UDWORD  i;
 
362
        Vector3i scatPos;
361
363
 
362
364
        if(number==0)
363
365
        {
392
394
        }
393
395
}
394
396
 
395
 
// ----------------------------------------------------------------------------------------
396
397
UDWORD  getNumActiveEffects( void )
397
398
{
398
399
        return(activeEffects);
399
400
}
400
 
// ----------------------------------------------------------------------------------------
 
401
 
401
402
UDWORD  getMissCount( void )
402
403
{
403
404
        return(missCount);
412
413
{
413
414
        return(letThrough);
414
415
}
415
 
// ----------------------------------------------------------------------------------------
416
 
 
417
 
UDWORD Reject1;
418
 
 
419
 
void    addEffect(Vector3i *pos, EFFECT_GROUP group, EFFECT_TYPE type,BOOL specified, iIMDShape *imd, BOOL lit)
 
416
 
 
417
 
 
418
void    addEffect(Vector3i *pos, EFFECT_GROUP group, EFFECT_TYPE type,BOOL specified, iIMDShape *imd, int lit)
420
419
{
 
420
        static unsigned int aeCalls = 0;
421
421
        UDWORD  essentialCount;
422
422
        UDWORD  i;
423
 
        BOOL    bSmoke;
 
423
        EFFECT  *psEffect = NULL;
424
424
 
425
425
        aeCalls++;
426
426
 
435
435
                /*      If effect is essentail - then let it through */
436
436
                if(!essentialEffect(group,type) )
437
437
                {
 
438
                        bool bSmoke = false;
 
439
 
438
440
                        /* Some we can get rid of right away */
439
441
                        if ( utterlyReject( group ) )
440
442
                        {
446
448
                        {
447
449
                                bSmoke = true;
448
450
                        }
449
 
                        else
450
 
                        {
451
 
                                bSmoke = false;
452
 
                        }
 
451
 
453
452
                        /* Others intermittently (50/50 for most and 25/100 for smoke */
454
453
                        if(bSmoke ? (aeCalls & 0x03) : (aeCalls & 0x01) )
455
454
                        {
462
461
        }
463
462
 
464
463
 
465
 
        for(i=freeEffect,essentialCount=0; (asEffectsList[i].control & EFFECT_ESSENTIAL)
466
 
                && essentialCount<MAX_EFFECTS; i++)
 
464
        for (i = freeEffect, essentialCount = 0; (asEffectsList[i].control & EFFECT_ESSENTIAL)
 
465
                && essentialCount < MAX_EFFECTS; i++)
467
466
        {
468
467
                /* Check for wrap around */
469
 
                if(i>= (MAX_EFFECTS-1))
 
468
                if (i >= (MAX_EFFECTS-1))
470
469
                {
471
470
                        /* Go back to the first one */
472
471
                        i = 0;
476
475
        }
477
476
 
478
477
        /* Check the list isn't just full of essential effects */
479
 
        if(essentialCount>=MAX_EFFECTS)
 
478
        if (essentialCount >= MAX_EFFECTS)
480
479
        {
481
480
                /* All of the effects are essential!?!? */
482
481
                return;
483
482
        }
484
 
        else
485
 
        {
486
 
                freeEffect = i;
487
 
        }
 
483
 
 
484
        freeEffect = i;
 
485
 
 
486
        psEffect = &asEffectsList[freeEffect];
488
487
 
489
488
        /* Store away it's position - into FRACTS */
490
 
        asEffectsList[freeEffect].position.x = pos->x;
491
 
        asEffectsList[freeEffect].position.y = pos->y;
492
 
        asEffectsList[freeEffect].position.z = pos->z;
493
 
 
 
489
        psEffect->position.x = pos->x;
 
490
        psEffect->position.y = pos->y;
 
491
        psEffect->position.z = pos->z;
494
492
 
495
493
        /* Now, note group and type */
496
 
        asEffectsList[freeEffect].group = group;
497
 
        asEffectsList[freeEffect].type = type;
 
494
        psEffect->group = group;
 
495
        psEffect->type = type;
498
496
 
499
497
        /* Set when it entered the world */
500
 
        asEffectsList[freeEffect].birthTime = asEffectsList[freeEffect].lastFrame = gameTime;
 
498
        psEffect->birthTime = psEffect->lastFrame = gameTime;
501
499
 
502
500
        if(group == EFFECT_GRAVITON && (type == GRAVITON_TYPE_GIBLET || type == GRAVITON_TYPE_EMITTING_DR))
503
501
        {
504
 
                asEffectsList[freeEffect].frameNumber = lit;
 
502
                psEffect->frameNumber = lit;
505
503
        }
506
504
 
507
505
        else
508
506
        {
509
507
                /* Starts off on frame zero */
510
 
                asEffectsList[freeEffect].frameNumber = 0;
 
508
                psEffect->frameNumber = 0;
511
509
        }
512
510
 
513
511
        /*
514
512
                See what kind of effect it is - the add fucnction is different for each,
515
513
                although some things are shared
516
514
        */
517
 
        asEffectsList[freeEffect].imd = NULL;
 
515
        psEffect->imd = NULL;
518
516
        if(lit)
519
517
        {
520
 
                SET_LITABS(asEffectsList[freeEffect]);
 
518
                SET_LIT(psEffect);
521
519
        }
522
520
 
523
521
        if(specified)
524
522
        {
525
523
                /* We're specifying what the imd is - override */
526
 
                asEffectsList[freeEffect].imd = imd;
527
 
//              if(type == EXPLOSION_TYPE_SPECIFIED_FIXME)
528
 
//              {
529
 
//                      asEffectsList[freeEffect].size = EXPLOSION_SIZE;
530
 
//              }
531
 
//              else
532
 
//              {
533
 
                asEffectsList[freeEffect].size =(UWORD) specifiedSize;
534
 
//              }
 
524
                psEffect->imd = imd;
 
525
                psEffect->size = specifiedSize;
535
526
        }
536
527
 
537
528
        /* Do all the effect type specific stuff */
538
529
        switch(group)
539
530
        {
540
531
                case EFFECT_SMOKE:
541
 
                        effectSetupSmoke(&asEffectsList[freeEffect]);
 
532
                        effectSetupSmoke(psEffect);
542
533
                        break;
543
534
                case EFFECT_GRAVITON:
544
 
                        effectSetupGraviton(&asEffectsList[freeEffect]);
 
535
                        effectSetupGraviton(psEffect);
545
536
                        break;
546
537
                case EFFECT_EXPLOSION:
547
 
                        effectSetupExplosion(&asEffectsList[freeEffect]);
 
538
                        effectSetupExplosion(psEffect);
548
539
                        break;
549
540
                case EFFECT_CONSTRUCTION:
550
 
                        effectSetupConstruction(&asEffectsList[freeEffect]);
 
541
                        effectSetupConstruction(psEffect);
551
542
                        break;
552
543
                case EFFECT_WAYPOINT:
553
 
                        effectSetupWayPoint(&asEffectsList[freeEffect]);
 
544
                        effectSetupWayPoint(psEffect);
554
545
                        break;
555
546
                case EFFECT_BLOOD:
556
 
                        effectSetupBlood(&asEffectsList[freeEffect]);
 
547
                        effectSetupBlood(psEffect);
557
548
                        break;
558
549
                case EFFECT_DESTRUCTION:
559
 
                        effectSetupDestruction(&asEffectsList[freeEffect]);
 
550
                        effectSetupDestruction(psEffect);
560
551
                        break;
561
552
                case EFFECT_FIRE:
562
 
                        effectSetupFire(&asEffectsList[freeEffect]);
 
553
                        effectSetupFire(psEffect);
563
554
                        break;
564
555
                case EFFECT_SAT_LASER:
565
 
                        effectSetUpSatLaser(&asEffectsList[freeEffect]);
 
556
                        effectSetUpSatLaser(psEffect);
566
557
                        break;
567
558
                case EFFECT_FIREWORK:
568
 
                        effectSetUpFirework(&asEffectsList[freeEffect]);
 
559
                        effectSetUpFirework(psEffect);
569
560
                        break;
570
 
                default:
 
561
                case EFFECT_STRUCTURE:
 
562
                case EFFECT_DUST_BALL:
571
563
                        ASSERT( false,"Weirdy group type for an effect" );
572
564
                        break;
573
565
        }
578
570
        /* As of yet, it hasn't bounced (or whatever)... */
579
571
        if(type!=EXPLOSION_TYPE_LAND_LIGHT)
580
572
        {
581
 
                asEffectsList[freeEffect].specific = 0;
582
 
        }
583
 
 
584
 
        /* Looks like we didn't establish an imd for the effect */
585
 
        /*
586
 
        ASSERT( asEffectsList[freeEffect].imd != NULL || group == EFFECT_DESTRUCTION || group == EFFECT_FIRE || group == EFFECT_SAT_LASER,
587
 
                "null effect imd" );
588
 
        */
589
 
 
590
 
#ifdef DEBUG
591
 
        if ( validatePie( group, asEffectsList[freeEffect].imd ) == false )
592
 
        {
593
 
                ASSERT( false,"No PIE found or specified for an effect" );
594
 
        }
595
 
#endif
 
573
                psEffect->specific = 0;
 
574
        }
 
575
 
 
576
        ASSERT(psEffect->imd != NULL || group == EFFECT_DESTRUCTION || group == EFFECT_FIRE || group == EFFECT_SAT_LASER, "null effect imd");
596
577
 
597
578
        /* No more slots available? */
598
579
        if(freeEffect++ >= (MAX_EFFECTS-1))
602
583
        }
603
584
}
604
585
 
605
 
#ifdef DEBUG
606
 
// ----------------------------------------------------------------------------------------
607
 
static BOOL validatePie( EFFECT_GROUP group, iIMDShape *pie )
608
 
{
609
 
 
610
 
        /* If we haven't got a pie */
611
 
        if(pie == NULL)
612
 
        {
613
 
                if(group == EFFECT_DESTRUCTION || group == EFFECT_FIRE || group == EFFECT_SAT_LASER)
614
 
                {
615
 
                        /* Ok in these cases */
616
 
                        return(true);
617
 
                }
618
 
 
619
 
                return(false);
620
 
        }
621
 
        else
622
 
        {
623
 
                return(true);
624
 
        }
625
 
}
626
 
// ----------------------------------------------------------------------------------------
627
 
#endif
628
 
 
629
586
/* Calls all the update functions for each different currently active effect */
630
587
void    processEffects(void)
631
588
{
652
609
                                /* Add it to the bucket */
653
610
                                bucketAddTypeToList(RENDER_EFFECT,&asEffectsList[i]);
654
611
                        }
655
 
 
656
612
                }
657
613
        }
658
614
 
666
622
        skippedEffects = skipped;
667
623
}
668
624
 
669
 
// ----------------------------------------------------------------------------------------
670
625
/* The general update function for all effects - calls a specific one for each */
671
626
static void updateEffect(EFFECT *psEffect)
672
627
{
675
630
        {
676
631
        case EFFECT_EXPLOSION:
677
632
                updateExplosion(psEffect);
678
 
                break;
 
633
                return;
679
634
 
680
635
        case EFFECT_WAYPOINT:
681
636
                if(!gamePaused()) updateWaypoint(psEffect);
682
 
                break;
 
637
                return;
683
638
 
684
639
        case EFFECT_CONSTRUCTION:
685
640
                if(!gamePaused()) updateConstruction(psEffect);
686
 
                break;
 
641
                return;
687
642
 
688
643
        case EFFECT_SMOKE:
689
644
                if(!gamePaused()) updatePolySmoke(psEffect);
690
 
                break;
 
645
                return;
691
646
 
692
647
        case EFFECT_STRUCTURE:
693
 
                break;
 
648
                return;
694
649
 
695
650
        case EFFECT_GRAVITON:
696
651
                if(!gamePaused()) updateGraviton(psEffect);
697
 
                break;
 
652
                return;
698
653
 
699
654
        case EFFECT_BLOOD:
700
655
                if(!gamePaused()) updateBlood(psEffect);
701
 
                break;
 
656
                return;
702
657
 
703
658
        case EFFECT_DESTRUCTION:
704
659
                if(!gamePaused()) updateDestruction(psEffect);
705
 
                break;
 
660
                return;
706
661
 
707
662
        case EFFECT_FIRE:
708
663
                if(!gamePaused()) updateFire(psEffect);
709
 
                break;
 
664
                return;
710
665
 
711
666
        case EFFECT_SAT_LASER:
712
667
                if(!gamePaused()) updateSatLaser(psEffect);
713
 
                break;
 
668
                return;
 
669
 
714
670
        case EFFECT_FIREWORK:
715
671
                if(!gamePaused()) updateFirework(psEffect);
716
 
                break;
717
 
        default:
718
 
                debug( LOG_ERROR, "Weirdy class of effect passed to updateEffect" );
719
 
                abort();
720
 
                break;
 
672
                return;
721
673
        }
 
674
 
 
675
        debug( LOG_ERROR, "Weirdy class of effect passed to updateEffect" );
722
676
}
723
677
 
724
678
// ----------------------------------------------------------------------------------------
725
679
// ALL THE UPDATE FUNCTIONS
726
680
// ----------------------------------------------------------------------------------------
727
 
/* Update the waypoint effects.*/
 
681
/** Update the waypoint effects.*/
728
682
static void updateWaypoint(EFFECT *psEffect)
729
683
{
730
684
        if(!(keyDown(KEY_LCTRL) || keyDown(KEY_RCTRL) ||
734
688
        }
735
689
}
736
690
 
737
 
 
738
 
// ----------------------------------------------------------------------------------------
739
691
static void updateFirework(EFFECT *psEffect)
740
692
{
741
693
        UDWORD  height;
822
774
                        psEffect->lastFrame = gameTime;
823
775
 
824
776
                        /* Are we on the last frame? */
825
 
                        if(++psEffect->frameNumber >= EffectGetNumFrames(psEffect))
 
777
                        if(++psEffect->frameNumber >= effectGetNumFrames(psEffect))
826
778
                        {
827
779
                                /* Does the anim wrap around? */
828
780
                                if(TEST_CYCLIC(psEffect))
851
803
        }
852
804
}
853
805
 
854
 
// ----------------------------------------------------------------------------------------
855
806
static void updateSatLaser(EFFECT *psEffect)
856
807
{
857
808
        Vector3i dv;
945
896
        }
946
897
}
947
898
 
948
 
// ----------------------------------------------------------------------------------------
949
 
/* The update function for the explosions */
 
899
/** The update function for the explosions */
950
900
static void updateExplosion(EFFECT *psEffect)
951
901
{
952
902
        LIGHT light;
1002
952
        {
1003
953
                psEffect->size += timeAdjustedIncrement(SHOCKWAVE_SPEED, true);
1004
954
                scaling = (float)psEffect->size / (float)MAX_SHOCKWAVE_SIZE;
1005
 
                psEffect->frameNumber = scaling * EffectGetNumFrames(psEffect);
 
955
                psEffect->frameNumber = scaling * effectGetNumFrames(psEffect);
1006
956
 
1007
957
                light.position.x = psEffect->position.x;
1008
958
                light.position.y = psEffect->position.y;
1027
977
                        psEffect->lastFrame = gameTime;
1028
978
                        /* Are we on the last frame? */
1029
979
 
1030
 
                        if(++psEffect->frameNumber >= EffectGetNumFrames(psEffect))
 
980
                        if(++psEffect->frameNumber >= effectGetNumFrames(psEffect))
1031
981
                        {
1032
982
                                if(psEffect->type!=EXPLOSION_TYPE_LAND_LIGHT)
1033
983
                                {
1054
1004
        }
1055
1005
}
1056
1006
 
1057
 
// ----------------------------------------------------------------------------------------
1058
 
/* The update function for blood */
 
1007
 
 
1008
 
 
1009
/** The update function for blood */
1059
1010
static void updateBlood(EFFECT *psEffect)
1060
1011
{
1061
1012
        /* Time to update the frame number on the blood */
1063
1014
        {
1064
1015
                psEffect->lastFrame = gameTime;
1065
1016
                /* Are we on the last frame? */
1066
 
                if(++psEffect->frameNumber >= EffectGetNumFrames(psEffect))
 
1017
                if(++psEffect->frameNumber >= effectGetNumFrames(psEffect))
1067
1018
                {
1068
1019
                        /* Kill it off */
1069
1020
                        killEffect(psEffect);
1076
1027
        psEffect->position.z += timeAdjustedIncrement(psEffect->velocity.z, true);
1077
1028
}
1078
1029
 
1079
 
// ----------------------------------------------------------------------------------------
1080
 
/* Processes all the drifting smoke
 
1030
/** Processes all the drifting smoke
1081
1031
        Handles the smoke puffing out the factory as well */
1082
1032
static void updatePolySmoke(EFFECT *psEffect)
1083
1033
{
1089
1039
                psEffect->lastFrame = gameTime;
1090
1040
 
1091
1041
                /* Are we on the last frame? */
1092
 
                if(++psEffect->frameNumber >= EffectGetNumFrames(psEffect))
 
1042
                if(++psEffect->frameNumber >= effectGetNumFrames(psEffect))
1093
1043
                {
1094
1044
                        /* Does the anim wrap around? */
1095
1045
                        if(TEST_CYCLIC(psEffect))
1131
1081
        }
1132
1082
}
1133
1083
 
1134
 
// ----------------------------------------------------------------------------------------
1135
 
/*
 
1084
/**
1136
1085
        Gravitons just fly up for a bit and then drop down and are
1137
1086
        killed off when they hit the ground
1138
1087
*/
1281
1230
}
1282
1231
 
1283
1232
 
1284
 
// ----------------------------------------------------------------------------------------
1285
 
/* updateDestruction
1286
 
This isn't really an on-screen effect itself - it just spawns other ones....
1287
 
  */
 
1233
/** This isn't really an on-screen effect itself - it just spawns other ones.... */
1288
1234
static void updateDestruction(EFFECT *psEffect)
1289
1235
{
1290
1236
        Vector3i pos;
1461
1407
        }
1462
1408
}
1463
1409
 
1464
 
// ----------------------------------------------------------------------------------------
1465
 
/*
1466
 
updateConstruction:-
1467
 
Moves the construction graphic about - dust cloud or whatever....
1468
 
*/
 
1410
/** Moves the construction graphic about - dust cloud or whatever.... */
1469
1411
static void updateConstruction(EFFECT *psEffect)
1470
1412
{
1471
1413
 
1474
1416
        {
1475
1417
                psEffect->lastFrame = gameTime;
1476
1418
                /* Are we on the last frame? */
1477
 
                if(++psEffect->frameNumber >= EffectGetNumFrames(psEffect))
 
1419
                if(++psEffect->frameNumber >= effectGetNumFrames(psEffect))
1478
1420
                {
1479
1421
                        /* Is it a cyclic sprite? */
1480
1422
                        if(TEST_CYCLIC(psEffect))
1515
1457
        }
1516
1458
}
1517
1459
 
1518
 
// ----------------------------------------------------------------------------------------
1519
 
/* Update fire sequences */
 
1460
/** Update fire sequences */
1520
1461
static void updateFire(EFFECT *psEffect)
1521
1462
{
1522
1463
        Vector3i pos;
1542
1483
                psEffect->lastFrame = gameTime;
1543
1484
                pos.x = (psEffect->position.x + ((rand() % psEffect->radius) - (rand() % (2 * psEffect->radius))));
1544
1485
                pos.z = (psEffect->position.z + ((rand() % psEffect->radius) - (rand() % (2 * psEffect->radius))));
1545
 
                
 
1486
 
1546
1487
                // Effect is off map, no need to update it anymore
1547
1488
                if(!worldOnMap(pos.x, pos.z))
1548
1489
                {
1549
1490
                        killEffect(psEffect);
1550
1491
                        return;
1551
1492
                }
1552
 
                
 
1493
 
1553
1494
                pos.y = map_Height(pos.x,pos.z);
1554
1495
 
1555
1496
                if(psEffect->type == FIRE_TYPE_SMOKY_BLUE)
1605
1546
// ----------------------------------------------------------------------------------------
1606
1547
// ALL THE RENDER FUNCTIONS
1607
1548
// ----------------------------------------------------------------------------------------
1608
 
/*
1609
 
renderEffect:-
1610
 
Calls the appropriate render routine for each type of effect
1611
 
*/
 
1549
/** Calls the appropriate render routine for each type of effect */
1612
1550
void    renderEffect(EFFECT *psEffect)
1613
1551
{
1614
1552
                /* What type of effect are we dealing with? */
1616
1554
        {
1617
1555
        case EFFECT_WAYPOINT:
1618
1556
                renderWaypointEffect(psEffect);
1619
 
                break;
 
1557
                return;
1620
1558
 
1621
1559
        case EFFECT_EXPLOSION:
1622
1560
                renderExplosionEffect(psEffect);
1623
 
                break;
 
1561
                return;
1624
1562
 
1625
1563
        case EFFECT_CONSTRUCTION:
1626
1564
                renderConstructionEffect(psEffect);
1627
 
                break;
 
1565
                return;
1628
1566
 
1629
1567
        case EFFECT_SMOKE:
1630
1568
                renderSmokeEffect(psEffect);
1631
 
                break;
 
1569
                return;
1632
1570
 
1633
1571
        case EFFECT_GRAVITON:
1634
1572
                renderGravitonEffect(psEffect);
1635
 
                break;
 
1573
                return;
1636
1574
 
1637
1575
        case EFFECT_BLOOD:
1638
1576
                renderBloodEffect(psEffect);
1639
 
                break;
 
1577
                return;
1640
1578
 
1641
1579
        case EFFECT_STRUCTURE:
1642
 
                break;
 
1580
                return;
1643
1581
 
1644
1582
        case EFFECT_DESTRUCTION:
1645
1583
                /*      There is no display func for a destruction effect -
1646
1584
                        it merely spawn other effects over time */
1647
1585
                renderDestructionEffect(psEffect);
1648
 
                break;
 
1586
                return;
 
1587
 
1649
1588
        case EFFECT_FIRE:
1650
1589
                /* Likewise */
1651
 
                break;
 
1590
                return;
 
1591
 
1652
1592
        case EFFECT_SAT_LASER:
1653
1593
                /* Likewise */
1654
 
                break;
 
1594
                return;
 
1595
 
1655
1596
        case EFFECT_FIREWORK:
1656
1597
                renderFirework(psEffect);
1657
 
                break;
1658
 
        default:
1659
 
                debug( LOG_ERROR, "Weirdy class of effect passed to renderEffect" );
1660
 
                abort();
1661
 
                break;
 
1598
                return;
1662
1599
        }
 
1600
 
 
1601
        debug( LOG_ERROR, "Weirdy class of effect passed to renderEffect" );
1663
1602
}
1664
1603
 
1665
 
// ----------------------------------------------------------------------------------------
1666
 
/* drawing func for wapypoints . AJL. */
1667
 
void    renderWaypointEffect(EFFECT *psEffect)
 
1604
/** drawing func for wapypoints */
 
1605
static void renderWaypointEffect(EFFECT *psEffect)
1668
1606
{
1669
1607
        positionEffect(psEffect);
1670
1608
 
1672
1610
        iV_MatrixEnd();
1673
1611
}
1674
1612
 
1675
 
// ----------------------------------------------------------------------------------------
1676
 
void    renderFirework(EFFECT *psEffect)
 
1613
static void renderFirework(EFFECT *psEffect)
1677
1614
{
1678
1615
        /* these don't get rendered */
1679
1616
        if(psEffect->type == FIREWORK_TYPE_LAUNCHER)
1691
1628
        iV_MatrixEnd();
1692
1629
}
1693
1630
 
1694
 
// ----------------------------------------------------------------------------------------
1695
 
/* drawing func for blood. */
1696
 
void    renderBloodEffect(EFFECT *psEffect)
 
1631
/** drawing func for blood. */
 
1632
static void renderBloodEffect(EFFECT *psEffect)
1697
1633
{
1698
1634
        positionEffect(psEffect);
1699
1635
 
1705
1641
        iV_MatrixEnd();
1706
1642
}
1707
1643
 
1708
 
// ----------------------------------------------------------------------------------------
1709
 
void    renderDestructionEffect(EFFECT *psEffect)
 
1644
static void renderDestructionEffect(EFFECT *psEffect)
1710
1645
{
1711
1646
        float   div;
1712
1647
        SDWORD  percent;
1736
1671
        iV_MatrixEnd();
1737
1672
}
1738
1673
 
1739
 
// ----------------------------------------------------------------------------------------
1740
 
static BOOL     rejectLandLight(LAND_LIGHT_SPEC type)
 
1674
static bool rejectLandLight(LAND_LIGHT_SPEC type)
1741
1675
{
1742
 
UDWORD  timeSlice;
 
1676
        unsigned int timeSlice = gameTime%2000;
1743
1677
 
1744
 
        timeSlice = gameTime%2000;
1745
 
        if(timeSlice<400)
1746
 
        {
1747
 
                if(type == LL_MIDDLE) return(false); else return(true); // reject all expect middle
1748
 
        }
1749
 
        else if(timeSlice<800)
1750
 
        {
1751
 
                if(type == LL_OUTER) return(true); else return(false);  // reject only outer
1752
 
        }
1753
 
        else if(timeSlice<1200)
1754
 
        {
1755
 
                return(false);  //reject none
1756
 
        }
1757
 
        else if(timeSlice<1600)
1758
 
        {
1759
 
                if(type == LL_OUTER) return(true); else return(false);  // reject only outer
 
1678
        if (timeSlice < 400)
 
1679
        {
 
1680
                return (type != LL_MIDDLE); // reject all expect middle
 
1681
        }
 
1682
        else if (timeSlice < 800)
 
1683
        {
 
1684
                return (type == LL_OUTER); // reject only outer
 
1685
        }
 
1686
        else if (timeSlice < 1200)
 
1687
        {
 
1688
                return(false); //reject none
 
1689
        }
 
1690
        else if (timeSlice < 1600)
 
1691
        {
 
1692
                return (type == LL_OUTER); // reject only outer
1760
1693
        }
1761
1694
        else
1762
1695
        {
1763
 
                if(type == LL_MIDDLE) return(false); else return(true); // reject all expect middle
 
1696
                return (type != LL_MIDDLE); // reject all expect middle
1764
1697
        }
1765
1698
}
1766
1699
 
1767
 
// ----------------------------------------------------------------------------------------
1768
 
/* Renders the standard explosion effect */
1769
 
void    renderExplosionEffect(EFFECT *psEffect)
 
1700
/** Renders the standard explosion effect */
 
1701
static void renderExplosionEffect(EFFECT *psEffect)
1770
1702
{
1771
1703
        SDWORD  percent;
1772
1704
        const PIELIGHT brightness = WZCOL_WHITE;
1823
1755
        iV_MatrixEnd();
1824
1756
}
1825
1757
 
1826
 
// ----------------------------------------------------------------------------------------
1827
 
void    renderGravitonEffect(EFFECT *psEffect)
 
1758
static void renderGravitonEffect(EFFECT *psEffect)
1828
1759
{
1829
1760
 
1830
1761
        positionEffect(psEffect);
1850
1781
        iV_MatrixEnd();
1851
1782
}
1852
1783
 
1853
 
// ----------------------------------------------------------------------------------------
1854
 
/*
1855
 
renderConstructionEffect:-
1856
 
Renders the standard construction effect */
1857
 
void    renderConstructionEffect(EFFECT *psEffect)
 
1784
/** Renders the standard construction effect */
 
1785
static void renderConstructionEffect(EFFECT *psEffect)
1858
1786
{
1859
1787
        Vector3i null;
1860
1788
        SDWORD  percent;
1898
1826
        iV_MatrixEnd();
1899
1827
}
1900
1828
 
1901
 
// ----------------------------------------------------------------------------------------
1902
 
/*
1903
 
renderSmokeEffect:-
1904
 
Renders the standard smoke effect - it is now scaled in real-time as well
1905
 
*/
1906
 
void    renderSmokeEffect(EFFECT *psEffect)
 
1829
/** Renders the standard smoke effect - it is now scaled in real-time as well */
 
1830
static void renderSmokeEffect(EFFECT *psEffect)
1907
1831
{
1908
1832
        UDWORD  transparency = 0;
1909
1833
        const PIELIGHT brightness = WZCOL_WHITE;
2026
1950
 
2027
1951
}
2028
1952
 
2029
 
// ----------------------------------------------------------------------------------------
2030
1953
void    effectSetupSmoke(EFFECT *psEffect)
2031
1954
{
2032
1955
        /* everything except steam drifts about */
2111
2034
        }
2112
2035
}
2113
2036
 
2114
 
// ----------------------------------------------------------------------------------------
2115
2037
void effectSetUpSatLaser(EFFECT *psEffect)
2116
2038
{
2117
2039
        /* Does nothing at all..... Runs only for one frame! */
2119
2041
        return;
2120
2042
}
2121
2043
 
2122
 
// ----------------------------------------------------------------------------------------
2123
2044
void    effectSetupGraviton(EFFECT *psEffect)
2124
2045
{
2125
2046
        switch(psEffect->type)
2167
2088
        }
2168
2089
}
2169
2090
 
2170
 
// ----------------------------------------------------------------------------------------
2171
2091
void effectSetupExplosion(EFFECT *psEffect)
2172
2092
{
2173
2093
        /* Get an imd if it's not established */
2295
2215
        }
2296
2216
}
2297
2217
 
2298
 
// ----------------------------------------------------------------------------------------
2299
2218
void    effectSetupConstruction(EFFECT *psEffect)
2300
2219
{
2301
2220
        psEffect->velocity.x = 0.f;//(1-rand()%3);
2322
2241
        }
2323
2242
}
2324
2243
 
2325
 
// ----------------------------------------------------------------------------------------
2326
2244
void    effectSetupFire(EFFECT *psEffect)
2327
2245
{
 
2246
        const int posX = map_coord(psEffect->position.x);
 
2247
        const int posY = map_coord(psEffect->position.z);
 
2248
        MAPTILE *psTile = mapTile(posX, posY);
 
2249
 
 
2250
        ASSERT(psTile, "Cannot place a fire effect %d, %d - outside map!", posX, posY);
 
2251
        if (psTile)
 
2252
        {
 
2253
                psTile->tileInfoBits |= BITS_ON_FIRE;
 
2254
        }
2328
2255
        psEffect->frameDelay = 300;        // needs to be investigated...
2329
2256
        psEffect->radius = auxVar;      // needs to be investigated
2330
2257
        psEffect->lifeSpan = (UWORD)auxVarSec;
2333
2260
 
2334
2261
}
2335
2262
 
2336
 
// ----------------------------------------------------------------------------------------
2337
2263
void    effectSetupWayPoint(EFFECT *psEffect)
2338
2264
{
2339
2265
        psEffect->imd = pProximityMsgIMD;
2342
2268
        SET_ESSENTIAL(psEffect);
2343
2269
}
2344
2270
 
2345
 
// ----------------------------------------------------------------------------------------
2346
 
void    effectSetupBlood(EFFECT *psEffect)
 
2271
 
 
2272
static void effectSetupBlood(EFFECT *psEffect)
2347
2273
{
2348
2274
        psEffect->frameDelay = BLOOD_FRAME_DELAY;
2349
2275
        psEffect->velocity.y = (float)BLOOD_FALL_SPEED;
2351
2277
        psEffect->size = (UBYTE)BLOOD_SIZE;
2352
2278
}
2353
2279
 
2354
 
// ----------------------------------------------------------------------------------------
2355
 
void    effectSetupDestruction(EFFECT *psEffect)
 
2280
static void effectSetupDestruction(EFFECT *psEffect)
2356
2281
{
2357
2282
 
2358
2283
        if(psEffect->type == DESTRUCTION_TYPE_SKYSCRAPER)
2387
2312
 
2388
2313
#define FX_PER_EDGE 6
2389
2314
#define SMOKE_SHIFT     (16 - (rand()%32))
2390
 
// ----------------------------------------------------------------------------------------
2391
2315
void    initPerimeterSmoke(iIMDShape *pImd, UDWORD x, UDWORD y, UDWORD z)
2392
2316
{
2393
2317
        SDWORD  i;
2475
2399
        }
2476
2400
}
2477
2401
 
2478
 
// ----------------------------------------------------------------------------------------
2479
 
UDWORD  getNumEffects( void )
2480
 
{
2481
 
        return(numEffects);
2482
 
}
2483
 
 
2484
 
 
2485
 
// ----------------------------------------------------------------------------------------
2486
 
UDWORD EffectGetNumFrames(EFFECT *psEffect)
2487
 
{
2488
 
 
 
2402
 
 
2403
static UDWORD effectGetNumFrames(EFFECT *psEffect)
 
2404
{
2489
2405
        return psEffect->imd->numFrames;
2490
 
 
2491
 
}
2492
 
 
2493
 
UDWORD IMDGetNumFrames(iIMDShape *Shape)
2494
 
{
2495
 
 
2496
 
        return Shape->numFrames;
2497
 
 
2498
 
}
2499
 
 
2500
 
UDWORD IMDGetAnimInterval(iIMDShape *Shape)
2501
 
{
2502
 
 
2503
 
        return Shape->animInterval;
2504
 
 
2505
 
}
 
2406
}
 
2407
 
2506
2408
 
2507
2409
void    effectGiveAuxVar( UDWORD var)
2508
2410
{
2509
2411
        auxVar = var;
2510
2412
}
2511
2413
 
 
2414
 
2512
2415
void    effectGiveAuxVarSec( UDWORD var)
2513
2416
{
2514
2417
        auxVarSec = var;
2515
2418
}
2516
2419
 
2517
 
// ----------------------------------------------------------------------------------------
2518
 
/* Runs all the spot effect stuff for the droids - adding of dust and the like... */
 
2420
/** Runs all the spot effect stuff for the droids - adding of dust and the like... */
2519
2421
static void effectDroidUpdates(void)
2520
2422
{
2521
2423
        unsigned int i;
2562
2464
        }
2563
2465
}
2564
2466
 
2565
 
// ----------------------------------------------------------------------------------------
2566
 
/* Runs all the structure effect stuff - steam puffing out etc */
 
2467
/** Runs all the structure effect stuff - steam puffing out etc */
2567
2468
static void effectStructureUpdates(void)
2568
2469
{
2569
2470
        UDWORD          i;
2685
2586
        }
2686
2587
}
2687
2588
 
2688
 
UDWORD  getFreeEffect( void )
2689
 
{
2690
 
        return(freeEffect);
2691
 
}
2692
 
 
2693
 
 
2694
 
// ----------------------------------------------------------------------------------------
 
2589
 
2695
2590
void    effectResetUpdates( void )
2696
2591
{
2697
 
UDWORD  i;
 
2592
        UDWORD  i;
2698
2593
 
2699
2594
        for(i=0; i<EFFECT_DROID_DIVISION; i++)
2700
2595
        {
2707
2602
}
2708
2603
 
2709
2604
 
2710
 
// -----------------------------------------------------------------------------------
2711
 
bool fireOnLocation(unsigned int x, unsigned int y)
2712
 
{
2713
 
        unsigned int i;
2714
 
 
2715
 
        for(i = 0; i < MAX_EFFECTS; ++i)
2716
 
        {
2717
 
                if (effectStatus[i] == ES_ACTIVE
2718
 
                 && asEffectsList[i].group == EFFECT_FIRE)
2719
 
                {
2720
 
                        const unsigned int posX = asEffectsList[i].position.x;
2721
 
                        const unsigned int posY = asEffectsList[i].position.z;
2722
 
 
2723
 
                        if (posX == x
2724
 
                         && posY == y)
2725
 
                        {
2726
 
                                return true;
2727
 
                        }
2728
 
                }
2729
 
        }
2730
 
 
2731
 
        return false;
2732
 
}
2733
 
 
2734
2605
static const char FXData_tag_definition[] = "tagdefinitions/savegame/effects.def";
2735
2606
static const char FXData_file_identifier[] = "FXData";
2736
2607
 
2737
 
// -----------------------------------------------------------------------------------
2738
 
/* This will save out the effects data */
 
2608
/** This will save out the effects data */
2739
2609
bool writeFXData(const char* fileName)
2740
2610
{
2741
2611
        unsigned int count, i;
2801
2671
        return true;
2802
2672
}
2803
2673
 
2804
 
// -----------------------------------------------------------------------------------
2805
 
/* This will read in the effects data */
 
2674
/** This will read in the effects data */
2806
2675
bool readFXData(const char* fileName)
2807
2676
{
2808
2677
        unsigned int count, i;