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

« back to all changes in this revision

Viewing changes to src/game.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
24
24
#include <string.h>
25
25
 
26
26
/* Warzone src and library headers */
 
27
#include "lib/framework/endian_hack.h"
 
28
#include "lib/framework/file.h"
 
29
#include "lib/framework/frameint.h"
 
30
#include "lib/framework/physfs_ext.h"
27
31
#include "lib/framework/strres.h"
28
 
#include "lib/framework/frameint.h"
29
32
#include "lib/framework/tagfile.h"
30
 
#include "lib/framework/file.h"
31
 
#include "lib/framework/physfs_ext.h"
32
33
 
33
34
#include "lib/gamelib/gtime.h"
34
35
#include "lib/ivis_common/ivisdef.h"
42
43
 
43
44
#include "game.h"
44
45
 
 
46
#include "fpath.h"
45
47
#include "map.h"
46
48
#include "droid.h"
47
49
#include "action.h"
314
316
typedef struct _save_weapon_v19
315
317
{
316
318
        char                            name[MAX_SAVE_NAME_SIZE_V19];
317
 
        UDWORD                          hitPoints;  //- remove at some point
 
319
        UDWORD                          hitPoints;  // UNUSED: only here to keep struct size intact
318
320
        UDWORD                          ammo;
319
321
        UDWORD                          lastFired;
320
322
} SAVE_WEAPON_V19;
322
324
typedef struct _save_weapon
323
325
{
324
326
        char                            name[MAX_SAVE_NAME_SIZE];
325
 
        UDWORD                          hitPoints;  //- remove at some point
 
327
        UDWORD                          hitPoints;  // UNUSED: only here to keep struct size intact
326
328
        UDWORD                          ammo;
327
329
        UDWORD                          lastFired;
328
330
} SAVE_WEAPON;
500
502
             && PHYSFS_write(fileHandle, serializeDesc->host, 1, 16) == 16
501
503
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwMaxPlayers)
502
504
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwCurrentPlayers)
503
 
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUser1)
504
 
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUser2)
505
 
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUser3)
506
 
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUser4));
 
505
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUserFlags[0])
 
506
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUserFlags[1])
 
507
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUserFlags[2])
 
508
             && PHYSFS_writeSBE32(fileHandle, serializeDesc->dwUserFlags[3]));
507
509
}
508
510
 
509
511
static bool deserializeSessionDesc(PHYSFS_file* fileHandle, SESSIONDESC* serializeDesc)
513
515
             && PHYSFS_read(fileHandle, serializeDesc->host, 1, 16) == 16
514
516
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwMaxPlayers)
515
517
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwCurrentPlayers)
516
 
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUser1)
517
 
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUser2)
518
 
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUser3)
519
 
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUser4));
 
518
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUserFlags[0])
 
519
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUserFlags[1])
 
520
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUserFlags[2])
 
521
             && PHYSFS_readSBE32(fileHandle, &serializeDesc->dwUserFlags[3]));
520
522
}
521
523
 
522
524
static bool serializeGameStruct(PHYSFS_file* fileHandle, const GAMESTRUCT* serializeGame)
1469
1471
#define SAVE_COMP_PROGRAM       8
1470
1472
#define SAVE_COMP_WEAPON        9
1471
1473
 
 
1474
typedef struct _path_point
 
1475
{
 
1476
       UBYTE           x,y;
 
1477
} PATH_POINT;
 
1478
 
 
1479
#define TRAVELSIZE      100
 
1480
 
1472
1481
typedef struct _save_move_control
1473
1482
{
1474
1483
        UBYTE   Status;                                         // Inactive, Navigating or moving point to point status
1583
1592
        DROID_SAVE_V18;
1584
1593
} SAVE_DROID_V18;
1585
1594
 
1586
 
 
1587
1595
//DROID_SAVE_20 replaces all previous saves uses 60 character names
1588
1596
#define DROID_SAVE_V20          \
1589
1597
        OBJECT_SAVE_V20;                        \
2140
2148
static BOOL loadSaveDroidInitV2(char *pFileData, UDWORD filesize,UDWORD quantity);
2141
2149
 
2142
2150
static BOOL loadSaveDroidInit(char *pFileData, UDWORD filesize);
2143
 
static DROID_TEMPLATE *FindDroidTemplate(char *name,UDWORD player);
 
2151
static DROID_TEMPLATE *FindDroidTemplate(const char * const name);
2144
2152
 
2145
2153
static BOOL loadSaveDroid(char *pFileData, UDWORD filesize, DROID **ppsCurrentDroidLists);
2146
2154
static BOOL loadSaveDroidV11(char *pFileData, UDWORD filesize, UDWORD numDroids, UDWORD version, DROID **ppsCurrentDroidLists);
2211
2219
 
2212
2220
//adjust the name depending on type of save game and whether resourceNames are used
2213
2221
static BOOL getSaveObjectName(char *pName);
 
2222
static bool gameLoad(const char* fileName);
2214
2223
 
2215
2224
/* set the global scroll values to use for the save game */
2216
2225
static void setMapScroll(void);
2236
2245
        if (!gameLoad(fileName))
2237
2246
        {
2238
2247
                debug(LOG_ERROR, "Corrupted savegame file %s, Unable to load!", fileName);
2239
 
 
2240
2248
                // NOTE: why do we start the game clock on a *failed* load?
2241
 
                // Start the game clock 
 
2249
                // Start the game clock
2242
2250
                gameTimeStart();
2243
2251
 
2244
2252
                return false;
2330
2338
                freeAllStructs();
2331
2339
                freeAllFeatures();
2332
2340
 
2333
 
        //      droidTemplateShutDown();
2334
 
                if (psMapTiles)
2335
 
                {
2336
 
//                      free(psMapTiles);
2337
 
                }
2338
2341
                //clear all the messages?
2339
2342
                releaseAllProxDisp();
2340
2343
        }
2341
2344
 
2342
 
 
2343
2345
        if (!keepObjects)
2344
2346
        {
2345
2347
                //initialise the lists
2379
2381
                memset(asReArmUpgrade, 0, MAX_PLAYERS * sizeof(REARM_UPGRADE));
2380
2382
 
2381
2383
                //initialise the upgrade structures
2382
 
                memset(asWeaponUpgrade, 0, MAX_PLAYERS * NUM_WEAPON_SUBCLASS * sizeof(WEAPON_UPGRADE));
 
2384
                memset(asWeaponUpgrade, 0, MAX_PLAYERS * WSC_NUM_WEAPON_SUBCLASSES * sizeof(WEAPON_UPGRADE));
2383
2385
                memset(asSensorUpgrade, 0, MAX_PLAYERS * sizeof(SENSOR_UPGRADE));
2384
2386
                memset(asECMUpgrade, 0, MAX_PLAYERS * sizeof(ECM_UPGRADE));
2385
2387
                memset(asRepairUpgrade, 0, MAX_PLAYERS * sizeof(REPAIR_UPGRADE));
2387
2389
                //JPS 25 feb
2388
2390
        }
2389
2391
 
2390
 
 
2391
2392
        if (saveGameVersion >= VERSION_11)
2392
2393
        {
2393
2394
                //camera position
2629
2630
        if (gameType != GTYPE_SCENARIO_EXPAND
2630
2631
         || UserSaveGame)
2631
2632
        {
2632
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2633
2633
                //load in the terrain type map
2634
2634
                aFileName[fileExten] = '\0';
2635
2635
                strcat(aFileName, "ttypes.ttp");
2654
2654
        }
2655
2655
 
2656
2656
        //load up the Droid Templates BEFORE any structures are loaded
2657
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
2658
2657
        if (IsScenario==false)
2659
2658
        {
2660
2659
                //NOT ANY MORE - use multiPlayerID (unique template id) to prevent duplicate's being loaded
2694
2693
                }
2695
2694
 
2696
2695
//load in the templates
2697
 
                LOADBARCALLBACK();      //      loadingScreenCallback();
2698
2696
                aFileName[fileExten] = '\0';
2699
2697
                strcat(aFileName, "templ.bjo");
2700
2698
                /* Load in the chosen file data */
2715
2713
 
2716
2714
        if (saveGameOnMission && UserSaveGame)
2717
2715
        {
2718
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2719
2716
 
2720
2717
                //the scroll limits for the mission map have already been written
2721
2718
                if (saveGameVersion >= VERSION_29)
2727
2724
                }
2728
2725
 
2729
2726
                //load the map and the droids then swap pointers
2730
 
//              psMapTiles = NULL;
2731
2727
                //load in the map file
2732
2728
                aFileName[fileExten] = '\0';
2733
2729
                strcat(aFileName, "mission.map");
2754
2750
                }
2755
2751
 
2756
2752
        // reload the objects that were in the mission list
2757
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2758
2753
                //load in the features -do before the structures
2759
2754
                aFileName[fileExten] = '\0';
2760
2755
                strcat(aFileName, "mfeat.bjo");
2792
2787
                        goto error;
2793
2788
                }
2794
2789
 
2795
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2796
2790
 
2797
2791
                if (bMultiPlayer)
2798
2792
                {
2803
2797
                        }
2804
2798
                }
2805
2799
 
2806
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2807
2800
                //load in the mission droids
2808
2801
                aFileName[fileExten] = '\0';
2809
2802
 
2846
2839
                        }
2847
2840
                }
2848
2841
 
2849
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2850
2842
                //load in the flag list file
2851
2843
                aFileName[fileExten] = '\0';
2852
2844
                strcat(aFileName, "mflagstate.bjo");
2884
2876
        //if Campaign Expand then don't load in another map
2885
2877
        if (gameType != GTYPE_SCENARIO_EXPAND)
2886
2878
        {
2887
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2888
2879
                psMapTiles = NULL;
2889
2880
                //load in the map file
2890
2881
                aFileName[fileExten] = '\0';
2906
2897
 
2907
2898
        //save game stuff added after map load
2908
2899
 
2909
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
2910
2900
        if (saveGameVersion >= VERSION_16)
2911
2901
        {
2912
2902
                for (inc = 0; inc < MAX_NOGO_AREAS; inc++)
2928
2918
        if ((gameType == GTYPE_SAVE_START) ||
2929
2919
                (gameType == GTYPE_SAVE_MIDMISSION))
2930
2920
        {
2931
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2932
2921
                //load in the research list file
2933
2922
                aFileName[fileExten] = '\0';
2934
2923
                strcat(aFileName, "resstate.bjo");
2953
2942
 
2954
2943
        if(IsScenario==true)
2955
2944
        {
2956
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2957
2945
                //load in the droid initialisation file
2958
2946
                aFileName[fileExten] = '\0';
2959
2947
                strcat(aFileName, "dinit.bjo");
2974
2962
        }
2975
2963
        else
2976
2964
        {
2977
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
2978
2965
                //load in the droids
2979
2966
                aFileName[fileExten] = '\0';
2980
2967
                if (saveGameVersion < VERSION_27)//V27
3019
3006
                        }
3020
3007
                }
3021
3008
 
3022
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3023
3009
                if (saveGameVersion >= 12)
3024
3010
                {
3025
3011
                        if (!saveGameOnMission)
3049
3035
                }
3050
3036
        }
3051
3037
 
3052
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3053
3038
        if (saveGameVersion >= VERSION_23)
3054
3039
        {
3055
3040
                //load in the limbo droids
3069
3054
 
3070
3055
        }
3071
3056
 
3072
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3073
3057
        //load in the features -do before the structures
3074
3058
        aFileName[fileExten] = '\0';
3075
3059
        strcat(aFileName, "feat.bjo");
3092
3076
        //load droid templates moved from here to BEFORE any structures loaded in
3093
3077
 
3094
3078
        //load in the structures
3095
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3096
3079
        initStructLimits();
3097
3080
        aFileName[fileExten] = '\0';
3098
3081
        strcat(aFileName, "struct.bjo");
3110
3093
                goto error;
3111
3094
        }
3112
3095
 
3113
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3114
3096
        if ((gameType == GTYPE_SAVE_START) ||
3115
3097
                (gameType == GTYPE_SAVE_MIDMISSION))
3116
3098
        {
3125
3107
        if ((gameType == GTYPE_SAVE_START) ||
3126
3108
                (gameType == GTYPE_SAVE_MIDMISSION))
3127
3109
        {
3128
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3129
3110
                //load in the component list file
3130
3111
                aFileName[fileExten] = '\0';
3131
3112
                strcat(aFileName, "compl.bjo");
3147
3128
                                goto error;
3148
3129
                        }
3149
3130
                }
3150
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3151
3131
                //load in the structure type list file
3152
3132
                aFileName[fileExten] = '\0';
3153
3133
                strcat(aFileName, "strtype.bjo");
3171
3151
                }
3172
3152
        }
3173
3153
 
3174
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3175
 
 
3176
3154
        if (saveGameVersion >= VERSION_11)
3177
3155
        {
3178
3156
                //if user save game then load up the Visibility
3192
3170
                }
3193
3171
        }
3194
3172
 
3195
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3196
 
 
3197
3173
        if (saveGameVersion > VERSION_12)
3198
3174
        {
3199
3175
                //if user save game then load up the Visibility
3220
3196
 
3221
3197
                }
3222
3198
        }
3223
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3224
3199
 
3225
3200
        if (saveGameVersion > VERSION_12)
3226
3201
        {
3241
3216
                }
3242
3217
        }
3243
3218
 
3244
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3245
 
 
3246
3219
        if (saveGameVersion >= VERSION_16)
3247
3220
        {
3248
3221
                //if user save game then load up the FX
3262
3235
                }
3263
3236
        }
3264
3237
 
3265
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3266
 
 
3267
3238
        if (saveGameVersion >= VERSION_12)
3268
3239
        {
3269
3240
                //if user save game then load up the flags AFTER any droids or structures are loaded
3294
3265
                }
3295
3266
        }
3296
3267
 
3297
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3298
 
 
3299
3268
        if (saveGameVersion >= VERSION_21)
3300
3269
        {
3301
3270
                //rebuild the apsCommandDesignation AFTER all droids and structures are loaded
3314
3283
                }
3315
3284
        }
3316
3285
 
3317
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3318
 
 
3319
3286
        if ((saveGameVersion >= VERSION_15) && UserSaveGame)
3320
3287
        {
3321
3288
                //load in the mission structures
3345
3312
                setCurrentStructQuantity(true);
3346
3313
        }
3347
3314
 
3348
 
 
3349
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3350
 
 
3351
3315
        //check that delivery points haven't been put down in invalid location
3352
3316
        checkDeliveryPoints(saveGameVersion);
3353
3317
 
3354
3318
        if ((gameType == GTYPE_SAVE_START) ||
3355
3319
                (gameType == GTYPE_SAVE_MIDMISSION))
3356
3320
        {
3357
 
                LOADBARCALLBACK();      //      loadingScreenCallback();
3358
3321
                for(pl=0;pl<MAX_PLAYERS;pl++)   // ajl. must do for every player to stop multiplay/pc players going gaga.
3359
3322
                {
3360
3323
                        //reverse the structure lists so the Research Facilities are in the same order as when saved
3361
3324
                        reverseTemplateList((DROID_TEMPLATE**)&apsDroidTemplates[pl]);
3362
3325
                }
3363
3326
 
3364
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3365
3327
                for(pl=0;pl<MAX_PLAYERS;pl++)
3366
3328
                {
3367
3329
                        //reverse the droid lists so selections occur in the same order
3368
3330
                        reverseObjectList((BASE_OBJECT**)&apsLimboDroids[pl]);
3369
3331
                }
3370
3332
 
3371
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3372
3333
                for(pl=0;pl<MAX_PLAYERS;pl++)
3373
3334
                {
3374
3335
                        //reverse the droid lists so selections occur in the same order
3375
3336
                        reverseObjectList((BASE_OBJECT**)&apsDroidLists[pl]);
3376
3337
                }
3377
3338
 
3378
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3379
3339
                for(pl=0;pl<MAX_PLAYERS;pl++)
3380
3340
                {
3381
3341
                        //reverse the droid lists so selections occur in the same order
3382
3342
                        reverseObjectList((BASE_OBJECT**)&mission.apsDroidLists[pl]);
3383
3343
                }
3384
3344
 
3385
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3386
3345
                for(pl=0;pl<MAX_PLAYERS;pl++)
3387
3346
                {
3388
3347
                        //reverse the struct lists so selections occur in the same order
3389
3348
                        reverseObjectList((BASE_OBJECT**)&mission.apsStructLists[pl]);
3390
3349
                }
3391
3350
 
3392
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3393
3351
                for(pl=0;pl<MAX_PLAYERS;pl++)
3394
3352
                {
3395
3353
                        //reverse the droid lists so selections occur in the same order
3396
3354
                        reverseObjectList((BASE_OBJECT**)&apsFeatureLists[pl]);
3397
3355
                }
3398
3356
 
3399
 
                LOADBARCALLBACK();      //              loadingScreenCallback();
3400
3357
                for(pl=0;pl<MAX_PLAYERS;pl++)
3401
3358
                {
3402
3359
                        //reverse the droid lists so selections occur in the same order
3407
3364
        //turn power on for rest of game
3408
3365
        powerCalculated = true;
3409
3366
 
3410
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3411
 
 
3412
3367
        if (saveGameVersion > VERSION_12)
3413
3368
        {
3414
3369
                if (!keepObjects)//only reset the pointers if they were set
3418
3373
                }
3419
3374
        }
3420
3375
 
3421
 
        LOADBARCALLBACK();      //      loadingScreenCallback();
3422
 
 
3423
3376
        if (saveGameVersion > VERSION_20)
3424
3377
        {
3425
3378
                if (!keepObjects)//only reset the pointers if they were set
3541
3494
        UDWORD                  fileExtension;
3542
3495
        DROID                   *psDroid, *psNext;
3543
3496
 
3544
 
        ASSERT(aFileName && strlen(aFileName) > 4, "Bad savegame filename");
3545
 
        if (!aFileName || strlen(aFileName) < 4)
3546
 
        {
3547
 
                return false;
3548
 
        }
 
3497
        ASSERT_OR_RETURN(false, aFileName && strlen(aFileName) > 4, "Bad savegame filename");
3549
3498
 
3550
3499
        debug(LOG_WZ, "saveGame: %s", aFileName);
3551
3500
 
3856
3805
                swapMissionPointers();
3857
3806
        }
3858
3807
 
 
3808
        // strip the last filename
 
3809
        aFileName[fileExtension-1] = '\0';
 
3810
 
3859
3811
        /* Start the game clock */
3860
3812
        gameTimeStart();
3861
3813
        return true;
3925
3877
                      fileHeader.aFileType[3]);
3926
3878
 
3927
3879
                PHYSFS_close(fileHandle);
3928
 
                abort();
 
3880
 
3929
3881
                return false;
3930
3882
        }
3931
3883
 
3939
3891
        {
3940
3892
                debug(LOG_ERROR, "gameLoad: unsupported save format version %d", fileHeader.version);
3941
3893
                PHYSFS_close(fileHandle);
3942
 
                abort();
 
3894
 
3943
3895
                return false;
3944
3896
        }
3945
3897
        else if (fileHeader.version < VERSION_9)
3958
3910
        {
3959
3911
                debug(LOG_ERROR, "gameLoad: undefined save format version %u", fileHeader.version);
3960
3912
                PHYSFS_close(fileHandle);
3961
 
                abort();
 
3913
 
3962
3914
                return false;
3963
3915
        }
3964
3916
}
3977
3929
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwFlags);
3978
3930
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwMaxPlayers);
3979
3931
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwCurrentPlayers);
3980
 
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUser1);
3981
 
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUser2);
3982
 
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUser3);
3983
 
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUser4);
 
3932
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUserFlags[0]);
 
3933
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUserFlags[1]);
 
3934
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUserFlags[2]);
 
3935
                        endian_sdword(&psSaveGame->sNetPlay.games[i].desc.dwUserFlags[3]);
3984
3936
                }
3985
3937
                for(i = 0; i < MAX_PLAYERS; i++)
3986
3938
                        endian_udword(&psSaveGame->sNetPlay.players[i].dpid);
4119
4071
                if (PHYSFS_read(fileHandle, &saveGame, sizeof(SAVE_GAME_V14), 1) != 1)
4120
4072
                {
4121
4073
                        debug(LOG_ERROR, "getCampaignV: error while reading file: %s", PHYSFS_getLastError());
4122
 
                        abort();
 
4074
 
4123
4075
                        return 0;
4124
4076
                }
4125
4077
 
4131
4083
                if (!deserializeSaveGameV14Data(fileHandle, &saveGame))
4132
4084
                {
4133
4085
                        debug(LOG_ERROR, "getCampaignV: error while reading file: %s", PHYSFS_getLastError());
4134
 
                        abort();
 
4086
 
4135
4087
                        return 0;
4136
4088
                }
4137
4089
        }
4178
4130
                      fileHeader.aFileType[3]);
4179
4131
 
4180
4132
                PHYSFS_close(fileHandle);
4181
 
                abort();
 
4133
 
4182
4134
                return false;
4183
4135
        }
4184
4136
 
4211
4163
        {
4212
4164
                debug(LOG_ERROR, "getCampaign: undefined save format version %d", fileHeader.version);
4213
4165
                PHYSFS_close(fileHandle);
4214
 
                abort();
 
4166
 
4215
4167
                return 0;
4216
4168
        }
4217
4169
 
4235
4187
        if (PHYSFS_read(fileHandle, &saveGame, sizeof(saveGame), 1) != 1)
4236
4188
        {
4237
4189
                debug(LOG_ERROR, "gameLoadV7: error while reading file: %s", PHYSFS_getLastError());
4238
 
                abort();
 
4190
 
4239
4191
                return false;
4240
4192
        }
4241
4193
 
4273
4225
                if (psNewLevel == NULL)
4274
4226
                {
4275
4227
                        debug( LOG_ERROR, "gameLoadV7: couldn't find level data" );
4276
 
                        abort();
 
4228
 
4277
4229
                        return false;
4278
4230
                }
4279
4231
                //check to see whether mission automatically starts
4314
4266
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V10), 1) != 1)
4315
4267
                {
4316
4268
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4317
 
                        abort();
 
4269
 
4318
4270
                        return false;
4319
4271
                }
4320
4272
        }
4323
4275
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V11), 1) != 1)
4324
4276
                {
4325
4277
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4326
 
                        abort();
 
4278
 
4327
4279
                        return false;
4328
4280
                }
4329
4281
        }
4332
4284
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V12), 1) != 1)
4333
4285
                {
4334
4286
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4335
 
                        abort();
 
4287
 
4336
4288
                        return false;
4337
4289
                }
4338
4290
        }
4341
4293
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V14), 1) != 1)
4342
4294
                {
4343
4295
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4344
 
                        abort();
 
4296
 
4345
4297
                        return false;
4346
4298
                }
4347
4299
        }
4350
4302
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V15), 1) != 1)
4351
4303
                {
4352
4304
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4353
 
                        abort();
 
4305
 
4354
4306
                        return false;
4355
4307
                }
4356
4308
        }
4359
4311
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V16), 1) != 1)
4360
4312
                {
4361
4313
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4362
 
                        abort();
 
4314
 
4363
4315
                        return false;
4364
4316
                }
4365
4317
        }
4368
4320
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V17), 1) != 1)
4369
4321
                {
4370
4322
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4371
 
                        abort();
 
4323
 
4372
4324
                        return false;
4373
4325
                }
4374
4326
        }
4377
4329
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V18), 1) != 1)
4378
4330
                {
4379
4331
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4380
 
                        abort();
 
4332
 
4381
4333
                        return false;
4382
4334
                }
4383
4335
        }
4386
4338
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V19), 1) != 1)
4387
4339
                {
4388
4340
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4389
 
                        abort();
 
4341
 
4390
4342
                        return false;
4391
4343
                }
4392
4344
        }
4395
4347
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V20), 1) != 1)
4396
4348
                {
4397
4349
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4398
 
                        abort();
 
4350
 
4399
4351
                        return false;
4400
4352
                }
4401
4353
        }
4404
4356
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V22), 1) != 1)
4405
4357
                {
4406
4358
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4407
 
                        abort();
 
4359
 
4408
4360
                        return false;
4409
4361
                }
4410
4362
        }
4413
4365
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V24), 1) != 1)
4414
4366
                {
4415
4367
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4416
 
                        abort();
 
4368
 
4417
4369
                        return false;
4418
4370
                }
4419
4371
        }
4422
4374
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V27), 1) != 1)
4423
4375
                {
4424
4376
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4425
 
                        abort();
 
4377
 
4426
4378
                        return false;
4427
4379
                }
4428
4380
        }
4431
4383
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V29), 1) != 1)
4432
4384
                {
4433
4385
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4434
 
                        abort();
 
4386
 
4435
4387
                        return false;
4436
4388
                }
4437
4389
        }
4440
4392
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V30), 1) != 1)
4441
4393
                {
4442
4394
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4443
 
                        abort();
 
4395
 
4444
4396
                        return false;
4445
4397
                }
4446
4398
        }
4449
4401
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V31), 1) != 1)
4450
4402
                {
4451
4403
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4452
 
                        abort();
 
4404
 
4453
4405
                        return false;
4454
4406
                }
4455
4407
        }
4458
4410
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V33), 1) != 1)
4459
4411
                {
4460
4412
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4461
 
                        abort();
 
4413
 
4462
4414
                        return false;
4463
4415
                }
4464
4416
        }
4467
4419
                if (PHYSFS_read(fileHandle, &saveGameData, sizeof(SAVE_GAME_V34), 1) != 1)
4468
4420
                {
4469
4421
                        debug(LOG_ERROR, "gameLoadV: error while reading file (with version number %u): %s", version, PHYSFS_getLastError());
4470
 
                        abort();
 
4422
 
4471
4423
                        return false;
4472
4424
                }
4473
4425
        }
4476
4428
                if (!deserializeSaveGameData(fileHandle, &saveGameData))
4477
4429
                {
4478
4430
                        debug(LOG_ERROR, "gameLoadV: error while reading data from file for deserialization (with version number %u): %s", version, PHYSFS_getLastError());
4479
 
                        abort();
 
4431
 
4480
4432
                        return false;
4481
4433
                }
4482
4434
        }
4483
4435
        else
4484
4436
        {
4485
4437
                debug(LOG_ERROR, "gameLoadV: out of range version number (%u) for savegame", version);
4486
 
                abort();
 
4438
 
4487
4439
                return false;
4488
4440
        }
4489
4441
 
4880
4832
        saveGame.GameType = saveType;
4881
4833
 
4882
4834
        //save the current level so we can load up the STARTING point of the mission
4883
 
        if (strlen(aLevelName) > MAX_LEVEL_SIZE)
4884
 
        {
4885
 
                ASSERT( false,
4886
 
                        "writeGameFile:Unable to save level name - too long (max20) - %s",
4887
 
                        aLevelName );
4888
 
 
4889
 
                return false;
4890
 
        }
 
4835
        ASSERT_OR_RETURN(false, strlen(aLevelName) < MAX_LEVEL_SIZE, "Unable to save level name - too long (max %d) - %s",
 
4836
                         (int)MAX_LEVEL_SIZE, aLevelName);
4891
4837
        sstrcpy(saveGame.levelName, aLevelName);
4892
4838
 
4893
4839
        //save out the players power
5038
4984
        if (psHeader->aFileType[0] != 'd' || psHeader->aFileType[1] != 'i' ||
5039
4985
                psHeader->aFileType[2] != 'n' || psHeader->aFileType[3] != 't') {
5040
4986
                debug( LOG_ERROR, "loadSaveUnitInit: Incorrect file type" );
5041
 
                abort();
 
4987
 
5042
4988
                return false;
5043
4989
        }
5044
4990
 
5053
4999
        if (psHeader->version < VERSION_7)
5054
5000
        {
5055
5001
                debug( LOG_ERROR, "UnitInit; unsupported save format version %d", psHeader->version );
5056
 
                abort();
 
5002
 
5057
5003
                return false;
5058
5004
        }
5059
5005
        else if (psHeader->version <= CURRENT_VERSION_NUM)
5066
5012
        else
5067
5013
        {
5068
5014
                debug( LOG_ERROR, "UnitInit: undefined save format version %d", psHeader->version );
5069
 
                abort();
 
5015
 
5070
5016
                return false;
5071
5017
        }
5072
5018
 
5106
5052
                }
5107
5053
 
5108
5054
 
5109
 
                psTemplate = (DROID_TEMPLATE *)FindDroidTemplate(pDroidInit->name,pDroidInit->player);
 
5055
                psTemplate = (DROID_TEMPLATE *)FindDroidTemplate(pDroidInit->name);
5110
5056
 
5111
5057
                if(psTemplate==NULL)
5112
5058
                {
5133
5079
                                {
5134
5080
 
5135
5081
                                        debug( LOG_ERROR, "This droid cannot be built - %s", pDroidInit->name );
5136
 
                                        abort();
 
5082
                                        return false;
5137
5083
                                }
5138
5084
                        }
5139
5085
                }
5140
5086
                pDroidInit++;
5141
5087
        }
5142
 
        if(NumberOfSkippedDroids) {
 
5088
        if(NumberOfSkippedDroids)
 
5089
        {
5143
5090
                debug( LOG_ERROR, "unitLoad: Bad Player number in %d unit(s)... assigned to the last player!\n", NumberOfSkippedDroids );
5144
 
                abort();
 
5091
                return false;
5145
5092
        }
5146
5093
        return true;
5147
5094
}
5148
5095
 
5149
5096
 
5150
5097
// -----------------------------------------------------------------------------------------
5151
 
DROID_TEMPLATE *FindDroidTemplate(char *name,UDWORD player)
 
5098
DROID_TEMPLATE *FindDroidTemplate(const char * const name)
5152
5099
{
5153
5100
        UDWORD                  TempPlayer;
5154
5101
        DROID_TEMPLATE *Template;
5155
 
        UDWORD                  id;
5156
5102
 
5157
 
        //get the name from the resource associated with it
5158
 
        if (!strresGetIDNum(psStringRes, name, &id))
 
5103
        // get the name from the resource associated with it
 
5104
        const char * const nameStr = strresGetString(psStringRes, name);
 
5105
        if (!nameStr)
5159
5106
        {
5160
5107
                debug( LOG_ERROR, "Cannot find resource for template - %s", name );
5161
 
                abort();
5162
5108
                return NULL;
5163
5109
        }
5164
 
        //get the string from the id
5165
 
        name = strresGetString(psStringRes, id);
5166
5110
 
5167
5111
        for(TempPlayer=0; TempPlayer<MAX_PLAYERS; TempPlayer++) {
5168
5112
                Template = apsDroidTemplates[TempPlayer];
5169
5113
 
5170
5114
                while(Template) {
5171
5115
 
5172
 
                        //if(strcmp(name,Template->pName)==0) {
5173
 
                        if(strcmp(name,Template->aName)==0) {
 
5116
                        //if(strcmp(nameStr,Template->pName)==0) {
 
5117
                        if(strcmp(nameStr,Template->aName)==0) {
5174
5118
                                return Template;
5175
5119
                        }
5176
5120
                        Template = Template->psNext;
5200
5144
                psHeader->aFileType[2] != 'o' || psHeader->aFileType[3] != 'd')
5201
5145
        {
5202
5146
                debug( LOG_ERROR, "loadSaveUnit: Incorrect file type" );
5203
 
                abort();
 
5147
 
5204
5148
                return false;
5205
5149
        }
5206
5150
 
5215
5159
        if (psHeader->version < VERSION_9)
5216
5160
        {
5217
5161
                debug( LOG_ERROR, "UnitLoad; unsupported save format version %d", psHeader->version );
5218
 
                abort();
 
5162
 
5219
5163
                return false;
5220
5164
        }
5221
5165
        else if (psHeader->version == VERSION_11)
5242
5186
        else
5243
5187
        {
5244
5188
                debug( LOG_ERROR, "UnitLoad: undefined save format version %d", psHeader->version );
5245
 
                abort();
 
5189
 
5246
5190
                return false;
5247
5191
        }
5248
5192
 
5276
5220
                {
5277
5221
 
5278
5222
                        debug( LOG_ERROR, "This component no longer exists - %s, the droid will be deleted", psSaveDroid->asBits[i].name );
5279
 
                        abort();
 
5223
 
5280
5224
                        found = false;
5281
5225
                        break;//continue;
5282
5226
                }
5291
5235
        for (i=0; i < psSaveDroid->numWeaps; i++)
5292
5236
        {
5293
5237
                int weapon = getCompFromName(COMP_WEAPON, psSaveDroid->asWeaps[i].name);
5294
 
                if( weapon < 0)
5295
 
                {
5296
 
                        ASSERT(false, "This component does not exist : %s", psSaveDroid->asWeaps[i].name );
5297
 
                        return NULL;
5298
 
                }
 
5238
                ASSERT_OR_RETURN(false, weapon >= 0, "This component does not exist : %s", psSaveDroid->asWeaps[i].name);
5299
5239
                psTemplate->asWeaps[i] = weapon;
5300
5240
        }
5301
5241
 
5317
5257
                if (psDroid->asWeaps[i].nStat > 0)
5318
5258
                {
5319
5259
                        //only one weapon now
5320
 
                        psDroid->asWeaps[i].hitPoints = psSaveDroid->asWeaps[i].hitPoints;
5321
5260
                        psDroid->asWeaps[i].ammo = psSaveDroid->asWeaps[i].ammo;
5322
5261
                        psDroid->asWeaps[i].lastFired = psSaveDroid->asWeaps[i].lastFired;
5323
5262
                }
5343
5282
        //version 11
5344
5283
        for (i=0; i < psDroid->numWeaps; i++)
5345
5284
        {
5346
 
                psDroid->turretRotation[i] = psSaveDroid->turretRotation;
5347
 
                psDroid->turretPitch[i] = psSaveDroid->turretPitch;
 
5285
                psDroid->asWeaps[i].rotation = psSaveDroid->turretRotation;
 
5286
                psDroid->asWeaps[i].pitch = psSaveDroid->turretPitch;
5348
5287
        }
5349
5288
 
5350
5289
 
5385
5324
                {
5386
5325
 
5387
5326
                        debug( LOG_ERROR, "This component no longer exists - %s, the droid will be deleted", psSaveDroid->asBits[i].name );
5388
 
                        abort();
5389
5327
 
5390
5328
                        found = false;
5391
5329
                        break;//continue;
5392
5330
                }
5393
5331
                psTemplate->asParts[i] = (UDWORD)compInc;
5394
5332
        }
5395
 
        if (!found)
5396
 
        {
5397
 
                //ignore this record
5398
 
                ASSERT( found,"buildUnitFromSavedUnit; failed to find weapon" );
5399
 
                return NULL;
5400
 
        }
 
5333
        ASSERT_OR_RETURN(NULL, found, "Failed to find weapon");
5401
5334
        psTemplate->numWeaps = psSaveDroid->numWeaps;
5402
5335
 
5403
5336
        if (psSaveDroid->numWeaps > 0)
5405
5338
                for(i = 0;i < psTemplate->numWeaps;i++)
5406
5339
                {
5407
5340
                        int weapon = getCompFromName(COMP_WEAPON, psSaveDroid->asWeaps[i].name);
5408
 
                        if( weapon < 0)
5409
 
                        {
5410
 
                                ASSERT(false, "This component does not exist : %s", psSaveDroid->asWeaps[i].name );
5411
 
                                return NULL;
5412
 
                        }
 
5341
                        ASSERT_OR_RETURN(NULL, weapon >= 0, "This component does not exist : %s", psSaveDroid->asWeaps[i].name);
5413
5342
                        psTemplate->asWeaps[i] = weapon;
5414
5343
                }
5415
5344
        }
5441
5370
                        psSaveDroid->player, false);
5442
5371
        }
5443
5372
 
5444
 
        if(psDroid == NULL)
5445
 
        {
5446
 
                ASSERT( false,"buildUnitFromSavedUnit; failed to build unit" );
5447
 
                return NULL;
5448
 
        }
5449
 
 
 
5373
        ASSERT_OR_RETURN(NULL, psDroid, "Failed to build unit");
5450
5374
 
5451
5375
        //copy the droid's weapon stats
5452
5376
        for (i=0; i < psDroid->numWeaps; i++)
5453
5377
        {
5454
5378
                if (psDroid->asWeaps[i].nStat > 0)
5455
5379
                {
5456
 
                        psDroid->asWeaps[i].hitPoints = psSaveDroid->asWeaps[i].hitPoints;
5457
5380
                        psDroid->asWeaps[i].ammo = psSaveDroid->asWeaps[i].ammo;
5458
5381
                        psDroid->asWeaps[i].lastFired = psSaveDroid->asWeaps[i].lastFired;
5459
5382
                }
5484
5407
                //Watermelon:make it back-compatible with older versions of save
5485
5408
                for (i=0; i < psDroid->numWeaps; i++)
5486
5409
                {
5487
 
                        psDroid->turretRotation[i] = psSaveDroid->turretRotation;
5488
 
                        psDroid->turretPitch[i] = psSaveDroid->turretPitch;
 
5410
                        psDroid->asWeaps[i].rotation = psSaveDroid->turretRotation;
 
5411
                        psDroid->asWeaps[i].pitch = psSaveDroid->turretPitch;
5489
5412
                }
5490
5413
        }
5491
5414
        if (version >= VERSION_12)//version 12
5598
5521
        // Copy over the endian neutral stuff (all UBYTE)
5599
5522
        psSaveDroid->sMove.Status    = psDroid->sMove.Status;
5600
5523
        psSaveDroid->sMove.Position  = psDroid->sMove.Position;
5601
 
        psSaveDroid->sMove.numPoints = psDroid->sMove.numPoints;
5602
 
        memcpy(&psSaveDroid->sMove.asPath, &psDroid->sMove.asPath, sizeof(psSaveDroid->sMove.asPath));
 
5524
        psSaveDroid->sMove.numPoints = MIN(psDroid->sMove.numPoints, TRAVELSIZE);
 
5525
        memcpy(&psSaveDroid->sMove.asPath, psDroid->sMove.asPath,
 
5526
               MIN(sizeof(psSaveDroid->sMove.asPath), sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints));
5603
5527
 
5604
5528
        // Little endian SDWORDs
5605
5529
        psSaveDroid->sMove.DestinationX = PHYSFS_swapSLE32(psDroid->sMove.DestinationX);
5666
5590
        psDroid->sMove.Status      = psSaveDroid->sMove.Status;
5667
5591
        psDroid->sMove.Position    = psSaveDroid->sMove.Position;
5668
5592
        psDroid->sMove.numPoints   = psSaveDroid->sMove.numPoints;
5669
 
        memcpy(&psDroid->sMove.asPath, &psSaveDroid->sMove.asPath, sizeof(psSaveDroid->sMove.asPath));
 
5593
        psDroid->sMove.asPath      = malloc(sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints);
 
5594
        memcpy(psDroid->sMove.asPath, &psSaveDroid->sMove.asPath, sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints);
5670
5595
 
5671
5596
        // Little endian SDWORDs
5672
5597
        psDroid->sMove.DestinationX = PHYSFS_swapSLE32(psSaveDroid->sMove.DestinationX);
5736
5661
                        }
5737
5662
                }
5738
5663
        }
 
5664
 
 
5665
        // Recreate path-finding jobs
 
5666
        if (psDroid->sMove.Status == MOVEWAITROUTE)
 
5667
        {
 
5668
                psDroid->sMove.Status = MOVEINACTIVE;
 
5669
                fpathDroidRoute(psDroid, psDroid->sMove.DestinationX, psDroid->sMove.DestinationY);
 
5670
                psDroid->sMove.Status = MOVEWAITROUTE;
 
5671
        }
5739
5672
}
5740
5673
 
5741
5674
// -----------------------------------------------------------------------------------------
5785
5718
        }
5786
5719
                else if (compInc < 0)
5787
5720
                {
5788
 
 
5789
 
                        debug( LOG_ERROR, "This component no longer exists - %s, the droid will be deleted", psSaveDroid->asBits[i].name );
5790
 
                        abort();
5791
 
 
 
5721
                        ASSERT(compInc >= 0, "This component no longer exists - %s, the droid will be deleted", psSaveDroid->asBits[i].name);
5792
5722
                        found = false;
5793
5723
                        break;//continue;
5794
5724
                }
5795
5725
                psTemplate->asParts[i] = (UDWORD)compInc;
5796
5726
        }
5797
 
        if (!found)
5798
 
        {
5799
 
                //ignore this record
5800
 
                ASSERT( found,"buildUnitFromSavedUnit; failed to find weapon" );
5801
 
                return NULL;
5802
 
        }
 
5727
        ASSERT_OR_RETURN(NULL, found, "Failed to find weapon");
5803
5728
        psTemplate->numWeaps = psSaveDroid->numWeaps;
5804
5729
        if (psSaveDroid->numWeaps > 0)
5805
5730
        {
5806
5731
                for(i = 0;i < psTemplate->numWeaps;i++)
5807
5732
                {
5808
5733
                        int weapon = getCompFromName(COMP_WEAPON, psSaveDroid->asWeaps[i].name);
5809
 
                        if( weapon < 0)
5810
 
                        {
5811
 
                                ASSERT(false, "This component does not exist : %s", psSaveDroid->asWeaps[i].name );
5812
 
                                return NULL;
5813
 
                        }
 
5734
                        ASSERT_OR_RETURN(NULL, weapon >= 0, "This component does not exist : %s", psSaveDroid->asWeaps[i].name);
5814
5735
                        psTemplate->asWeaps[i] = weapon;
5815
5736
                }
5816
5737
        }
5844
5765
                        psSaveDroid->player, false);
5845
5766
        }
5846
5767
 
5847
 
        if(psDroid == NULL)
5848
 
        {
5849
 
                ASSERT( false,"buildUnitFromSavedUnit; failed to build unit" );
5850
 
                return NULL;
5851
 
        }
 
5768
        ASSERT_OR_RETURN(NULL, psDroid, "Failed to build unit");
5852
5769
 
5853
5770
        turnOffMultiMsg(false);
5854
5771
 
5858
5775
        {
5859
5776
                if (psDroid->asWeaps[i].nStat > 0)
5860
5777
                {
5861
 
                        psDroid->asWeaps[i].hitPoints = psSaveDroid->asWeaps[i].hitPoints;
5862
5778
                        psDroid->asWeaps[i].ammo = psSaveDroid->asWeaps[i].ammo;
5863
5779
                        psDroid->asWeaps[i].lastFired = psSaveDroid->asWeaps[i].lastFired;
5864
5780
                }
5890
5806
        {
5891
5807
                if (version >= VERSION_24)
5892
5808
                {
5893
 
                        psDroid->turretRotation[i] = psSaveDroid->turretRotation[i];
5894
 
                        psDroid->turretPitch[i] = psSaveDroid->turretPitch[i];
 
5809
                        psDroid->asWeaps[i].rotation = psSaveDroid->turretRotation[i];
 
5810
                        psDroid->asWeaps[i].pitch = psSaveDroid->turretPitch[i];
5895
5811
                }
5896
5812
                else
5897
5813
                {
5898
 
                        psDroid->turretRotation[i] = psSaveDroid->turretRotation[0];
5899
 
                        psDroid->turretPitch[i] = psSaveDroid->turretPitch[0];
 
5814
                        psDroid->asWeaps[i].rotation = psSaveDroid->turretRotation[0];
 
5815
                        psDroid->asWeaps[i].pitch = psSaveDroid->turretPitch[0];
5900
5816
                }
5901
5817
        }
5902
5818
        //version 12
6138
6054
                filesize)
6139
6055
        {
6140
6056
                debug( LOG_ERROR, "unitLoad: unexpected end of file" );
6141
 
                abort();
 
6057
 
6142
6058
                return false;
6143
6059
        }
6144
6060
 
6164
6080
                endian_udword(&psSaveDroid->burnDamage);
6165
6081
                for(i = 0; i < TEMP_DROID_MAXPROGS; i++) {
6166
6082
                        /* SAVE_WEAPON_V19 */
6167
 
                        endian_udword(&psSaveDroid->asWeaps[i].hitPoints);
6168
6083
                        endian_udword(&psSaveDroid->asWeaps[i].ammo);
6169
6084
                        endian_udword(&psSaveDroid->asWeaps[i].lastFired);
6170
6085
                }
6182
6097
                if (psDroid == NULL)
6183
6098
                {
6184
6099
                        debug( LOG_ERROR, "unitLoad: Template not found for unit\n" );
6185
 
                        abort();
 
6100
                        return false;
6186
6101
                }
6187
6102
                else if (psSaveDroid->saveType == DROID_ON_TRANSPORT)
6188
6103
                {
6220
6135
        if (NumberOfSkippedDroids>0)
6221
6136
        {
6222
6137
                debug( LOG_ERROR, "unitLoad: Bad Player number in %d unit(s)... assigned to the last player!\n", NumberOfSkippedDroids );
6223
 
                abort();
 
6138
                return false;
6224
6139
        }
6225
6140
 
6226
6141
        ppsCurrentDroidLists = NULL;//ensure it always gets set
6270
6185
                filesize)
6271
6186
        {
6272
6187
                debug( LOG_ERROR, "unitLoad: unexpected end of file" );
6273
 
                abort();
 
6188
 
6274
6189
                return false;
6275
6190
        }
6276
6191
 
6317
6232
                endian_udword(&psSaveDroid->burnDamage);
6318
6233
                for(i = 0; i < TEMP_DROID_MAXPROGS; i++) {
6319
6234
                        /* SAVE_WEAPON_V19 */
6320
 
                        endian_udword(&psSaveDroid->asWeaps[i].hitPoints);
6321
6235
                        endian_udword(&psSaveDroid->asWeaps[i].ammo);
6322
6236
                        endian_udword(&psSaveDroid->asWeaps[i].lastFired);
6323
6237
                }
6375
6289
        if (NumberOfSkippedDroids>0)
6376
6290
        {
6377
6291
                debug( LOG_ERROR, "unitLoad: Bad Player number in %d unit(s)... assigned to the last player!\n", NumberOfSkippedDroids );
6378
 
                abort();
 
6292
                return false;
6379
6293
        }
6380
6294
 
6381
6295
        ppsCurrentDroidLists = NULL;//ensure it always gets set
6414
6328
                filesize)
6415
6329
        {
6416
6330
                debug( LOG_ERROR, "unitLoad: unexpected end of file" );
6417
 
                abort();
 
6331
 
6418
6332
                return false;
6419
6333
        }
6420
6334
 
6479
6393
                endian_udword(&psSaveDroid->burnDamage);
6480
6394
                for(i = 0; i < TEMP_DROID_MAXPROGS; i++) {
6481
6395
                        /* SAVE_WEAPON */
6482
 
                        endian_udword(&psSaveDroid->asWeaps[i].hitPoints);
6483
6396
                        endian_udword(&psSaveDroid->asWeaps[i].ammo);
6484
6397
                        endian_udword(&psSaveDroid->asWeaps[i].lastFired);
6485
6398
                }
6539
6452
        if (NumberOfSkippedDroids>0)
6540
6453
        {
6541
6454
                debug( LOG_ERROR, "unitLoad: Bad Player number in %d unit(s)... assigned to the last player!\n", NumberOfSkippedDroids );
6542
 
                abort();
 
6455
                return false;
6543
6456
        }
6544
6457
 
6545
6458
        ppsCurrentDroidLists = NULL;//ensure it always gets set
6557
6470
                        the translated name - old versions of save games should load because
6558
6471
                        templates are loaded from Access AND the save game so they should all
6559
6472
                        still exist*/
6560
 
                        ASSERT(strlen(psCurr->aName) + 1 < sizeof(psSaveDroid->name), "Truncation of droid name occurred! Max droid length (without truncation while saving) is %zu", sizeof(psSaveDroid->name) - 1);
 
6473
 
6561
6474
                        sstrcpy(psSaveDroid->name, psCurr->aName);
6562
6475
 
6563
6476
                        // not interested in first comp - COMP_UNKNOWN
6583
6496
                                        if (getNameFromComp(COMP_WEAPON, psSaveDroid->asWeaps[i].name, psCurr->asWeaps[i].nStat))
6584
6497
 
6585
6498
                                        {
6586
 
                                        psSaveDroid->asWeaps[i].hitPoints = psCurr->asWeaps[i].hitPoints;
6587
6499
                                        psSaveDroid->asWeaps[i].ammo = psCurr->asWeaps[i].ammo;
6588
6500
                                        psSaveDroid->asWeaps[i].lastFired = psCurr->asWeaps[i].lastFired;
6589
6501
                                        }
6602
6514
                        //Watermelon:endian_udword for new save format
6603
6515
                        for(i = 0;i < psCurr->numWeaps;i++)
6604
6516
                        {
6605
 
                                psSaveDroid->turretRotation[i] = psCurr->turretRotation[i];
6606
 
                                psSaveDroid->turretPitch[i]     = psCurr->turretPitch[i];
 
6517
                                psSaveDroid->turretRotation[i] = psCurr->asWeaps[i].rotation;
 
6518
                                psSaveDroid->turretPitch[i]     = psCurr->asWeaps[i].pitch;
6607
6519
                        }
6608
6520
                        //version 12
6609
6521
                        psSaveDroid->order                      = psCurr->order;
6709
6621
                        endian_udword(&psSaveDroid->body);
6710
6622
                        endian_udword(&psSaveDroid->saveType);
6711
6623
                        for(i = 0; i < TEMP_DROID_MAXPROGS; i++) {
6712
 
                                endian_udword(&psSaveDroid->asWeaps[i].hitPoints);
6713
6624
                                endian_udword(&psSaveDroid->asWeaps[i].ammo);
6714
6625
                                endian_udword(&psSaveDroid->asWeaps[i].lastFired);
6715
6626
                        }
6788
6699
                                        if (psTrans->psGrpNext == dangling_ptr)
6789
6700
                                        {
6790
6701
                                                debug( LOG_ERROR, "transporter ->psGrpNext not reset" );
6791
 
                                                abort();
 
6702
                                                return false;
6792
6703
                                        }
6793
6704
                                }
6794
6705
#endif
6880
6791
                psHeader->aFileType[2] != 'r' || psHeader->aFileType[3] != 'u')
6881
6792
        {
6882
6793
                debug( LOG_ERROR, "loadSaveStructure: Incorrect file type" );
6883
 
                abort();
 
6794
 
6884
6795
                return false;
6885
6796
        }
6886
6797
 
6895
6806
        if (psHeader->version < VERSION_7)
6896
6807
        {
6897
6808
                debug( LOG_ERROR, "StructLoad: unsupported save format version %d", psHeader->version );
6898
 
                abort();
 
6809
 
6899
6810
                return false;
6900
6811
        }
6901
6812
        else if (psHeader->version < VERSION_9)
6922
6833
        else
6923
6834
        {
6924
6835
                debug( LOG_ERROR, "StructLoad: undefined save format version %d", psHeader->version );
6925
 
                abort();
 
6836
 
6926
6837
                return false;
6927
6838
        }
6928
6839
 
6949
6860
                filesize)
6950
6861
        {
6951
6862
                debug( LOG_ERROR, "structureLoad: unexpected end of file" );
6952
 
                abort();
 
6863
 
6953
6864
                return false;
6954
6865
        }
6955
6866
 
7011
6922
                if (!found)
7012
6923
                {
7013
6924
                        debug( LOG_ERROR, "This structure no longer exists - %s", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure) );
7014
 
                        abort();
 
6925
                        //ignore this
7015
6926
                        continue;
7016
6927
                }
7017
6928
 
7023
6934
                        if (psStructure == NULL)
7024
6935
                        {
7025
6936
                                debug( LOG_ERROR, "No owning structure for module - %s for player - %d", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure), psSaveStructure->player );
7026
 
                                abort();
7027
6937
                                //ignore this module
7028
6938
                                continue;
7029
6939
                        }
7041
6951
         || map_coord(psSaveStructure->x) > mapWidth - TOO_NEAR_EDGE)
7042
6952
        {
7043
6953
                        debug( LOG_ERROR, "Structure %s, x coord too near the edge of the map. id - %d", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure), psSaveStructure->id );
7044
 
                        abort();
 
6954
                        //ignore this
7045
6955
            continue;
7046
6956
        }
7047
6957
        if (map_coord(psSaveStructure->y) < TOO_NEAR_EDGE
7048
6958
         || map_coord(psSaveStructure->y) > mapHeight - TOO_NEAR_EDGE)
7049
6959
        {
7050
6960
                        debug( LOG_ERROR, "Structure %s, y coord too near the edge of the map. id - %d", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure), psSaveStructure->id );
7051
 
                        abort();
 
6961
                        //ignore this
7052
6962
            continue;
7053
6963
        }
7054
6964
 
7055
6965
        psStructure = buildStructure(psStats, psSaveStructure->x, psSaveStructure->y,
7056
6966
                        psSaveStructure->player,true);
7057
 
                if (!psStructure)
7058
 
                {
7059
 
                        ASSERT( false, "loadSaveStructure:Unable to create structure" );
7060
 
                        return false;
7061
 
                }
 
6967
        ASSERT_OR_RETURN(false, psStructure, "Unable to create structure");
7062
6968
 
7063
6969
        /*The original code here didn't work and so the scriptwriters worked
7064
6970
        round it by using the module ID - so making it work now will screw up
7146
7052
                                psRepair->psDeliveryPoint = NULL;
7147
7053
                                psRepair->psObj = NULL;
7148
7054
                                psRepair->currentPtsAdded = 0;
 
7055
                                psRepair->droidQueue = 0;
7149
7056
                                break;
7150
7057
                        default:
7151
7058
                                break;
7155
7062
        if (NumberOfSkippedStructures>0)
7156
7063
        {
7157
7064
                debug( LOG_ERROR, "structureLoad: invalid player number in %d structures ... assigned to the last player!\n\n", NumberOfSkippedStructures );
7158
 
                abort();
 
7065
                return false;
7159
7066
        }
7160
7067
 
7161
7068
        return true;
7178
7085
        }
7179
7086
 
7180
7087
        debug( LOG_ERROR, "Unknown research - %s", pName );
7181
 
        abort();
 
7088
 
7182
7089
        return NULL_ID;
7183
7090
}
7184
7091
 
7230
7137
                filesize)
7231
7138
        {
7232
7139
                debug( LOG_ERROR, "structureLoad: unexpected end of file" );
7233
 
                abort();
 
7140
 
7234
7141
                return false;
7235
7142
        }
7236
7143
 
7302
7209
                if (!found)
7303
7210
                {
7304
7211
                        debug( LOG_ERROR, "This structure no longer exists - %s", getSaveStructNameV19(psSaveStructure) );
7305
 
                        abort();
 
7212
                        //ignore this
7306
7213
                        continue;
7307
7214
                }
7308
7215
                /*create the Structure */
7314
7221
                        if (psStructure == NULL)
7315
7222
                        {
7316
7223
                                debug( LOG_ERROR, "No owning structure for module - %s for player - %d", getSaveStructNameV19(psSaveStructure), psSaveStructure->player );
7317
 
                                abort();
7318
7224
                                //ignore this module
7319
7225
                                continue;
7320
7226
                        }
7330
7236
         || map_coord(psSaveStructure->x) > mapWidth - TOO_NEAR_EDGE)
7331
7237
        {
7332
7238
                        debug( LOG_ERROR, "Structure %s, x coord too near the edge of the map. id - %d", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure), psSaveStructure->id );
7333
 
                        abort();
 
7239
                        //ignore this
7334
7240
            continue;
7335
7241
        }
7336
7242
        if (map_coord(psSaveStructure->y) < TOO_NEAR_EDGE
7337
7243
         || map_coord(psSaveStructure->y) > mapHeight - TOO_NEAR_EDGE)
7338
7244
        {
7339
7245
                        debug( LOG_ERROR, "Structure %s, y coord too near the edge of the map. id - %d", getSaveStructNameV19((SAVE_STRUCTURE_V17*)psSaveStructure), psSaveStructure->id );
7340
 
                        abort();
 
7246
                        //ignore this
7341
7247
            continue;
7342
7248
        }
7343
7249
 
7344
 
                psStructure = buildStructure(psStats, psSaveStructure->x, psSaveStructure->y,
7345
 
                        psSaveStructure->player,true);
7346
 
                if (!psStructure)
7347
 
                {
7348
 
                        ASSERT( false, "loadSaveStructure:Unable to create structure" );
7349
 
                        return false;
7350
 
                }
 
7250
        psStructure = buildStructure(psStats, psSaveStructure->x, psSaveStructure->y, psSaveStructure->player,true);
 
7251
        ASSERT_OR_RETURN(false, psStructure, "Unable to create structure");
7351
7252
 
7352
7253
        /*The original code here didn't work and so the scriptwriters worked
7353
7254
        round it by using the module ID - so making it work now will screw up
7628
7529
        if (NumberOfSkippedStructures>0)
7629
7530
        {
7630
7531
                debug( LOG_ERROR, "structureLoad: invalid player number in %d structures ... assigned to the last player!\n\n", NumberOfSkippedStructures );
7631
 
                abort();
 
7532
                return false;
7632
7533
        }
7633
7534
 
7634
7535
        return true;
7671
7572
                filesize)
7672
7573
        {
7673
7574
                debug( LOG_ERROR, "structureLoad: unexpected end of file" );
7674
 
                abort();
 
7575
 
7675
7576
                return false;
7676
7577
        }
7677
7578
 
7743
7644
                if (!found)
7744
7645
                {
7745
7646
                        debug( LOG_ERROR, "This structure no longer exists - %s", getSaveStructNameV(psSaveStructure) );
7746
 
                        abort();
 
7647
                        //ignore this
7747
7648
                        continue;
7748
7649
                }
7749
7650
                /*create the Structure */
7755
7656
                        if (psStructure == NULL)
7756
7657
                        {
7757
7658
                                debug( LOG_ERROR, "No owning structure for module - %s for player - %d", getSaveStructNameV(psSaveStructure), psSaveStructure->player );
7758
 
                                abort();
7759
7659
                                //ignore this module
7760
7660
                                continue;
7761
7661
                        }
7771
7671
         || map_coord(psSaveStructure->x) > mapWidth - TOO_NEAR_EDGE)
7772
7672
        {
7773
7673
                        debug( LOG_ERROR, "Structure %s, x coord too near the edge of the map. id - %d", getSaveStructNameV((SAVE_STRUCTURE*)psSaveStructure), psSaveStructure->id );
7774
 
                        abort();
 
7674
                        //ignore this
7775
7675
            continue;
7776
7676
        }
7777
7677
        if (map_coord(psSaveStructure->y) < TOO_NEAR_EDGE
7778
7678
         || map_coord(psSaveStructure->y) > mapHeight - TOO_NEAR_EDGE)
7779
7679
        {
7780
7680
                        debug( LOG_ERROR, "Structure %s, y coord too near the edge of the map. id - %d", getSaveStructNameV((SAVE_STRUCTURE*)psSaveStructure), psSaveStructure->id );
7781
 
                        abort();
 
7681
                        //ignore this
7782
7682
            continue;
7783
7683
        }
7784
7684
 
7785
 
                psStructure = buildStructure(psStats, psSaveStructure->x, psSaveStructure->y,
7786
 
                        psSaveStructure->player,true);
7787
 
                if (!psStructure)
7788
 
                {
7789
 
                        ASSERT( false, "loadSaveStructure:Unable to create structure" );
7790
 
                        return false;
7791
 
                }
 
7685
        psStructure = buildStructure(psStats, psSaveStructure->x, psSaveStructure->y, psSaveStructure->player, true);
 
7686
        ASSERT_OR_RETURN(false, psStructure, "Unable to create structure");
7792
7687
 
7793
7688
        /*The original code here didn't work and so the scriptwriters worked
7794
7689
        round it by using the module ID - so making it work now will screw up
7960
7855
/*
7961
7856
        // The group the droids to be repaired by this facility belong to
7962
7857
        struct _droid_group             *psGroup;
7963
 
        struct _droid                   *psGrpNext;
 
7858
        struct DROID                    *psGrpNext;
7964
7859
*/
7965
7860
                                psRepair = ((REPAIR_FACILITY *)psStructure->pFunctionality);
7966
7861
 
8062
7957
        if (NumberOfSkippedStructures>0)
8063
7958
        {
8064
7959
                debug( LOG_ERROR, "structureLoad: invalid player number in %d structures ... assigned to the last player!\n\n", NumberOfSkippedStructures );
8065
 
                abort();
 
7960
                return false;
8066
7961
        }
8067
7962
 
8068
7963
        return true;
8469
8364
                psHeader->aFileType[2] != 'a' || psHeader->aFileType[3] != 't')
8470
8365
        {
8471
8366
                debug( LOG_ERROR, "loadSaveFeature: Incorrect file type" );
8472
 
                abort();
 
8367
 
8473
8368
                return false;
8474
8369
        }
8475
8370
 
8484
8379
        if (psHeader->version < VERSION_7)
8485
8380
        {
8486
8381
                debug( LOG_ERROR, "FeatLoad: unsupported save format version %d", psHeader->version );
8487
 
                abort();
 
8382
 
8488
8383
                return false;
8489
8384
        }
8490
8385
        else if (psHeader->version <= VERSION_19)
8504
8399
        else
8505
8400
        {
8506
8401
                debug( LOG_ERROR, "FeatLoad: undefined save format version %d", psHeader->version );
8507
 
                abort();
 
8402
 
8508
8403
                return false;
8509
8404
        }
8510
8405
 
8537
8432
                filesize)
8538
8433
        {
8539
8434
                debug( LOG_ERROR, "featureLoad: unexpected end of file" );
8540
 
                abort();
 
8435
 
8541
8436
                return false;
8542
8437
        }
8543
8438
 
8590
8485
                {
8591
8486
 
8592
8487
                        debug( LOG_ERROR, "This feature no longer exists - %s", psSaveFeature->name );
8593
 
                        abort();
 
8488
                        //ignore this
8594
8489
                        continue;
8595
8490
                }
8596
8491
                //create the Feature
8599
8494
                pFeature = buildFeature(psStats, psSaveFeature->x, psSaveFeature->y,true);
8600
8495
                //will be added to the top of the linked list
8601
8496
                //pFeature = apsFeatureLists[0];
8602
 
                if (!pFeature)
8603
 
                {
8604
 
                        ASSERT( false, "loadSaveFeature:Unable to create feature" );
8605
 
                        return false;
8606
 
                }
 
8497
                ASSERT_OR_RETURN(false, pFeature, "Unable to create feature");
8607
8498
                //restore values
8608
8499
                pFeature->id = psSaveFeature->id;
8609
8500
                pFeature->direction = psSaveFeature->direction;
8641
8532
                filesize)
8642
8533
        {
8643
8534
                debug( LOG_ERROR, "featureLoad: unexpected end of file" );
8644
 
                abort();
 
8535
 
8645
8536
                return false;
8646
8537
        }
8647
8538
 
8693
8584
                {
8694
8585
 
8695
8586
                        debug( LOG_ERROR, "This feature no longer exists - %s", psSaveFeature->name );
8696
 
                        abort();
8697
 
 
 
8587
                        //ignore this
8698
8588
                        continue;
8699
8589
                }
8700
8590
                //create the Feature
8703
8593
                pFeature = buildFeature(psStats, psSaveFeature->x, psSaveFeature->y,true);
8704
8594
                //will be added to the top of the linked list
8705
8595
                //pFeature = apsFeatureLists[0];
8706
 
                if (!pFeature)
8707
 
                {
8708
 
                        ASSERT( false, "loadSaveFeature:Unable to create feature" );
8709
 
                        return false;
8710
 
                }
 
8596
                ASSERT_OR_RETURN(false, pFeature, "Unable to create feature");
8711
8597
                //restore values
8712
8598
                pFeature->id = psSaveFeature->id;
8713
8599
                pFeature->direction = psSaveFeature->direction;
8827
8713
                psHeader->aFileType[2] != 'm' || psHeader->aFileType[3] != 'p')
8828
8714
        {
8829
8715
                debug( LOG_ERROR, "loadSaveTemplate: Incorrect file type" );
8830
 
                abort();
 
8716
 
8831
8717
                return false;
8832
8718
        }
8833
8719
 
8842
8728
        if (psHeader->version < VERSION_7)
8843
8729
        {
8844
8730
                debug( LOG_ERROR, "TemplateLoad: unsupported save format version %d", psHeader->version );
8845
 
                abort();
 
8731
 
8846
8732
                return false;
8847
8733
        }
8848
8734
        else if (psHeader->version < VERSION_14)
8869
8755
        else
8870
8756
        {
8871
8757
                debug( LOG_ERROR, "TemplateLoad: undefined save format version %d", psHeader->version );
8872
 
                abort();
 
8758
 
8873
8759
                return false;
8874
8760
        }
8875
8761
        return true;
8890
8776
        if ((sizeof(SAVE_TEMPLATE_V2) * numTemplates + TEMPLATE_HEADER_SIZE) > filesize)
8891
8777
        {
8892
8778
                debug( LOG_ERROR, "templateLoad: unexpected end of file" );
8893
 
                abort();
 
8779
 
8894
8780
                return false;
8895
8781
        }
8896
8782
 
8943
8829
                        {
8944
8830
 
8945
8831
                                debug( LOG_ERROR, "This component no longer exists - %s, the template will be deleted", psSaveTemplate->asParts[i] );
8946
 
                                abort();
8947
8832
 
8948
8833
                                found = false;
8949
8834
                                //continue;
8968
8853
                        {
8969
8854
 
8970
8855
                                debug( LOG_ERROR, "This weapon no longer exists - %s, the template will be deleted", psSaveTemplate->asWeaps[i] );
8971
 
                                abort();
8972
8856
 
8973
8857
                                found = false;
8974
8858
                                //continue;
9021
8905
        if ((sizeof(SAVE_TEMPLATE_V14) * numTemplates + TEMPLATE_HEADER_SIZE) > filesize)
9022
8906
        {
9023
8907
                debug( LOG_ERROR, "templateLoad: unexpected end of file" );
9024
 
                abort();
 
8908
 
9025
8909
                return false;
9026
8910
        }
9027
8911
 
9049
8933
                if (psTemplate == NULL)
9050
8934
                {
9051
8935
                        debug(LOG_ERROR, "loadSaveTemplateV14: Out of memory");
9052
 
                        abort();
 
8936
 
9053
8937
                        goto error;
9054
8938
                }
9055
8939
                //copy the values across
9076
8960
                        {
9077
8961
 
9078
8962
                                debug( LOG_ERROR, "This component no longer exists - %s, the template will be deleted", psSaveTemplate->asParts[i] );
9079
 
                                abort();
9080
8963
 
9081
8964
                                found = false;
9082
8965
                                //continue;
9100
8983
                        if (compInc < 0)
9101
8984
                        {
9102
8985
                                debug( LOG_ERROR, "This weapon no longer exists - %s, the template will be deleted", psSaveTemplate->asWeaps[i] );
9103
 
                                abort();
9104
8986
 
9105
8987
                                found = false;
9106
8988
                                //continue;
9175
9057
        if ((sizeof(SAVE_TEMPLATE) * numTemplates + TEMPLATE_HEADER_SIZE) > filesize)
9176
9058
        {
9177
9059
                debug( LOG_ERROR, "templateLoad: unexpected end of file" );
9178
 
                abort();
 
9060
 
9179
9061
                return false;
9180
9062
        }
9181
9063
 
9248
9130
                        {
9249
9131
 
9250
9132
                                debug( LOG_ERROR, "This component no longer exists - %s, the template will be deleted", psSaveTemplate->asParts[i] );
9251
 
                                abort();
9252
9133
 
9253
9134
                                found = false;
9254
9135
                                //continue;
9273
9154
                        {
9274
9155
 
9275
9156
                                debug( LOG_ERROR, "This weapon no longer exists - %s, the template will be deleted", psSaveTemplate->asWeaps[i] );
9276
 
                                abort();
9277
 
 
9278
9157
 
9279
9158
                                found = false;
9280
9159
                                //continue;
9383
9262
        {
9384
9263
                for(psCurr = apsDroidTemplates[player]; psCurr != NULL; psCurr = psCurr->psNext)
9385
9264
                {
9386
 
                        ASSERT(strlen(psCurr->aName) + 1 < sizeof(psSaveTemplate->name), "Truncation of droid name occurred! Max droid length (without truncation while saving) is %zu", sizeof(psSaveTemplate->name) - 1);
9387
9265
                        sstrcpy(psSaveTemplate->name, psCurr->aName);
9388
9266
 
9389
9267
                        psSaveTemplate->ref = psCurr->ref;
9451
9329
        if (filesize < TILETYPE_HEADER_SIZE)
9452
9330
        {
9453
9331
                debug( LOG_ERROR, "loadTerrainTypeMap: file too small" );
9454
 
                abort();
9455
9332
                return false;
9456
9333
        }
9457
9334
 
9461
9338
                psHeader->aFileType[2] != 'y' || psHeader->aFileType[3] != 'p')
9462
9339
        {
9463
9340
                debug( LOG_ERROR, "loadTerrainTypeMap: Incorrect file type" );
9464
 
                abort();
 
9341
 
9465
9342
                return false;
9466
9343
        }
9467
9344
 
9475
9352
        // Load the terrain type mapping
9476
9353
        pType = (UWORD *)(pFileData + TILETYPE_HEADER_SIZE);
9477
9354
        endian_uword(pType);
 
9355
        if (psHeader->quantity >= MAX_TILE_TEXTURES)
 
9356
        {
 
9357
                // Workaround for fugly map editor bug, since we can't fix the map editor
 
9358
                psHeader->quantity = MAX_TILE_TEXTURES - 1;
 
9359
        }
9478
9360
        for(i = 0; i < psHeader->quantity; i++)
9479
9361
        {
9480
 
                if (i >= MAX_TILE_TEXTURES)
9481
 
                {
9482
 
                        debug( LOG_ERROR, "loadTerrainTypeMap: too many types" );
9483
 
                        abort();
9484
 
                        return false;
9485
 
 
9486
 
                }
9487
9362
                if (*pType > TER_MAX)
9488
9363
                {
9489
9364
                        debug( LOG_ERROR, "loadTerrainTypeMap: terrain type out of range" );
9490
 
                        abort();
 
9365
 
9491
9366
                        return false;
9492
9367
                }
9493
9368
 
9560
9435
                psHeader->aFileType[2] != 'p' || psHeader->aFileType[3] != 'l')
9561
9436
        {
9562
9437
                debug( LOG_ERROR, "loadSaveCompList: Incorrect file type" );
9563
 
                abort();
 
9438
 
9564
9439
                return false;
9565
9440
        }
9566
9441
 
9575
9450
        if (psHeader->version < VERSION_7)
9576
9451
        {
9577
9452
                debug( LOG_ERROR, "CompLoad: unsupported save format version %d", psHeader->version );
9578
 
                abort();
 
9453
 
9579
9454
                return false;
9580
9455
        }
9581
9456
        else if (psHeader->version <= VERSION_19)
9595
9470
        else
9596
9471
        {
9597
9472
                debug( LOG_ERROR, "CompLoad: undefined save format version %d", psHeader->version );
9598
 
                abort();
 
9473
 
9599
9474
                return false;
9600
9475
        }
9601
9476
 
9613
9488
                filesize)
9614
9489
        {
9615
9490
                debug( LOG_ERROR, "CompListLoad: unexpected end of file" );
9616
 
                abort();
 
9491
 
9617
9492
                return false;
9618
9493
        }
9619
9494
 
9680
9555
                filesize)
9681
9556
        {
9682
9557
                debug( LOG_ERROR, "CompListLoad: unexpected end of file" );
9683
 
                abort();
 
9558
 
9684
9559
                return false;
9685
9560
        }
9686
9561
 
9729
9604
        char *pFileData;
9730
9605
        SAVE_COMPLIST                   *psSaveCompList;
9731
9606
        UDWORD                                  fileSize, totalComp, player, i;
9732
 
        COMP_BASE_STATS                 *psStats;
 
9607
        COMPONENT_STATS                 *psStats;
9733
9608
 
9734
9609
        // Calculate the file size
9735
9610
        totalComp = (numBodyStats + numWeaponStats + numConstructStats + numECMStats +
9760
9635
        {
9761
9636
                for(i = 0; i < numBodyStats; i++)
9762
9637
                {
9763
 
                        psStats = (COMP_BASE_STATS *)(asBodyStats + i);
 
9638
                        psStats = (COMPONENT_STATS *)(asBodyStats + i);
9764
9639
 
9765
9640
                        strcpy(psSaveCompList->name, psStats->pName);
9766
9641
 
9771
9646
                }
9772
9647
                for(i = 0; i < numWeaponStats; i++)
9773
9648
                {
9774
 
                        psStats = (COMP_BASE_STATS *)(asWeaponStats + i);
 
9649
                        psStats = (COMPONENT_STATS *)(asWeaponStats + i);
9775
9650
 
9776
9651
                        strcpy(psSaveCompList->name, psStats->pName);
9777
9652
 
9782
9657
                }
9783
9658
                for(i = 0; i < numConstructStats; i++)
9784
9659
                {
9785
 
                        psStats = (COMP_BASE_STATS *)(asConstructStats + i);
 
9660
                        psStats = (COMPONENT_STATS *)(asConstructStats + i);
9786
9661
 
9787
9662
                        strcpy(psSaveCompList->name, psStats->pName);
9788
9663
 
9793
9668
                }
9794
9669
                for(i = 0; i < numECMStats; i++)
9795
9670
                {
9796
 
                        psStats = (COMP_BASE_STATS *)(asECMStats + i);
 
9671
                        psStats = (COMPONENT_STATS *)(asECMStats + i);
9797
9672
 
9798
9673
                        strcpy(psSaveCompList->name, psStats->pName);
9799
9674
 
9804
9679
                }
9805
9680
                for(i = 0; i < numPropulsionStats; i++)
9806
9681
                {
9807
 
                        psStats = (COMP_BASE_STATS *)(asPropulsionStats + i);
 
9682
                        psStats = (COMPONENT_STATS *)(asPropulsionStats + i);
9808
9683
 
9809
9684
                        strcpy(psSaveCompList->name, psStats->pName);
9810
9685
 
9815
9690
                }
9816
9691
                for(i = 0; i < numSensorStats; i++)
9817
9692
                {
9818
 
                        psStats = (COMP_BASE_STATS *)(asSensorStats + i);
 
9693
                        psStats = (COMPONENT_STATS *)(asSensorStats + i);
9819
9694
 
9820
9695
                        strcpy(psSaveCompList->name, psStats->pName);
9821
9696
 
9826
9701
                }
9827
9702
                for(i = 0; i < numRepairStats; i++)
9828
9703
                {
9829
 
                        psStats = (COMP_BASE_STATS *)(asRepairStats + i);
 
9704
                        psStats = (COMPONENT_STATS *)(asRepairStats + i);
9830
9705
 
9831
9706
                        strcpy(psSaveCompList->name, psStats->pName);
9832
9707
 
9837
9712
                }
9838
9713
                for(i = 0; i < numBrainStats; i++)
9839
9714
                {
9840
 
                        psStats = (COMP_BASE_STATS *)(asBrainStats + i);
 
9715
                        psStats = (COMPONENT_STATS *)(asBrainStats + i);
9841
9716
 
9842
9717
                        strcpy(psSaveCompList->name, psStats->pName);
9843
9718
 
9873
9748
                psHeader->aFileType[2] != 'r' || psHeader->aFileType[3] != 'l')
9874
9749
        {
9875
9750
                debug( LOG_ERROR, "loadSaveStructTypeList: Incorrect file type" );
9876
 
                abort();
 
9751
 
9877
9752
                return false;
9878
9753
        }
9879
9754
 
9888
9763
        if (psHeader->version < VERSION_7)
9889
9764
        {
9890
9765
                debug( LOG_ERROR, "StructTypeLoad: unsupported save format version %d", psHeader->version );
9891
 
                abort();
 
9766
 
9892
9767
                return false;
9893
9768
        }
9894
9769
        else if (psHeader->version <= VERSION_19)
9908
9783
        else
9909
9784
        {
9910
9785
                debug( LOG_ERROR, "StructTypeLoad: undefined save format version %d", psHeader->version );
9911
 
                abort();
 
9786
 
9912
9787
                return false;
9913
9788
        }
9914
9789
 
9927
9802
                filesize)
9928
9803
        {
9929
9804
                debug( LOG_ERROR, "StructListLoad: unexpected end of file" );
9930
 
                abort();
 
9805
 
9931
9806
                return false;
9932
9807
        }
9933
9808
 
9986
9861
                filesize)
9987
9862
        {
9988
9863
                debug( LOG_ERROR, "StructListLoad: unexpected end of file" );
9989
 
                abort();
 
9864
 
9990
9865
                return false;
9991
9866
        }
9992
9867
 
10107
9982
                psHeader->aFileType[2] != 's' || psHeader->aFileType[3] != 'h')
10108
9983
        {
10109
9984
                debug( LOG_ERROR, "loadSaveResearch: Incorrect file type" );
10110
 
                abort();
 
9985
 
10111
9986
                return false;
10112
9987
        }
10113
9988
 
10122
9997
        if (psHeader->version < VERSION_8)
10123
9998
        {
10124
9999
                debug( LOG_ERROR, "ResearchLoad: unsupported save format version %d", psHeader->version );
10125
 
                abort();
 
10000
 
10126
10001
                return false;
10127
10002
        }
10128
10003
        else if (psHeader->version <= VERSION_19)
10142
10017
        else
10143
10018
        {
10144
10019
                debug( LOG_ERROR, "ResearchLoad: undefined save format version %d", psHeader->version );
10145
 
                abort();
 
10020
 
10146
10021
                return false;
10147
10022
        }
10148
10023
 
10162
10037
                filesize)
10163
10038
        {
10164
10039
                debug( LOG_ERROR, "loadSaveResearch: unexpected end of file" );
10165
 
                abort();
 
10040
 
10166
10041
                return false;
10167
10042
        }
10168
10043
 
10246
10121
                filesize)
10247
10122
        {
10248
10123
                debug( LOG_ERROR, "loadSaveResearch: unexpected end of file" );
10249
 
                abort();
 
10124
 
10250
10125
                return false;
10251
10126
        }
10252
10127
 
10389
10264
                psHeader->aFileType[2] != 's' || psHeader->aFileType[3] != 's')
10390
10265
        {
10391
10266
                debug( LOG_ERROR, "loadSaveMessage: Incorrect file type" );
10392
 
                abort();
 
10267
 
10393
10268
                return false;
10394
10269
        }
10395
10270
 
10449
10324
                filesize)
10450
10325
        {
10451
10326
                debug( LOG_ERROR, "loadSaveMessage: unexpected end of file" );
10452
 
                abort();
 
10327
 
10453
10328
                return false;
10454
10329
        }
10455
10330
 
10561
10436
                filesize)
10562
10437
        {
10563
10438
                debug( LOG_ERROR, "loadSaveMessage: unexpected end of file" );
10564
 
                abort();
 
10439
 
10565
10440
                return false;
10566
10441
        }
10567
10442
 
10805
10680
                psHeader->aFileType[2] != 'a' || psHeader->aFileType[3] != 'g')
10806
10681
        {
10807
10682
                debug( LOG_ERROR, "loadSaveflag: Incorrect file type" );
10808
 
                abort();
 
10683
 
10809
10684
                return false;
10810
10685
        }
10811
10686
 
10852
10727
        if ((sizeOfSaveFlag * numflags + FLAG_HEADER_SIZE) > filesize)
10853
10728
        {
10854
10729
                debug( LOG_ERROR, "loadSaveflag: unexpected end of file" );
10855
 
                abort();
 
10730
 
10856
10731
                return false;
10857
10732
        }
10858
10733
 
11159
11034
                psHeader->aFileType[2] != 'o' || psHeader->aFileType[3] != 'd')
11160
11035
        {
11161
11036
                debug( LOG_ERROR, "loadSaveProduction: Incorrect file type" );
11162
 
                abort();
 
11037
 
11163
11038
                return false;
11164
11039
        }
11165
11040
 
11189
11064
                filesize)
11190
11065
        {
11191
11066
                debug( LOG_ERROR, "loadSaveProduction: unexpected end of file" );
11192
 
                abort();
 
11067
 
11193
11068
                return false;
11194
11069
        }
11195
11070
 
11303
11178
                psHeader->aFileType[2] != 't' || psHeader->aFileType[3] != 's')
11304
11179
        {
11305
11180
                debug( LOG_ERROR, "loadSaveStructLimits: Incorrect file type" );
11306
 
                abort();
 
11181
 
11307
11182
                return false;
11308
11183
        }
11309
11184
 
11332
11207
        else
11333
11208
        {
11334
11209
                debug( LOG_ERROR, "loadSaveStructLimits: Incorrect file format version" );
11335
 
                abort();
 
11210
 
11336
11211
                return false;
11337
11212
        }
11338
11213
        return true;
11360
11235
                filesize)
11361
11236
        {
11362
11237
                debug( LOG_ERROR, "loadSaveStructLimits: unexpected end of file" );
11363
 
                abort();
 
11238
 
11364
11239
                return false;
11365
11240
        }
11366
11241
 
11386
11261
                if (!found)
11387
11262
                {
11388
11263
                        debug( LOG_ERROR, "The structure no longer exists. The limits have not been set! - %s", psSaveLimits->name );
11389
 
                        abort();
 
11264
 
11390
11265
                        continue;
11391
11266
                }
11392
11267
 
11404
11279
        if (SkippedRecords>0)
11405
11280
        {
11406
11281
                debug( LOG_ERROR, "Skipped %d records in structure limits due to bad player number\n", SkippedRecords );
11407
 
                abort();
 
11282
                free(psSaveLimits);
 
11283
                return false;
11408
11284
        }
11409
11285
        free(psSaveLimits);
11410
11286
        return true;
11431
11307
                filesize)
11432
11308
        {
11433
11309
                debug( LOG_ERROR, "loadSaveStructLimits: unexpected end of file" );
11434
 
                abort();
 
11310
 
11435
11311
                return false;
11436
11312
        }
11437
11313
 
11457
11333
                if (!found)
11458
11334
                {
11459
11335
                        debug( LOG_ERROR, "The structure no longer exists. The limits have not been set! - %s", psSaveLimits->name );
11460
 
                        abort();
 
11336
 
11461
11337
                        continue;
11462
11338
                }
11463
11339
 
11475
11351
        if (SkippedRecords>0)
11476
11352
        {
11477
11353
                debug( LOG_ERROR, "Skipped %d records in structure limits due to bad player number\n", SkippedRecords );
11478
 
                abort();
 
11354
                free(psSaveLimits);
 
11355
                return false;
11479
11356
        }
11480
11357
        free(psSaveLimits);
11481
11358
        return true;
11627
11504
// write the event state to a file on disk
11628
11505
static BOOL     writeScriptState(char *pFileName)
11629
11506
{
 
11507
        static const int32_t current_event_version = 4;
 
11508
 
11630
11509
        char    *pBuffer;
11631
11510
        UDWORD  fileSize;
11632
11511
 
11633
 
        if (!eventSaveState(3, &pBuffer, &fileSize))
 
11512
        if (!eventSaveState(current_event_version, &pBuffer, &fileSize))
11634
11513
        {
11635
11514
                return false;
11636
11515
        }
11659
11538
        if (!loadFileToBuffer(pFileName, pFileData, FILE_LOAD_BUFFER_SIZE, &fileSize))
11660
11539
        {
11661
11540
                debug( LOG_ERROR, "loadScriptState: couldn't load %s", pFileName );
11662
 
                abort();
 
11541
 
11663
11542
                return false;
11664
11543
        }
11665
11544
 
11760
11639
                break;
11761
11640
        default:
11762
11641
                debug( LOG_ERROR, "Invalid component type - game.c" );
11763
 
                abort();
 
11642
 
11764
11643
                return false;
11765
11644
        }
11766
11645
 
11771
11650
// -----------------------------------------------------------------------------------------
11772
11651
// END
11773
11652
 
11774
 
//======================================================
11775
 
//draws stuff into our newer bitmap.
11776
 
BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWORD offY)
 
11653
/**
 
11654
 * \param[out] backDropSprite The premade map texture.
 
11655
 * \param scale               Scale of the map texture.
 
11656
 * \param offX,offY           X and Y offset for map
 
11657
 * \param[out] playeridpos    Will contain the position on the map where the player's HQ are located.
 
11658
 *
 
11659
 * Reads the current map and colours the map preview for any structures
 
11660
 * present. Additionally we load the player's HQ location into playeridpos so
 
11661
 * we know the player's starting location.
 
11662
 */
 
11663
BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWORD offY,Vector2i playeridpos[])
11777
11664
{
11778
11665
        SAVE_STRUCTURE                          sSave;  // close eyes now.
11779
11666
        SAVE_STRUCTURE                          *psSaveStructure = &sSave; // assumes save_struct is larger than all previous ones...
11792
11679
        char                    *pFileData = NULL;
11793
11680
        LEVEL_DATASET   *psLevel;
11794
11681
        PIELIGHT color = WZCOL_BLACK ;
 
11682
        bool HQ = false;
 
11683
 
11795
11684
 
11796
11685
        psLevel = levFindDataSet(game.map);
11797
11686
        strcpy(aFileName,psLevel->apDataFiles[0]);
11810
11699
                psHeader->aFileType[2] != 'r' || psHeader->aFileType[3] != 'u')
11811
11700
        {
11812
11701
                debug( LOG_ERROR, "plotStructurePreview16: Incorrect file type" );
11813
 
                abort();
 
11702
 
11814
11703
                return false;
11815
11704
        }
11816
11705
 
11879
11768
                        endian_udword(&psSaveStructure2->burnStart);
11880
11769
                        endian_udword(&psSaveStructure2->burnDamage);
11881
11770
 
11882
 
                        xx = map_coord(psSaveStructure2->x);
11883
 
                        yy = map_coord(psSaveStructure2->y);
 
11771
                        // we are specifically looking for the HQ, and it seems this is the only way to
 
11772
                        // find it via parsing map.
 
11773
                        // We store the coordinates of the structure, into a array for as many players as are on the map.
 
11774
                        // all map versions follow this pattern, and I will not comment the other routines.
11884
11775
                        playerid = psSaveStructure2->player;
 
11776
                        if(strncmp(psSaveStructure2->name,"A0CommandCentre",15)  == 0 )
 
11777
                        {
 
11778
                                HQ = true;
 
11779
                                xx = playeridpos[playerid].x = map_coord(psSaveStructure2->x);
 
11780
                                yy = playeridpos[playerid].y = map_coord(psSaveStructure2->y);
 
11781
                        }
 
11782
                        else
 
11783
                        {
 
11784
                                HQ = false;
 
11785
                                xx = map_coord(psSaveStructure2->x);
 
11786
                                yy = map_coord(psSaveStructure2->y);
 
11787
                        }
11885
11788
                }
11886
11789
                else if (psHeader->version < VERSION_14)
11887
11790
                {
11913
11816
                        endian_udword(&psSaveStructure12->player);
11914
11817
                        endian_udword(&psSaveStructure12->burnStart);
11915
11818
                        endian_udword(&psSaveStructure12->burnDamage);
11916
 
 
11917
 
                        xx = map_coord(psSaveStructure12->x);
11918
 
                        yy = map_coord(psSaveStructure12->y);
11919
11819
                        playerid = psSaveStructure12->player;
 
11820
 
 
11821
                        if(strncmp(psSaveStructure12->name,"A0CommandCentre",15)  == 0 )
 
11822
                        {
 
11823
                                HQ = true;
 
11824
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure12->x);
 
11825
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure12->y);
 
11826
                        }
 
11827
                        else
 
11828
                        {
 
11829
                                HQ = false;
 
11830
                                xx = map_coord(psSaveStructure12->x);
 
11831
                                yy = map_coord(psSaveStructure12->y);
 
11832
                        }
11920
11833
                }
11921
11834
                else if (psHeader->version <= VERSION_14)
11922
11835
                {
11949
11862
                        endian_udword(&psSaveStructure14->player);
11950
11863
                        endian_udword(&psSaveStructure14->burnStart);
11951
11864
                        endian_udword(&psSaveStructure14->burnDamage);
11952
 
 
11953
 
                        xx = map_coord(psSaveStructure14->x);
11954
 
                        yy = map_coord(psSaveStructure14->y);
11955
11865
                        playerid = psSaveStructure14->player;
 
11866
 
 
11867
                        if(strncmp(psSaveStructure14->name,"A0CommandCentre",15)  == 0 )
 
11868
                        {
 
11869
                                HQ = true;
 
11870
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure14->x);
 
11871
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure14->y);
 
11872
                        }
 
11873
                        else
 
11874
                        {
 
11875
                                HQ = false;
 
11876
                                xx = map_coord(psSaveStructure14->x);
 
11877
                                yy = map_coord(psSaveStructure14->y);
 
11878
                        }
11956
11879
                }
11957
11880
                else if (psHeader->version <= VERSION_16)
11958
11881
                {
11986
11909
                        endian_udword(&psSaveStructure15->player);
11987
11910
                        endian_udword(&psSaveStructure15->burnStart);
11988
11911
                        endian_udword(&psSaveStructure15->burnDamage);
11989
 
 
11990
 
                        xx = map_coord(psSaveStructure15->x);
11991
 
                        yy = map_coord(psSaveStructure15->y);
11992
11912
                        playerid = psSaveStructure15->player;
 
11913
 
 
11914
                        if(strncmp(psSaveStructure15->name,"A0CommandCentre",15)  == 0 )
 
11915
                        {
 
11916
                                HQ = true;
 
11917
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure15->x);
 
11918
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure15->y);
 
11919
                        }
 
11920
                        else
 
11921
                        {
 
11922
                                HQ = false;
 
11923
                                xx = map_coord(psSaveStructure15->x);
 
11924
                                yy = map_coord(psSaveStructure15->y);
 
11925
                        }
11993
11926
                }
11994
11927
                else if (psHeader->version <= VERSION_19)
11995
11928
                {
12025
11958
                        endian_udword(&psSaveStructure17->player);
12026
11959
                        endian_udword(&psSaveStructure17->burnStart);
12027
11960
                        endian_udword(&psSaveStructure17->burnDamage);
12028
 
 
12029
 
                        xx = map_coord(psSaveStructure17->x);
12030
 
                        yy = map_coord(psSaveStructure17->y);
12031
11961
                        playerid = psSaveStructure17->player;
 
11962
 
 
11963
                        if(strncmp(psSaveStructure17->name,"A0CommandCentre",15)  == 0 )
 
11964
                        {
 
11965
                                HQ = true;
 
11966
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure17->x);
 
11967
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure17->y);
 
11968
                        }
 
11969
                        else
 
11970
                        {
 
11971
                                HQ = false;
 
11972
                                xx = map_coord(psSaveStructure17->x);
 
11973
                                yy = map_coord(psSaveStructure17->y);
 
11974
                        }
12032
11975
                }
12033
11976
                else if (psHeader->version <= VERSION_20)
12034
11977
                {
12061
12004
                        endian_udword(&psSaveStructure20->player);
12062
12005
                        endian_udword(&psSaveStructure20->burnStart);
12063
12006
                        endian_udword(&psSaveStructure20->burnDamage);
12064
 
 
12065
 
                        xx = map_coord(psSaveStructure20->x);
12066
 
                        yy = map_coord(psSaveStructure20->y);
12067
12007
                        playerid = psSaveStructure20->player;
 
12008
 
 
12009
                        if(strncmp(psSaveStructure20->name,"A0CommandCentre",15)  == 0 )
 
12010
                        {
 
12011
                                HQ = true;
 
12012
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure20->x);
 
12013
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure20->y);
 
12014
                        }
 
12015
                        else
 
12016
                        {
 
12017
                                HQ = false;
 
12018
                                xx = map_coord(psSaveStructure20->x);
 
12019
                                yy = map_coord(psSaveStructure20->y);
 
12020
                        }
12068
12021
                }
12069
12022
                else
12070
12023
                {
12100
12053
                        endian_udword(&psSaveStructure->player);
12101
12054
                        endian_udword(&psSaveStructure->burnStart);
12102
12055
                        endian_udword(&psSaveStructure->burnDamage);
12103
 
 
12104
 
                        xx = map_coord(psSaveStructure->x);
12105
 
                        yy = map_coord(psSaveStructure->y);
12106
12056
                        playerid = psSaveStructure->player;
 
12057
 
 
12058
                        if(strncmp(psSaveStructure->name,"A0CommandCentre",15)  == 0 )
 
12059
                        {
 
12060
                                HQ = true;
 
12061
                                xx = playeridpos[playerid].x  = map_coord(psSaveStructure->x);
 
12062
                                yy = playeridpos[playerid].y  = map_coord(psSaveStructure->y);
 
12063
                        }
 
12064
                        else
 
12065
                        {
 
12066
                                HQ = false;
 
12067
                                xx = map_coord(psSaveStructure->x);
 
12068
                                yy = map_coord(psSaveStructure->y);
 
12069
                        }
12107
12070
                }
12108
12071
                // if human player, then use clan color.  If AI, then use something else.
12109
12072
                if( isHumanPlayer(playerid) )
12112
12075
                        color.rgba = clanColours[playerid].rgba;
12113
12076
                        // kludge to fix black, so you can see it on some maps.
12114
12077
                        if ( playerid == 3 )    // in this case 3 = pallete entry for black.
12115
 
                        {       
12116
 
        
 
12078
                        {
12117
12079
                                color = WZCOL_GREY;
12118
12080
                        }
12119
12081
                }
12122
12084
                        color = WZCOL_MAP_PREVIEW_AIPLAYER ;
12123
12085
                }
12124
12086
 
 
12087
                if(HQ)
 
12088
                {       // This shows where the HQ is on the map in a special color.
 
12089
                        // We could do the same for anything else (oil/whatever) also.
 
12090
                        // Possible future enhancement?
 
12091
                        color.byte.b=0xff;
 
12092
                        color.byte.g=0;
 
12093
                        color.byte.r=0xff;
 
12094
                }
 
12095
 
 
12096
                // and now we blit the color to the texture
12125
12097
                for(x = (xx*scale);x < (xx*scale)+scale ;x++)
12126
12098
                {
12127
12099
                        for(y = (yy*scale);y< (yy*scale)+scale ;y++)
12128
12100
                        {
12129
 
                                backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX)] = color.byte.r;      
 
12101
                                backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX)] = color.byte.r;
12130
12102
                                backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX) + 1] = color.byte.g;
12131
12103
                                backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX) + 2] = color.byte.b;
12132
12104
                        }
12133
12105
                }
12134
12106
        }
 
12107
 
 
12108
        // NOTE: would do fallback if FBO is not available here.
12135
12109
        return true;
12136
 
 
12137
12110
}