mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Minor adjustments to some of the rendering functions to grant a bit more control to the code. Adjusted the mouse areas for key and item popup windows. Added the pocket capacity indicator to sector inventory when using NewInv mode. Added the right click option to sector inventory so you can view/manipulate stacks and view item descriptions without first equiping an item. Updated sector inventory so that capacity values appear in all pockets. Not just currently filled one. Updated sector inventory so that newly placed items could be right-clicked on for details. Increased the mouse region for the various stack popups so there is always room to close the popup without activating the description box. Fixed a bug in the sector inventory description panel that caused a crash when trying to remove an attachment. Fixed sector inventory so you can add attachments to weapons. Fixed some weight issues. Fixed a crash resulting from right-clicking in sector inventory while Item Desc window was already open. Fixed the "Active Squad" message so it displays the squad that is actually activated. Fixed a bug that allowed you to start a new game in NewInv mode while in 640x480 resolution. Updated the Item Description windows so you can load a gun as well as unload. Added new CTRL+SHIFT+D hotkey to delete all items in sector. Added new CTRL+SHIFT+S hotkey to sell all items in sector, assuming you have the ALT+LMB option turned on in your INI file. Fixed a problem with sector inventory item description where the status did not appear for items that couldn't stack. Fixed a problem with Nails so he always starts with his leather jacket, even if you don't buy his gear. Incorporated a failsafe so that NewInv mode can't be selected, nor NIV saves loaded, when no custom data path is set. Add new IC_BELTCLIP item class. Update pocket definition restrictions to use bitwise compare. Add failsafe so that you can't merge LBENODEs. Reset VC2005 so it doesn't point to a specific drive. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1936 3b4a5df2-a311-0410-b5c6-a8a6f20db521
6825 lines
181 KiB
C++
6825 lines
181 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "JA2 All.h"
|
|
#include "PreBattle Interface.h"
|
|
#include "civ quotes.h"
|
|
#include "Militia Control.h"
|
|
#include "Strategic Event Handler.h"
|
|
#include "HelpScreen.h"
|
|
#include "Cheats.h"
|
|
#include "Animated ProgressBar.h"
|
|
#include "Shopkeeper Interface.h"
|
|
#else
|
|
#include "Types.h"
|
|
#include "Soldier Profile.h"
|
|
#include "FileMan.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "Debug.h"
|
|
#include "OverHead.h"
|
|
#include "Keys.h"
|
|
#include "finances.h"
|
|
#include "History.h"
|
|
#include "files.h"
|
|
#include "Laptop.h"
|
|
#include "iniReader.h"
|
|
#include "Email.h"
|
|
#include "Strategicmap.h"
|
|
#include "Game Events.h"
|
|
#include "Game Clock.h"
|
|
#include "Soldier Create.h"
|
|
#include "WorldDef.h"
|
|
#include "LaptopSave.h"
|
|
#include "strategicmap.h"
|
|
#include "Queen Command.h"
|
|
#include "SaveLoadGame.h"
|
|
#include "Tactical Save.h"
|
|
#include "Squads.h"
|
|
#include "Environment.h"
|
|
#include "Lighting.h"
|
|
#include "Strategic Movement.h"
|
|
#include "Strategic.h"
|
|
#include "Isometric Utils.h"
|
|
#include "Quests.h"
|
|
#include "opplist.h"
|
|
#include "message.h"
|
|
#include "NPC.h"
|
|
#include "Merc Hiring.h"
|
|
#include "SaveLoadScreen.h"
|
|
#include "GameVersion.h"
|
|
#include "GameSettings.h"
|
|
#include "Music Control.h"
|
|
#include "GameScreen.h"
|
|
#include "Options Screen.h"
|
|
#include "Ai.h"
|
|
#include "RenderWorld.h"
|
|
#include "SmokeEffects.h"
|
|
#include "Random.h"
|
|
#include "Map Screen Interface.h"
|
|
#include "Map Screen Interface Border.h"
|
|
#include "Map Screen Interface Bottom.h"
|
|
|
|
#include "Interface.h"
|
|
#include "Map Screen Helicopter.h"
|
|
#include "Environment.h"
|
|
#include "Arms Dealer Init.h"
|
|
#include "Tactical Placement GUI.h"
|
|
|
|
#include "Strategic Mines.h"
|
|
#include "Strategic Town Loyalty.h"
|
|
#include "Vehicles.h"
|
|
#include "Merc Contract.h"
|
|
#include "Bullets.h"
|
|
#include "air raid.h"
|
|
#include "physics.h"
|
|
#include "Strategic Pathing.h"
|
|
|
|
#include "TeamTurns.h"
|
|
|
|
#include "explosion control.h"
|
|
#include "Creature Spreading.h"
|
|
#include "Strategic Status.h"
|
|
#include "Prebattle Interface.h"
|
|
#include "Boxing.h"
|
|
#include "Strategic AI.h"
|
|
#include "Map Screen Interface Map.h"
|
|
|
|
#include "Meanwhile.h"
|
|
#include "dialogue control.h"
|
|
#include "text.h"
|
|
#include "Map Screen Interface.h"
|
|
#include "lighteffects.h"
|
|
#include "HelpScreen.h"
|
|
#include "Animated ProgressBar.h"
|
|
#include "merctextbox.h"
|
|
#include "render dirty.h"
|
|
#include "Map Information.h"
|
|
#include "Interface Items.h"
|
|
#include "Civ Quotes.h"
|
|
#include "Scheduling.h"
|
|
#include "Animation Data.h"
|
|
#include "Game Init.h"
|
|
#include "cheats.h"
|
|
#include "Strategic Event Handler.h"
|
|
#include "interface panels.h"
|
|
#include "interface dialogue.h"
|
|
#include "Assignments.h"
|
|
#include "Interface Items.h"
|
|
#include "Shopkeeper Interface.h"
|
|
#endif
|
|
|
|
#include "BobbyR.h"
|
|
#include "Imp Portraits.h"
|
|
#include "Loading Screen.h"
|
|
#include "Interface Utils.h"
|
|
#include "Squads.h"
|
|
#include "IMP Confirm.h"
|
|
#include "Enemy Soldier Save.h"
|
|
#include "BobbyRMailOrder.h"
|
|
#include "Mercs.h"
|
|
#include "INIReader.h"
|
|
|
|
//rain
|
|
#include "Rain.h"
|
|
//end rain
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Local Defines
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
|
|
|
|
void GetBestPossibleSectorXYZValues( INT16 *psSectorX, INT16 *psSectorY, INT8 *pbSectorZ );
|
|
extern void NextLoopCheckForEnoughFreeHardDriveSpace();
|
|
extern void UpdatePersistantGroupsFromOldSave( UINT32 uiSavedGameVersion );
|
|
extern void TrashAllSoldiers( );
|
|
extern void ResetJA2ClockGlobalTimers( void );
|
|
|
|
extern void BeginLoadScreen( void );
|
|
extern void EndLoadScreen();
|
|
|
|
//Global variable used
|
|
#ifdef JA2BETAVERSION
|
|
UINT32 guiNumberOfMapTempFiles; //Test purposes
|
|
UINT32 guiSizeOfTempFiles;
|
|
CHAR gzNameOfMapTempFile[128];
|
|
#endif
|
|
|
|
extern SOLDIERTYPE *gpSMCurrentMerc;
|
|
extern INT32 giSortStateForMapScreenList;
|
|
extern INT16 sDeadMercs[ NUMBER_OF_SQUADS ][ NUMBER_OF_SOLDIERS_PER_SQUAD ];
|
|
extern INT32 giRTAILastUpdateTime;
|
|
extern BOOLEAN gfRedrawSaveLoadScreen;
|
|
extern UINT8 gubScreenCount;
|
|
extern INT16 sWorldSectorLocationOfFirstBattle;
|
|
extern BOOLEAN gfGamePaused;
|
|
extern BOOLEAN gfLockPauseState;
|
|
extern BOOLEAN gfLoadedGame;
|
|
extern HELP_SCREEN_STRUCT gHelpScreen;
|
|
extern UINT8 gubDesertTemperature;
|
|
extern UINT8 gubGlobalTemperature;
|
|
extern BOOLEAN gfCreatureMeanwhileScenePlayed;
|
|
#ifdef JA2BETAVERSION
|
|
extern UINT8 gubReportMapscreenLock;
|
|
#endif
|
|
|
|
BOOLEAN gMusicModeToPlay = FALSE;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
BOOLEAN gfDisplaySaveGamesNowInvalidatedMsg = FALSE;
|
|
#endif
|
|
|
|
BOOLEAN gfUseConsecutiveQuickSaveSlots = FALSE;
|
|
UINT32 guiCurrentQuickSaveNumber = 0;
|
|
UINT32 guiLastSaveGameNum;
|
|
BOOLEAN DoesAutoSaveFileExist( BOOLEAN fLatestAutoSave );
|
|
|
|
UINT32 guiJA2EncryptionSet = 0;
|
|
UINT32 CalcJA2EncryptionSet( SAVED_GAME_HEADER * pSaveGameHeader );
|
|
|
|
typedef struct
|
|
{
|
|
//The screen that the gaem was saved from
|
|
UINT32 uiCurrentScreen;
|
|
|
|
UINT32 uiCurrentUniqueSoldierId;
|
|
|
|
//The music that was playing when the game was saved
|
|
UINT8 ubMusicMode;
|
|
|
|
//Flag indicating that we have purchased something from Tony
|
|
BOOLEAN fHavePurchasedItemsFromTony;
|
|
|
|
//The selected soldier in tactical
|
|
UINT16 usSelectedSoldier;
|
|
|
|
// The x and y scroll position
|
|
INT16 sRenderCenterX;
|
|
INT16 sRenderCenterY;
|
|
|
|
BOOLEAN fAtLeastOneMercWasHired;
|
|
|
|
//General Map screen state flags
|
|
BOOLEAN fShowItemsFlag;
|
|
BOOLEAN fShowTownFlag;
|
|
BOOLEAN fShowTeamFlag;
|
|
BOOLEAN fShowMineFlag;
|
|
BOOLEAN fShowAircraftFlag;
|
|
|
|
// is the helicopter available to player?
|
|
BOOLEAN fHelicopterAvailable;
|
|
|
|
// helicopter vehicle id
|
|
INT32 iHelicopterVehicleId;
|
|
|
|
// total distance travelled
|
|
INT32 UNUSEDiTotalHeliDistanceSinceRefuel;
|
|
|
|
// total owed to player
|
|
INT32 iTotalAccumulatedCostByPlayer;
|
|
|
|
// whether or not skyrider is alive and well? and on our side yet?
|
|
BOOLEAN fSkyRiderAvailable;
|
|
|
|
// skyrider engaging in a monologue
|
|
BOOLEAN UNUSEDfSkyriderMonologue;
|
|
|
|
// list of sector locations
|
|
INT16 UNUSED[ 2 ][ 2 ];
|
|
|
|
// is the heli in the air?
|
|
BOOLEAN fHelicopterIsAirBorne;
|
|
|
|
// is the pilot returning straight to base?
|
|
BOOLEAN fHeliReturnStraightToBase;
|
|
|
|
// heli hovering
|
|
BOOLEAN fHoveringHelicopter;
|
|
|
|
// time started hovering
|
|
UINT32 uiStartHoverTime;
|
|
|
|
// what state is skyrider's dialogue in in?
|
|
UINT32 uiHelicopterSkyriderTalkState;
|
|
|
|
// the flags for skyrider events
|
|
BOOLEAN fShowEstoniRefuelHighLight;
|
|
BOOLEAN fShowOtherSAMHighLight;
|
|
BOOLEAN fShowDrassenSAMHighLight;
|
|
|
|
UINT32 uiEnvWeather;
|
|
|
|
UINT8 ubDefaultButton;
|
|
|
|
|
|
|
|
|
|
BOOLEAN fSkyriderEmptyHelpGiven;
|
|
BOOLEAN fEnterMapDueToContract;
|
|
UINT8 ubHelicopterHitsTaken;
|
|
UINT8 ubQuitType;
|
|
BOOLEAN fSkyriderSaidCongratsOnTakingSAM;
|
|
INT16 sContractRehireSoldierID;
|
|
|
|
|
|
GAME_OPTIONS GameOptions;
|
|
|
|
UINT32 uiSeedNumber;
|
|
|
|
//The GetJA2Clock() value
|
|
UINT32 uiBaseJA2Clock;
|
|
|
|
INT16 sCurInterfacePanel;
|
|
|
|
UINT8 ubSMCurrentMercID;
|
|
|
|
BOOLEAN fFirstTimeInMapScreen;
|
|
|
|
BOOLEAN fDisableDueToBattleRoster;
|
|
|
|
BOOLEAN fDisableMapInterfaceDueToBattle;
|
|
|
|
INT16 sBoxerGridNo[ NUM_BOXERS ];
|
|
UINT8 ubBoxerID[ NUM_BOXERS ];
|
|
BOOLEAN fBoxerFought[ NUM_BOXERS ];
|
|
|
|
BOOLEAN fHelicopterDestroyed; //if the chopper is destroyed
|
|
BOOLEAN fShowMapScreenHelpText; //If true, displays help in mapscreen
|
|
|
|
INT32 iSortStateForMapScreenList;
|
|
BOOLEAN fFoundTixa;
|
|
|
|
UINT32 uiTimeOfLastSkyriderMonologue;
|
|
BOOLEAN fShowCambriaHospitalHighLight;
|
|
BOOLEAN fSkyRiderSetUp;
|
|
BOOLEAN fRefuelingSiteAvailable[ NUMBER_OF_REFUEL_SITES ];
|
|
|
|
|
|
//Meanwhile stuff
|
|
MEANWHILE_DEFINITION gCurrentMeanwhileDef;
|
|
|
|
BOOLEAN ubPlayerProgressSkyriderLastCommentedOn;
|
|
|
|
BOOLEAN gfMeanwhileTryingToStart;
|
|
BOOLEAN gfInMeanwhile;
|
|
|
|
// list of dead guys for squads...in id values->-1 means no one home
|
|
INT16 sDeadMercs[ NUMBER_OF_SQUADS ][ NUMBER_OF_SOLDIERS_PER_SQUAD ];
|
|
|
|
// levels of publicly known noises
|
|
INT8 gbPublicNoiseLevel[MAXTEAMS];
|
|
|
|
UINT8 gubScreenCount;
|
|
|
|
UINT16 usOldMeanWhileFlags;
|
|
|
|
INT32 iPortraitNumber;
|
|
|
|
INT16 sWorldSectorLocationOfFirstBattle;
|
|
|
|
BOOLEAN fUnReadMailFlag;
|
|
BOOLEAN fNewMailFlag;
|
|
BOOLEAN fOldUnReadFlag;
|
|
BOOLEAN fOldNewMailFlag;
|
|
|
|
BOOLEAN fShowMilitia;
|
|
|
|
BOOLEAN fNewFilesInFileViewer;
|
|
|
|
BOOLEAN fLastBoxingMatchWonByPlayer;
|
|
|
|
UINT32 uiUNUSED;
|
|
|
|
BOOLEAN fSamSiteFound[ MAX_NUMBER_OF_SAMS ];
|
|
|
|
UINT8 ubNumTerrorists;
|
|
UINT8 ubCambriaMedicalObjects;
|
|
|
|
BOOLEAN fDisableTacticalPanelButtons;
|
|
|
|
INT16 sSelMapX;
|
|
INT16 sSelMapY;
|
|
INT32 iCurrentMapSectorZ;
|
|
|
|
UINT16 usHasPlayerSeenHelpScreenInCurrentScreen;
|
|
BOOLEAN fHideHelpInAllScreens;
|
|
UINT8 ubBoxingMatchesWon;
|
|
|
|
UINT8 ubBoxersRests;
|
|
BOOLEAN fBoxersResting;
|
|
UINT8 ubDesertTemperature;
|
|
UINT8 ubGlobalTemperature;
|
|
|
|
INT16 sMercArriveSectorX;
|
|
INT16 sMercArriveSectorY;
|
|
|
|
BOOLEAN fCreatureMeanwhileScenePlayed;
|
|
UINT8 ubPlayerNum;
|
|
//New stuff for the Prebattle interface / autoresolve
|
|
BOOLEAN fPersistantPBI;
|
|
UINT8 ubEnemyEncounterCode;
|
|
|
|
BOOLEAN ubExplicitEnemyEncounterCode;
|
|
BOOLEAN fBlitBattleSectorLocator;
|
|
UINT8 ubPBSectorX;
|
|
UINT8 ubPBSectorY;
|
|
|
|
UINT8 ubPBSectorZ;
|
|
BOOLEAN fCantRetreatInPBI;
|
|
BOOLEAN fExplosionQueueActive;
|
|
UINT8 ubUnused[1];
|
|
|
|
UINT32 uiMeanWhileFlags;
|
|
|
|
INT8 bSelectedInfoChar;
|
|
INT8 bHospitalPriceModifier;
|
|
INT8 bUnused2[ 2 ];
|
|
|
|
INT32 iHospitalTempBalance;
|
|
INT32 iHospitalRefund;
|
|
|
|
INT8 fPlayerTeamSawJoey;
|
|
INT8 fMikeShouldSayHi;
|
|
|
|
UINT8 ubFiller[550]; //This structure should be 1024 bytes
|
|
|
|
} GENERAL_SAVE_INFO;
|
|
|
|
|
|
|
|
UINT32 guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Global Variables
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
|
|
//CHAR8 gsSaveGameNameWithPath[ 512 ];
|
|
|
|
CHAR8 gSaveDir[ MAX_PATH ]; // Snap: Initilized by InitSaveDir
|
|
|
|
UINT8 gubSaveGameLoc=0;
|
|
|
|
UINT32 guiScreenToGotoAfterLoadingSavedGame = 0;
|
|
|
|
extern EmailPtr pEmailList;
|
|
extern UINT32 guiCurrentUniqueSoldierId;
|
|
extern BOOLEAN gfHavePurchasedItemsFromTony;
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
|
|
BOOLEAN SaveMercProfiles( HWFILE hFile );
|
|
BOOLEAN LoadSavedMercProfiles( HWFILE hwFile );
|
|
|
|
BOOLEAN SaveSoldierStructure( HWFILE hFile );
|
|
BOOLEAN LoadSoldierStructure( HWFILE hFile );
|
|
|
|
// CHRISL: New functions to save and load LBENODE data
|
|
BOOLEAN SaveLBENODEToSaveGameFile( HWFILE hFile );
|
|
BOOLEAN LoadLBENODEFromSaveGameFile( HWFILE hFile );
|
|
|
|
//BOOLEAN SavePtrInfo( PTR *pData, UINT32 uiSizeOfObject, HWFILE hFile );
|
|
//BOOLEAN LoadPtrInfo( PTR *pData, UINT32 uiSizeOfObject, HWFILE hFile );
|
|
|
|
BOOLEAN SaveEmailToSavedGame( HWFILE hFile );
|
|
BOOLEAN LoadEmailFromSavedGame( HWFILE hFile );
|
|
|
|
BOOLEAN SaveTacticalStatusToSavedGame( HWFILE hFile );
|
|
BOOLEAN LoadTacticalStatusFromSavedGame( HWFILE hFile );
|
|
|
|
|
|
BOOLEAN SetMercsInsertionGridNo( );
|
|
|
|
BOOLEAN LoadOppListInfoFromSavedGame( HWFILE hFile );
|
|
BOOLEAN SaveOppListInfoToSavedGame( HWFILE hFile );
|
|
|
|
BOOLEAN LoadMercPathToSoldierStruct( HWFILE hFilem, UINT8 ubID );
|
|
BOOLEAN SaveMercPathFromSoldierStruct( HWFILE hFilem, UINT8 ubID );
|
|
|
|
BOOLEAN LoadGeneralInfo( HWFILE hFile );
|
|
BOOLEAN SaveGeneralInfo( HWFILE hFile );
|
|
BOOLEAN SavePreRandomNumbersToSaveGameFile( HWFILE hFile );
|
|
BOOLEAN LoadPreRandomNumbersFromSaveGameFile( HWFILE hFile );
|
|
|
|
BOOLEAN SaveWatchedLocsToSavedGame( HWFILE hFile );
|
|
BOOLEAN LoadWatchedLocsFromSavedGame( HWFILE hFile );
|
|
|
|
BOOLEAN LoadMeanwhileDefsFromSaveGameFile( HWFILE hFile );
|
|
BOOLEAN SaveMeanwhileDefsFromSaveGameFile( HWFILE hFile );
|
|
|
|
void PauseBeforeSaveGame( void );
|
|
void UnPauseAfterSaveGame( void );
|
|
void UpdateMercMercContractInfo();
|
|
void HandleOldBobbyRMailOrders();
|
|
//ppp
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
void InitSaveGameFilePosition();
|
|
void InitLoadGameFilePosition();
|
|
void SaveGameFilePosition( INT32 iPos, STR pMsg );
|
|
void LoadGameFilePosition( INT32 iPos, STR pMsg );
|
|
|
|
|
|
void WriteTempFileNameToFile( STR pFileName, UINT32 uiSizeOfFile, HFILE hSaveFile );
|
|
void InitShutDownMapTempFileTest( BOOLEAN fInit, STR pNameOfFile, UINT8 ubSaveGameID );
|
|
#endif
|
|
|
|
#ifdef JA2BETAVERSION
|
|
extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode );
|
|
#endif
|
|
void TruncateStrategicGroupSizes();
|
|
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// Functions
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
|
|
//ADB
|
|
//Some notes on saving and loading functions:
|
|
//some of these classes are saved in 2 places, in the savegame and in the sector file
|
|
//when this happens, the class data saved to the sector file is not encrypted,
|
|
//while the savegame may or may not be, this is why there is a bool for save.
|
|
|
|
//to load from a sector, the data is first loaded in one fell swoop and put in a buffer
|
|
//then, each class's data is read from the buffer, so it needs a function that takes a buffer not a file
|
|
//this function can automatically assume it is reading non encrypted data
|
|
//the regular loading function may or may not be reading encrypted data
|
|
//but that is determined on a class by class basis
|
|
|
|
//when saving encrypted data there is only one new function,
|
|
//but there are 2 loading functions to support really old versions
|
|
|
|
//the encryption set is determined by the savegame header, so make sure
|
|
//that saving and loading are logically mirrors, or when changing
|
|
//savegame versions you'll try decrypting it differently
|
|
|
|
//some class's structure have changed. for these, there is a conversion that needs to take place
|
|
//the savegame version is read and the data loaded accordingly, then converted
|
|
//load once, convert as many times as necessary
|
|
|
|
//when changing the structure of some class, check if it is someplace in
|
|
//LoadWorld, if it is, you've got to rebuild the maps
|
|
|
|
//if all that sounds compilcated, it is
|
|
|
|
extern int gLastLBEUniqueID;
|
|
/*
|
|
// CHRISL: New function to save/load LBENODE data
|
|
BOOLEAN SaveLBENODEToSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, &gLastLBEUniqueID, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN LoadLBENODEFromSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
if ( !FileRead( hFile, &gLastLBEUniqueID, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
*/
|
|
BOOLEAN LBENODE::Load( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_LBENODE_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if (uniqueID >= gLastLBEUniqueID) {
|
|
//can happen because of the order things are saved and loaded,
|
|
//when combined with copy assignment which makes a new LBENODE
|
|
gLastLBEUniqueID = uniqueID + 1;
|
|
}
|
|
int size;
|
|
if ( !FileRead( hFile, &size, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
inv.resize(size);
|
|
for (std::vector<OBJECTTYPE>::iterator iter = inv.begin(); iter != inv.end(); ++iter) {
|
|
if (! iter->Load(hFile)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//we shouldn't be loading from anything before the first change
|
|
Assert(guiCurrentSaveGameVersion >= FIRST_SAVEGAME_DATATYPE_CHANGE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN LBENODE::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion )
|
|
{
|
|
if (dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 ) {
|
|
LOADDATA( this, *hBuffer, SIZEOF_LBENODE_POD );
|
|
if (uniqueID >= gLastLBEUniqueID) {
|
|
//can happen because of the order things are saved and loaded,
|
|
//when combined with copy assignment which makes a new LBENODE
|
|
gLastLBEUniqueID = uniqueID + 1;
|
|
}
|
|
int size;
|
|
LOADDATA( &size, *hBuffer, sizeof(int) );
|
|
inv.resize(size);
|
|
for (std::vector<OBJECTTYPE>::iterator iter = inv.begin(); iter != inv.end(); ++iter) {
|
|
iter->Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
|
|
}
|
|
}
|
|
else {
|
|
Assert(guiCurrentSaveGameVersion >= FIRST_SAVEGAME_DATATYPE_CHANGE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN LBENODE::Save( HWFILE hFile, bool fSavingMap )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
int size = inv.size();
|
|
|
|
if ( !FileWrite( hFile, this, SIZEOF_LBENODE_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &size, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
for (std::vector<OBJECTTYPE>::iterator iter = inv.begin(); iter != inv.end(); ++iter) {
|
|
//we are not saving to a map, at least not yet
|
|
if (! iter->Save(hFile, false)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN LoadArmsDealerInventoryFromSavedGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
UINT8 ubArmsDealer;
|
|
UINT16 usItemIndex;
|
|
|
|
//Free all the dealers special inventory arrays
|
|
ShutDownArmsDealers();
|
|
|
|
if (guiCurrentSaveGameVersion >= FIRST_SAVEGAME_DATATYPE_CHANGE) {
|
|
int dealers;
|
|
if (!FileRead( hFile, &dealers, sizeof( int ), &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
gArmsDealersInventory.resize(dealers);
|
|
|
|
if (!FileRead( hFile, gArmsDealerStatus, sizeof( gArmsDealerStatus ), &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
//loop through all the dealers inventories
|
|
for( ubArmsDealer=0; ubArmsDealer<dealers; ubArmsDealer++ )
|
|
{
|
|
int size;
|
|
if (!FileRead( hFile, &size, sizeof( int ), &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
gArmsDealersInventory[ubArmsDealer].resize(size);
|
|
|
|
//loop through this dealer's individual items
|
|
for (DealerItemList::iterator iter = gArmsDealersInventory[ubArmsDealer].begin();
|
|
iter != gArmsDealersInventory[ubArmsDealer].end(); ++iter) {
|
|
if (! iter->Load(hFile) ) {
|
|
return FALSE;
|
|
}
|
|
//CHRISL: Because of the "100rnd" bug that Tony is experiencing, lets look at each item as we create it. If the
|
|
// item is ammo, reset the bItemCondition value to equal the number of rounds. Hopefully this will be unneccessary
|
|
// but for the time being, it may help to alleviate the "100rnd" bug.
|
|
if(Item[iter->object.usItem].usItemClass == IC_AMMO)
|
|
{
|
|
//This condition should catch any dealer ammo items that have both invalid bItemCondition and ubShotsLeft values.
|
|
// We'll only make bItemCondition valid at this point. Let the next condition correct ubShotsLeft.
|
|
if(iter->bItemCondition > Magazine[Item[iter->object.usItem].ubClassIndex].ubMagSize)
|
|
{
|
|
iter->bItemCondition = Magazine[Item[iter->object.usItem].ubClassIndex].ubMagSize;
|
|
}
|
|
//This condition should catch any dealer ammo items that have an invalid bItemCondition assuming ubShotsLeft is valid
|
|
if(iter->bItemCondition != iter->object[0]->data.ubShotsLeft)
|
|
{
|
|
iter->bItemCondition = iter->object[0]->data.ubShotsLeft;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//the format has changed and needs to be updated
|
|
OLD_ARMS_DEALER_STATUS_101 gOldArmsDealerStatus[NUM_ARMS_DEALERS];
|
|
//OLD_DEALER_ITEM_HEADER_101 gOldArmsDealersInventory[NUM_ARMS_DEALERS][MAXITEMS];
|
|
|
|
//pointer to an array of OLD_DEALER_ITEM_HEADER_101 that is sized [NUM_ARMS_DEALERS][MAXITEMS]
|
|
typedef OLD_DEALER_ITEM_HEADER_101(*pointerToArmsDealersInventoryArray)[NUM_ARMS_DEALERS][MAXITEMS];
|
|
|
|
pointerToArmsDealersInventoryArray pOldArmsDealersInventory
|
|
= (pointerToArmsDealersInventoryArray) new OLD_DEALER_ITEM_HEADER_101[NUM_ARMS_DEALERS][MAXITEMS];
|
|
|
|
|
|
// Elgin was added to the dealers list in Game Version #54, enlarging these 2 tables...
|
|
// Manny was added to the dealers list in Game Version #55, enlarging these 2 tables...
|
|
bool fIncludesElgin = guiCurrentSaveGameVersion >= 54;
|
|
bool fIncludesManny = guiCurrentSaveGameVersion >= 55;
|
|
UINT32 uiDealersSaved;
|
|
if (fIncludesElgin && fIncludesManny ){
|
|
uiDealersSaved = NUM_ORIGINAL_ARMS_DEALERS;
|
|
}
|
|
else if ( !fIncludesElgin ) {
|
|
// read 2 fewer element without Elgin or Manny in there...
|
|
uiDealersSaved = NUM_ORIGINAL_ARMS_DEALERS - 2;
|
|
}
|
|
else {
|
|
// read one fewer element without Elgin in there...
|
|
uiDealersSaved = NUM_ORIGINAL_ARMS_DEALERS - 1;
|
|
}
|
|
gArmsDealersInventory.resize(uiDealersSaved);
|
|
|
|
if (!FileRead( hFile, gOldArmsDealerStatus, uiDealersSaved * sizeof( OLD_ARMS_DEALER_STATUS_101 ), &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
if (!FileRead( hFile, (*pOldArmsDealersInventory), uiDealersSaved * sizeof( OLD_DEALER_ITEM_HEADER_101 ) * MAXITEMS, &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( !fIncludesElgin ) {
|
|
// initialize Elgin now...
|
|
InitializeOneArmsDealer( ARMS_DEALER_ELGIN );
|
|
}
|
|
if ( !fIncludesManny ) {
|
|
// initialize Manny now...
|
|
InitializeOneArmsDealer( ARMS_DEALER_MANNY );
|
|
}
|
|
|
|
OLD_DEALER_SPECIAL_ITEM_101 oldSpecial;
|
|
DEALER_SPECIAL_ITEM loadedSpecial;
|
|
//loop through all the dealers inventories
|
|
for( ubArmsDealer=0; ubArmsDealer<uiDealersSaved; ubArmsDealer++ )
|
|
{
|
|
gArmsDealerStatus[ubArmsDealer] = gOldArmsDealerStatus[ubArmsDealer];
|
|
|
|
//loop through this dealer's individual items
|
|
for(usItemIndex = 1; usItemIndex < MAXITEMS; usItemIndex++ )
|
|
{
|
|
if ( Item[usItemIndex].usItemClass == 0 )
|
|
continue;
|
|
|
|
//some things are much much better stored in status now
|
|
gArmsDealerStatus[ubArmsDealer].fPreviouslyEligible[usItemIndex] = (*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].fPreviouslyEligible;
|
|
gArmsDealerStatus[ubArmsDealer].ubStrayAmmo[usItemIndex] = (*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubStrayAmmo;
|
|
|
|
//if there are any perfect items, insert them immediately
|
|
if ((*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubPerfectItems) {
|
|
gArmsDealersInventory[ubArmsDealer].push_back(DEALER_SPECIAL_ITEM());
|
|
DEALER_SPECIAL_ITEM* pPerfectItem = &gArmsDealersInventory[ubArmsDealer].back();
|
|
CreateObjectForDealer(usItemIndex, 100, (*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubPerfectItems, &pPerfectItem->object);
|
|
//cannot set to 100, could be ammo
|
|
pPerfectItem->bItemCondition = pPerfectItem->object[0]->data.objectStatus;
|
|
}
|
|
|
|
//if there are any items on order, order them
|
|
if ((*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubQtyOnOrder) {
|
|
OrderDealerItems(ubArmsDealer, usItemIndex,
|
|
(*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubQtyOnOrder,
|
|
(*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].uiOrderArrivalTime);
|
|
}
|
|
|
|
//if there are any special elements allocated for this item, load them
|
|
for ( int x = 0; x < (*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex].ubElementsAlloced; ++x) {
|
|
if (!FileRead( hFile, &oldSpecial, sizeof( OLD_DEALER_SPECIAL_ITEM_101 ), &uiNumBytesRead ))
|
|
{
|
|
return( FALSE );
|
|
}
|
|
//not all elements alloced are full, some are empty!
|
|
//convert and add to arms dealer list (if applicable)
|
|
loadedSpecial.ConvertFrom101((*pOldArmsDealersInventory)[ubArmsDealer][usItemIndex], oldSpecial, ubArmsDealer, usItemIndex);
|
|
}
|
|
}
|
|
}
|
|
delete [] pOldArmsDealersInventory;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN DEALER_SPECIAL_ITEM::Save(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, this, SIZEOF_DEALER_SPECIAL_ITEM_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->object.Save(hFile, FALSE) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN DEALER_SPECIAL_ITEM::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_DEALER_SPECIAL_ITEM_POD, &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->object.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//this will never be loaded from sometime before the first change
|
|
Assert(guiCurrentSaveGameVersion >= FIRST_SAVEGAME_DATATYPE_CHANGE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN REAL_OBJECT::Save(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, this, SIZEOF_REAL_OBJECT_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->Obj.Save(hFile, FALSE) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN REAL_OBJECT::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_REAL_OBJECT_POD, &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->Obj.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OLD_REAL_OBJECT_101 oldObject;
|
|
if ( !FileRead( hFile, &oldObject, sizeof( OLD_REAL_OBJECT_101 ), &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
*this = oldObject;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN INVENTORY_IN_SLOT::Save(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, this, SIZEOF_INVENTORY_IN_SLOT_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->ItemObject.Save(hFile, FALSE) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN INVENTORY_IN_SLOT::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_INVENTORY_IN_SLOT_POD, &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->ItemObject.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OLD_INVENTORY_IN_SLOT_101 oldItem;
|
|
if ( !FileRead( hFile, &oldItem, sizeof( OLD_INVENTORY_IN_SLOT_101 ), &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
*this = oldItem;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN MERC_LEAVE_ITEM::Save(HWFILE hFile)
|
|
{
|
|
if ( !this->object.Save(hFile, FALSE) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN MERC_LEAVE_ITEM::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !this->object.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OLD_MERC_LEAVE_ITEM_101 oldItem;
|
|
if ( !FileRead( hFile, &oldItem, sizeof( OLD_MERC_LEAVE_ITEM_101 ), &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
this->object = oldItem.oldObject;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN ITEM_CURSOR_SAVE_INFO::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
//3 bytes of info, screw being neat
|
|
if ( !FileRead( hFile, this, 3, &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->ItemPointerInfo.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OLD_ITEM_CURSOR_SAVE_INFO_101 oldInfo101;
|
|
if ( !FileRead( hFile, &oldInfo101, sizeof(OLD_ITEM_CURSOR_SAVE_INFO_101), &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
*this = oldInfo101;
|
|
}
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN ITEM_CURSOR_SAVE_INFO::Save(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
//3 bytes of info, screw being neat
|
|
if ( !FileWrite( hFile, this, 3, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->ItemPointerInfo.Save(hFile, FALSE) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN SOLDIERCREATE_STRUCT::Save(HWFILE hFile, bool fSavingMap)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, this, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( !this->Inv.Save(hFile, fSavingMap) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//ADB screw checksums, they suck, also, checksums aren't always saved
|
|
/*
|
|
if (fSavingMap == false) {
|
|
UINT16 usCheckSum = GetChecksum();
|
|
if ( !FileWrite( hFile, &usCheckSum, 2, &uiNumBytesWritten ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
*/
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN SOLDIERCREATE_STRUCT::Load(INT8 **hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion)
|
|
{
|
|
if (dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 ) {
|
|
LOADDATA( this, *hBuffer, SIZEOF_SOLDIERCREATE_STRUCT_POD );
|
|
this->Inv.Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
|
|
}
|
|
else {
|
|
//ADB checksum was not saved under these circumstances!
|
|
OLD_SOLDIERCREATE_STRUCT_101 OldSavedSoldierInfo101;
|
|
LOADDATA( &OldSavedSoldierInfo101, *hBuffer, SIZEOF_OLD_SOLDIERCREATE_STRUCT_101_POD );
|
|
OldSavedSoldierInfo101.CopyOldInventoryToNew();
|
|
*this = OldSavedSoldierInfo101;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN SOLDIERCREATE_STRUCT::Load(HWFILE hFile, int versionToLoad, bool loadChecksum)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
//ADB need to overwrite guiCurrentSaveGameVersion so that the other things loaded (like inv) are loaded ok
|
|
int tempVersion = guiCurrentSaveGameVersion;
|
|
guiCurrentSaveGameVersion = versionToLoad;
|
|
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION)
|
|
{
|
|
//the info has changed at version 102
|
|
//first, load the POD
|
|
if ( !FileRead( hFile, this, SIZEOF_SOLDIERCREATE_STRUCT_POD, &uiNumBytesRead ) )
|
|
{
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return(FALSE);
|
|
}
|
|
|
|
//load the OO inventory
|
|
if ( !this->Inv.Load(hFile) )
|
|
{
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OLD_SOLDIERCREATE_STRUCT_101 OldSavedSoldierInfo101;
|
|
//we are loading an older version (only load once, so use "else if")
|
|
//first load the data based on what version was stored
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
if ( !FileRead( hFile, &OldSavedSoldierInfo101, SIZEOF_OLD_SOLDIERCREATE_STRUCT_101_POD, &uiNumBytesRead ) )
|
|
{
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return FALSE;
|
|
}
|
|
}
|
|
/*
|
|
else if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
OldSavedSoldierInfo999.initialize();
|
|
FileRead( hFile, &OldSavedSoldierInfo999, SIZEOF_OLD_SOLDIERCREATE_STRUCT_999_POD, &uiNumBytesRead );
|
|
*/
|
|
|
|
//now we have the data that needs to be converted (keep on converting up, so use "if")
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OldSavedSoldierInfo101.CopyOldInventoryToNew();
|
|
*this = OldSavedSoldierInfo101;
|
|
//OldSavedSoldierInfo999 = OldSavedSoldierInfo101;
|
|
}
|
|
//change this when changing the file version again
|
|
/*
|
|
if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
*this = OldSavedSoldierInfo999;
|
|
}
|
|
*/
|
|
|
|
|
|
//ADB need to make sure we are loading the checksum only if the older version saved it
|
|
if (loadChecksum == true) {
|
|
#ifdef JA2TESTVERSION
|
|
CHAR8 zReason[256];
|
|
#endif
|
|
|
|
UINT16 usCheckSum;
|
|
FileRead( hFile, &usCheckSum, 2, &uiNumBytesRead );
|
|
if( uiNumBytesRead != 2 )
|
|
{
|
|
#ifdef JA2TESTVERSION
|
|
sprintf( zReason, "Load SoldierCreateStruct -- EOF while reading usCheckSum. KM" );
|
|
AssertMsg( 0, zReason );
|
|
#endif
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return FALSE;
|
|
}
|
|
//ADB screw checksums, they suck
|
|
/*
|
|
//verify the checksum equation (anti-hack) -- see save
|
|
UINT16 usFileCheckSum = GetChecksum();
|
|
if( usCheckSum != usFileCheckSum )
|
|
{ //Hacker has modified the stats on the enemy placements.
|
|
#ifdef JA2TESTVERSION
|
|
sprintf( zReason, "EnemySoldier -- checksum for placement %d failed. KM", usFileCheckSum );
|
|
AssertMsg( 0, zReason );
|
|
#endif
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return FALSE;
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
return TRUE;
|
|
}
|
|
|
|
// Changed by ADB, rev 1513
|
|
//BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion)
|
|
BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool forceLoadOldEncryption, bool wasSavedWithEncryption)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
this->initialize();
|
|
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION && forceLoadOldVersion == false)
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_MERCPROFILESTRUCT_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
int size;
|
|
if ( !FileRead( hFile, &size, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
inv.resize(size);
|
|
bInvStatus.resize(size);
|
|
bInvNumber.resize(size);
|
|
int item;
|
|
int status;
|
|
int number;
|
|
for (int x = 0; x < size; ++x) {
|
|
if ( !FileRead( hFile, &item, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &status, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &number, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
inv[x] = item;
|
|
bInvStatus[x] = status;
|
|
bInvNumber[x] = number;
|
|
}
|
|
if ( this->uiProfileChecksum != this->GetChecksum() )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//we are loading an older version (only load once, so use "else if")
|
|
//first load the data based on what version was stored
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE || forceLoadOldVersion == true)
|
|
{
|
|
OLD_MERCPROFILESTRUCT_101 old;
|
|
typedef BOOLEAN (*functionPtr) ( HWFILE hFile, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead );
|
|
functionPtr pLoadingFunction;
|
|
// Changed by ADB, rev 1513
|
|
//if ( guiCurrentSaveGameVersion < 87 || forceLoadOldVersion == true)
|
|
if (wasSavedWithEncryption == false) {
|
|
pLoadingFunction = &FileRead;
|
|
}
|
|
else if ( guiCurrentSaveGameVersion < 87 || forceLoadOldEncryption == true)
|
|
{
|
|
pLoadingFunction = &JA2EncryptedFileRead;
|
|
}
|
|
else
|
|
{
|
|
pLoadingFunction = &NewJA2EncryptedFileRead;
|
|
}
|
|
|
|
if ( !(*pLoadingFunction)( hFile, &old, SIZEOF_OLD_MERCPROFILESTRUCT_101_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
*this = old;
|
|
}
|
|
//skip checksum
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN MERCPROFILESTRUCT::Save(HWFILE hFile)
|
|
{
|
|
//for now the MERCPROFILESTRUCT remains unchanged
|
|
//it does not have any data types that need their own saving function
|
|
//if that ever changes this will make updating saves easier
|
|
UINT32 uiNumBytesWritten;
|
|
this->uiProfileChecksum = this->GetChecksum();
|
|
if ( !FileWrite( hFile, this, SIZEOF_MERCPROFILESTRUCT_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
int size = inv.size();
|
|
if ( !FileWrite( hFile, &size, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
for (int x = 0; x < size; ++x) {
|
|
int item = inv[x];
|
|
int status = bInvStatus[x];
|
|
int number = bInvNumber[x];
|
|
if ( !FileWrite( hFile, &item, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &status, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &number, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN SOLDIERTYPE::Save(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
// calculate checksum for soldier
|
|
this->uiMercChecksum = this->GetChecksum();
|
|
if ( !FileWrite( hFile, this, SIZEOF_SOLDIERTYPE_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//save OO data like inventory
|
|
if ( !this->inv.Save(hFile, FALSE) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if ( !FileWrite( hFile, &this->aiData, sizeof(STRUCT_AIData), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->flags, sizeof(STRUCT_Flags), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->timeChanges, sizeof(STRUCT_TimeChanges), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->timeCounters, sizeof(STRUCT_TimeCounters), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->drugs, sizeof(STRUCT_Drugs), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &this->pathing, sizeof(STRUCT_Pathing), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
//the soldier type info has changed at version 102
|
|
//first, load the POD
|
|
if ( !FileRead( hFile, this, SIZEOF_SOLDIERTYPE_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//load the OO inventory
|
|
if ( !this->inv.Load(hFile) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//load some structs, atm just POD but could change
|
|
if ( !FileRead( hFile, &this->aiData, sizeof(STRUCT_AIData), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->flags, sizeof(STRUCT_Flags), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->timeChanges, sizeof(STRUCT_TimeChanges), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->timeCounters, sizeof(STRUCT_TimeCounters), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->drugs, sizeof(STRUCT_Drugs), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &this->pathing, sizeof(STRUCT_Pathing), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
// check checksum
|
|
if ( this->GetChecksum() != this->uiMercChecksum )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OLDSOLDIERTYPE_101 OldSavedSoldierInfo101;
|
|
//we are loading an older version (only load once, so use "else if")
|
|
//first load the data based on what version was stored
|
|
typedef BOOLEAN (*functionPtr) ( HWFILE hFile, PTR pDest, UINT32 uiBytesToRead, UINT32 *puiBytesRead );
|
|
functionPtr pLoadingFunction;
|
|
if ( guiCurrentSaveGameVersion < 87 )
|
|
{
|
|
pLoadingFunction = &JA2EncryptedFileRead;
|
|
}
|
|
else
|
|
{
|
|
pLoadingFunction = &NewJA2EncryptedFileRead;
|
|
}
|
|
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OldSavedSoldierInfo101.initialize();
|
|
if ( !(*pLoadingFunction)( hFile, &OldSavedSoldierInfo101, SIZEOF_OLDSOLDIERTYPE_101_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
/*
|
|
else if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
OldSavedSoldierInfo999.initialize();
|
|
(*pLoadingFunction)( hFile, &OldSavedSoldierInfo999, SIZEOF_OLDSOLDIERTYPE_999_POD, &uiNumBytesRead );
|
|
*/
|
|
|
|
//now we have the data that needs to be converted (keep on converting up, so use "if")
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
OldSavedSoldierInfo101.CopyOldInventoryToNew();
|
|
(*this) = OldSavedSoldierInfo101;
|
|
//OldSavedSoldierInfo999 = OldSavedSoldierInfo101;
|
|
}
|
|
//change this when changing the file version again
|
|
/*
|
|
if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
*this = OldSavedSoldierInfo999;
|
|
}
|
|
*/
|
|
//assume checksum is ok
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN WORLDITEM::Save(HWFILE hFile, bool fSavingMap)
|
|
{
|
|
//save the POD
|
|
UINT32 uiNumBytesWritten;
|
|
if ( !FileWrite( hFile, this, SIZEOF_WORLDITEM_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//save the OO OBJECTTYPE
|
|
if ( !this->object.Save(hFile, fSavingMap) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN WORLDITEM::Load(INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion)
|
|
{
|
|
//if we are at the most current MAP version, 5.0 and 27, then fine
|
|
if (dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 )
|
|
{
|
|
//load the POD
|
|
LOADDATA( this, *hBuffer, SIZEOF_WORLDITEM_POD );
|
|
|
|
//now load the OO OBJECTTYPE
|
|
this->object.Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
|
|
}
|
|
//if we need to load an older save
|
|
else {
|
|
//load the old data into a suitable structure, it's just POD
|
|
OLD_WORLDITEM_101 oldWorldItem;
|
|
LOADDATA( &oldWorldItem, *hBuffer, sizeof( OLD_WORLDITEM_101 ) );
|
|
*this = oldWorldItem;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN WORLDITEM::Load(HWFILE hFile)
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
//load the POD
|
|
if ( !FileRead( hFile, this, SIZEOF_WORLDITEM_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//now load the OO OBJECTTYPE
|
|
if ( !this->object.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
//if we need to load an older save
|
|
else {
|
|
//load the old data into a suitable structure, it's just POD
|
|
OLD_WORLDITEM_101 oldWorldItem;
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
if ( !FileRead( hFile, &oldWorldItem, sizeof(OLD_WORLDITEM_101), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
//now we have the data that needs to be converted (keep on converting up, so use "if")
|
|
//the first conversion is simple enough that it can be done here
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
*this = oldWorldItem;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN StackedObjectData::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion )
|
|
{
|
|
//when this function is called, the file has been loaded into a buffer using FileRead
|
|
//if we are at the most current version, then fine
|
|
//but we can also be loading this from a map that is up to date when the savegame isn't!
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION
|
|
|| (dMajorMapVersion == gdMajorMapVersion && gubMinorMapVersion == ubMinorMapVersion))
|
|
{
|
|
int size;
|
|
LOADDATA(&(this->data), *hBuffer, sizeof(ObjectData) );
|
|
LOADDATA(&size, *hBuffer, sizeof(int) );
|
|
attachments.resize(size);
|
|
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
|
|
if (! iter->Load( hBuffer, dMajorMapVersion, ubMinorMapVersion ) ) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//we shouldn't be loading this
|
|
Assert(false);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN StackedObjectData::Load( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, &(this->data), sizeof(ObjectData), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
int size;
|
|
if ( !FileRead( hFile, &size, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
attachments.resize(size);
|
|
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
|
|
if (! iter->Load(hFile) ) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//we shouldn't be loading this
|
|
Assert(false);
|
|
}
|
|
return TRUE;
|
|
}
|
|
BOOLEAN StackedObjectData::Save( HWFILE hFile, bool fSavingMap )
|
|
{
|
|
//if we are saving this to a map file it will be loaded with FileRead
|
|
UINT32 uiNumBytesWritten;
|
|
int size = 0;
|
|
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
|
|
if (iter->exists() == true) {
|
|
++size;
|
|
}
|
|
else {
|
|
//attachments should always exist, if they didn't they should have been removed from the list
|
|
DebugBreakpoint();
|
|
}
|
|
}
|
|
|
|
if ( !FileWrite( hFile, &(this->data), sizeof(ObjectData), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &size, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
|
|
if (iter->exists() == true) {
|
|
if (! iter->Save(hFile, fSavingMap)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN OBJECTTYPE::Load( HWFILE hFile )
|
|
{
|
|
|
|
UINT32 uiNumBytesRead;
|
|
//if we are at the most current version, then fine
|
|
if ( guiCurrentSaveGameVersion >= CURRENT_SAVEGAME_DATATYPE_VERSION )
|
|
{
|
|
if ( !FileRead( hFile, this, SIZEOF_OBJECTTYPE_POD, &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
int size;
|
|
if ( !FileRead( hFile, &size, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
objectStack.resize(size);
|
|
int x = 0;
|
|
for (StackedObjects::iterator iter = objectStack.begin(); iter != objectStack.end(); ++iter, ++x) {
|
|
if (! iter->Load(hFile)) {
|
|
return FALSE;
|
|
}
|
|
if (this->IsActiveLBE(x) == true) {
|
|
LBEArray.push_back(LBENODE());
|
|
if (! LBEArray.back().Load(hFile)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OLD_OBJECTTYPE_101 OldSavedObject101;
|
|
//we are loading an older version (only load once, so use "else if")
|
|
//first load the data based on what version was stored
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
if ( !FileRead( hFile, &OldSavedObject101, sizeof(OLD_OBJECTTYPE_101), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
/*
|
|
else if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
(*pLoadingFunction)( hFile, &OldSavedObject999, sizeof(OLD_OBJECTTYPE_999), &uiNumBytesRead );
|
|
*/
|
|
|
|
//now we have the data that needs to be converted (keep on converting up, so use "if")
|
|
if ( guiCurrentSaveGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
(*this) = OldSavedObject101;
|
|
//OldSavedObject999 = OldSavedObject101;
|
|
}
|
|
//change this when changing the file version again
|
|
/*
|
|
if ( guiCurrentSaveGameVersion < SECOND_SAVEGAME_DATATYPE_CHANGE )
|
|
{
|
|
(*this) = OldSavedObject999;
|
|
}
|
|
*/
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN OBJECTTYPE::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion )
|
|
{
|
|
//when this function is called, the file has been loaded into a buffer using FileRead
|
|
//if we are at the most current MAP version, 6.27, then fine
|
|
if (dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26 )
|
|
{
|
|
int size;
|
|
LOADDATA(this, *hBuffer, SIZEOF_OBJECTTYPE_POD );
|
|
LOADDATA(&size, *hBuffer, sizeof(int) );
|
|
objectStack.resize(size);
|
|
int x = 0;
|
|
for (StackedObjects::iterator iter = objectStack.begin(); iter != objectStack.end(); ++iter, ++x) {
|
|
iter->Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
|
|
if (this->IsActiveLBE(x) == true) {
|
|
LBEArray.push_back(LBENODE());
|
|
if (! LBEArray.back().Load(hBuffer, dMajorMapVersion, ubMinorMapVersion)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OLD_OBJECTTYPE_101 OldSavedObject101;
|
|
LOADDATA( &OldSavedObject101, *hBuffer, sizeof(OLD_OBJECTTYPE_101) );
|
|
(*this) = OldSavedObject101;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN OBJECTTYPE::Save( HWFILE hFile, bool fSavingMap )
|
|
{
|
|
//if we are saving this to a map file it will be loaded with FileRead
|
|
UINT32 uiNumBytesWritten;
|
|
int size = objectStack.size();
|
|
if ( !FileWrite( hFile, this, SIZEOF_OBJECTTYPE_POD, &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &size, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
int x = 0;
|
|
for (StackedObjects::iterator iter = objectStack.begin(); iter != objectStack.end(); ++iter, ++x) {
|
|
if (! iter->Save(hFile, fSavingMap)) {
|
|
return FALSE;
|
|
}
|
|
if (this->IsActiveLBE(x) == true) {
|
|
LBENODE* pLBE = this->GetLBEPointer(x);
|
|
if (! pLBE->Save(hFile, fSavingMap)) {
|
|
return FALSE;
|
|
}
|
|
//CHRISL: I've remarked this to resolve a problem when the autosave option is active where LBEArray info is
|
|
// lost and not rebuilt until after combat is over. This may not be the best way to resolve this, though,
|
|
// as ADB may well have had a valid reason to erase the LBEArray during saves.
|
|
/*
|
|
int uniqueID = (*this)[x]->data.lbe.uniqueID;
|
|
for (std::list<LBENODE>::iterator iter = LBEArray.begin(); iter != LBEArray.end(); ++iter) {
|
|
if (iter->uniqueID == uniqueID) {
|
|
LBEArray.erase(iter);
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN Inventory::Load( HWFILE hFile )
|
|
{
|
|
|
|
UINT32 uiNumBytesRead;
|
|
int sizeInventory;//how many items are in the stack?
|
|
if ( !FileRead( hFile, &sizeInventory, sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (sizeInventory < 0 || sizeInventory > NUM_INV_SLOTS)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
inv.resize(sizeInventory);
|
|
bNewItemCount.resize(sizeInventory);
|
|
bNewItemCycleCount.resize(sizeInventory);
|
|
for (int x = 0; x < sizeInventory; ++x) {
|
|
//load the OO OBJECTTYPE
|
|
if ( !inv[x].Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
UINT32 uiNumBytesRead;
|
|
if ( !FileRead( hFile, &bNewItemCount[x], sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileRead( hFile, &bNewItemCycleCount[x], sizeof(int), &uiNumBytesRead ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
return (TRUE);
|
|
}
|
|
|
|
BOOLEAN Inventory::Load(INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion)
|
|
{
|
|
int sizeInventory;
|
|
LOADDATA(&sizeInventory, *hBuffer, sizeof(int) );
|
|
if (sizeInventory < 0 || sizeInventory > NUM_INV_SLOTS)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
inv.resize(sizeInventory);
|
|
bNewItemCount.resize(sizeInventory);
|
|
bNewItemCycleCount.resize(sizeInventory);
|
|
|
|
for (int x = 0; x < sizeInventory; ++x) {
|
|
//load the OO OBJECTTYPE
|
|
if ( !inv[x].Load(hBuffer, dMajorMapVersion, ubMinorMapVersion) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
LOADDATA( &bNewItemCount[x], *hBuffer, sizeof(int) );
|
|
LOADDATA( &bNewItemCycleCount[x], *hBuffer, sizeof(int) );
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN Inventory::Save( HWFILE hFile, bool fSavingMap )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
int sizeInventory = size();//how many items are in the stack?
|
|
if ( !FileWrite( hFile, &sizeInventory, sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
for (int x = 0; x < sizeInventory; ++x) {
|
|
//save the OO OBJECTTYPE
|
|
if ( !inv[x].Save(hFile, fSavingMap) )
|
|
{
|
|
return (FALSE);
|
|
}
|
|
|
|
if ( !FileWrite( hFile, &(bNewItemCount[x]), sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if ( !FileWrite( hFile, &(bNewItemCycleCount[x]), sizeof(int), &uiNumBytesWritten ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Snap: Initializes gSaveDir global, creating the save directory if necessary
|
|
// The save directory now resides in the data directory (default or custom)
|
|
BOOLEAN InitSaveDir()
|
|
{
|
|
// Look for a custom data dir first
|
|
std::string dataDir = gCustomDataCat.GetRootDir();
|
|
if( dataDir.empty() || FileGetAttributes( (STR) dataDir.c_str() ) == 0xFFFFFFFF ) {
|
|
dataDir = gDefaultDataCat.GetRootDir();
|
|
}
|
|
|
|
// The locale-specific save dir location is of the form L"..\\SavedGames"
|
|
// This has not changed; instead, we strip the ".." at the beginning
|
|
sprintf( gSaveDir, "%s%S", dataDir.c_str(), pMessageStrings[ MSG_SAVEDIRECTORY ] + 2 );
|
|
|
|
// This was moved here from SaveGame
|
|
//Check to see if the save directory exists
|
|
if( FileGetAttributes( (STR) gSaveDir ) == 0xFFFFFFFF )
|
|
{
|
|
//ok the direcotry doesnt exist, create it
|
|
if( !MakeFileManDirectory( (CHAR8 *)gSaveDir ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc )
|
|
{
|
|
UINT32 uiNumBytesWritten=0;
|
|
HWFILE hFile=0;
|
|
SAVED_GAME_HEADER SaveGameHeader;
|
|
CHAR8 zSaveGameName[ MAX_PATH ];
|
|
//UINT8 saveDir[100];
|
|
BOOLEAN fPausedStateBeforeSaving = gfGamePaused;
|
|
BOOLEAN fLockPauseStateBeforeSaving = gfLockPauseState;
|
|
INT32 iSaveLoadGameMessageBoxID = -1;
|
|
UINT16 usPosX, usActualWidth, usActualHeight;
|
|
BOOLEAN fWePausedIt = FALSE;
|
|
|
|
|
|
//sprintf( saveDir, "%S", pMessageStrings[ MSG_SAVEDIRECTORY ] );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
#ifndef CRIPPLED_VERSION
|
|
//AssertMsg( uiSizeOfGeneralInfo == 1024, String( "Saved General info is NOT 1024, it is %d. DF 1.", uiSizeOfGeneralInfo ) );
|
|
//AssertMsg( sizeof( LaptopSaveInfoStruct ) == 7440, String( "LaptopSaveStruct is NOT 7440, it is %d. DF 1.", sizeof( LaptopSaveInfoStruct ) ) );
|
|
#endif
|
|
#endif
|
|
|
|
if( ubSaveGameID >= NUM_SAVE_GAMES && ubSaveGameID != SAVE__ERROR_NUM && ubSaveGameID != SAVE__END_TURN_NUM )
|
|
return( FALSE ); //ddd
|
|
|
|
//clear out the save game header
|
|
memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) );
|
|
|
|
if ( !GamePaused() )
|
|
{
|
|
PauseBeforeSaveGame();
|
|
fWePausedIt = TRUE;
|
|
}
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitShutDownMapTempFileTest( TRUE, "SaveMapTempFile", ubSaveGameID );
|
|
#endif
|
|
|
|
|
|
//Place a message on the screen telling the user that we are saving the game
|
|
iSaveLoadGameMessageBoxID = PrepareMercPopupBox( iSaveLoadGameMessageBoxID, BASIC_MERC_POPUP_BACKGROUND, BASIC_MERC_POPUP_BORDER, zSaveLoadText[ SLG_SAVING_GAME_MESSAGE ], 300, 0, 0, 0, &usActualWidth, &usActualHeight);
|
|
usPosX = ( SCREEN_WIDTH - usActualWidth ) / 2 ;
|
|
|
|
RenderMercPopUpBoxFromIndex( iSaveLoadGameMessageBoxID, usPosX, iScreenHeightOffset + 160, FRAME_BUFFER );
|
|
|
|
InvalidateRegion(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
|
|
|
|
ExecuteBaseDirtyRectQueue( );
|
|
EndFrameBufferRender( );
|
|
RefreshScreen( NULL );
|
|
|
|
if( RemoveMercPopupBoxFromIndex( iSaveLoadGameMessageBoxID ) )
|
|
{
|
|
iSaveLoadGameMessageBoxID = -1;
|
|
}
|
|
|
|
//
|
|
// make sure we redraw the screen when we are done
|
|
//
|
|
|
|
//if we are in the game screen
|
|
if( guiCurrentScreen == GAME_SCREEN )
|
|
{
|
|
SetRenderFlags( RENDER_FLAG_FULL );
|
|
}
|
|
|
|
else if( guiCurrentScreen == MAP_SCREEN )
|
|
{
|
|
fMapPanelDirty = TRUE;
|
|
fTeamPanelDirty = TRUE;
|
|
fCharacterInfoPanelDirty = TRUE;
|
|
}
|
|
|
|
else if( guiCurrentScreen == SAVE_LOAD_SCREEN )
|
|
{
|
|
gfRedrawSaveLoadScreen = TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
gubSaveGameLoc = ubSaveGameID;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitSaveGameFilePosition();
|
|
#endif
|
|
|
|
|
|
//Set the fact that we are saving a game
|
|
gTacticalStatus.uiFlags |= LOADING_SAVED_GAME;
|
|
|
|
|
|
//ADB this has been moved ahead of SaveCurrentSectorsInformationToTempItemFile
|
|
//there was a problem loading savegames if the savegame version changed, because
|
|
//the encryption algorithm uses the version of the header
|
|
//
|
|
// Setup the save game header
|
|
//
|
|
|
|
SaveGameHeader.uiSavedGameVersion = SAVE_GAME_VERSION;
|
|
wcscpy( SaveGameHeader.sSavedGameDesc, pGameDesc );
|
|
strcpy( SaveGameHeader.zGameVersionNumber, czVersionNumber );
|
|
|
|
SaveGameHeader.uiFlags;
|
|
|
|
//The following will be used to quickly access info to display in the save/load screen
|
|
SaveGameHeader.uiDay = GetWorldDay();
|
|
SaveGameHeader.ubHour = (UINT8)GetWorldHour();
|
|
SaveGameHeader.ubMin = (UINT8)guiMin;
|
|
|
|
//copy over the initial game options
|
|
memcpy( &SaveGameHeader.sInitialGameOptions, &gGameOptions, sizeof( GAME_OPTIONS ) );
|
|
|
|
|
|
SaveGameHeader.ubNumOfMercsOnPlayersTeam = NumberOfMercsOnPlayerTeam();
|
|
SaveGameHeader.iCurrentBalance = LaptopSaveInfo.iCurrentBalance;
|
|
|
|
|
|
SaveGameHeader.uiCurrentScreen = guiPreviousOptionScreen;
|
|
|
|
SaveGameHeader.fAlternateSector = GetSectorFlagStatus( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, SF_USE_ALTERNATE_MAP );
|
|
|
|
if( gfWorldLoaded )
|
|
{
|
|
SaveGameHeader.fWorldLoaded = TRUE;
|
|
SaveGameHeader.ubLoadScreenID = GetLoadScreenID( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
}
|
|
else
|
|
{
|
|
SaveGameHeader.fWorldLoaded = FALSE;
|
|
SaveGameHeader.ubLoadScreenID = 0;
|
|
}
|
|
|
|
SaveGameHeader.uiRandom = Random( RAND_MAX );
|
|
|
|
// CHRISL: We need to know what inventory system we're using early on
|
|
SaveGameHeader.ubInventorySystem = gGameOptions.ubInventorySystem;
|
|
|
|
//
|
|
// Save the Save Game header file
|
|
//
|
|
guiJA2EncryptionSet = CalcJA2EncryptionSet( &SaveGameHeader );
|
|
|
|
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("starting SaveCurrentSectorsInformationToTempItemFile" ) );
|
|
//Save the current sectors open temp files to the disk
|
|
if( !SaveCurrentSectorsInformationToTempItemFile() )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR in SaveCurrentSectorsInformationToTempItemFile()");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
|
|
|
|
//if we are saving the quick save,
|
|
if( ubSaveGameID == 0 )
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
//Increment the quicksave counter
|
|
guiCurrentQuickSaveNumber++;
|
|
|
|
if( gfUseConsecutiveQuickSaveSlots )
|
|
swprintf( pGameDesc, L"%s%03d", pMessageStrings[ MSG_QUICKSAVE_NAME ], guiCurrentQuickSaveNumber );
|
|
else
|
|
#endif
|
|
swprintf( pGameDesc, pMessageStrings[ MSG_QUICKSAVE_NAME ] );
|
|
wcscpy(SaveGameHeader.sSavedGameDesc, pGameDesc);
|
|
}
|
|
|
|
//If there was no string, add one
|
|
if( pGameDesc[0] == '\0' )
|
|
wcscpy( pGameDesc, pMessageStrings[ MSG_NODESC ] );
|
|
|
|
//Check to see if the save directory exists
|
|
/*if( FileGetAttributes( (STR) saveDir ) == 0xFFFFFFFF )
|
|
{
|
|
//ok the direcotry doesnt exist, create it
|
|
if( !MakeFileManDirectory( (CHAR8 *)saveDir ) )
|
|
{
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
}*/
|
|
|
|
//Create the name of the file
|
|
CreateSavedGameFileNameFromNumber( ubSaveGameID, zSaveGameName );
|
|
|
|
//if the file already exists, delete it
|
|
if( FileExists( zSaveGameName ) )
|
|
{
|
|
if( !FileDelete( zSaveGameName ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR deleting old save");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
}
|
|
|
|
// create the save game file
|
|
hFile = FileOpen( zSaveGameName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
|
|
if( !hFile )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR creating new save");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Just Opened File" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// If there are no enemy or civilians to save, we have to check BEFORE savinf the sector info struct because
|
|
// the NewWayOfSavingEnemyAndCivliansToTempFile will RESET the civ or enemy flag AFTER they have been saved.
|
|
//
|
|
NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE, TRUE );
|
|
NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE, TRUE );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Get the sector value to save.
|
|
GetBestPossibleSectorXYZValues( &SaveGameHeader.sSectorX, &SaveGameHeader.sSectorY, &SaveGameHeader.bSectorZ );
|
|
|
|
/*
|
|
|
|
//if the current sector is valid
|
|
if( gfWorldLoaded )
|
|
{
|
|
SaveGameHeader.sSectorX = gWorldSectorX;
|
|
SaveGameHeader.sSectorY = gWorldSectorY;
|
|
SaveGameHeader.bSectorZ = gbWorldSectorZ;
|
|
}
|
|
else if( Squad[ iCurrentTacticalSquad ][ 0 ] && iCurrentTacticalSquad != NO_CURRENT_SQUAD )
|
|
{
|
|
// if( Squad[ iCurrentTacticalSquad ][ 0 ]->bAssignment != IN_TRANSIT )
|
|
{
|
|
SaveGameHeader.sSectorX = Squad[ iCurrentTacticalSquad ][ 0 ]->sSectorX;
|
|
SaveGameHeader.sSectorY = Squad[ iCurrentTacticalSquad ][ 0 ]->sSectorY;
|
|
SaveGameHeader.bSectorZ = Squad[ iCurrentTacticalSquad ][ 0 ]->bSectorZ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT16 sSoldierCnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
INT16 bLastTeamID;
|
|
INT8 bCount=0;
|
|
BOOLEAN fFoundAMerc=FALSE;
|
|
|
|
// Set locator to first merc
|
|
sSoldierCnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
|
|
|
|
for ( pSoldier = MercPtrs[ sSoldierCnt ]; sSoldierCnt <= bLastTeamID; sSoldierCnt++,pSoldier++)
|
|
{
|
|
if( pSoldier->bActive )
|
|
{
|
|
if ( pSoldier->bAssignment != IN_TRANSIT && !pSoldier->flags.fBetweenSectors)
|
|
{
|
|
SaveGameHeader.sSectorX = pSoldier->sSectorX;
|
|
SaveGameHeader.sSectorY = pSoldier->sSectorY;
|
|
SaveGameHeader.bSectorZ = pSoldier->bSectorZ;
|
|
fFoundAMerc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !fFoundAMerc )
|
|
{
|
|
SaveGameHeader.sSectorX = gWorldSectorX;
|
|
SaveGameHeader.sSectorY = gWorldSectorY;
|
|
SaveGameHeader.bSectorZ = gbWorldSectorZ;
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
FileWrite( hFile, &SaveGameHeader, sizeof( SAVED_GAME_HEADER ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( SAVED_GAME_HEADER ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing save game header");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Save Game Header" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
//Save the gTactical Status array, plus the curent secotr location
|
|
//
|
|
if( !SaveTacticalStatusToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing tactical status");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Tactical Status" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// save the game clock info
|
|
if( !SaveGameClock( hFile, fPausedStateBeforeSaving, fLockPauseStateBeforeSaving ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing game clock");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Game Clock" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// save the strategic events
|
|
if( !SaveStrategicEventsToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic events");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Strategic Events" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveLaptopInfoToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing laptop info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Laptop Info" );
|
|
#endif
|
|
|
|
//
|
|
// Save the merc profiles
|
|
//
|
|
if( !SaveMercProfiles( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing merc profiles");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Merc Profiles" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
// Save the soldier structure
|
|
//
|
|
if( !SaveSoldierStructure( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing soldier structure");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Soldier Structure" );
|
|
#endif
|
|
|
|
|
|
//Save the Finaces Data file
|
|
if( !SaveFilesToSavedGame( FINANCES_DATA_FILE, hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing finances");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Finances Data File" );
|
|
#endif
|
|
|
|
|
|
|
|
//Save the history file
|
|
if( !SaveFilesToSavedGame( HISTORY_DATA_FILE, hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing history");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "History file" );
|
|
#endif
|
|
|
|
|
|
|
|
//Save the Laptop File file
|
|
if( !SaveFilesToSavedGame( FILES_DAT_FILE, hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing laptop files");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "The Laptop FILES file" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//Save email stuff to save file
|
|
if( !SaveEmailToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing email");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Email " );
|
|
#endif
|
|
|
|
|
|
|
|
//Save the strategic information
|
|
if( !SaveStrategicInfoToSavedFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Strategic Information" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//save the underground information
|
|
if( !SaveUnderGroundSectorInfoToSaveGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing underground info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Underground Information" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//save the squad info
|
|
if( !SaveSquadInfoToSavedGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing squad info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Squad Info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if( !SaveStrategicMovementGroupsToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic movements");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Strategic Movement Groups" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//Save all the map temp files from the maps\temp directory into the saved game file
|
|
if( !SaveMapTempFilesToSavedGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing map temp files");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "All the Map Temp files" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveQuestInfoToSavedGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing quest info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Quest Info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if( !SaveOppListInfoToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing opplist");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "OppList info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveMapScreenMessagesToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing map screen messages");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "MapScreen Messages" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveNPCInfoToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing NPC info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "NPC Info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveKeyTableToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing key table");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "KeyTable" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if( !SaveTempNpcQuoteArrayToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing NPC quotes");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "NPC Temp Quote File" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SavePreRandomNumbersToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing pre random numbers");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "PreGenerated Random Files" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveSmokeEffectsToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing smoke effects");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Smoke Effect Structures" );
|
|
#endif
|
|
|
|
|
|
if( !SaveArmsDealerInventoryToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing arms dealer inventory");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Arms Dealers Inventory" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if( !SaveGeneralInfo( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR general info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Misc. Info" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveMineStatusToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing mine status");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Mine Status" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if( !SaveStrategicTownLoyaltyToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing town loyalty");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Town Loyalty" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveVehicleInformationToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing vehicle info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Vehicle Information" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveBulletStructureToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing bullet structure");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Bullet Information" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SavePhysicsTableToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing physics table");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Physics Table" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if( !SaveAirRaidInfoToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing air raid info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Air Raid Info" );
|
|
#endif
|
|
|
|
|
|
if( !SaveTeamTurnsToTheSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing team turns");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Team Turn Info" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveExplosionTableToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing explosions");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Explosion Table" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveCreatureDirectives( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing creature directives");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Creature Spreading" );
|
|
#endif
|
|
|
|
|
|
if( !SaveStrategicStatusToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic status");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Strategic Status" );
|
|
#endif
|
|
|
|
|
|
|
|
if( !SaveStrategicAI( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic AI");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Strategic AI" );
|
|
#endif
|
|
|
|
|
|
if( !SaveLightEffectsToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing light effects");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Lighting Effects" );
|
|
#endif
|
|
|
|
|
|
if( !SaveWatchedLocsToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing watched locs");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Watched Locs Info" );
|
|
#endif
|
|
|
|
if( !SaveItemCursorToSavedGame( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing item cursor");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "ItemCursor Info" );
|
|
#endif
|
|
|
|
if( !SaveCivQuotesToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing civ quotes");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Civ Quote System" );
|
|
#endif
|
|
|
|
if( !SaveBackupNPCInfoToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing backup NPC info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Backed up NPC Info" );
|
|
#endif
|
|
|
|
if ( !SaveMeanwhileDefsFromSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing meanwhiles");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Meanwhile Definitions" );
|
|
#endif
|
|
|
|
// save meanwhiledefs
|
|
|
|
if ( !SaveSchedules( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing schedules");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Schedules" );
|
|
#endif
|
|
|
|
// Save extra vehicle info
|
|
if ( !NewSaveVehicleMovementInfoToSavedGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing vehicle movement info");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Vehicle Movement Stuff" );
|
|
#endif
|
|
|
|
|
|
// Save contract renewal sequence stuff
|
|
if ( !SaveContractRenewalDataToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing contract renewal");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Contract Renewal Data" );
|
|
#endif
|
|
|
|
|
|
// Save leave list stuff
|
|
if ( !SaveLeaveItemList( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing leave items list");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "leave list" );
|
|
#endif
|
|
|
|
|
|
//do the new way of saving bobbyr mail order items
|
|
if( !NewWayOfSavingBobbyRMailOrdersToSaveGameFile( hFile ) )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing mail orders");
|
|
goto FAILED_TO_SAVE;
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "New way of saving Bobby R mailorders" );
|
|
#endif
|
|
|
|
|
|
|
|
//Close the saved game file
|
|
FileClose( hFile );
|
|
|
|
|
|
//if we succesfully saved the game, mark this entry as the last saved game file
|
|
if( ubSaveGameID != SAVE__ERROR_NUM && ubSaveGameID != SAVE__END_TURN_NUM )
|
|
{
|
|
gGameSettings.bLastSavedGameSlot = ubSaveGameID;
|
|
}
|
|
|
|
//Save the save game settings
|
|
SaveGameSettings();
|
|
|
|
//
|
|
// Display a screen message that the save was succesful
|
|
//
|
|
|
|
//if its the quick save slot
|
|
if( ubSaveGameID == 0 )
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, pMessageStrings[ MSG_SAVESUCCESS ] );
|
|
}
|
|
//#ifdef JA2BETAVERSION
|
|
else if( ubSaveGameID == SAVE__END_TURN_NUM )
|
|
{
|
|
// ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, pMessageStrings[ MSG_END_TURN_AUTO_SAVE ] );
|
|
}
|
|
//#endif
|
|
else
|
|
{
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, pMessageStrings[ MSG_SAVESLOTSUCCESS ] );
|
|
}
|
|
|
|
//restore the music mode
|
|
SetMusicMode( gubMusicMode );
|
|
|
|
//Unset the fact that we are saving a game
|
|
gTacticalStatus.uiFlags &= ~LOADING_SAVED_GAME;
|
|
|
|
UnPauseAfterSaveGame();
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitShutDownMapTempFileTest( FALSE, "SaveMapTempFile", ubSaveGameID );
|
|
#endif
|
|
|
|
#ifdef JA2BETAVERSION
|
|
ValidateSoldierInitLinks( 2 );
|
|
#endif
|
|
|
|
//Check for enough free hard drive space
|
|
NextLoopCheckForEnoughFreeHardDriveSpace();
|
|
|
|
return( TRUE );
|
|
|
|
//if there is an error saving the game
|
|
FAILED_TO_SAVE:
|
|
|
|
#ifdef JA2BETAVERSION
|
|
SaveGameFilePosition( FileGetPos( hFile ), "Failed to Save!!!" );
|
|
#endif
|
|
|
|
FileClose( hFile );
|
|
|
|
if ( fWePausedIt )
|
|
{
|
|
UnPauseAfterSaveGame();
|
|
}
|
|
|
|
//Delete the failed attempt at saving
|
|
#if 0
|
|
// 0verhaul: Temporarily disabled to try to troubleshoot save game problems
|
|
DeleteSaveGameNumber( ubSaveGameID );
|
|
#endif
|
|
|
|
//Put out an error message
|
|
ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, zSaveLoadText[SLG_SAVE_GAME_ERROR] );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitShutDownMapTempFileTest( FALSE, "SaveMapTempFile", ubSaveGameID );
|
|
#endif
|
|
|
|
//Check for enough free hard drive space
|
|
NextLoopCheckForEnoughFreeHardDriveSpace();
|
|
|
|
#ifdef JA2BETAVERSION
|
|
if( fDisableDueToBattleRoster || fDisableMapInterfaceDueToBattle )
|
|
{
|
|
gubReportMapscreenLock = 2;
|
|
}
|
|
#endif
|
|
|
|
Assert(guiCurrentSaveGameVersion == SAVE_GAME_VERSION);
|
|
guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
|
|
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
UINT32 guiBrokenSaveGameVersion = 0;
|
|
extern int gEnemyPreservedTempFileVersion[256];
|
|
extern int gCivPreservedTempFileVersion[256];
|
|
|
|
BOOLEAN LoadSavedGame( UINT8 ubSavedGameID )
|
|
{
|
|
HWFILE hFile;
|
|
SAVED_GAME_HEADER SaveGameHeader;
|
|
UINT32 uiNumBytesRead=0;
|
|
|
|
INT16 sLoadSectorX;
|
|
INT16 sLoadSectorY;
|
|
INT8 bLoadSectorZ;
|
|
CHAR8 zSaveGameName[ MAX_PATH ];
|
|
UINT32 uiRelStartPerc;
|
|
UINT32 uiRelEndPerc;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
gfDisplaySaveGamesNowInvalidatedMsg = FALSE;
|
|
#endif
|
|
|
|
uiRelStartPerc = uiRelEndPerc =0;
|
|
|
|
TrashAllSoldiers( );
|
|
|
|
//Empty the dialogue Queue cause someone could still have a quote in waiting
|
|
EmptyDialogueQueue( );
|
|
|
|
//If there is someone talking, stop them
|
|
StopAnyCurrentlyTalkingSpeech( );
|
|
|
|
ZeroAnimSurfaceCounts( );
|
|
|
|
ShutdownNPCQuotes();
|
|
|
|
//very small TODO
|
|
//Bugfix = Stop the chopter sound
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//AssertMsg( uiSizeOfGeneralInfo == 1024, String( "Saved General info is NOT 1024, it is %d. DF 1.", uiSizeOfGeneralInfo ) );
|
|
#endif
|
|
|
|
//is it a valid save number
|
|
if( ubSavedGameID >= NUM_SAVE_GAMES )
|
|
{
|
|
if( ubSavedGameID != SAVE__END_TURN_NUM )
|
|
return( FALSE );
|
|
}
|
|
else if( !gbSaveGameArray[ ubSavedGameID ] )
|
|
return( FALSE );
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitShutDownMapTempFileTest( TRUE, "LoadMapTempFile", ubSavedGameID );
|
|
#endif
|
|
|
|
|
|
//Used in mapescreen to disable the annoying 'swoosh' transitions
|
|
gfDontStartTransitionFromLaptop = TRUE;
|
|
|
|
// Reset timer callbacks
|
|
gpCustomizableTimerCallback = NULL;
|
|
|
|
gubSaveGameLoc = ubSavedGameID;
|
|
#ifdef JA2BETAVERSION
|
|
InitLoadGameFilePosition();
|
|
#endif
|
|
|
|
//Set the fact that we are loading a saved game
|
|
gTacticalStatus.uiFlags |= LOADING_SAVED_GAME;
|
|
|
|
//Trash the existing world. This is done to ensure that if we are loading a game that doesn't have
|
|
//a world loaded, that we trash it beforehand -- else the player could theoretically enter that sector
|
|
//where it would be in a pre-load state.
|
|
TrashWorld();
|
|
|
|
// Lesh: To kill memory leaks during re-loading a saved game
|
|
// release strategic layer resources
|
|
ShutdownStrategicLayer();
|
|
FreeGlobalMessageList();
|
|
|
|
//Deletes all the Temp files in the Maps\Temp directory
|
|
InitTacticalSave( TRUE );
|
|
|
|
// ATE; Added to empry dialogue q
|
|
EmptyDialogueQueue( );
|
|
|
|
//Create the name of the file
|
|
CreateSavedGameFileNameFromNumber( ubSavedGameID, zSaveGameName );
|
|
|
|
// open the save game file
|
|
hFile = FileOpen( zSaveGameName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
|
|
if( !hFile )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FileOpen failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Just Opened File" );
|
|
#endif
|
|
|
|
|
|
//Load the Save Game header file
|
|
FileRead( hFile, &SaveGameHeader, sizeof( SAVED_GAME_HEADER ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( SAVED_GAME_HEADER ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Loading Save Game Header failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Save Game Header" );
|
|
#endif
|
|
|
|
guiJA2EncryptionSet = CalcJA2EncryptionSet( &SaveGameHeader );
|
|
guiCurrentSaveGameVersion = SaveGameHeader.uiSavedGameVersion;
|
|
guiBrokenSaveGameVersion = SaveGameHeader.uiSavedGameVersion;
|
|
|
|
// CHRISL: We need to know what inventory system we're using early on
|
|
if(SaveGameHeader.uiSavedGameVersion < FIRST_SAVEGAME_DATATYPE_CHANGE)
|
|
SaveGameHeader.ubInventorySystem = 0;
|
|
gGameOptions.ubInventorySystem = SaveGameHeader.ubInventorySystem;
|
|
if((UsingNewInventorySystem() == true))
|
|
{
|
|
if(iResolution == 0 || gCustomDataCat.GetRootDir() == ""){
|
|
// Only load NewInv in higher screen res
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
InitInventoryNew();
|
|
InitNewInventorySystem();
|
|
InitializeSMPanelCoordsNew();
|
|
InitializeInvPanelCoordsNew();
|
|
}
|
|
else
|
|
{
|
|
InitInventoryOld();
|
|
InitOldInventorySystem();
|
|
InitializeSMPanelCoordsOld();
|
|
InitializeInvPanelCoordsOld();
|
|
}
|
|
|
|
//if the player is loading up an older version of the game, and the person DOESNT have the cheats on,
|
|
if( guiCurrentSaveGameVersion < 65 && !CHEATER_CHEAT_LEVEL( ) )
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
gfDisplaySaveGamesNowInvalidatedMsg = TRUE;
|
|
#endif
|
|
//Fail loading the save
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
|
|
//Store the loading screenID that was saved
|
|
gubLastLoadingScreenID = SaveGameHeader.ubLoadScreenID;
|
|
|
|
|
|
/*
|
|
if( !LoadGeneralInfo( hFile ) )
|
|
{
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Misc info" );
|
|
#endif
|
|
*/
|
|
|
|
|
|
|
|
//Load the gtactical status structure plus the current sector x,y,z
|
|
if( !LoadTacticalStatusFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadTacticalStatusFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Tactical Status" );
|
|
#endif
|
|
|
|
|
|
//This gets reset by the above function
|
|
gTacticalStatus.uiFlags |= LOADING_SAVED_GAME;
|
|
|
|
|
|
//Load the game clock ingo
|
|
if( !LoadGameClock( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadGameClock failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Game Clock" );
|
|
#endif
|
|
|
|
|
|
//if we are suppose to use the alternate sector
|
|
if( SaveGameHeader.fAlternateSector )
|
|
{
|
|
SetSectorFlag( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, SF_USE_ALTERNATE_MAP );
|
|
gfUseAlternateMap = TRUE;
|
|
}
|
|
|
|
|
|
for (int x = 0; x < 256; ++x) {
|
|
gEnemyPreservedTempFileVersion[x] = guiCurrentSaveGameVersion;
|
|
gCivPreservedTempFileVersion[x] = guiCurrentSaveGameVersion;
|
|
}
|
|
|
|
//if the world was loaded when saved, reload it, otherwise dont
|
|
if( SaveGameHeader.fWorldLoaded || guiCurrentSaveGameVersion < 50 )
|
|
{
|
|
//Get the current world sector coordinates
|
|
sLoadSectorX = gWorldSectorX;
|
|
sLoadSectorY = gWorldSectorY;
|
|
bLoadSectorZ = gbWorldSectorZ;
|
|
|
|
// This will guarantee that the sector will be loaded
|
|
gbWorldSectorZ = -1;
|
|
|
|
|
|
//if we should load a sector ( if the person didnt just start the game game )
|
|
if( ( gWorldSectorX != 0 ) && ( gWorldSectorY != 0 ) )
|
|
{
|
|
//Load the sector
|
|
SetCurrentWorldSector( sLoadSectorX, sLoadSectorY, bLoadSectorZ );
|
|
}
|
|
}
|
|
else
|
|
{ //By clearing these values, we can avoid "in sector" checks -- at least, that's the theory.
|
|
gWorldSectorX = gWorldSectorY = 0;
|
|
|
|
//Since there is no
|
|
if( SaveGameHeader.sSectorX == -1 || SaveGameHeader.sSectorY == -1 || SaveGameHeader.bSectorZ == -1 )
|
|
gubLastLoadingScreenID = LOADINGSCREEN_HELI;
|
|
else
|
|
gubLastLoadingScreenID = GetLoadScreenID( SaveGameHeader.sSectorX, SaveGameHeader.sSectorY, SaveGameHeader.bSectorZ );
|
|
|
|
BeginLoadScreen();
|
|
}
|
|
|
|
CreateLoadingScreenProgressBar();
|
|
SetProgressBarColor( 0, 0, 0, 150 );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//set the font
|
|
SetProgressBarMsgAttributes( 0, FONT12ARIAL, FONT_MCOLOR_WHITE, 0 );
|
|
|
|
//
|
|
// Set the tile so we don see the text come up
|
|
//
|
|
|
|
//if the world is unloaded, we must use the save buffer for the text
|
|
if( SaveGameHeader.fWorldLoaded )
|
|
SetProgressBarTextDisplayFlag( 0, TRUE, TRUE, FALSE );
|
|
else
|
|
SetProgressBarTextDisplayFlag( 0, TRUE, TRUE, TRUE );
|
|
#endif
|
|
|
|
uiRelStartPerc = 0;
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Strategic Events..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
//load the game events
|
|
if( !LoadStrategicEventsFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicEventsFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Strategic Events" );
|
|
#endif
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Laptop Info" );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadLaptopInfoFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadLaptopInfoFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Laptop Info" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Merc Profiles..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
//
|
|
// Load all the saved Merc profiles
|
|
//
|
|
if( !LoadSavedMercProfiles( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadSavedMercProfiles failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Merc Profiles" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 30;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Soldier Structure..." );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//
|
|
// Load the soldier structure info
|
|
//
|
|
if( !LoadSoldierStructure( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadSoldierStructure failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Soldier Structure" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Finances Data File..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//
|
|
// Load the Finances Data and write it to a new file
|
|
//
|
|
if( !LoadFilesFromSavedGame( FINANCES_DATA_FILE, hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadFilesFromSavedGame FINANCES_DATA_FILE failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Finances Data File" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"History File..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//
|
|
// Load the History Data and write it to a new file
|
|
//
|
|
if( !LoadFilesFromSavedGame( HISTORY_DATA_FILE, hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadFilesFromSavedGame HISTORY_DATA_FILE failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "History File" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"The Laptop FILES file..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//
|
|
// Load the Files Data and write it to a new file
|
|
//
|
|
if( !LoadFilesFromSavedGame( FILES_DAT_FILE, hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadFilesFromSavedGame FILES_DAT_FILE failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "The Laptop FILES file" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Email..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
// Load the data for the emails
|
|
if( !LoadEmailFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadEmailFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Email" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Strategic Information..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
//Load the strategic Information
|
|
if( !LoadStrategicInfoFromSavedFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicInfoFromSavedFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Strategic Information" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"UnderGround Information..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//Load the underground information
|
|
if( !LoadUnderGroundSectorInfoFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadUnderGroundSectorInfoFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "UnderGround Information" );
|
|
#endif
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Squad Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
// Load all the squad info from the saved game file
|
|
if( !LoadSquadInfoFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadSquadInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Squad Info" );
|
|
#endif
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Strategic Movement Groups..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//Load the group linked list
|
|
if( !LoadStrategicMovementGroupsFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicMovementGroupsFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Strategic Movement Groups" );
|
|
#endif
|
|
|
|
|
|
uiRelEndPerc += 30;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"All the Map Temp files..." );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
// Load all the map temp files from the saved game file into the maps\temp directory
|
|
if( !LoadMapTempFilesFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadMapTempFilesFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "All the Map Temp files" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Quest Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadQuestInfoFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadQuestInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Quest Info" );
|
|
#endif
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"OppList Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
if( !LoadOppListInfoFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadOppListInfoFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "OppList Info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"MapScreen Messages..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadMapScreenMessagesFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadMapScreenMessagesFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "MapScreen Messages" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"NPC Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadNPCInfoFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadNPCInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "NPC Info" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"KeyTable..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadKeyTableFromSaveedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadKeyTableFromSaveedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "KeyTable" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Npc Temp Quote File..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
if( !LoadTempNpcQuoteArrayToSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadTempNpcQuoteArrayToSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Npc Temp Quote File" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"PreGenerated Random Files..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
if( !LoadPreRandomNumbersFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadPreRandomNumbersFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "PreGenerated Random Files" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Smoke Effect Structures..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadSmokeEffectsFromLoadGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadSmokeEffectsFromLoadGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Smoke Effect Structures" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Arms Dealers Inventory..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadArmsDealerInventoryFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadArmsDealerInventoryFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Arms Dealers Inventory" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Misc info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
if( !LoadGeneralInfo( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadGeneralInfo failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Misc info" );
|
|
#endif
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Mine Status..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( !LoadMineStatusFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadMineStatusFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Mine Status" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Town Loyalty..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 21 )
|
|
{
|
|
if( !LoadStrategicTownLoyaltyFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicTownLoyaltyFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Town Loyalty" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Vehicle Information..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 22 )
|
|
{
|
|
if( !LoadVehicleInformationFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadVehicleInformationFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Vehicle Information" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Bullet Information..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 24 )
|
|
{
|
|
if( !LoadBulletStructureFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadBulletStructureFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Bullet Information" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Physics table..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 24 )
|
|
{
|
|
if( !LoadPhysicsTableFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadPhysicsTableFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Physics table" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Air Raid Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 24 )
|
|
{
|
|
if( !LoadAirRaidInfoFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadAirRaidInfoFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Air Raid Info" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 0;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Team Turn Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 24 )
|
|
{
|
|
if( !LoadTeamTurnsFromTheSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadTeamTurnsFromTheSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Team Turn Info" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Explosion Table..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 25 )
|
|
{
|
|
if( !LoadExplosionTableFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadExplosionTableFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Explosion Table" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Creature Spreading..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 27 )
|
|
{
|
|
if( !LoadCreatureDirectives( hFile, guiCurrentSaveGameVersion ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadCreatureDirectives failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Creature Spreading" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Strategic Status..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 28 )
|
|
{
|
|
if( !LoadStrategicStatusFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicStatusFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Strategic Status" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Strategic AI..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 31 )
|
|
{
|
|
if( !LoadStrategicAI( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicAI failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Strategic AI" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Lighting Effects..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 37 )
|
|
{
|
|
if( !LoadLightEffectsFromLoadGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadLightEffectsFromLoadGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return(FALSE);
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Lighting Effects" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Watched Locs Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 38 )
|
|
{
|
|
if ( !LoadWatchedLocsFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadWatchedLocsFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Watched Locs Info" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Item cursor Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 39 )
|
|
{
|
|
if ( !LoadItemCursorFromSavedGame( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadItemCursorFromSavedGame failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Item cursor Info" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Civ Quote System..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 51 )
|
|
{
|
|
if( !LoadCivQuotesFromLoadGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadCivQuotesFromLoadGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return FALSE;
|
|
}
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Civ Quote System" );
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Backed up NPC Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 53 )
|
|
{
|
|
if( !LoadBackupNPCInfoFromSavedGameFile( hFile, guiCurrentSaveGameVersion ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadBackupNPCInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Backed up NPC Info" );
|
|
#endif
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Meanwhile definitions..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 58 )
|
|
{
|
|
if( !LoadMeanwhileDefsFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadMeanwhileDefsFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Meanwhile definitions" );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
memcpy( &gMeanwhileDef[gCurrentMeanwhileDef.ubMeanwhileID], &gCurrentMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) );
|
|
}
|
|
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Schedules..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 59 )
|
|
{
|
|
// trash schedules loaded from map
|
|
DestroyAllSchedulesWithoutDestroyingEvents();
|
|
if ( !LoadSchedulesFromSave( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadSchedulesFromSave failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Schedules" );
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Extra Vehicle Info..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 61 )
|
|
{
|
|
if( guiCurrentSaveGameVersion < 84 )
|
|
{
|
|
if ( !LoadVehicleMovementInfoFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadVehicleMovementInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Extra Vehicle Info" );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if ( !NewLoadVehicleMovementInfoFromSavedGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("NewLoadVehicleMovementInfoFromSavedGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Extra Vehicle Info" );
|
|
#endif
|
|
}
|
|
}
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Contract renweal sequence stuff..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
if( guiCurrentSaveGameVersion < 62 )
|
|
{
|
|
// the older games had a bug where this flag was never being set
|
|
gfResetAllPlayerKnowsEnemiesFlags = TRUE;
|
|
}
|
|
|
|
if( guiCurrentSaveGameVersion >= 67 )
|
|
{
|
|
if ( !LoadContractRenewalDataFromSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadContractRenewalDataFromSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Contract renweal sequence stuff" );
|
|
#endif
|
|
}
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 70 )
|
|
{
|
|
if ( !LoadLeaveItemList( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadLeaveItemList failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "Leave List" );
|
|
#endif
|
|
}
|
|
|
|
if( guiCurrentSaveGameVersion <= 73 )
|
|
{
|
|
// Patch vehicle fuel
|
|
AddVehicleFuelToSave( );
|
|
}
|
|
|
|
|
|
if( guiCurrentSaveGameVersion >= 85 )
|
|
{
|
|
if ( !NewWayOfLoadingBobbyRMailOrdersToSaveGameFile( hFile ) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("NewWayOfLoadingBobbyRMailOrdersToSaveGameFile failed" ) );
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
#ifdef JA2BETAVERSION
|
|
LoadGameFilePosition( FileGetPos( hFile ), "New way of loading Bobby R mailorders" );
|
|
#endif
|
|
}
|
|
|
|
//If there are any old Bobby R Mail orders, tranfer them to the new system
|
|
if( guiCurrentSaveGameVersion < 85 )
|
|
{
|
|
HandleOldBobbyRMailOrders();
|
|
}
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
|
|
//
|
|
//Close the saved game file
|
|
//
|
|
FileClose( hFile );
|
|
|
|
// ATE: Patch? Patch up groups.....( will only do for old saves.. )
|
|
UpdatePersistantGroupsFromOldSave( guiCurrentSaveGameVersion );
|
|
|
|
|
|
if( guiCurrentSaveGameVersion <= 40 )
|
|
{
|
|
// Cancel all pending purchase orders for BobbyRay's. Starting with version 41, the BR orders events are
|
|
// posted with the usItemIndex itself as the parameter, rather than the inventory slot index. This was
|
|
// done to make it easier to modify BR's traded inventory lists later on without breaking saves.
|
|
CancelAllPendingBRPurchaseOrders();
|
|
}
|
|
|
|
|
|
//if the world is loaded, apply the temp files to the loaded map
|
|
if( SaveGameHeader.fWorldLoaded || guiCurrentSaveGameVersion < 50 )
|
|
{
|
|
//the current sector has been updated, we need to temporarily change the game version we are loading!
|
|
UINT32 tempVersion = guiCurrentSaveGameVersion;
|
|
guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
|
|
|
|
// Load the current sectors Information From the temporary files
|
|
if( !LoadCurrentSectorsInformationFromTempItemsFile() )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadCurrentSectorsInformationFromTempItemsFile failed" ) );
|
|
InitExitGameDialogBecauseFileHackDetected();
|
|
return( TRUE );
|
|
}
|
|
guiCurrentSaveGameVersion = tempVersion;
|
|
}
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
InitAI();
|
|
|
|
//Update the mercs in the sector with the new soldier info
|
|
UpdateMercsInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
|
|
|
//ReconnectSchedules();
|
|
PostSchedules();
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//Reset the lighting level if we are outside
|
|
if( gbWorldSectorZ == 0 )
|
|
LightSetBaseLevel( GetTimeOfDayAmbientLightLevel() );
|
|
|
|
//if we have been to this sector before
|
|
// if( SectorInfo[ SECTOR( gWorldSectorX,gWorldSectorY) ].uiFlags & SF_ALREADY_VISITED )
|
|
{
|
|
//Reset the fact that we are loading a saved game
|
|
gTacticalStatus.uiFlags &= ~LOADING_SAVED_GAME;
|
|
}
|
|
|
|
// CJC January 13: we can't do this because (a) it resets militia IN THE MIDDLE OF
|
|
// COMBAT, and (b) if we add militia to the teams while LOADING_SAVED_GAME is set,
|
|
// the team counters will not be updated properly!!!
|
|
// ResetMilitia();
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
//if the UI was locked in the saved game file
|
|
if( gTacticalStatus.ubAttackBusyCount > 1 )
|
|
{
|
|
//Lock the ui
|
|
SetUIBusy( (UINT8)gusSelectedSoldier );
|
|
}
|
|
|
|
//Reset the shadow
|
|
SetFontShadow( DEFAULT_SHADOW );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//AssertMsg( uiSizeOfGeneralInfo == 1024, String( "Saved General info is NOT 1024, it is %d. DF 1.", uiSizeOfGeneralInfo ) );
|
|
#endif
|
|
|
|
//if we succesfully LOADED! the game, mark this entry as the last saved game file
|
|
gGameSettings.bLastSavedGameSlot = ubSavedGameID;
|
|
|
|
//Save the save game settings
|
|
SaveGameSettings();
|
|
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
//Reset the Ai Timer clock
|
|
giRTAILastUpdateTime = 0;
|
|
|
|
//if we are in tactical
|
|
if( guiScreenToGotoAfterLoadingSavedGame == GAME_SCREEN )
|
|
{
|
|
//Initialize the current panel
|
|
InitializeCurrentPanel( );
|
|
|
|
SelectSoldier( gusSelectedSoldier, FALSE, TRUE );
|
|
}
|
|
|
|
uiRelEndPerc += 1;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
|
|
RenderProgressBar( 0, 100 );
|
|
uiRelStartPerc = uiRelEndPerc;
|
|
|
|
|
|
// init extern faces
|
|
InitalizeStaticExternalNPCFaces( );
|
|
|
|
// load portraits
|
|
LoadCarPortraitValues( );
|
|
|
|
// OK, turn OFF show all enemies....
|
|
gTacticalStatus.uiFlags&= (~SHOW_ALL_MERCS );
|
|
gTacticalStatus.uiFlags &= ~SHOW_ALL_ITEMS ;
|
|
|
|
#ifdef JA2BETAVERSION
|
|
InitShutDownMapTempFileTest( FALSE, "LoadMapTempFile", ubSavedGameID );
|
|
#endif
|
|
|
|
if ( (gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Setting attack busy count to 0 from load" ) );
|
|
#ifdef DEBUG_ATTACKBUSY
|
|
OutputDebugString( "Resetting attack busy due to load game.\n");
|
|
#endif
|
|
gTacticalStatus.ubAttackBusyCount = 0;
|
|
}
|
|
|
|
if( guiCurrentSaveGameVersion < 64 )
|
|
{ //Militia/enemies/creature team sizes have been changed from 32 to 20. This function
|
|
//will simply kill off the excess. This will allow the ability to load previous saves, though
|
|
//there will still be problems, though a LOT less than there would be without this call.
|
|
TruncateStrategicGroupSizes();
|
|
}
|
|
|
|
// ATE: if we are within this window where skyridder was foobared, fix!
|
|
if ( guiCurrentSaveGameVersion >= 61 && guiCurrentSaveGameVersion <= 65 )
|
|
{
|
|
SOLDIERTYPE *pSoldier;
|
|
MERCPROFILESTRUCT *pProfile;
|
|
|
|
if ( !fSkyRiderSetUp )
|
|
{
|
|
// see if we can find him and remove him if so....
|
|
pSoldier = FindSoldierByProfileID( SKYRIDER, FALSE );
|
|
|
|
if ( pSoldier != NULL )
|
|
{
|
|
TacticalRemoveSoldier( pSoldier->ubID );
|
|
}
|
|
|
|
// add the pilot at a random location!
|
|
pProfile = &(gMercProfiles[ SKYRIDER ]);
|
|
switch( Random( 4 ) )
|
|
{
|
|
case 0:
|
|
pProfile->sSectorX = 15;
|
|
pProfile->sSectorY = MAP_ROW_B;
|
|
pProfile->bSectorZ = 0;
|
|
break;
|
|
case 1:
|
|
pProfile->sSectorX = 14;
|
|
pProfile->sSectorY = MAP_ROW_E;
|
|
pProfile->bSectorZ = 0;
|
|
break;
|
|
case 2:
|
|
pProfile->sSectorX = 12;
|
|
pProfile->sSectorY = MAP_ROW_D;
|
|
pProfile->bSectorZ = 0;
|
|
break;
|
|
case 3:
|
|
pProfile->sSectorX = 16;
|
|
pProfile->sSectorY = MAP_ROW_C;
|
|
pProfile->bSectorZ = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( guiCurrentSaveGameVersion < 68 )
|
|
{
|
|
// correct bVehicleUnderRepairID for all mercs
|
|
UINT8 ubID;
|
|
for( ubID = 0; ubID < MAXMERCS; ubID++ )
|
|
{
|
|
Menptr[ ubID ].bVehicleUnderRepairID = -1;
|
|
}
|
|
}
|
|
|
|
if ( guiCurrentSaveGameVersion < 73 )
|
|
{
|
|
if( LaptopSaveInfo.fMercSiteHasGoneDownYet )
|
|
LaptopSaveInfo.fFirstVisitSinceServerWentDown = 2;
|
|
}
|
|
|
|
|
|
//Update the MERC merc contract lenght. Before save version 77 the data was stored in the SOLDIERTYPE,
|
|
//after 77 the data is stored in the profile
|
|
if ( guiCurrentSaveGameVersion < 77 )
|
|
{
|
|
UpdateMercMercContractInfo();
|
|
}
|
|
|
|
|
|
if ( guiCurrentSaveGameVersion <= 89 )
|
|
{
|
|
// ARM: A change was made in version 89 where refuel site availability now also depends on whether the player has
|
|
// airspace control over that sector. To update the settings immediately, must call it here.
|
|
UpdateRefuelSiteAvailability();
|
|
}
|
|
|
|
if( guiCurrentSaveGameVersion < 91 )
|
|
{
|
|
//update the amount of money that has been paid to speck
|
|
CalcAproximateAmountPaidToSpeck();
|
|
}
|
|
|
|
gfLoadedGame = TRUE;
|
|
|
|
uiRelEndPerc = 100;
|
|
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Done!" );
|
|
RenderProgressBar( 0, 100 );
|
|
|
|
RemoveLoadingScreenProgressBar();
|
|
|
|
SetMusicMode( gMusicModeToPlay );
|
|
|
|
#ifndef JA2TESTVERSION
|
|
RESET_CHEAT_LEVEL( );
|
|
#endif
|
|
|
|
#ifdef JA2BETAVERSION
|
|
if( fDisableDueToBattleRoster || fDisableMapInterfaceDueToBattle )
|
|
{
|
|
gubReportMapscreenLock = 1;
|
|
}
|
|
#endif
|
|
|
|
// reset once-per-convo records for everyone in the loaded sector
|
|
ResetOncePerConvoRecordsForAllNPCsInLoadedSector();
|
|
|
|
if ( !(gTacticalStatus.uiFlags & INCOMBAT) )
|
|
{
|
|
// fix lingering attack busy count problem on loading saved game by resetting a.b.c
|
|
// if we're not in combat.
|
|
gTacticalStatus.ubAttackBusyCount = 0;
|
|
#ifdef DEBUG_ATTACKBUSY
|
|
OutputDebugString( "Resetting attack busy due to load game.\n");
|
|
#endif
|
|
}
|
|
|
|
// fix squads
|
|
CheckSquadMovementGroups();
|
|
|
|
//The above function LightSetBaseLevel adjusts ALL the level node light values including the merc node,
|
|
//we must reset the values
|
|
HandlePlayerTogglingLightEffects( FALSE );
|
|
|
|
//now change the savegame format so that temp files are saved and loaded correctly
|
|
guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOLEAN SaveMercProfiles( HWFILE hFile )
|
|
{
|
|
UINT16 cnt;
|
|
//Loop through all the profiles to save
|
|
for( cnt=0; cnt< NUM_PROFILES; cnt++)
|
|
{
|
|
if ( !gMercProfiles[ cnt ].Save(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN LoadSavedMercProfiles( HWFILE hFile )
|
|
{
|
|
UINT16 cnt;
|
|
//Loop through all the profiles to Load
|
|
for( cnt=0; cnt< NUM_PROFILES; cnt++)
|
|
{
|
|
// Changed by ADB, rev 1513
|
|
//if ( !gMercProfiles[cnt].Load(hFile, false) )
|
|
if ( !gMercProfiles[cnt].Load(hFile, false, false, true) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
//Not saving any of these in the soldier struct
|
|
|
|
// struct TAG_level_node *pLevelNode;
|
|
// struct TAG_level_node *pExternShadowLevelNode;
|
|
// struct TAG_level_node *pRoofUILevelNode;
|
|
// UINT16 *pBackGround;
|
|
// UINT16 *pZBackground;
|
|
// UINT16 *pForcedShade;
|
|
//
|
|
// UINT16 *pEffectShades[ NUM_SOLDIER_EFFECTSHADES ]; // Shading tables for effects
|
|
// THROW_PARAMS *pThrowParams;
|
|
// UINT16 *pCurrentShade;
|
|
// UINT16 *pGlowShades[ 20 ]; //
|
|
// UINT16 *pShades[ NUM_SOLDIER_SHADES ]; // Shading tables
|
|
// UINT16 *p16BPPPalette;
|
|
// SGPPaletteEntry *p8BPPPalette
|
|
// OBJECTTYPE *pTempObject;
|
|
|
|
//Not saving any of these in the soldier struct
|
|
|
|
BOOLEAN SaveSoldierStructure( HWFILE hFile )
|
|
{
|
|
UINT16 cnt;
|
|
UINT32 uiNumBytesWritten=0;
|
|
UINT8 ubOne = 1;
|
|
UINT8 ubZero = 0;
|
|
|
|
//Loop through all the soldier structs to save
|
|
for( cnt=0; cnt< TOTAL_SOLDIERS; cnt++)
|
|
{
|
|
|
|
//if the soldier isnt active, dont add them to the saved game file.
|
|
if( !Menptr[ cnt ].bActive )
|
|
{
|
|
// Save the byte specifing to NOT load the soldiers
|
|
FileWrite( hFile, &ubZero, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
// Save the byte specifing to load the soldiers
|
|
FileWrite( hFile, &ubOne, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
// Save the soldier structure
|
|
if ( !Menptr[ cnt ].Save(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Save all the pointer info from the structure
|
|
//
|
|
//Save the pMercPath
|
|
if( !SaveMercPathFromSoldierStruct( hFile, (UINT8)cnt ) )
|
|
return( FALSE );
|
|
|
|
//
|
|
//do we have a KEY_ON_RING *pKeyRing;
|
|
//
|
|
|
|
if( Menptr[ cnt ].pKeyRing != NULL )
|
|
{
|
|
// write to the file saying we have the ....
|
|
FileWrite( hFile, &ubOne, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
// Now save the ....
|
|
FileWrite( hFile, Menptr[ cnt ].pKeyRing, NUM_KEYS * sizeof( KEY_ON_RING ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != NUM_KEYS * sizeof( KEY_ON_RING ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// write to the file saying we DO NOT have the Key ring
|
|
FileWrite( hFile, &ubZero, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LoadSoldierStructure( HWFILE hFile )
|
|
{
|
|
UINT16 cnt;
|
|
UINT32 uiNumBytesRead=0;
|
|
UINT8 ubId;
|
|
UINT8 ubOne = 1;
|
|
UINT8 ubActive = 1;
|
|
UINT32 uiPercentage;
|
|
SOLDIERTYPE SavedSoldierInfo;
|
|
|
|
//Loop through all the soldier and delete them all
|
|
for( cnt=0; cnt< TOTAL_SOLDIERS; cnt++)
|
|
{
|
|
TacticalRemoveSoldier( cnt );
|
|
}
|
|
|
|
//Loop through all the soldier structs to load
|
|
for( cnt=0; cnt< TOTAL_SOLDIERS; cnt++)
|
|
{
|
|
//update the progress bar
|
|
uiPercentage = (cnt * 100) / (TOTAL_SOLDIERS-1);
|
|
RenderProgressBar( 0, uiPercentage );
|
|
|
|
//Read in a byte to tell us whether or not there is a soldier loaded here.
|
|
FileRead( hFile, &ubActive, 1, &uiNumBytesRead );
|
|
if( uiNumBytesRead != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
// if the soldier is not active, continue
|
|
if( !ubActive )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// else if there is a soldier
|
|
else
|
|
{
|
|
//Read in the saved soldier info into a Temp structure
|
|
if ( !SavedSoldierInfo.Load(hFile) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//Make sure all the pointer references are NULL'ed out.
|
|
SavedSoldierInfo.pTempObject = NULL;
|
|
SavedSoldierInfo.pKeyRing = NULL;
|
|
SavedSoldierInfo.p8BPPPalette = NULL;
|
|
SavedSoldierInfo.p16BPPPalette = NULL;
|
|
memset( SavedSoldierInfo.pShades, 0, sizeof( UINT16* ) * NUM_SOLDIER_SHADES );
|
|
memset( SavedSoldierInfo.pGlowShades, 0, sizeof( UINT16* ) * 20 );
|
|
SavedSoldierInfo.pCurrentShade = NULL;
|
|
SavedSoldierInfo.pThrowParams = NULL;
|
|
SavedSoldierInfo.pLevelNode = NULL;
|
|
SavedSoldierInfo.pExternShadowLevelNode = NULL;
|
|
SavedSoldierInfo.pRoofUILevelNode = NULL;
|
|
SavedSoldierInfo.pBackGround = NULL;
|
|
SavedSoldierInfo.pZBackground = NULL;
|
|
SavedSoldierInfo.pForcedShade = NULL;
|
|
SavedSoldierInfo.pMercPath = NULL;
|
|
memset( SavedSoldierInfo.pEffectShades, 0, sizeof( UINT16* ) * NUM_SOLDIER_EFFECTSHADES );
|
|
|
|
|
|
//if the soldier wasnt active, dont add them now. Advance to the next merc
|
|
//if( !SavedSoldierInfo.bActive )
|
|
// continue;
|
|
|
|
|
|
//Create the new merc
|
|
SOLDIERCREATE_STRUCT CreateStruct;
|
|
CreateStruct.bTeam = SavedSoldierInfo.bTeam;
|
|
CreateStruct.ubProfile = SavedSoldierInfo.ubProfile;
|
|
CreateStruct.fUseExistingSoldier = TRUE;
|
|
CreateStruct.pExistingSoldier = &SavedSoldierInfo;
|
|
|
|
if( !TacticalCreateSoldier( &CreateStruct, &ubId ) )
|
|
return( FALSE );
|
|
|
|
|
|
// Load the pMercPath
|
|
if( !LoadMercPathToSoldierStruct( hFile, ubId ) )
|
|
return( FALSE );
|
|
|
|
|
|
//
|
|
//do we have a KEY_ON_RING *pKeyRing;
|
|
//
|
|
|
|
// Read the file to see if we have to load the keys
|
|
FileRead( hFile, &ubOne, 1, &uiNumBytesRead );
|
|
if( uiNumBytesRead != 1 )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
if( ubOne )
|
|
{
|
|
// Now Load the ....
|
|
FileRead( hFile, Menptr[ cnt ].pKeyRing, NUM_KEYS * sizeof( KEY_ON_RING ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != NUM_KEYS * sizeof( KEY_ON_RING ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
Assert( Menptr[ cnt ].pKeyRing == NULL );
|
|
}
|
|
|
|
//if the soldier is an IMP character
|
|
if( Menptr[cnt].ubWhatKindOfMercAmI == MERC_TYPE__PLAYER_CHARACTER && Menptr[cnt].bTeam == gbPlayerNum )
|
|
{
|
|
ResetIMPCharactersEyesAndMouthOffsets( Menptr[ cnt ].ubProfile );
|
|
}
|
|
|
|
//if the saved game version is before x, calculate the amount of money paid to mercs
|
|
if( guiCurrentSaveGameVersion < 83 )
|
|
{
|
|
//if the soldier is someone
|
|
if( Menptr[ cnt ].ubProfile != NO_PROFILE )
|
|
{
|
|
if( Menptr[cnt].ubWhatKindOfMercAmI == MERC_TYPE__MERC )
|
|
{
|
|
gMercProfiles[ Menptr[ cnt ].ubProfile ].uiTotalCostToDate = gMercProfiles[ Menptr[ cnt ].ubProfile ].sSalary * gMercProfiles[ Menptr[ cnt ].ubProfile ].iMercMercContractLength;
|
|
}
|
|
else
|
|
{
|
|
gMercProfiles[ Menptr[ cnt ].ubProfile ].uiTotalCostToDate = gMercProfiles[ Menptr[ cnt ].ubProfile ].sSalary * Menptr[ cnt ].iTotalContractLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef GERMAN
|
|
// Fix neutral flags
|
|
if ( guiCurrentSaveGameVersion < 94 )
|
|
{
|
|
if ( Menptr[ cnt].bTeam == OUR_TEAM && Menptr[ cnt ].aiData.bNeutral && Menptr[ cnt ].bAssignment != ASSIGNMENT_POW )
|
|
{
|
|
// turn off neutral flag
|
|
Menptr[ cnt].aiData.bNeutral = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
// JA2Gold: fix next-to-previous attacker value
|
|
if ( guiCurrentSaveGameVersion < 99 )
|
|
{
|
|
Menptr[ cnt ].ubNextToPreviousAttackerID = NOBODY;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// Fix robot
|
|
if ( guiCurrentSaveGameVersion <= 87 )
|
|
{
|
|
SOLDIERTYPE * pSoldier;
|
|
|
|
if ( gMercProfiles[ ROBOT ].inv[ VESTPOS ] == SPECTRA_VEST )
|
|
{
|
|
// update this
|
|
gMercProfiles[ ROBOT ].inv[ VESTPOS ] = SPECTRA_VEST_18;
|
|
gMercProfiles[ ROBOT ].inv[ HELMETPOS ] = SPECTRA_HELMET_18;
|
|
gMercProfiles[ ROBOT ].inv[ LEGPOS ] = SPECTRA_LEGGINGS_18;
|
|
gMercProfiles[ ROBOT ].bAgility = 50;
|
|
pSoldier = FindSoldierByProfileID( ROBOT, FALSE );
|
|
if ( pSoldier )
|
|
{
|
|
pSoldier->inv[ VESTPOS ].usItem = SPECTRA_VEST_18;
|
|
pSoldier->inv[ HELMETPOS ].usItem = SPECTRA_HELMET_18;
|
|
pSoldier->inv[ LEGPOS ].usItem = SPECTRA_LEGGINGS_18;
|
|
pSoldier->stats.bAgility = 50;
|
|
}
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
/*
|
|
BOOLEAN SavePtrInfo( PTR *pData, UINT32 uiSizeOfObject, HWFILE hFile )
|
|
{
|
|
UINT8 ubOne = 1;
|
|
UINT8 ubZero = 0;
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
if( pData != NULL )
|
|
{
|
|
// write to the file saying we have the ....
|
|
FileWrite( hFile, &ubOne, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Write Soldier Structure to File" ) );
|
|
return(FALSE);
|
|
}
|
|
|
|
// Now save the ....
|
|
FileWrite( hFile, pData, uiSizeOfObject, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSizeOfObject )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Write Soldier Structure to File" ) );
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// write to the file saying we DO NOT have the ...
|
|
FileWrite( hFile, &ubZero, 1, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != 1 )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Write Soldier Structure to File" ) );
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN LoadPtrInfo( PTR *pData, UINT32 uiSizeOfObject, HWFILE hFile )
|
|
{
|
|
UINT8 ubOne = 1;
|
|
UINT8 ubZero = 0;
|
|
UINT32 uiNumBytesRead;
|
|
|
|
// Read the file to see if we have to load the ....
|
|
FileRead( hFile, &ubOne, 1, &uiNumBytesRead );
|
|
if( uiNumBytesRead != 1 )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Read Soldier Structure from File" ) );
|
|
return(FALSE);
|
|
}
|
|
|
|
if( ubOne )
|
|
{
|
|
// if there is memory already allocated, free it
|
|
MemFree( pData );
|
|
|
|
//Allocate space for the structure data
|
|
*pData = MemAlloc( uiSizeOfObject );
|
|
if( pData == NULL )
|
|
return( FALSE );
|
|
|
|
// Now Load the ....
|
|
FileRead( hFile, pData, uiSizeOfObject, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiSizeOfObject )
|
|
{
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Write Soldier Structure to File" ) );
|
|
return(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if there is memory already allocated, free it
|
|
if( pData )
|
|
{
|
|
MemFree( pData );
|
|
pData = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
return( TRUE );
|
|
}
|
|
*/
|
|
|
|
BOOLEAN SaveFilesToSavedGame( STR pSrcFileName, HWFILE hFile )
|
|
{
|
|
UINT32 uiFileSize;
|
|
UINT32 uiNumBytesWritten=0;
|
|
HWFILE hSrcFile;
|
|
UINT8 *pData;
|
|
UINT32 uiNumBytesRead;
|
|
|
|
|
|
//open the file
|
|
hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
|
|
if( !hSrcFile )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
guiNumberOfMapTempFiles++; //Increment counter: To determine where the temp files are crashing
|
|
#endif
|
|
|
|
|
|
//Get the file size of the source data file
|
|
uiFileSize = FileGetSize( hSrcFile );
|
|
if( uiFileSize == 0 )
|
|
return( FALSE );
|
|
|
|
// Write the the size of the file to the saved game file
|
|
FileWrite( hFile, &uiFileSize, sizeof( UINT32 ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
//Allocate a buffer to read the data into
|
|
pData = (UINT8 *) MemAlloc( uiFileSize );
|
|
if( pData == NULL )
|
|
return( FALSE );
|
|
memset( pData, 0, uiFileSize);
|
|
|
|
// Read the saource file into the buffer
|
|
FileRead( hSrcFile, pData, uiFileSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiFileSize )
|
|
{
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
// Write the buffer to the saved game file
|
|
FileWrite( hFile, pData, uiFileSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiFileSize )
|
|
{
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
//Clsoe the source data file
|
|
FileClose( hSrcFile );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//Write out the name of the temp file so we can track whcih ones get loaded, and saved
|
|
WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile );
|
|
#endif
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LoadFilesFromSavedGame( STR pSrcFileName, HWFILE hFile )
|
|
{
|
|
UINT32 uiFileSize;
|
|
UINT32 uiNumBytesWritten=0;
|
|
HWFILE hSrcFile;
|
|
UINT8 *pData;
|
|
UINT32 uiNumBytesRead;
|
|
|
|
|
|
|
|
//If the source file exists, delete it
|
|
if( FileExists( pSrcFileName ) )
|
|
{
|
|
if( !FileDelete( pSrcFileName ) )
|
|
{
|
|
//unable to delete the original file
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
guiNumberOfMapTempFiles++; //Increment counter: To determine where the temp files are crashing
|
|
#endif
|
|
|
|
//open the destination file to write to
|
|
hSrcFile = FileOpen( pSrcFileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
|
|
if( !hSrcFile )
|
|
{
|
|
//error, we cant open the saved game file
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// Read the size of the data
|
|
FileRead( hFile, &uiFileSize, sizeof( UINT32 ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) )
|
|
{
|
|
FileClose( hSrcFile );
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//if there is nothing in the file, return;
|
|
if( uiFileSize == 0 )
|
|
{
|
|
FileClose( hSrcFile );
|
|
return( TRUE );
|
|
}
|
|
|
|
//Allocate a buffer to read the data into
|
|
pData = (UINT8 *) MemAlloc( uiFileSize );
|
|
if( pData == NULL )
|
|
{
|
|
FileClose( hSrcFile );
|
|
return( FALSE );
|
|
}
|
|
//ADB looks hardly necessary if there is a read right below
|
|
//memset( pData, 0, uiFileSize);
|
|
|
|
// Read into the buffer
|
|
FileRead( hFile, pData, uiFileSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiFileSize )
|
|
{
|
|
FileClose( hSrcFile );
|
|
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
|
|
// Write the buffer to the new file
|
|
FileWrite( hSrcFile, pData, uiFileSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiFileSize )
|
|
{
|
|
FileClose( hSrcFile );
|
|
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Write to the %s File", pSrcFileName ) );
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
//Free the buffer
|
|
MemFree( pData );
|
|
|
|
//Close the source data file
|
|
FileClose( hSrcFile );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
WriteTempFileNameToFile( pSrcFileName, uiFileSize, hFile );
|
|
#endif
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN SaveEmailToSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumOfEmails=0;
|
|
UINT32 uiSizeOfEmails=0;
|
|
EmailPtr pEmail = pEmailList;
|
|
UINT32 cnt;
|
|
UINT32 uiStringLength=0;
|
|
UINT32 uiNumBytesWritten=0;
|
|
|
|
SavedEmailStruct SavedEmail;
|
|
|
|
//loop through all the email to find out the total number
|
|
while(pEmail)
|
|
{
|
|
pEmail=pEmail->Next;
|
|
uiNumOfEmails++;
|
|
}
|
|
|
|
uiSizeOfEmails = sizeof( Email ) * uiNumOfEmails;
|
|
|
|
//write the number of email messages
|
|
FileWrite( hFile, &uiNumOfEmails, sizeof( UINT32 ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//loop trhough all the emails, add each one individually
|
|
pEmail = pEmailList;
|
|
for( cnt=0; cnt<uiNumOfEmails; cnt++)
|
|
{
|
|
//Get the strng length of the subject
|
|
uiStringLength = ( wcslen( pEmail->pSubject ) + 1 ) * 2;
|
|
|
|
//write the length of the current emails subject to the saved game file
|
|
FileWrite( hFile, &uiStringLength, sizeof( UINT32 ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//write the subject of the current email to the saved game file
|
|
FileWrite( hFile, pEmail->pSubject, uiStringLength, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiStringLength )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//Get the current emails data and asign it to the 'Saved email' struct
|
|
SavedEmail.usOffset = pEmail->usOffset;
|
|
SavedEmail.usLength = pEmail->usLength;
|
|
SavedEmail.ubSender = pEmail->ubSender;
|
|
SavedEmail.iDate = pEmail->iDate;
|
|
SavedEmail.iId = pEmail->iId;
|
|
SavedEmail.iFirstData = pEmail->iFirstData;
|
|
SavedEmail.uiSecondData = pEmail->uiSecondData;
|
|
SavedEmail.fRead = pEmail->fRead;
|
|
SavedEmail.fNew = pEmail->fNew;
|
|
SavedEmail.iThirdData = pEmail->iThirdData;
|
|
SavedEmail.iFourthData = pEmail->iFourthData;
|
|
SavedEmail.uiFifthData = pEmail->uiFifthData;
|
|
SavedEmail.uiSixData = pEmail->uiSixData;
|
|
SavedEmail.iCurrentIMPPosition = pEmail->iCurrentIMPPosition;
|
|
|
|
// write the email header to the saved game file
|
|
FileWrite( hFile, &SavedEmail, sizeof( SavedEmailStruct ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( SavedEmailStruct ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//advance to the next email
|
|
pEmail = pEmail->Next;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LoadEmailFromSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumOfEmails=0;
|
|
UINT32 uiSizeOfSubject=0;
|
|
EmailPtr pEmail = pEmailList;
|
|
EmailPtr pTempEmail = NULL;
|
|
UINT8 *pData = NULL;
|
|
UINT32 cnt;
|
|
SavedEmailStruct SavedEmail;
|
|
UINT32 uiNumBytesRead=0;
|
|
|
|
//Delete the existing list of emails
|
|
ShutDownEmailList();
|
|
|
|
pEmailList = NULL;
|
|
//Allocate memory for the header node
|
|
pEmailList = (EmailPtr) MemAlloc( sizeof( Email ) );
|
|
if( pEmailList == NULL )
|
|
return( FALSE );
|
|
|
|
memset( pEmailList, 0, sizeof( Email ) );
|
|
|
|
//read in the number of email messages
|
|
FileRead( hFile, &uiNumOfEmails, sizeof( UINT32 ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//loop through all the emails, add each one individually
|
|
pEmail = pEmailList;
|
|
for( cnt=0; cnt<uiNumOfEmails; cnt++)
|
|
{
|
|
//get the length of the email subject
|
|
FileRead( hFile, &uiSizeOfSubject, sizeof( UINT32 ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//allocate space for the subject
|
|
pData = (UINT8 *) MemAlloc( EMAIL_SUBJECT_LENGTH * sizeof( CHAR16 ) );
|
|
if( pData == NULL )
|
|
return( FALSE );
|
|
memset( pData, 0, EMAIL_SUBJECT_LENGTH * sizeof( CHAR16 ) );
|
|
|
|
//Get the subject
|
|
FileRead( hFile, pData, uiSizeOfSubject, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiSizeOfSubject )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//get the rest of the data from the email
|
|
FileRead( hFile, &SavedEmail, sizeof( SavedEmailStruct ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( SavedEmailStruct ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
//add the email
|
|
//
|
|
|
|
//if we havent allocated space yet
|
|
pTempEmail = (EmailPtr) MemAlloc( sizeof( Email ) );
|
|
if( pTempEmail == NULL )
|
|
return( FALSE );
|
|
memset( pTempEmail, 0, sizeof( Email ) );
|
|
|
|
pTempEmail->usOffset = SavedEmail.usOffset;
|
|
pTempEmail->usLength = SavedEmail.usLength;
|
|
pTempEmail->ubSender = SavedEmail.ubSender;
|
|
pTempEmail->iDate = SavedEmail.iDate;
|
|
pTempEmail->iId = SavedEmail.iId;
|
|
pTempEmail->fRead = SavedEmail.fRead;
|
|
pTempEmail->fNew = SavedEmail.fNew;
|
|
pTempEmail->pSubject = (STR16) pData;
|
|
pTempEmail->iFirstData = SavedEmail.iFirstData;
|
|
pTempEmail->uiSecondData = SavedEmail.uiSecondData;
|
|
pTempEmail->iThirdData = SavedEmail.iThirdData;
|
|
pTempEmail->iFourthData = SavedEmail.iFourthData;
|
|
pTempEmail->uiFifthData = SavedEmail.uiFifthData;
|
|
pTempEmail->uiSixData = SavedEmail.uiSixData;
|
|
pTempEmail->iCurrentIMPPosition = SavedEmail.iCurrentIMPPosition;
|
|
|
|
//add the current email in
|
|
pEmail->Next = pTempEmail;
|
|
pTempEmail->Prev = pEmail;
|
|
|
|
//moved to the next email
|
|
pEmail = pEmail->Next;
|
|
|
|
AddMessageToPages( pTempEmail->iId );
|
|
|
|
}
|
|
|
|
//if there are emails
|
|
if( cnt )
|
|
{
|
|
//the first node of the LL was a dummy, node,get rid of it
|
|
pTempEmail = pEmailList;
|
|
pEmailList = pEmailList->Next;
|
|
pEmailList->Prev = NULL;
|
|
MemFree( pTempEmail );
|
|
}
|
|
else
|
|
{
|
|
MemFree( pEmailList );
|
|
pEmailList = NULL;
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN SaveTacticalStatusToSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
//write the gTacticalStatus to the saved game file
|
|
FileWrite( hFile, &gTacticalStatus, sizeof( TacticalStatusType ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( TacticalStatusType ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
//Save the current sector location to the saved game file
|
|
//
|
|
|
|
// save gWorldSectorX
|
|
FileWrite( hFile, &gWorldSectorX, sizeof( gWorldSectorX ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( gWorldSectorX ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// save gWorldSectorY
|
|
FileWrite( hFile, &gWorldSectorY, sizeof( gWorldSectorY ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( gWorldSectorY ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// save gbWorldSectorZ
|
|
FileWrite( hFile, &gbWorldSectorZ, sizeof( gbWorldSectorZ ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( gbWorldSectorZ ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN LoadTacticalStatusFromSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
//Read the gTacticalStatus to the saved game file
|
|
FileRead( hFile, &gTacticalStatus, sizeof( TacticalStatusType ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( TacticalStatusType ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
//Load the current sector location to the saved game file
|
|
//
|
|
|
|
// Load gWorldSectorX
|
|
FileRead( hFile, &gWorldSectorX, sizeof( gWorldSectorX ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( gWorldSectorX ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Load gWorldSectorY
|
|
FileRead( hFile, &gWorldSectorY, sizeof( gWorldSectorY ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( gWorldSectorY ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
// Load gbWorldSectorZ
|
|
FileRead( hFile, &gbWorldSectorZ, sizeof( gbWorldSectorZ ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( gbWorldSectorZ ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN CopySavedSoldierInfoToNewSoldier( SOLDIERTYPE *pDestSourceInfo, SOLDIERTYPE *pSourceInfo )
|
|
{
|
|
*pDestSourceInfo = *pSourceInfo;
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN SetMercsInsertionGridNo( )
|
|
{
|
|
UINT16 cnt=0;
|
|
|
|
// loop through all the mercs
|
|
for ( cnt=0; cnt < TOTAL_SOLDIERS; cnt++ )
|
|
{
|
|
//if the soldier is active
|
|
if( Menptr[ cnt ].bActive )
|
|
{
|
|
|
|
if( Menptr[ cnt ].sGridNo != NOWHERE )
|
|
{
|
|
//set the insertion type to gridno
|
|
Menptr[ cnt ].ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
|
|
|
|
//set the insertion gridno
|
|
Menptr[ cnt ].usStrategicInsertionData = Menptr[ cnt ].sGridNo;
|
|
|
|
//set the gridno
|
|
Menptr[ cnt ].sGridNo = NOWHERE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN SaveOppListInfoToSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiSaveSize=0;
|
|
UINT32 uiNumBytesWritten=0;
|
|
|
|
|
|
// Save the Public Opplist
|
|
uiSaveSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gbPublicOpplist, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Save the Seen Oppenents
|
|
uiSaveSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gbSeenOpponents, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
// Save the Last Known Opp Locations
|
|
uiSaveSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gsLastKnownOppLoc, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Save the Last Known Opp Level
|
|
uiSaveSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gbLastKnownOppLevel, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// Save the Public Last Known Opp Locations
|
|
uiSaveSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gsPublicLastKnownOppLoc, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Save the Public Last Known Opp Level
|
|
uiSaveSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileWrite( hFile, gbPublicLastKnownOppLevel, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// Save the Public Noise Volume
|
|
uiSaveSize = MAXTEAMS;
|
|
FileWrite( hFile, gubPublicNoiseVolume, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Save the Public Last Noise Gridno
|
|
uiSaveSize = MAXTEAMS;
|
|
FileWrite( hFile, gsPublicNoiseGridno, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LoadOppListInfoFromSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiLoadSize=0;
|
|
UINT32 uiNumBytesRead=0;
|
|
|
|
// Load the Public Opplist
|
|
uiLoadSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gbPublicOpplist, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Load the Seen Oppenents
|
|
uiLoadSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gbSeenOpponents, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
|
|
// Load the Last Known Opp Locations
|
|
uiLoadSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gsLastKnownOppLoc, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Load the Last Known Opp Level
|
|
uiLoadSize = TOTAL_SOLDIERS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gbLastKnownOppLevel, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// Load the Public Last Known Opp Locations
|
|
uiLoadSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gsPublicLastKnownOppLoc, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Load the Public Last Known Opp Level
|
|
uiLoadSize = MAXTEAMS * TOTAL_SOLDIERS;
|
|
FileRead( hFile, gbPublicLastKnownOppLevel, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
// Load the Public Noise Volume
|
|
uiLoadSize = MAXTEAMS;
|
|
FileRead( hFile, gubPublicNoiseVolume, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
// Load the Public Last Noise Gridno
|
|
uiLoadSize = MAXTEAMS;
|
|
FileRead( hFile, gsPublicNoiseGridno, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN SaveWatchedLocsToSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiArraySize;
|
|
UINT32 uiSaveSize=0;
|
|
UINT32 uiNumBytesWritten=0;
|
|
|
|
uiArraySize = TOTAL_SOLDIERS * NUM_WATCHED_LOCS;
|
|
|
|
// save locations of watched points
|
|
uiSaveSize = uiArraySize * sizeof( INT16 );
|
|
FileWrite( hFile, gsWatchedLoc, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
uiSaveSize = uiArraySize * sizeof( INT8 );
|
|
|
|
FileWrite( hFile, gbWatchedLocLevel, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
FileWrite( hFile, gubWatchedLocPoints, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
FileWrite( hFile, gfWatchedLocReset, uiSaveSize, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiSaveSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
BOOLEAN LoadWatchedLocsFromSavedGame( HWFILE hFile )
|
|
{
|
|
UINT32 uiArraySize;
|
|
UINT32 uiLoadSize=0;
|
|
UINT32 uiNumBytesRead=0;
|
|
|
|
uiArraySize = TOTAL_SOLDIERS * NUM_WATCHED_LOCS;
|
|
|
|
uiLoadSize = uiArraySize * sizeof( INT16 );
|
|
FileRead( hFile, gsWatchedLoc, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
uiLoadSize = uiArraySize * sizeof( INT8 );
|
|
FileRead( hFile, gbWatchedLocLevel, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
FileRead( hFile, gubWatchedLocPoints, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
FileRead( hFile, gfWatchedLocReset, uiLoadSize, &uiNumBytesRead );
|
|
if( uiNumBytesRead != uiLoadSize )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
void CreateSavedGameFileNameFromNumber( UINT8 ubSaveGameID, STR pzNewFileName )
|
|
{
|
|
//if we are creating the QuickSave file
|
|
if( ubSaveGameID == 0 )
|
|
{
|
|
#ifdef JA2BETAVERSION
|
|
//if the user wants to have consecutive quick saves
|
|
if( gfUseConsecutiveQuickSaveSlots )
|
|
{
|
|
//if we are loading a game, and the user hasnt saved any consecutinve saves, load the defualt save
|
|
if( guiCurrentQuickSaveNumber == 0 )
|
|
sprintf( pzNewFileName , "%s\\%S.%S", gSaveDir, pMessageStrings[ MSG_QUICKSAVE_NAME ], pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
else
|
|
sprintf( pzNewFileName , "%s\\%S%02d.%S", gSaveDir, pMessageStrings[ MSG_QUICKSAVE_NAME ], guiCurrentQuickSaveNumber, pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
}
|
|
else
|
|
#endif
|
|
sprintf( pzNewFileName , "%s\\%S.%S", gSaveDir, pMessageStrings[ MSG_QUICKSAVE_NAME ], pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
}
|
|
//#ifdef JA2BETAVERSION
|
|
else if( ubSaveGameID == SAVE__END_TURN_NUM )
|
|
{
|
|
//The name of the file
|
|
sprintf( pzNewFileName , "%s\\Auto%02d.%S", gSaveDir, guiLastSaveGameNum, pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
|
|
//increment end turn number
|
|
guiLastSaveGameNum++;
|
|
|
|
//just have 2 saves
|
|
if( guiLastSaveGameNum == 2 )
|
|
{
|
|
guiLastSaveGameNum = 0;
|
|
}
|
|
}
|
|
//#endif
|
|
|
|
else
|
|
sprintf( pzNewFileName , "%s\\%S%02d.%S", gSaveDir, pMessageStrings[ MSG_SAVE_NAME ], ubSaveGameID, pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOLEAN SaveMercPathFromSoldierStruct( HWFILE hFile, UINT8 ubID )
|
|
{
|
|
UINT32 uiNumOfNodes=0;
|
|
PathStPtr pTempPath = Menptr[ ubID ].pMercPath;
|
|
UINT32 uiNumBytesWritten=0;
|
|
|
|
|
|
//loop through to get all the nodes
|
|
while( pTempPath )
|
|
{
|
|
uiNumOfNodes++;
|
|
pTempPath = pTempPath->pNext;
|
|
}
|
|
|
|
|
|
//Save the number of the nodes
|
|
FileWrite( hFile, &uiNumOfNodes, sizeof( UINT32 ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//loop through all the nodes and add them
|
|
pTempPath = Menptr[ ubID ].pMercPath;
|
|
|
|
|
|
//loop through nodes and save all the nodes
|
|
while( pTempPath )
|
|
{
|
|
//Save the number of the nodes
|
|
FileWrite( hFile, pTempPath, sizeof( PathSt ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( PathSt ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
pTempPath = pTempPath->pNext;
|
|
}
|
|
|
|
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN LoadMercPathToSoldierStruct( HWFILE hFile, UINT8 ubID )
|
|
{
|
|
UINT32 uiNumOfNodes=0;
|
|
PathStPtr pTempPath = NULL;
|
|
PathStPtr pTemp = NULL;
|
|
UINT32 uiNumBytesRead=0;
|
|
UINT32 cnt;
|
|
|
|
|
|
|
|
//The list SHOULD be empty at this point
|
|
/*
|
|
//if there is nodes, loop through and delete them
|
|
if( Menptr[ ubID ].pMercPath )
|
|
{
|
|
pTempPath = Menptr[ ubID ].pMercPath;
|
|
while( pTempPath )
|
|
{
|
|
pTemp = pTempPath;
|
|
pTempPath = pTempPath->pNext;
|
|
|
|
MemFree( pTemp );
|
|
pTemp=NULL;
|
|
}
|
|
|
|
Menptr[ ubID ].pMercPath = NULL;
|
|
}
|
|
*/
|
|
|
|
//Load the number of the nodes
|
|
FileRead( hFile, &uiNumOfNodes, sizeof( UINT32 ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
//load all the nodes
|
|
for( cnt=0; cnt<uiNumOfNodes; cnt++ )
|
|
{
|
|
//Allocate memory for the new node
|
|
pTemp = (PathStPtr) MemAlloc( sizeof( PathSt ) );
|
|
if( pTemp == NULL )
|
|
{
|
|
pTempPath = MoveToBeginningOfPathList( pTempPath );
|
|
ClearStrategicPathList( pTempPath, -1 );
|
|
return( FALSE );
|
|
}
|
|
memset( pTemp, 0 , sizeof( PathSt ) );
|
|
|
|
|
|
//Load the node
|
|
FileRead( hFile, pTemp, sizeof( PathSt ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( PathSt ) )
|
|
{
|
|
MemFree( pTemp);
|
|
pTempPath = MoveToBeginningOfPathList( pTempPath );
|
|
ClearStrategicPathList( pTempPath, -1 );
|
|
return(FALSE);
|
|
}
|
|
|
|
//Put the node into the list
|
|
if( cnt == 0 )
|
|
{
|
|
pTempPath = pTemp;
|
|
pTemp->pPrev = NULL;
|
|
}
|
|
else
|
|
{
|
|
pTempPath->pNext = pTemp;
|
|
pTemp->pPrev = pTempPath;
|
|
|
|
pTempPath = pTempPath->pNext;
|
|
}
|
|
|
|
pTemp->pNext = NULL;
|
|
}
|
|
|
|
//move to beginning of list
|
|
pTempPath = MoveToBeginningOfPathList( pTempPath );
|
|
|
|
Menptr[ ubID ].pMercPath = pTempPath;
|
|
if( Menptr[ ubID ].pMercPath )
|
|
Menptr[ ubID ].pMercPath->pPrev = NULL;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
void InitSaveGameFilePosition()
|
|
{
|
|
CHAR8 zFileName[ MAX_PATH ];
|
|
|
|
sprintf( zFileName, "%s\\SaveGameFilePos%2d.txt", gSaveDir, gubSaveGameLoc );
|
|
|
|
FileDelete( zFileName );
|
|
}
|
|
|
|
void SaveGameFilePosition( INT32 iPos, STR pMsg )
|
|
{
|
|
HWFILE hFile;
|
|
CHAR8 zTempString[512];
|
|
UINT32 uiNumBytesWritten;
|
|
UINT32 uiStrLen=0;
|
|
CHAR8 zFileName[MAX_PATH];
|
|
|
|
sprintf( zFileName, "%s\\SaveGameFilePos%2d.txt", gSaveDir, gubSaveGameLoc );
|
|
|
|
// create the save game file
|
|
hFile = FileOpen( zFileName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
|
|
if( !hFile )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileSeek( hFile, 0, FILE_SEEK_FROM_END );
|
|
|
|
sprintf( zTempString, "%8d %s\n", iPos, pMsg );
|
|
uiStrLen = strlen( zTempString );
|
|
|
|
FileWrite( hFile, zTempString, uiStrLen, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiStrLen )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileClose( hFile );
|
|
}
|
|
|
|
|
|
|
|
void InitLoadGameFilePosition()
|
|
{
|
|
CHAR8 zFileName[MAX_PATH];
|
|
|
|
sprintf( zFileName, "%s\\LoadGameFilePos%2d.txt", gSaveDir, gubSaveGameLoc );
|
|
|
|
FileDelete( zFileName );
|
|
}
|
|
void LoadGameFilePosition( INT32 iPos, STR pMsg )
|
|
{
|
|
HWFILE hFile;
|
|
CHAR8 zTempString[512];
|
|
UINT32 uiNumBytesWritten;
|
|
UINT32 uiStrLen=0;
|
|
|
|
CHAR8 zFileName[MAX_PATH];
|
|
|
|
sprintf( zFileName, "%s\\LoadGameFilePos%2d.txt", gSaveDir, gubSaveGameLoc );
|
|
|
|
// create the save game file
|
|
hFile = FileOpen( zFileName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
|
|
if( !hFile )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileSeek( hFile, 0, FILE_SEEK_FROM_END );
|
|
|
|
sprintf( zTempString, "%8d %s\n", iPos, pMsg );
|
|
uiStrLen = strlen( zTempString );
|
|
|
|
FileWrite( hFile, zTempString, uiStrLen, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiStrLen )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileClose( hFile );
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
BOOLEAN SaveGeneralInfo( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
GENERAL_SAVE_INFO sGeneralInfo;
|
|
memset( &sGeneralInfo, 0, sizeof( GENERAL_SAVE_INFO ) );
|
|
|
|
sGeneralInfo.ubMusicMode = gubMusicMode;
|
|
sGeneralInfo.uiCurrentUniqueSoldierId = guiCurrentUniqueSoldierId;
|
|
sGeneralInfo.uiCurrentScreen = guiPreviousOptionScreen;
|
|
|
|
sGeneralInfo.usSelectedSoldier = gusSelectedSoldier;
|
|
sGeneralInfo.sRenderCenterX = gsRenderCenterX;
|
|
sGeneralInfo.sRenderCenterY = gsRenderCenterY;
|
|
sGeneralInfo.fAtLeastOneMercWasHired = gfAtLeastOneMercWasHired;
|
|
sGeneralInfo.fHavePurchasedItemsFromTony = gfHavePurchasedItemsFromTony;
|
|
|
|
sGeneralInfo.fShowItemsFlag = fShowItemsFlag;
|
|
sGeneralInfo.fShowTownFlag = fShowTownFlag;
|
|
sGeneralInfo.fShowMineFlag = fShowMineFlag;
|
|
sGeneralInfo.fShowAircraftFlag = fShowAircraftFlag;
|
|
sGeneralInfo.fShowTeamFlag = fShowTeamFlag;
|
|
|
|
sGeneralInfo.fHelicopterAvailable = fHelicopterAvailable;
|
|
|
|
// helicopter vehicle id
|
|
sGeneralInfo.iHelicopterVehicleId = iHelicopterVehicleId;
|
|
|
|
// total distance travelled
|
|
// sGeneralInfo.iTotalHeliDistanceSinceRefuel = iTotalHeliDistanceSinceRefuel;
|
|
|
|
// total owed by player
|
|
sGeneralInfo.iTotalAccumulatedCostByPlayer = iTotalAccumulatedCostByPlayer;
|
|
|
|
// whether or not skyrider is alive and well? and on our side yet?
|
|
sGeneralInfo.fSkyRiderAvailable = fSkyRiderAvailable;
|
|
|
|
// is the heli in the air?
|
|
sGeneralInfo.fHelicopterIsAirBorne = fHelicopterIsAirBorne;
|
|
|
|
// is the pilot returning straight to base?
|
|
sGeneralInfo.fHeliReturnStraightToBase = fHeliReturnStraightToBase;
|
|
|
|
// heli hovering
|
|
sGeneralInfo.fHoveringHelicopter = fHoveringHelicopter;
|
|
|
|
// time started hovering
|
|
sGeneralInfo.uiStartHoverTime = uiStartHoverTime;
|
|
|
|
// what state is skyrider's dialogue in in?
|
|
sGeneralInfo.uiHelicopterSkyriderTalkState = guiHelicopterSkyriderTalkState;
|
|
|
|
// the flags for skyrider events
|
|
sGeneralInfo.fShowEstoniRefuelHighLight = fShowEstoniRefuelHighLight;
|
|
sGeneralInfo.fShowOtherSAMHighLight = fShowOtherSAMHighLight;
|
|
sGeneralInfo.fShowDrassenSAMHighLight = fShowDrassenSAMHighLight;
|
|
sGeneralInfo.fShowCambriaHospitalHighLight = fShowCambriaHospitalHighLight;
|
|
|
|
//The current state of the weather
|
|
sGeneralInfo.uiEnvWeather = guiEnvWeather;
|
|
|
|
sGeneralInfo.ubDefaultButton = gubDefaultButton;
|
|
|
|
sGeneralInfo.fSkyriderEmptyHelpGiven = gfSkyriderEmptyHelpGiven;
|
|
sGeneralInfo.ubHelicopterHitsTaken = gubHelicopterHitsTaken;
|
|
sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM = gfSkyriderSaidCongratsOnTakingSAM;
|
|
sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn = gubPlayerProgressSkyriderLastCommentedOn;
|
|
|
|
sGeneralInfo.fEnterMapDueToContract = fEnterMapDueToContract;
|
|
sGeneralInfo.ubQuitType = ubQuitType;
|
|
|
|
if( pContractReHireSoldier != NULL )
|
|
sGeneralInfo.sContractRehireSoldierID = pContractReHireSoldier->ubID;
|
|
else
|
|
sGeneralInfo.sContractRehireSoldierID = -1;
|
|
|
|
memcpy( &sGeneralInfo.GameOptions, &gGameOptions, sizeof( GAME_OPTIONS ) );
|
|
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//Everytime we save get, and set a seed value, when reload, seed again
|
|
sGeneralInfo.uiSeedNumber = GetJA2Clock();
|
|
srand( sGeneralInfo.uiSeedNumber );
|
|
#endif
|
|
|
|
//Save the Ja2Clock()
|
|
sGeneralInfo.uiBaseJA2Clock = guiBaseJA2Clock;
|
|
|
|
// Save the current tactical panel mode
|
|
sGeneralInfo.sCurInterfacePanel = gsCurInterfacePanel;
|
|
|
|
// Save the selected merc
|
|
if( gpSMCurrentMerc )
|
|
sGeneralInfo.ubSMCurrentMercID = gpSMCurrentMerc->ubID;
|
|
else
|
|
sGeneralInfo.ubSMCurrentMercID = 255;
|
|
|
|
//Save the fact that it is the first time in mapscreen
|
|
sGeneralInfo.fFirstTimeInMapScreen = fFirstTimeInMapScreen;
|
|
|
|
//save map screen disabling buttons
|
|
sGeneralInfo.fDisableDueToBattleRoster = fDisableDueToBattleRoster;
|
|
sGeneralInfo.fDisableMapInterfaceDueToBattle = fDisableMapInterfaceDueToBattle;
|
|
|
|
// Save boxing info
|
|
memcpy( &sGeneralInfo.sBoxerGridNo, &gsBoxerGridNo, NUM_BOXERS * sizeof( INT16 ) );
|
|
memcpy( &sGeneralInfo.ubBoxerID, &gubBoxerID, NUM_BOXERS * sizeof( INT8 ) );
|
|
memcpy( &sGeneralInfo.fBoxerFought, &gfBoxerFought, NUM_BOXERS * sizeof( BOOLEAN ) );
|
|
|
|
//Save the helicopter status
|
|
sGeneralInfo.fHelicopterDestroyed = fHelicopterDestroyed;
|
|
sGeneralInfo.fShowMapScreenHelpText = fShowMapScreenHelpText;
|
|
|
|
sGeneralInfo.iSortStateForMapScreenList = giSortStateForMapScreenList;
|
|
sGeneralInfo.fFoundTixa = fFoundTixa;
|
|
|
|
sGeneralInfo.uiTimeOfLastSkyriderMonologue = guiTimeOfLastSkyriderMonologue;
|
|
sGeneralInfo.fSkyRiderSetUp = fSkyRiderSetUp;
|
|
|
|
memcpy( &sGeneralInfo.fRefuelingSiteAvailable, &fRefuelingSiteAvailable, NUMBER_OF_REFUEL_SITES * sizeof( BOOLEAN ) );
|
|
|
|
|
|
//Meanwhile stuff
|
|
memcpy( &sGeneralInfo.gCurrentMeanwhileDef, &gCurrentMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) );
|
|
//sGeneralInfo.gfMeanwhileScheduled = gfMeanwhileScheduled;
|
|
sGeneralInfo.gfMeanwhileTryingToStart = gfMeanwhileTryingToStart;
|
|
sGeneralInfo.gfInMeanwhile = gfInMeanwhile;
|
|
|
|
|
|
// list of dead guys for squads...in id values->-1 means no one home
|
|
memcpy( &sGeneralInfo.sDeadMercs, &sDeadMercs, sizeof( INT16 ) * NUMBER_OF_SQUADS * NUMBER_OF_SOLDIERS_PER_SQUAD );
|
|
|
|
// level of public noises
|
|
memcpy( &sGeneralInfo.gbPublicNoiseLevel, &gbPublicNoiseLevel, sizeof( INT8 ) * MAXTEAMS );
|
|
|
|
//The screen count for the initscreen
|
|
sGeneralInfo.gubScreenCount = gubScreenCount;
|
|
|
|
|
|
//used for the mean while screen
|
|
sGeneralInfo.uiMeanWhileFlags = uiMeanWhileFlags;
|
|
|
|
//Imp portrait number
|
|
sGeneralInfo.iPortraitNumber = iPortraitNumber;
|
|
|
|
// location of first enocunter with enemy
|
|
sGeneralInfo.sWorldSectorLocationOfFirstBattle = sWorldSectorLocationOfFirstBattle;
|
|
|
|
|
|
//State of email flags
|
|
sGeneralInfo.fUnReadMailFlag = fUnReadMailFlag;
|
|
sGeneralInfo.fNewMailFlag = fNewMailFlag;
|
|
sGeneralInfo.fOldUnReadFlag = fOldUnreadFlag;
|
|
sGeneralInfo.fOldNewMailFlag = fOldNewMailFlag;
|
|
|
|
sGeneralInfo.fShowMilitia = fShowMilitia;
|
|
|
|
sGeneralInfo.fNewFilesInFileViewer = fNewFilesInFileViewer;
|
|
|
|
sGeneralInfo.fLastBoxingMatchWonByPlayer = gfLastBoxingMatchWonByPlayer;
|
|
|
|
memcpy( &sGeneralInfo.fSamSiteFound, &fSamSiteFound, MAX_NUMBER_OF_SAMS * sizeof( BOOLEAN ) );
|
|
|
|
sGeneralInfo.ubNumTerrorists = gubNumTerrorists;
|
|
sGeneralInfo.ubCambriaMedicalObjects = gubCambriaMedicalObjects;
|
|
|
|
sGeneralInfo.fDisableTacticalPanelButtons = gfDisableTacticalPanelButtons;
|
|
|
|
sGeneralInfo.sSelMapX = sSelMapX;
|
|
sGeneralInfo.sSelMapY = sSelMapY;
|
|
sGeneralInfo.iCurrentMapSectorZ = iCurrentMapSectorZ;
|
|
|
|
//Save the current status of the help screens flag that say wether or not the user has been there before
|
|
sGeneralInfo.usHasPlayerSeenHelpScreenInCurrentScreen = gHelpScreen.usHasPlayerSeenHelpScreenInCurrentScreen;
|
|
|
|
sGeneralInfo.ubBoxingMatchesWon = gubBoxingMatchesWon;
|
|
sGeneralInfo.ubBoxersRests = gubBoxersRests;
|
|
sGeneralInfo.fBoxersResting = gfBoxersResting;
|
|
|
|
sGeneralInfo.ubDesertTemperature = gubDesertTemperature;
|
|
sGeneralInfo.ubGlobalTemperature = gubGlobalTemperature;
|
|
|
|
sGeneralInfo.sMercArriveSectorX = gsMercArriveSectorX;
|
|
sGeneralInfo.sMercArriveSectorY = gsMercArriveSectorY;
|
|
|
|
sGeneralInfo.fCreatureMeanwhileScenePlayed = gfCreatureMeanwhileScenePlayed;
|
|
|
|
//save the global player num
|
|
sGeneralInfo.ubPlayerNum = gbPlayerNum;
|
|
|
|
//New stuff for the Prebattle interface / autoresolve
|
|
sGeneralInfo.fPersistantPBI = gfPersistantPBI;
|
|
sGeneralInfo.ubEnemyEncounterCode = gubEnemyEncounterCode;
|
|
sGeneralInfo.ubExplicitEnemyEncounterCode = gubExplicitEnemyEncounterCode;
|
|
sGeneralInfo.fBlitBattleSectorLocator = gfBlitBattleSectorLocator;
|
|
sGeneralInfo.ubPBSectorX = gubPBSectorX;
|
|
sGeneralInfo.ubPBSectorY = gubPBSectorY;
|
|
sGeneralInfo.ubPBSectorZ = gubPBSectorZ;
|
|
sGeneralInfo.fCantRetreatInPBI = gfCantRetreatInPBI;
|
|
sGeneralInfo.fExplosionQueueActive = gfExplosionQueueActive;
|
|
|
|
sGeneralInfo.bSelectedInfoChar = bSelectedInfoChar;
|
|
|
|
sGeneralInfo.iHospitalTempBalance = giHospitalTempBalance;
|
|
sGeneralInfo.iHospitalRefund = giHospitalRefund;
|
|
sGeneralInfo.bHospitalPriceModifier = gbHospitalPriceModifier;
|
|
sGeneralInfo.fPlayerTeamSawJoey = gfPlayerTeamSawJoey;
|
|
sGeneralInfo.fMikeShouldSayHi = gfMikeShouldSayHi;
|
|
|
|
//Setup the
|
|
//Save the current music mode
|
|
FileWrite( hFile, &sGeneralInfo, sizeof( GENERAL_SAVE_INFO ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( GENERAL_SAVE_INFO ) )
|
|
{
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
//rain
|
|
extern UINT32 guiRainLoop;
|
|
//end rain
|
|
|
|
BOOLEAN LoadGeneralInfo( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
GENERAL_SAVE_INFO sGeneralInfo;
|
|
memset( &sGeneralInfo, 0, sizeof( GENERAL_SAVE_INFO ) );
|
|
|
|
|
|
//Load the current music mode
|
|
FileRead( hFile, &sGeneralInfo, sizeof( GENERAL_SAVE_INFO ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( GENERAL_SAVE_INFO ) )
|
|
{
|
|
FileClose( hFile );
|
|
return( FALSE );
|
|
}
|
|
|
|
gMusicModeToPlay = sGeneralInfo.ubMusicMode;
|
|
|
|
guiCurrentUniqueSoldierId = sGeneralInfo.uiCurrentUniqueSoldierId;
|
|
|
|
guiScreenToGotoAfterLoadingSavedGame = sGeneralInfo.uiCurrentScreen;
|
|
|
|
// gusSelectedSoldier = NOBODY;
|
|
gusSelectedSoldier = sGeneralInfo.usSelectedSoldier;
|
|
|
|
gsRenderCenterX = sGeneralInfo.sRenderCenterX;
|
|
gsRenderCenterY = sGeneralInfo.sRenderCenterY;
|
|
|
|
gfAtLeastOneMercWasHired = sGeneralInfo.fAtLeastOneMercWasHired;
|
|
|
|
|
|
|
|
gfHavePurchasedItemsFromTony = sGeneralInfo.fHavePurchasedItemsFromTony;
|
|
|
|
fShowItemsFlag = sGeneralInfo.fShowItemsFlag;
|
|
fShowTownFlag = sGeneralInfo.fShowTownFlag;
|
|
fShowMineFlag = sGeneralInfo.fShowMineFlag;
|
|
fShowAircraftFlag = sGeneralInfo.fShowAircraftFlag;
|
|
fShowTeamFlag = sGeneralInfo.fShowTeamFlag;
|
|
|
|
fHelicopterAvailable = sGeneralInfo.fHelicopterAvailable;
|
|
|
|
// helicopter vehicle id
|
|
iHelicopterVehicleId = sGeneralInfo.iHelicopterVehicleId;
|
|
|
|
// total distance travelled
|
|
// iTotalHeliDistanceSinceRefuel = sGeneralInfo.iTotalHeliDistanceSinceRefuel;
|
|
|
|
// total owed to player
|
|
iTotalAccumulatedCostByPlayer = sGeneralInfo.iTotalAccumulatedCostByPlayer;
|
|
|
|
// whether or not skyrider is alive and well? and on our side yet?
|
|
fSkyRiderAvailable = sGeneralInfo.fSkyRiderAvailable;
|
|
|
|
// is the heli in the air?
|
|
fHelicopterIsAirBorne = sGeneralInfo.fHelicopterIsAirBorne;
|
|
|
|
// is the pilot returning straight to base?
|
|
fHeliReturnStraightToBase = sGeneralInfo.fHeliReturnStraightToBase;
|
|
|
|
// heli hovering
|
|
fHoveringHelicopter = sGeneralInfo.fHoveringHelicopter;
|
|
|
|
// time started hovering
|
|
uiStartHoverTime = sGeneralInfo.uiStartHoverTime;
|
|
|
|
// what state is skyrider's dialogue in in?
|
|
guiHelicopterSkyriderTalkState = sGeneralInfo.uiHelicopterSkyriderTalkState;
|
|
|
|
// the flags for skyrider events
|
|
fShowEstoniRefuelHighLight = sGeneralInfo.fShowEstoniRefuelHighLight;
|
|
fShowOtherSAMHighLight = sGeneralInfo.fShowOtherSAMHighLight;
|
|
fShowDrassenSAMHighLight = sGeneralInfo.fShowDrassenSAMHighLight;
|
|
fShowCambriaHospitalHighLight = sGeneralInfo.fShowCambriaHospitalHighLight;
|
|
|
|
//The current state of the weather
|
|
guiEnvWeather = sGeneralInfo.uiEnvWeather;
|
|
|
|
//rain
|
|
if ( guiRainLoop != NO_SAMPLE )
|
|
{
|
|
SoundStop( guiRainLoop );
|
|
guiRainLoop = NO_SAMPLE;
|
|
}
|
|
//end rain
|
|
|
|
gubDefaultButton = sGeneralInfo.ubDefaultButton;
|
|
|
|
gfSkyriderEmptyHelpGiven = sGeneralInfo.fSkyriderEmptyHelpGiven;
|
|
gubHelicopterHitsTaken = sGeneralInfo.ubHelicopterHitsTaken;
|
|
gfSkyriderSaidCongratsOnTakingSAM = sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM;
|
|
gubPlayerProgressSkyriderLastCommentedOn = sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn;
|
|
|
|
fEnterMapDueToContract = sGeneralInfo.fEnterMapDueToContract;
|
|
ubQuitType = sGeneralInfo.ubQuitType;
|
|
|
|
//if the soldier id is valid
|
|
if( sGeneralInfo.sContractRehireSoldierID == -1 )
|
|
pContractReHireSoldier = NULL;
|
|
else
|
|
pContractReHireSoldier = &Menptr[ sGeneralInfo.sContractRehireSoldierID ];
|
|
|
|
memcpy( &gGameOptions, &sGeneralInfo.GameOptions, sizeof( GAME_OPTIONS ) );
|
|
|
|
#ifdef JA2BETAVERSION
|
|
//Reset the random 'seed' number
|
|
srand( sGeneralInfo.uiSeedNumber );
|
|
#endif
|
|
|
|
//Restore the JA2 Clock
|
|
guiBaseJA2Clock = sGeneralInfo.uiBaseJA2Clock;
|
|
|
|
// whenever guiBaseJA2Clock changes, we must reset all the timer variables that use it as a reference
|
|
ResetJA2ClockGlobalTimers();
|
|
|
|
|
|
// Restore the selected merc
|
|
if( sGeneralInfo.ubSMCurrentMercID == 255 )
|
|
gpSMCurrentMerc = NULL;
|
|
else
|
|
gpSMCurrentMerc = &Menptr[ sGeneralInfo.ubSMCurrentMercID ];
|
|
|
|
//Set the interface panel to the team panel
|
|
ShutdownCurrentPanel( );
|
|
|
|
//Restore the current tactical panel mode
|
|
gsCurInterfacePanel = sGeneralInfo.sCurInterfacePanel;
|
|
|
|
/*
|
|
//moved to last stage in the LoadSaveGame() function
|
|
//if we are in tactical
|
|
if( guiScreenToGotoAfterLoadingSavedGame == GAME_SCREEN )
|
|
{
|
|
//Initialize the current panel
|
|
InitializeCurrentPanel( );
|
|
|
|
SelectSoldier( gusSelectedSoldier, FALSE, TRUE );
|
|
}
|
|
*/
|
|
|
|
//Restore the fact that it is the first time in mapscreen
|
|
fFirstTimeInMapScreen = sGeneralInfo.fFirstTimeInMapScreen;
|
|
|
|
//Load map screen disabling buttons
|
|
fDisableDueToBattleRoster = sGeneralInfo.fDisableDueToBattleRoster;
|
|
fDisableMapInterfaceDueToBattle = sGeneralInfo.fDisableMapInterfaceDueToBattle;
|
|
|
|
memcpy( &gsBoxerGridNo, &sGeneralInfo.sBoxerGridNo, NUM_BOXERS * sizeof( INT16 ) );
|
|
memcpy( &gubBoxerID, &sGeneralInfo.ubBoxerID, NUM_BOXERS * sizeof( INT8 ) );
|
|
memcpy( &gfBoxerFought, &sGeneralInfo.fBoxerFought, NUM_BOXERS * sizeof( BOOLEAN ) );
|
|
|
|
//Load the helicopter status
|
|
fHelicopterDestroyed = sGeneralInfo.fHelicopterDestroyed;
|
|
fShowMapScreenHelpText = sGeneralInfo.fShowMapScreenHelpText;
|
|
|
|
|
|
giSortStateForMapScreenList = sGeneralInfo.iSortStateForMapScreenList;
|
|
fFoundTixa = sGeneralInfo.fFoundTixa;
|
|
|
|
guiTimeOfLastSkyriderMonologue = sGeneralInfo.uiTimeOfLastSkyriderMonologue;
|
|
fSkyRiderSetUp = sGeneralInfo.fSkyRiderSetUp;
|
|
|
|
memcpy( &fRefuelingSiteAvailable, &sGeneralInfo.fRefuelingSiteAvailable, NUMBER_OF_REFUEL_SITES * sizeof( BOOLEAN ) );
|
|
|
|
|
|
//Meanwhile stuff
|
|
memcpy( &gCurrentMeanwhileDef, &sGeneralInfo.gCurrentMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) );
|
|
// gfMeanwhileScheduled = sGeneralInfo.gfMeanwhileScheduled;
|
|
gfMeanwhileTryingToStart = sGeneralInfo.gfMeanwhileTryingToStart;
|
|
gfInMeanwhile = sGeneralInfo.gfInMeanwhile;
|
|
|
|
// list of dead guys for squads...in id values->-1 means no one home
|
|
memcpy( &sDeadMercs, &sGeneralInfo.sDeadMercs, sizeof( INT16 ) * NUMBER_OF_SQUADS * NUMBER_OF_SOLDIERS_PER_SQUAD );
|
|
|
|
// level of public noises
|
|
memcpy( &gbPublicNoiseLevel, &sGeneralInfo.gbPublicNoiseLevel, sizeof( INT8 ) * MAXTEAMS );
|
|
|
|
//the screen count for the init screen
|
|
gubScreenCount = sGeneralInfo.gubScreenCount;
|
|
|
|
//used for the mean while screen
|
|
if ( guiCurrentSaveGameVersion < 71 )
|
|
{
|
|
uiMeanWhileFlags = sGeneralInfo.usOldMeanWhileFlags;
|
|
}
|
|
else
|
|
{
|
|
uiMeanWhileFlags = sGeneralInfo.uiMeanWhileFlags;
|
|
}
|
|
|
|
//Imp portrait number
|
|
iPortraitNumber = sGeneralInfo.iPortraitNumber;
|
|
|
|
// location of first enocunter with enemy
|
|
sWorldSectorLocationOfFirstBattle = sGeneralInfo.sWorldSectorLocationOfFirstBattle;
|
|
|
|
fShowMilitia = sGeneralInfo.fShowMilitia;
|
|
|
|
fNewFilesInFileViewer = sGeneralInfo.fNewFilesInFileViewer;
|
|
|
|
gfLastBoxingMatchWonByPlayer = sGeneralInfo.fLastBoxingMatchWonByPlayer;
|
|
|
|
memcpy( &fSamSiteFound, &sGeneralInfo.fSamSiteFound, MAX_NUMBER_OF_SAMS * sizeof( BOOLEAN ) );
|
|
|
|
gubNumTerrorists = sGeneralInfo.ubNumTerrorists;
|
|
gubCambriaMedicalObjects = sGeneralInfo.ubCambriaMedicalObjects;
|
|
|
|
gfDisableTacticalPanelButtons = sGeneralInfo.fDisableTacticalPanelButtons;
|
|
|
|
sSelMapX = sGeneralInfo.sSelMapX;
|
|
sSelMapY = sGeneralInfo.sSelMapY;
|
|
iCurrentMapSectorZ = sGeneralInfo.iCurrentMapSectorZ;
|
|
|
|
//State of email flags
|
|
fUnReadMailFlag = sGeneralInfo.fUnReadMailFlag;
|
|
fNewMailFlag = sGeneralInfo.fNewMailFlag;
|
|
fOldUnreadFlag = sGeneralInfo.fOldUnReadFlag;
|
|
fOldNewMailFlag = sGeneralInfo.fOldNewMailFlag;
|
|
|
|
//Save the current status of the help screens flag that say wether or not the user has been there before
|
|
gHelpScreen.usHasPlayerSeenHelpScreenInCurrentScreen = sGeneralInfo.usHasPlayerSeenHelpScreenInCurrentScreen;
|
|
|
|
gubBoxingMatchesWon = sGeneralInfo.ubBoxingMatchesWon;
|
|
gubBoxersRests = sGeneralInfo.ubBoxersRests;
|
|
gfBoxersResting = sGeneralInfo.fBoxersResting;
|
|
|
|
gubDesertTemperature = sGeneralInfo.ubDesertTemperature;
|
|
gubGlobalTemperature = sGeneralInfo.ubGlobalTemperature;
|
|
|
|
gsMercArriveSectorX = sGeneralInfo.sMercArriveSectorX;
|
|
gsMercArriveSectorY = sGeneralInfo.sMercArriveSectorY;
|
|
|
|
gfCreatureMeanwhileScenePlayed = sGeneralInfo.fCreatureMeanwhileScenePlayed;
|
|
|
|
//load the global player num
|
|
gbPlayerNum = sGeneralInfo.ubPlayerNum;
|
|
|
|
//New stuff for the Prebattle interface / autoresolve
|
|
gfPersistantPBI = sGeneralInfo.fPersistantPBI;
|
|
gubEnemyEncounterCode = sGeneralInfo.ubEnemyEncounterCode;
|
|
gubExplicitEnemyEncounterCode = sGeneralInfo.ubExplicitEnemyEncounterCode;
|
|
gfBlitBattleSectorLocator = sGeneralInfo.fBlitBattleSectorLocator;
|
|
gubPBSectorX = sGeneralInfo.ubPBSectorX;
|
|
gubPBSectorY = sGeneralInfo.ubPBSectorY;
|
|
gubPBSectorZ = sGeneralInfo.ubPBSectorZ;
|
|
gfCantRetreatInPBI = sGeneralInfo.fCantRetreatInPBI;
|
|
gfExplosionQueueActive = sGeneralInfo.fExplosionQueueActive;
|
|
|
|
bSelectedInfoChar = sGeneralInfo.bSelectedInfoChar;
|
|
|
|
giHospitalTempBalance = sGeneralInfo.iHospitalTempBalance;
|
|
giHospitalRefund = sGeneralInfo.iHospitalRefund;
|
|
gbHospitalPriceModifier = sGeneralInfo.bHospitalPriceModifier;
|
|
gfPlayerTeamSawJoey = sGeneralInfo.fPlayerTeamSawJoey;
|
|
gfMikeShouldSayHi = sGeneralInfo.fMikeShouldSayHi;
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN SavePreRandomNumbersToSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
//Save the Prerandom number index
|
|
FileWrite( hFile, &guiPreRandomIndex, sizeof( UINT32 ), &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
//Save the Prerandom number index
|
|
FileWrite( hFile, guiPreRandomNums, sizeof( UINT32 ) * MAX_PREGENERATED_NUMS, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != sizeof( UINT32 ) * MAX_PREGENERATED_NUMS )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN LoadPreRandomNumbersFromSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
//Load the Prerandom number index
|
|
FileRead( hFile, &guiPreRandomIndex, sizeof( UINT32 ), &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
//Load the Prerandom number index
|
|
FileRead( hFile, guiPreRandomNums, sizeof( UINT32 ) * MAX_PREGENERATED_NUMS, &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( UINT32 ) * MAX_PREGENERATED_NUMS )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN LoadMeanwhileDefsFromSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesRead;
|
|
|
|
if ( guiCurrentSaveGameVersion < 72 )
|
|
{
|
|
//Load the array of meanwhile defs
|
|
FileRead( hFile, gMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) * (NUM_MEANWHILES-1), &uiNumBytesRead );
|
|
if ( uiNumBytesRead != sizeof( MEANWHILE_DEFINITION ) * (NUM_MEANWHILES-1) )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
// and set the last one
|
|
memset( &(gMeanwhileDef[ NUM_MEANWHILES - 1]), 0, sizeof( MEANWHILE_DEFINITION ) );
|
|
|
|
}
|
|
else
|
|
{
|
|
//Load the array of meanwhile defs
|
|
FileRead( hFile, gMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) * NUM_MEANWHILES, &uiNumBytesRead );
|
|
if( uiNumBytesRead != sizeof( MEANWHILE_DEFINITION ) * NUM_MEANWHILES )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN SaveMeanwhileDefsFromSaveGameFile( HWFILE hFile )
|
|
{
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
//Save the array of meanwhile defs
|
|
FileWrite( hFile, &gMeanwhileDef, sizeof( MEANWHILE_DEFINITION ) * NUM_MEANWHILES, &uiNumBytesWritten );
|
|
if ( uiNumBytesWritten != sizeof( MEANWHILE_DEFINITION ) * NUM_MEANWHILES )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
BOOLEAN DoesUserHaveEnoughHardDriveSpace()
|
|
{
|
|
UINT32 uiBytesFree=0;
|
|
|
|
uiBytesFree = GetFreeSpaceOnHardDriveWhereGameIsRunningFrom( );
|
|
|
|
//check to see if there is enough hard drive space
|
|
if( uiBytesFree < REQUIRED_FREE_SPACE )
|
|
{
|
|
return( FALSE );
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
#ifdef JA2BETAVERSION
|
|
|
|
void InitShutDownMapTempFileTest( BOOLEAN fInit, STR pNameOfFile, UINT8 ubSaveGameID )
|
|
{
|
|
CHAR8 zFileName[MAX_PATH];
|
|
HWFILE hFile;
|
|
CHAR8 zTempString[512];
|
|
UINT32 uiStrLen;
|
|
UINT32 uiNumBytesWritten;
|
|
|
|
//strcpy( gzNameOfMapTempFile, pNameOfFile);
|
|
sprintf( gzNameOfMapTempFile, "%s%d", pNameOfFile, ubSaveGameID );
|
|
|
|
sprintf( zFileName, "%s\\%s.txt", gSaveDir, gzNameOfMapTempFile );
|
|
|
|
if( fInit )
|
|
{
|
|
guiNumberOfMapTempFiles = 0; //Test: To determine where the temp files are crashing
|
|
guiSizeOfTempFiles = 0;
|
|
|
|
if( FileExists( zFileName ) )
|
|
{
|
|
FileDelete( zFileName );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// create the save game file
|
|
hFile = FileOpen( zFileName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
|
|
if( !hFile )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileSeek( hFile, 0, FILE_SEEK_FROM_END );
|
|
|
|
sprintf( zTempString, "Number Of Files: %6d. Size of all files: %6d.\n", guiNumberOfMapTempFiles, guiSizeOfTempFiles );
|
|
uiStrLen = strlen( zTempString );
|
|
|
|
FileWrite( hFile, zTempString, uiStrLen, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiStrLen )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileClose( hFile );
|
|
|
|
}
|
|
}
|
|
|
|
void WriteTempFileNameToFile( STR pFileName, UINT32 uiSizeOfFile, HFILE hSaveFile )
|
|
{
|
|
HWFILE hFile;
|
|
CHAR8 zTempString[512];
|
|
UINT32 uiNumBytesWritten;
|
|
UINT32 uiStrLen=0;
|
|
|
|
CHAR8 zFileName[MAX_PATH];
|
|
|
|
guiSizeOfTempFiles += uiSizeOfFile;
|
|
|
|
sprintf( zFileName, "%s\\%s.txt", gSaveDir, gzNameOfMapTempFile );
|
|
|
|
// create the save game file
|
|
hFile = FileOpen( zFileName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE );
|
|
if( !hFile )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileSeek( hFile, 0, FILE_SEEK_FROM_END );
|
|
|
|
sprintf( zTempString, "%8d %6d %s\n", FileGetPos( hSaveFile ), uiSizeOfFile, pFileName );
|
|
uiStrLen = strlen( zTempString );
|
|
|
|
FileWrite( hFile, zTempString, uiStrLen, &uiNumBytesWritten );
|
|
if( uiNumBytesWritten != uiStrLen )
|
|
{
|
|
FileClose( hFile );
|
|
return;
|
|
}
|
|
|
|
FileClose( hFile );
|
|
}
|
|
|
|
#endif
|
|
|
|
void GetBestPossibleSectorXYZValues( INT16 *psSectorX, INT16 *psSectorY, INT8 *pbSectorZ )
|
|
{
|
|
//if the current sector is valid
|
|
if( gfWorldLoaded )
|
|
{
|
|
*psSectorX = gWorldSectorX;
|
|
*psSectorY = gWorldSectorY;
|
|
*pbSectorZ = gbWorldSectorZ;
|
|
}
|
|
else if( iCurrentTacticalSquad != NO_CURRENT_SQUAD && Squad[ iCurrentTacticalSquad ][ 0 ] )
|
|
{
|
|
if( Squad[ iCurrentTacticalSquad ][ 0 ]->bAssignment != IN_TRANSIT )
|
|
{
|
|
*psSectorX = Squad[ iCurrentTacticalSquad ][ 0 ]->sSectorX;
|
|
*psSectorY = Squad[ iCurrentTacticalSquad ][ 0 ]->sSectorY;
|
|
*pbSectorZ = Squad[ iCurrentTacticalSquad ][ 0 ]->bSectorZ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
INT16 sSoldierCnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
INT16 bLastTeamID;
|
|
BOOLEAN fFoundAMerc=FALSE;
|
|
|
|
// Set locator to first merc
|
|
sSoldierCnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
|
|
|
|
//loop through all the mercs on the players team to find the one that is not moving
|
|
for ( pSoldier = MercPtrs[ sSoldierCnt ]; sSoldierCnt <= bLastTeamID; sSoldierCnt++,pSoldier++)
|
|
{
|
|
if( pSoldier->bActive )
|
|
{
|
|
if ( pSoldier->bAssignment != IN_TRANSIT && !pSoldier->flags.fBetweenSectors)
|
|
{
|
|
//we found an alive, merc that is not moving
|
|
*psSectorX = pSoldier->sSectorX;
|
|
*psSectorY = pSoldier->sSectorY;
|
|
*pbSectorZ = pSoldier->bSectorZ;
|
|
fFoundAMerc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//if we didnt find a merc
|
|
if( !fFoundAMerc )
|
|
{
|
|
// Set locator to first merc
|
|
sSoldierCnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
|
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
|
|
|
|
//loop through all the mercs and find one that is moving
|
|
for ( pSoldier = MercPtrs[ sSoldierCnt ]; sSoldierCnt <= bLastTeamID; sSoldierCnt++,pSoldier++)
|
|
{
|
|
if( pSoldier->bActive )
|
|
{
|
|
//we found an alive, merc that is not moving
|
|
*psSectorX = pSoldier->sSectorX;
|
|
*psSectorY = pSoldier->sSectorY;
|
|
*pbSectorZ = pSoldier->bSectorZ;
|
|
fFoundAMerc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//if we STILL havent found a merc, give up and use the -1, -1, -1
|
|
if( !fFoundAMerc )
|
|
{
|
|
*psSectorX = gWorldSectorX;
|
|
*psSectorY = gWorldSectorY;
|
|
*pbSectorZ = gbWorldSectorZ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PauseBeforeSaveGame( void )
|
|
{
|
|
//if we are not in the save load screen
|
|
if( guiCurrentScreen != SAVE_LOAD_SCREEN )
|
|
{
|
|
//Pause the game
|
|
PauseGame();
|
|
}
|
|
}
|
|
|
|
void UnPauseAfterSaveGame( void )
|
|
{
|
|
//if we are not in the save load screen
|
|
if( guiCurrentScreen != SAVE_LOAD_SCREEN )
|
|
{
|
|
//UnPause time compression
|
|
UnPauseGame();
|
|
}
|
|
}
|
|
|
|
void TruncateStrategicGroupSizes()
|
|
{
|
|
GROUP *pGroup;
|
|
SECTORINFO *pSector;
|
|
INT32 i;
|
|
|
|
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
|
|
|
|
|
|
for( i = SEC_A1; i < SEC_P16; i++ )
|
|
{
|
|
pSector = &SectorInfo[ i ];
|
|
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites > iMaxEnemyGroupSize )
|
|
{
|
|
if( pSector->ubNumAdmins > pSector->ubNumTroops )
|
|
{
|
|
if( pSector->ubNumAdmins > pSector->ubNumElites )
|
|
{
|
|
pSector->ubNumAdmins = 20;
|
|
pSector->ubNumTroops = 0;
|
|
pSector->ubNumElites = 0;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumAdmins = 0;
|
|
pSector->ubNumTroops = 0;
|
|
pSector->ubNumElites = 20;
|
|
}
|
|
}
|
|
else if( pSector->ubNumTroops > pSector->ubNumElites )
|
|
{
|
|
if( pSector->ubNumTroops > pSector->ubNumAdmins )
|
|
{
|
|
pSector->ubNumAdmins = 0;
|
|
pSector->ubNumTroops = 20;
|
|
pSector->ubNumElites = 0;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumAdmins = 20;
|
|
pSector->ubNumTroops = 0;
|
|
pSector->ubNumElites = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pSector->ubNumElites > pSector->ubNumTroops )
|
|
{
|
|
pSector->ubNumAdmins = 0;
|
|
pSector->ubNumTroops = 0;
|
|
pSector->ubNumElites = 20;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumAdmins = 0;
|
|
pSector->ubNumTroops = 20;
|
|
pSector->ubNumElites = 0;
|
|
}
|
|
}
|
|
}
|
|
//militia
|
|
if( pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2] > iMaxEnemyGroupSize )
|
|
{
|
|
if( pSector->ubNumberOfCivsAtLevel[0] > pSector->ubNumberOfCivsAtLevel[1] )
|
|
{
|
|
if( pSector->ubNumberOfCivsAtLevel[0] > pSector->ubNumberOfCivsAtLevel[2] )
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 20;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 0;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 20;
|
|
}
|
|
}
|
|
else if( pSector->ubNumberOfCivsAtLevel[1] > pSector->ubNumberOfCivsAtLevel[2] )
|
|
{
|
|
if( pSector->ubNumberOfCivsAtLevel[1] > pSector->ubNumberOfCivsAtLevel[0] )
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 20;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 0;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 20;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pSector->ubNumberOfCivsAtLevel[2] > pSector->ubNumberOfCivsAtLevel[1] )
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 20;
|
|
}
|
|
else
|
|
{
|
|
pSector->ubNumberOfCivsAtLevel[0] = 0;
|
|
pSector->ubNumberOfCivsAtLevel[1] = 20;
|
|
pSector->ubNumberOfCivsAtLevel[2] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//Enemy groups
|
|
pGroup = gpGroupList;
|
|
while( pGroup )
|
|
{
|
|
if( !pGroup->fPlayer )
|
|
{
|
|
if( pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites > iMaxEnemyGroupSize )
|
|
{
|
|
pGroup->ubGroupSize = 20;
|
|
if( pGroup->pEnemyGroup->ubNumAdmins > pGroup->pEnemyGroup->ubNumTroops )
|
|
{
|
|
if( pGroup->pEnemyGroup->ubNumAdmins > pGroup->pEnemyGroup->ubNumElites )
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 20;
|
|
pGroup->pEnemyGroup->ubNumTroops = 0;
|
|
pGroup->pEnemyGroup->ubNumElites = 0;
|
|
}
|
|
else
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 0;
|
|
pGroup->pEnemyGroup->ubNumTroops = 0;
|
|
pGroup->pEnemyGroup->ubNumElites = 20;
|
|
}
|
|
}
|
|
else if( pGroup->pEnemyGroup->ubNumTroops > pGroup->pEnemyGroup->ubNumElites )
|
|
{
|
|
if( pGroup->pEnemyGroup->ubNumTroops > pGroup->pEnemyGroup->ubNumAdmins )
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 0;
|
|
pGroup->pEnemyGroup->ubNumTroops = 20;
|
|
pGroup->pEnemyGroup->ubNumElites = 0;
|
|
}
|
|
else
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 20;
|
|
pGroup->pEnemyGroup->ubNumTroops = 0;
|
|
pGroup->pEnemyGroup->ubNumElites = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( pGroup->pEnemyGroup->ubNumElites > pGroup->pEnemyGroup->ubNumTroops )
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 0;
|
|
pGroup->pEnemyGroup->ubNumTroops = 0;
|
|
pGroup->pEnemyGroup->ubNumElites = 20;
|
|
}
|
|
else
|
|
{
|
|
pGroup->pEnemyGroup->ubNumAdmins = 0;
|
|
pGroup->pEnemyGroup->ubNumTroops = 20;
|
|
pGroup->pEnemyGroup->ubNumElites = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pGroup = pGroup->next;
|
|
}
|
|
}
|
|
|
|
|
|
void UpdateMercMercContractInfo()
|
|
{
|
|
UINT8 ubCnt;
|
|
SOLDIERTYPE *pSoldier;
|
|
|
|
for( ubCnt=BIFF; ubCnt<= BUBBA; ubCnt++ )
|
|
{
|
|
pSoldier = FindSoldierByProfileID( ubCnt, TRUE );
|
|
|
|
//if the merc is on the team
|
|
if( pSoldier == NULL )
|
|
continue;
|
|
|
|
gMercProfiles[ ubCnt ].iMercMercContractLength = pSoldier->iTotalContractLength;
|
|
|
|
pSoldier->iTotalContractLength = 0;
|
|
}
|
|
}
|
|
|
|
INT8 GetNumberForAutoSave( BOOLEAN fLatestAutoSave )
|
|
{
|
|
CHAR zFileName1[MAX_PATH];
|
|
CHAR zFileName2[MAX_PATH];
|
|
HWFILE hFile;
|
|
BOOLEAN fFile1Exist, fFile2Exist;
|
|
SGP_FILETIME CreationTime1, LastAccessedTime1, LastWriteTime1;
|
|
SGP_FILETIME CreationTime2, LastAccessedTime2, LastWriteTime2;
|
|
|
|
fFile1Exist = FALSE;
|
|
fFile2Exist = FALSE;
|
|
|
|
|
|
//The name of the file
|
|
sprintf( zFileName1, "%s\\Auto%02d.%S", gSaveDir, 0, pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
sprintf( zFileName2, "%s\\Auto%02d.%S", gSaveDir, 1, pMessageStrings[ MSG_SAVEEXTENSION ] );
|
|
|
|
if( FileExists( zFileName1 ) )
|
|
{
|
|
hFile = FileOpen( zFileName1, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
|
|
|
|
GetFileManFileTime( hFile, &CreationTime1, &LastAccessedTime1, &LastWriteTime1 );
|
|
|
|
FileClose( hFile );
|
|
|
|
fFile1Exist = TRUE;
|
|
}
|
|
|
|
if( FileExists( zFileName2 ) )
|
|
{
|
|
hFile = FileOpen( zFileName2, FILE_ACCESS_READ | FILE_OPEN_EXISTING, FALSE );
|
|
|
|
GetFileManFileTime( hFile, &CreationTime2, &LastAccessedTime2, &LastWriteTime2 );
|
|
|
|
FileClose( hFile );
|
|
|
|
fFile2Exist = TRUE;
|
|
}
|
|
|
|
if( !fFile1Exist && !fFile2Exist )
|
|
return( -1 );
|
|
else if( fFile1Exist && !fFile2Exist )
|
|
{
|
|
if( fLatestAutoSave )
|
|
return( 0 );
|
|
else
|
|
return( -1 );
|
|
}
|
|
else if( !fFile1Exist && fFile2Exist )
|
|
{
|
|
if( fLatestAutoSave )
|
|
return( 1 );
|
|
else
|
|
return( -1 );
|
|
}
|
|
else
|
|
{
|
|
if( CompareSGPFileTimes( &LastWriteTime1, &LastWriteTime2 ) > 0 )
|
|
return( 0 );
|
|
else
|
|
return( 1 );
|
|
}
|
|
}
|
|
|
|
void HandleOldBobbyRMailOrders()
|
|
{
|
|
INT32 iCnt;
|
|
INT32 iNewListCnt=0;
|
|
|
|
if( LaptopSaveInfo.usNumberOfBobbyRayOrderUsed != 0 )
|
|
{
|
|
//Allocate memory for the list
|
|
gpNewBobbyrShipments = (NewBobbyRayOrderStruct *) MemAlloc( sizeof( NewBobbyRayOrderStruct ) * LaptopSaveInfo.usNumberOfBobbyRayOrderUsed );
|
|
if( gpNewBobbyrShipments == NULL )
|
|
{
|
|
Assert(0);
|
|
return;
|
|
}
|
|
|
|
giNumberOfNewBobbyRShipment = LaptopSaveInfo.usNumberOfBobbyRayOrderUsed;
|
|
|
|
//loop through and add the old items to the new list
|
|
for( iCnt=0; iCnt< LaptopSaveInfo.usNumberOfBobbyRayOrderItems; iCnt++ )
|
|
{
|
|
//if this slot is used
|
|
if( LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray[iCnt].fActive )
|
|
{
|
|
//copy over the purchase info
|
|
memcpy( gpNewBobbyrShipments[ iNewListCnt ].BobbyRayPurchase,
|
|
LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray[iCnt].BobbyRayPurchase,
|
|
sizeof( BobbyRayPurchaseStruct ) * MAX_PURCHASE_AMOUNT );
|
|
|
|
gpNewBobbyrShipments[ iNewListCnt ].fActive = TRUE;
|
|
gpNewBobbyrShipments[ iNewListCnt ].ubDeliveryLoc = BR_DRASSEN;
|
|
gpNewBobbyrShipments[ iNewListCnt ].ubDeliveryMethod = 0;
|
|
gpNewBobbyrShipments[ iNewListCnt ].ubNumberPurchases = LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray[iCnt].ubNumberPurchases;
|
|
gpNewBobbyrShipments[ iNewListCnt ].uiPackageWeight = 1;
|
|
gpNewBobbyrShipments[ iNewListCnt ].uiOrderedOnDayNum = GetWorldDay();
|
|
gpNewBobbyrShipments[ iNewListCnt ].fDisplayedInShipmentPage = TRUE;
|
|
|
|
iNewListCnt++;
|
|
}
|
|
}
|
|
|
|
//Clear out the old list
|
|
LaptopSaveInfo.usNumberOfBobbyRayOrderUsed = 0;
|
|
MemFree( LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray );
|
|
LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
UINT32 CalcJA2EncryptionSet( SAVED_GAME_HEADER * pSaveGameHeader )
|
|
{
|
|
UINT32 uiEncryptionSet = 0;
|
|
|
|
uiEncryptionSet = pSaveGameHeader->uiSavedGameVersion;
|
|
uiEncryptionSet *= pSaveGameHeader->uiFlags;
|
|
uiEncryptionSet += pSaveGameHeader->iCurrentBalance;
|
|
uiEncryptionSet *= (pSaveGameHeader->ubNumOfMercsOnPlayersTeam + 1);
|
|
uiEncryptionSet += pSaveGameHeader->bSectorZ * 3;
|
|
uiEncryptionSet += pSaveGameHeader->ubLoadScreenID;
|
|
|
|
if ( pSaveGameHeader->fAlternateSector )
|
|
{
|
|
uiEncryptionSet += 7;
|
|
}
|
|
|
|
if ( pSaveGameHeader->uiRandom % 2 == 0 )
|
|
{
|
|
uiEncryptionSet++;
|
|
|
|
if ( pSaveGameHeader->uiRandom % 7 == 0)
|
|
{
|
|
uiEncryptionSet++;
|
|
if ( pSaveGameHeader->uiRandom % 23 == 0 )
|
|
{
|
|
uiEncryptionSet++;
|
|
}
|
|
if ( pSaveGameHeader->uiRandom % 79 == 0 )
|
|
{
|
|
uiEncryptionSet += 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef GERMAN
|
|
uiEncryptionSet *= 11;
|
|
#endif
|
|
|
|
uiEncryptionSet = uiEncryptionSet % 10;
|
|
|
|
uiEncryptionSet += pSaveGameHeader->uiDay / 10;
|
|
|
|
uiEncryptionSet = uiEncryptionSet % 19;
|
|
|
|
// now pick a different set of #s depending on what game options we've chosen
|
|
if ( pSaveGameHeader->sInitialGameOptions.fGunNut )
|
|
{
|
|
uiEncryptionSet += BASE_NUMBER_OF_ROTATION_ARRAYS * 6;
|
|
}
|
|
|
|
if ( pSaveGameHeader->sInitialGameOptions.ubGameStyle == STYLE_SCIFI)
|
|
{
|
|
uiEncryptionSet += BASE_NUMBER_OF_ROTATION_ARRAYS * 3;
|
|
}
|
|
|
|
switch( pSaveGameHeader->sInitialGameOptions.ubDifficultyLevel )
|
|
{
|
|
case DIF_LEVEL_EASY:
|
|
uiEncryptionSet += 0;
|
|
break;
|
|
case DIF_LEVEL_MEDIUM:
|
|
uiEncryptionSet += BASE_NUMBER_OF_ROTATION_ARRAYS;
|
|
break;
|
|
case DIF_LEVEL_HARD:
|
|
uiEncryptionSet += BASE_NUMBER_OF_ROTATION_ARRAYS * 2;
|
|
break;
|
|
case DIF_LEVEL_INSANE:
|
|
uiEncryptionSet += BASE_NUMBER_OF_ROTATION_ARRAYS * 3;
|
|
break;
|
|
}
|
|
|
|
return( uiEncryptionSet );
|
|
}
|