// Manages files for configuration and save state.
// Worthless Bums 2012.


// Creates an encryption string for the current save file.
function createEncryptionStringForSave ()
{//echo("createEncryptionStringForSave()";
	// Sets the file to directory path: "C:\Users\<user>\AppData\Roaming\Steam Marines\"
	%filePath = $UserDirectory @ "/Worthless Bums/Steam Marines/" @ "save" @ ".sav";
	// The save file object.
	%saveFile = new fileobject();
	// Check the file open status.
	%ret = %saveFile.OpenForRead(%filePath);
	
	// Can't open the file.
	if (!%ret)
	{//echo("Bad save file!");
		error("Invalid save file!");
		return false;
	}
	
	// String!
	%encryptionString = "";
	// Variables we track in the save file.
	for (%line = %saveFile.ReadLine(); !(%line $= ""); %line = %saveFile.ReadLine())
	{
		// Get a line.
		%wordCount = getWordCount(%line);
		for (%i = 0; %i < %wordCount; %i++)
		{
			// Get word.
			%word = getWord(%line, %i);
			
			// Append to encryption string.
			%encryptionString += %word;
			
			// Restrict precision.
			//%encryptionString = mFloatLength(%encryptionString, 32);
			//echo("%encryptionString =" SPC %encryptionString);
		}
	}
	
	// Restrict precision.
	%encryptionString = mFloatLength(%encryptionString, 32);
	//echo("%encryptionString =" SPC %encryptionString);
	
	// Close the file.
	%saveFile.close();
	
	// Writes the specified encryption string to save file.
	//writeEncryptionString(%encryptionString);
	
	// Return encryption string.
	return %encryptionString;
}
// Writes the specified encryption string to save file.
function writeEncryptionString (%encryptionString)
{//echo("writeEncryptionString()";
	// Sets the file to directory path: "C:\Users\<user>\AppData\Roaming\Steam Marines\"
	%filePath = $UserDirectory @ "/Worthless Bums/Steam Marines/" @ "save" @ ".sav";
	//%filePath = expandFilename(%filePath);
	// The save file object.
	%saveFile = new fileobject();
	// Check the file open status.
	%ret = %saveFile.OpenForAppend(%filePath);		// FAILS! Why?!?
	//echo("%filePath =" SPC %filePath);
	//echo("%ret =" SPC %ret);
	
	// Can't open the file.
	if (!%ret)
	{//echo("Bad save file!");
		error("Invalid save file!");
		return false;
	}
	
	// Append encryption string to EOF.
	%saveFile.WriteLine("EOFES " @ %encryptionString);
	
	// Close the file.
	%saveFile.close();
}

// Clears the persistent stats file state.
function clearPersistentStatsFile ()
{//echo("clearPersistentStatsFile()");
	// Only one save file at a time!
	//%userDirectory = $UserDirectory;
	//%savegameDirectory = %userDirectory @ "/Worthless Bums/Steam Marines/";
	//%filePath = %savegameDirectory @ "stats" @ ".per";
	%filePath = "../../../../stats.per";
	
	// Should get directory: "C:\Users\<user>\AppData\Roaming\".
	//%filePath = expandFilename(%filePath);
	
	// The save file object.
	%saveFile = new fileobject();
	// Check the file open status.
	%ret = %saveFile.OpenForRead(%filePath);
	
	// Can't open the file.
	if (!%ret)
	{//echo("No save file!");
		return false;
	}
	else
	{//echo("Deleting save file!");
		// Deletes the selected file!
		fileDelete(%filePath);
	}
	
	// Close the save file.
	%saveFile.close();
	
	
	return true;
}

// Clears the save file state.
function clearSaveFile ()
{//echo("clearSaveFile()");
	// Only one save file at a time!
	// Sets the file to directory path: "C:\Users\<user>\AppData\Roaming\Steam Marines\game\data\savegames"
	//%userDirectory = $UserDirectory;
	//%savegameDirectory = %userDirectory @ "/Worthless Bums/Steam Marines/";
	//%filePath = %savegameDirectory @ "save" @ ".sav";
	%filePath = getSaveGameFilePath();
	
	// Should get directory: "C:\Users\<user>\AppData\Roaming\".
	//%filePath = expandFilename(%filePath);
	
	// The save file object.
	%saveFile = new fileobject();
	// Check the file open status.
	%ret = %saveFile.OpenForRead(%filePath);
	
	// Can't open the file.
	if (!%ret)
	{//echo("No save file!");
		return false;
	}
	else
	{//echo("Deleting save file!");
		// Deletes the selected file!
		fileDelete(%filePath);
	}
	
	// Close the save file.
	%saveFile.close();
	
	
	return true;
}

// Checks the save state for display data on the main menu.
function checkSaveState ()
{//echo("checkSaveState()");
	// Only one save file at a time!
	// Sets the file to directory path: "C:\Users\<user>\AppData\Roaming\Steam Marines\game\data\savegames"
	//%userDirectory = $UserDirectory;
	//%savegameDirectory = %userDirectory @ "/Worthless Bums/Steam Marines/";
	//%filePath = %savegameDirectory @ "save" @ ".sav";
	%filePath = getSaveGameFilePath();
	
	// Should get directory: "C:\Users\<user>\AppData\Roaming\".
	//%filePath = expandFilename(%filePath);
	//echo("%filePath =" SPC %filePath);
	
	// Initialize keybindings.
	initializeKeybindOptions();
	
	// Load the save game data.
	// The save file object.
	%saveFile = new fileobject();
	// Check the file open status.
	%ret = %saveFile.OpenForRead(%filePath);
	
	// Can't open the file.
	if (!%ret)
	{//echo("Bad save file!");
		$validSaveState = false;
		return false;
	}
	else
	{
		// Set flag.
		$validSaveState = true;
	}
	
	// Variables we track in the save file.
	for (%line = %saveFile.ReadLine(); !(%line $= ""); %line = %saveFile.ReadLine())
	{
		// Get a line.
		%word = GetWord(%line, 0);
		//echo("%word =" SPC %word);
		
		// Load each parameter by line keyword.
		switch$ (%word)
		{
			// Save State Deck/Level data.
			case "overworldLocation":
				$saveStateDeck = restWords(%line);
			case "dungeonLevel":
				$dungeonLevel = restWords(%line);
				$saveStateLevel = $dungeonLevel;
			
			// New Game Plus data.
			case "NewGamePlus":
				$NewGamePlus = restWords(%line);
			case "NewGameStart":
				if (!$NewGameStart)
				{
					$NewGameStart = restWords(%line);
				}
			
			// Squad Leader data.
			case "leaderPersist":
				$leaderPersist = restWords(%line);
			case "leaderName":
				$squadLeaderName = restWords(%line);
			case "leaderClass":
				$squadLeaderClass = restWords(%line);
			case "leaderRank":
				$squadLeaderLevel = restWords(%line);
			case "leaderImageMap":
				$squadLeaderImageMap = restWords(%line);
			case "leaderWeapon":
				$squadLeaderWeaponImagemap = getWord(restWords(%line), 5);
			case "leaderArmor":
				$squadLeaderArmorImagemap = getWord(restWords(%line), 4);
				
			// Squad Scout data.
			case "scoutPersist":
				$scoutPersist = restWords(%line);
			case "scoutName":
				$squadScoutName = restWords(%line);
			case "scoutClass":
				$squadScoutClass = restWords(%line);
			case "scoutRank":
				$squadScoutLevel = restWords(%line);
			case "scoutImageMap":
				$squadScoutImageMap = restWords(%line);
			case "scoutWeapon":
				$squadScoutWeaponImagemap = getWord(restWords(%line), 5);
			case "scoutArmor":
				$squadScoutArmorImagemap = getWord(restWords(%line), 4);
				
			// Squad Grenadier data.
			case "grenadierPersist":
				$grenadierPersist = restWords(%line);
			case "grenadierName":
				$squadGrenadierName = restWords(%line);
			case "grenadierClass":
				$squadGrenadierClass = restWords(%line);
			case "grenadierRank":
				$squadGrenadierLevel = restWords(%line);
			case "grenadierImageMap":
				$squadGrenadierImageMap = restWords(%line);
			case "grenadierWeapon":
				$squadGrenadierWeaponImagemap = getWord(restWords(%line), 5);
			case "grenadierArmor":
				$squadGrenadierArmorImagemap = getWord(restWords(%line), 4);
				
			// Squad Support data.
			case "supportPersist":
				$supportPersist = restWords(%line);
			case "supportName":
				$squadSupportName = restWords(%line);
			case "supportClass":
				$squadSupportClass = restWords(%line);
			case "supportRank":
				$squadSupportLevel = restWords(%line);
			case "supportImageMap":
				$squadSupportImageMap = restWords(%line);
			case "supportWeapon":
				$squadSupportWeaponImagemap = getWord(restWords(%line), 5);
			case "supportArmor":
				$squadSupportArmorImagemap = getWord(restWords(%line), 4);
		}
	}
	
	// Close the save file.
	%saveFile.close();
	
	return true;
}

// Loads save data from file.
function loadSaveDataFromFile ()
{//echo("loadSaveDataFromFile()");
	%filePath = getSaveGameFilePath();
	initializeKeybindOptions();
	%saveFile = new fileobject();
	%ret = %saveFile.OpenForRead(%filePath);
	// Can't open the file.
	if (!%ret)
	{//echo("Bad save file!");
		error("Invalid save file!");
		return false;
	}
	
	// Variables we track in the save file.
	for (%line = %saveFile.ReadLine(); !(%line $= ""); %line = %saveFile.ReadLine())
	{
		// Get a line.
		%word = GetWord(%line, 0);
		//echo("%word =" SPC %word);
		
		// Load each parameter by line keyword.
		switch$ (%word)
		{
			// Difficulty Level.
			case "difficultyLevel":
				$difficultyLevel = restWords(%line);
				
			// Difficulty Level.
			case "gamePlayedTime":
				$gamePlayedTime = restWords(%line);
				
			// New Game Plus counter.
			case "NewGamePlus":
				$NewGamePlus = restWords(%line);
			// New Game Plus counter.
			case "NewGameStart":
				if (!$NewGameStart)
				{
					$NewGameStart = restWords(%line);
				}
			
			// On Overworld Map.
			case "onOverworldMap":
				$onOverworldMap = restWords(%line);
			// Overworld Location.
			case "overworldLocation":
				$overworldLocation = restWords(%line);
				
			// Infection Discovered.
			case "infectionDiscovered":
				$infectionDiscovered = restWords(%line);
				
			// Dungeon Level.
			case "dungeonLevel":
				$dungeonLevel = restWords(%line);
			// Command Deck Dungeon Level.
			case "commandDeckLevel":
				$commandDeckLevel = restWords(%line);
			// Engineering Deck Dungeon Level.
			case "engineeringDeckLevel":
				$engineeringDeckLevel = restWords(%line);
			// Medical Deck Dungeon Level.
			case "medicalDeckLevel":
				$medicalDeckLevel = restWords(%line);
			// Armory Deck Dungeon Level.
			case "armoryDeckLevel":
				$armoryDeckLevel = restWords(%line);
			// Bridge Deck Dungeon Level.
			case "bridgeDeckLevel":
				$bridgeDeckLevel = restWords(%line);
			// Alien Deck Dungeon Level.
			case "alienDeckLevel":
				$alienDeckLevel = restWords(%line);
				
			// Elevator power.
			case "elevatorPowered":
				$elevatorPowered = restWords(%line);
				
			// Active Character
			case "activeCharacter":
				$loadedActiveCharacter = restWords(%line);
				
			// Mission Objective data.
			case "primaryMissionID":
				$primaryMissionID = restWords(%line);
			case "primaryObjectiveStatus":
				$primaryObjectiveStatus = restWords(%line);
			case "secondaryMissionID":
				$secondaryMissionID = restWords(%line);
			case "secondaryObjectiveStatus":
				$secondaryObjectiveStatus = restWords(%line);
				
			// Squad State Flags.
			case "squadFoundStairs":
				$squadFoundStairs = restWords(%line);
				
			// Merchants Met Flag.
			case "MerchantsMet":
				$MerchantsMet = restWords(%line);
			// Times Merchant Accessed.
			case "merchantAccessed":
				$merchantAccessed = restWords(%line);
			// Squad Credits.
			case "squadCredits":
				$squadCredits = restWords(%line);
				
			// Disruptor Indices.
			case "disruptorIndices":
				%indices = restWords(%line);
				$ElevatorDisruptorXIndex = getWord(%indices, 0);
				$ElevatorDisruptorYIndex = getWord(%indices, 1);
				//createDisruptorAnimation($ElevatorDisruptorXIndex, $ElevatorDisruptorYIndex);
				
			// Multipass item used.
			case "multipassUsed":
				$multipassUsed = restWords(%line);
				
			// Gravity Well flag.
			case "GravityWellOn":
				$GravityWellOn = restWords(%line);
				
			// Load Ship Object Data.
			// Command Deck
			case "commandDeckHostileControl":
				$ship.commandDeckHostileControl = restWords(%line);
			case "commandDeckIntegrity":
				$ship.commandDeckIntegrity = restWords(%line);
			case "commandDeckMaxIntegrity":
				$ship.commandDeckMaxIntegrity = restWords(%line);
			case "commandDeckOxygen":
				$ship.commandDeckOxygen = restWords(%line);
			case "commandDeckMaxOxygen":
				$ship.commandDeckMaxOxygen = restWords(%line);
			case "commandDeckPower":
				$ship.commandDeckPower = restWords(%line);
			case "commandDeckMaxPower":
				$ship.commandDeckMaxPower = restWords(%line);
			case "commandDeckInfection":
				$ship.commandDeckInfection = restWords(%line);
			case "commandDeckMaxInfection":
				$ship.commandDeckMaxInfection = restWords(%line);
			case "commandDeckInvaded":
				$ship.commandDeckInvaded = restWords(%line);
			// Engineering Deck
			case "engineeringDeckHostileControl":
				$ship.engineeringDeckHostileControl = restWords(%line);
			case "engineeringDeckIntegrity":
				$ship.engineeringDeckIntegrity = restWords(%line);
			case "engineeringDeckMaxIntegrity":
				$ship.engineeringDeckMaxIntegrity = restWords(%line);
			case "engineeringDeckOxygen":
				$ship.engineeringDeckOxygen = restWords(%line);
			case "engineeringDeckMaxOxygen":
				$ship.engineeringDeckMaxOxygen = restWords(%line);
			case "engineeringDeckPower":
				$ship.engineeringDeckPower = restWords(%line);
			case "engineeringDeckMaxPower":
				$ship.engineeringDeckMaxPower = restWords(%line);
			case "engineeringDeckInfection":
				$ship.engineeringDeckInfection = restWords(%line);
			case "engineeringDeckMaxInfection":
				$ship.engineeringDeckMaxInfection = restWords(%line);
			case "engineeringDeckInvaded":
				$ship.engineeringDeckInvaded = restWords(%line);
			// Medical Deck
			case "medicalDeckHostileControl":
				$ship.medicalDeckHostileControl = restWords(%line);
			case "medicalDeckIntegrity":
				$ship.medicalDeckIntegrity = restWords(%line);
			case "medicalDeckMaxIntegrity":
				$ship.medicalDeckMaxIntegrity = restWords(%line);
			case "medicalDeckOxygen":
				$ship.medicalDeckOxygen = restWords(%line);
			case "medicalDeckMaxOxygen":
				$ship.medicalDeckMaxOxygen = restWords(%line);
			case "medicalDeckPower":
				$ship.medicalDeckPower = restWords(%line);
			case "medicalDeckMaxPower":
				$ship.medicalDeckMaxPower = restWords(%line);
			case "medicalDeckInfection":
				$ship.medicalDeckInfection = restWords(%line);
			case "medicalDeckMaxInfection":
				$ship.medicalDeckMaxInfection = restWords(%line);
			case "medicalDeckInvaded":
				$ship.medicalDeckInvaded = restWords(%line);
			// Armory Deck
			case "armoryDeckHostileControl":
				$ship.armoryDeckHostileControl = restWords(%line);
			case "armoryDeckIntegrity":
				$ship.armoryDeckIntegrity = restWords(%line);
			case "armoryDeckMaxIntegrity":
				$ship.armoryDeckMaxIntegrity = restWords(%line);
			case "armoryDeckOxygen":
				$ship.armoryDeckOxygen = restWords(%line);
			case "armoryDeckMaxOxygen":
				$ship.armoryDeckMaxOxygen = restWords(%line);
			case "armoryDeckPower":
				$ship.armoryDeckPower = restWords(%line);
			case "armoryDeckMaxPower":
				$ship.armoryDeckMaxPower = restWords(%line);
			case "armoryDeckInfection":
				$ship.commandDeckInfection = restWords(%line);
			case "armoryDeckMaxInfection":
				$ship.commandDeckMaxInfection = restWords(%line);
			case "armoryDeckInvaded":
				$ship.armoryDeckInvaded = restWords(%line);
			// Bridge Deck
			case "bridgeDeckHostileControl":
				$ship.bridgeDeckHostileControl = restWords(%line);
			case "bridgeDeckIntegrity":
				$ship.bridgeDeckIntegrity = restWords(%line);
			case "bridgeDeckMaxIntegrity":
				$ship.bridgeDeckMaxIntegrity = restWords(%line);
			case "bridgeDeckOxygen":
				$ship.bridgeDeckOxygen = restWords(%line);
			case "bridgeDeckMaxOxygen":
				$ship.bridgeDeckMaxOxygen = restWords(%line);
			case "bridgeDeckPower":
				$ship.bridgeDeckPower = restWords(%line);
			case "bridgeDeckMaxPower":
				$ship.bridgeDeckMaxPower = restWords(%line);
			case "bridgeDeckInfection":
				$ship.bridgeDeckInfection = restWords(%line);
			case "bridgeDeckMaxInfection":
				$ship.bridgeDeckMaxInfection = restWords(%line);
			case "bridgeDeckInvaded":
				$ship.bridgeDeckInvaded = restWords(%line);
			// Alien Deck
			case "alienDeckHostileControl":
				$ship.alienDeckHostileControl = restWords(%line);
			case "alienDeckIntegrity":
				$ship.alienDeckIntegrity = restWords(%line);
			case "alienDeckMaxIntegrity":
				$ship.alienDeckMaxIntegrity = restWords(%line);
			case "alienDeckOxygen":
				$ship.alienDeckOxygen = restWords(%line);
			case "alienDeckMaxOxygen":
				$ship.alienDeckMaxOxygen = restWords(%line);
			case "alienDeckPower":
				$ship.alienDeckPower = restWords(%line);
			case "alienDeckMaxPower":
				$ship.alienDeckMaxPower = restWords(%line);
			case "alienDeckInfection":
				$ship.alienDeckInfection = restWords(%line);
			case "alienDeckMaxInfection":
				$ship.alienDeckMaxInfection = restWords(%line);
			case "alienDeckInvaded":
				$ship.alienDeckInvaded = restWords(%line);
			
			// Global Statistics.
			case "currentTurn":
				$GlobalStats.currentTurn = restWords(%line);
			case "totalLevelsPassed":
				$GlobalStats.totalLevelsPassed = restWords(%line);
			case "totalPrimaryMissionObjectivesCompleted":
				$GlobalStats.totalPrimaryMissionObjectivesCompleted = restWords(%line);
			case "totalSecondaryMissionObjectivesCompleted":
				$GlobalStats.totalSecondaryMissionObjectivesCompleted = restWords(%line);
			case "totalGuardModes":
				$GlobalStats.totalGuardModes = restWords(%line);
			case "totalSquadMemberDeaths":
				$GlobalStats.totalSquadMemberDeaths = restWords(%line);
			case "totalSurvivorsRecruited":
				$GlobalStats.totalSurvivorsRecruited = restWords(%line);
			case "totalKills":
				$GlobalStats.totalKills = restWords(%line);
			case "totalAmmunitionExpended":
				$GlobalStats.totalAmmunitionExpended = restWords(%line);
			case "totalAmmunitionMassExpended":
				$GlobalStats.totalAmmunitionMassExpended = restWords(%line);
			case "totalMeleeAttacks":
				$GlobalStats.totalMeleeAttacks = restWords(%line);
			case "totalDamageDealt":
				$GlobalStats.totalDamageDealt = restWords(%line);
			case "totalDamageTaken":
				$GlobalStats.totalDamageTaken = restWords(%line);
			case "totalEnemiesKnockedIntoSpace":
				$GlobalStats.totalEnemiesKnockedIntoSpace = restWords(%line);
			case "totalWallsSmashed":
				$GlobalStats.totalWallsSmashed = restWords(%line);
			case "totalCratesSmashed":
				$GlobalStats.totalCratesSmashed = restWords(%line);
			case "totalDispensersUsed":
				$GlobalStats.totalDispensersUsed = restWords(%line);
			case "totalConsolesUsed":
				$GlobalStats.totalConsolesUsed = restWords(%line);
			case "totalDoorsOpened":
				$GlobalStats.totalDoorsOpened = restWords(%line);
			case "totalDoorsClosed":
				$GlobalStats.totalDoorsClosed = restWords(%line);
			case "totalItemsGrabbed":
				$GlobalStats.totalItemsGrabbed = restWords(%line);
			case "totalItemsUsed":
				$GlobalStats.totalItemsUsed = restWords(%line);
			case "totalChestsOpened":
				$GlobalStats.totalChestsOpened = restWords(%line);
			case "totalLightSwitchesUsed":
				$GlobalStats.totalLightSwitchesUsed = restWords(%line);
	
			
			// Squad Leader data.
			case "leaderPersist":
				$leaderPersist = restWords(%line);
			case "leaderName":
				$playerSquad[0].name = restWords(%line);
			case "leaderClass":
				$playerSquad[0].characterClass = restWords(%line);
			case "leaderRank":
				$playerSquad[0].rank = restWords(%line);
			case "leaderLevel":
				$playerSquad[0].level = restWords(%line);
			case "leaderExperience":
				$playerSquad[0].experience = restWords(%line);
			case "leaderGender":
				$playerSquad[0].gender = restWords(%line);
			case "leaderImageMap":
				$playerSquad[0].imageMap = restWords(%line);
				
			case "leaderPosition":
				$playerSquad[0].position = restWords(%line);
			case "leaderXIndex":
				$playerSquad[0].xIndex = restWords(%line);
			case "leaderYIndex":
				$playerSquad[0].yIndex = restWords(%line);
			case "leaderFacing":
				$playerSquad[0].facing = restWords(%line);
				
			case "leaderGuardMode":
				$playerSquad[0].guardMode = restWords(%line);
				
			case "leaderCurrentHealth":
				$playerSquad[0].currentHealth = restWords(%line);
			case "leaderMaxHealth":
				$playerSquad[0].maxHealth = restWords(%line);
			case "leaderArmorRating":
				$playerSquad[0].armorRating = restWords(%line);
			case "leaderCurrentActionPoints":
				$playerSquad[0].currentActionPoints = restWords(%line);
			case "leaderMaxActionPoints":
				$playerSquad[0].maxActionPoints = restWords(%line);
			case "leaderOxygen":
				$playerSquad[0].oxygen = restWords(%line);
			case "leaderSight":
				$playerSquad[0].sight = restWords(%line);
				
			case "leaderPower":
				$playerSquad[0].power = restWords(%line);
			case "leaderSpeed":
				$playerSquad[0].speed = restWords(%line);
			case "leaderEndurance":
				$playerSquad[0].endurance = restWords(%line);
				
			case "leaderBash":
				$playerSquad[0].bash = restWords(%line);
			case "leaderDemolitions":
				$playerSquad[0].demolitions = restWords(%line);
			case "leaderArms":
				$playerSquad[0].arms = restWords(%line);
			case "leaderRetraining":
				$playerSquad[0].retraining = restWords(%line);
				
			case "leaderWeapon":
				%weaponCode = restWords(%line);
				$playerSquad[0].weapon = createNewWeapon(restWords(%line));//restWords(%line);
				($playerSquad[0].weapon).currentAmmo = getWord(%weaponCode, 9);
			case "leaderArmor":
				$playerSquad[0].armor = createNewArmor(restWords(%line));//restWords(%line);
			case "leaderammo":
				$playerSquad[0].ammo = restWords(%line);
				
			case "leaderKills":
				$playerSquad[0].kills = restWords(%line);
				
			case "leaderEvasion":
				$playerSquad[0].evasion = restWords(%line);
				
			case "leaderTalentPoints":
				$playerSquad[0].talentPoints = restWords(%line);
			case "leaderStatPoints":
				$playerSquad[0].statPoints = restWords(%line);
			case "leaderSkillPoints":
				$playerSquad[0].skillPoints = restWords(%line);
			case "leaderTalents":
				$playerSquad[0].talents = restWords(%line);
			case "leaderPerks":
				$playerSquad[0].perks = restWords(%line);
			case "leaderWeaponAttachment":
				$leaderWeaponAttachment = restWords(%line);
				
			case "leaderVehicle":
				$playerSquad[0].vehicle = restWords(%line);
				setSquadMemberVehicleStatus(0);
			
			
			// Squad Scout data.
			case "scoutPersist":
				$scoutPersist = restWords(%line);
			case "scoutName":
				$playerSquad[1].name = restWords(%line);
			case "scoutClass":
				$playerSquad[1].characterClass = restWords(%line);
			case "scoutRank":
				$playerSquad[1].rank = restWords(%line);
			case "scoutLevel":
				$playerSquad[1].level = restWords(%line);
			case "scoutExperience":
				$playerSquad[1].experience = restWords(%line);
			case "scoutGender":
				$playerSquad[1].gender = restWords(%line);
			case "scoutImageMap":
				$playerSquad[1].imageMap = restWords(%line);
				
			case "scoutPosition":
				$playerSquad[1].position = restWords(%line);
			case "scoutXIndex":
				$playerSquad[1].xIndex = restWords(%line);
			case "scoutYIndex":
				$playerSquad[1].yIndex = restWords(%line);
			case "scoutFacing":
				$playerSquad[1].facing = restWords(%line);
				
			case "scoutGuardMode":
				$playerSquad[1].guardMode = restWords(%line);
				
			case "scoutCurrentHealth":
				$playerSquad[1].currentHealth = restWords(%line);
			case "scoutMaxHealth":
				$playerSquad[1].maxHealth = restWords(%line);
			case "scoutArmorRating":
				$playerSquad[1].armorRating = restWords(%line);
			case "scoutCurrentActionPoints":
				$playerSquad[1].currentActionPoints = restWords(%line);
			case "scoutMaxActionPoints":
				$playerSquad[1].maxActionPoints = restWords(%line);
			case "scoutOxygen":
				$playerSquad[1].oxygen = restWords(%line);
			case "scoutSight":
				$playerSquad[1].sight = restWords(%line);
				
			case "scoutPower":
				$playerSquad[1].power = restWords(%line);
			case "scoutSpeed":
				$playerSquad[1].speed = restWords(%line);
			case "scoutEndurance":
				$playerSquad[1].endurance = restWords(%line);
				
			case "scoutBash":
				$playerSquad[1].bash = restWords(%line);
			case "scoutDemolitions":
				$playerSquad[1].demolitions = restWords(%line);
			case "scoutArms":
				$playerSquad[1].arms = restWords(%line);
			case "scoutRetraining":
				$playerSquad[1].retraining = restWords(%line);
				
			case "scoutWeapon":
				$playerSquad[1].weapon = createNewWeapon(restWords(%line));//restWords(%line);
			case "scoutArmor":
				$playerSquad[1].armor = createNewArmor(restWords(%line));//restWords(%line);
			case "scoutammo":
				$playerSquad[1].ammo = restWords(%line);
				
			case "scoutKills":
				$playerSquad[1].kills = restWords(%line);
				
			case "scoutEvasion":
				$playerSquad[1].evasion = restWords(%line);
					
			case "scoutTalentPoints":
				$playerSquad[1].talentPoints = restWords(%line);
			case "scoutStatPoints":
				$playerSquad[1].statPoints = restWords(%line);
			case "scoutSkillPoints":
				$playerSquad[1].skillPoints = restWords(%line);
			case "scoutTalents":
				$playerSquad[1].talents = restWords(%line);
			case "scoutPerks":
				$playerSquad[1].perks = restWords(%line);
			case "scoutWeaponAttachment":
				$scoutWeaponAttachment = restWords(%line);
				
			case "scoutVehicle":
				$playerSquad[1].vehicle = restWords(%line);
				setSquadMemberVehicleStatus(1);
			
			
			// Squad Grenadier data.
			case "grenadierPersist":
				$grenadierPersist = restWords(%line);
			case "grenadierName":
				$playerSquad[2].name = restWords(%line);
			case "grenadierClass":
				$playerSquad[2].characterClass = restWords(%line);
			case "grenadierRank":
				$playerSquad[2].rank = restWords(%line);
			case "grenadierLevel":
				$playerSquad[2].level = restWords(%line);
			case "grenadierExperience":
				$playerSquad[2].experience = restWords(%line);
			case "grenadierGender":
				$playerSquad[2].gender = restWords(%line);
			case "grenadierImageMap":
				$playerSquad[2].imageMap = restWords(%line);
				
			case "grenadierPosition":
				$playerSquad[2].position = restWords(%line);
			case "grenadierXIndex":
				$playerSquad[2].xIndex = restWords(%line);
			case "grenadierYIndex":
				$playerSquad[2].yIndex = restWords(%line);
			case "grenadierFacing":
				$playerSquad[2].facing = restWords(%line);
				
			case "grenadierGuardMode":
				$playerSquad[2].guardMode = restWords(%line);
				
			case "grenadierCurrentHealth":
				$playerSquad[2].currentHealth = restWords(%line);
			case "grenadierMaxHealth":
				$playerSquad[2].maxHealth = restWords(%line);
			case "grenadierArmorRating":
				$playerSquad[2].armorRating = restWords(%line);
			case "grenadierCurrentActionPoints":
				$playerSquad[2].currentActionPoints = restWords(%line);
			case "grenadierMaxActionPoints":
				$playerSquad[2].maxActionPoints = restWords(%line);
			case "grenadierOxygen":
				$playerSquad[2].oxygen = restWords(%line);
			case "grenadierSight":
				$playerSquad[2].sight = restWords(%line);
				
			case "grenadierPower":
				$playerSquad[2].power = restWords(%line);
			case "grenadierSpeed":
				$playerSquad[2].speed = restWords(%line);
			case "grenadierEndurance":
				$playerSquad[2].endurance = restWords(%line);
				
			case "grenadierBash":
				$playerSquad[2].bash = restWords(%line);
			case "grenadierDemolitions":
				$playerSquad[2].demolitions = restWords(%line);
			case "grenadierArms":
				$playerSquad[2].arms = restWords(%line);
			case "grenadierRetraining":
				$playerSquad[2].retraining = restWords(%line);
				
			case "grenadierWeapon":
				$playerSquad[2].weapon = createNewWeapon(restWords(%line));//restWords(%line);
			case "grenadierArmor":
				$playerSquad[2].armor = createNewArmor(restWords(%line));//restWords(%line);
			case "grenadierammo":
				$playerSquad[2].ammo = restWords(%line);
				
			case "grenadierKills":
				$playerSquad[2].kills = restWords(%line);
				
			case "grenadierEvasion":
				$playerSquad[2].evasion = restWords(%line);
					
			case "grenadierTalentPoints":
				$playerSquad[2].talentPoints = restWords(%line);
			case "grenadierStatPoints":
				$playerSquad[2].statPoints = restWords(%line);
			case "grenadierSkillPoints":
				$playerSquad[2].skillPoints = restWords(%line);
			case "grenadierTalents":
				$playerSquad[2].talents = restWords(%line);
			case "grenadierPerks":
				$playerSquad[2].perks = restWords(%line);
			case "grenadierWeaponAttachment":
				$grenadierWeaponAttachment = restWords(%line);
				
			case "grenadierVehicle":
				$playerSquad[2].vehicle = restWords(%line);
				setSquadMemberVehicleStatus(2);
			
			
			// Squad Support data.
			case "supportPersist":
				$supportPersist = restWords(%line);
			case "supportName":
				$playerSquad[3].name = restWords(%line);
			case "supportClass":
				$playerSquad[3].characterClass = restWords(%line);
			case "supportRank":
				$playerSquad[3].rank = restWords(%line);
			case "supportLevel":
				$playerSquad[3].level = restWords(%line);
			case "supportExperience":
				$playerSquad[3].experience = restWords(%line);
			case "supportGender":
				$playerSquad[3].gender = restWords(%line);
			case "supportImageMap":
				$playerSquad[3].imageMap = restWords(%line);
				
			case "supportPosition":
				$playerSquad[3].position = restWords(%line);
			case "supportXIndex":
				$playerSquad[3].xIndex = restWords(%line);
			case "supportYIndex":
				$playerSquad[3].yIndex = restWords(%line);
			case "supportFacing":
				$playerSquad[3].facing = restWords(%line);
				
			case "supportGuardMode":
				$playerSquad[3].guardMode = restWords(%line);
				
			case "supportCurrentHealth":
				$playerSquad[3].currentHealth = restWords(%line);
			case "supportMaxHealth":
				$playerSquad[3].maxHealth = restWords(%line);
			case "supportArmorRating":
				$playerSquad[3].armorRating = restWords(%line);
			case "supportCurrentActionPoints":
				$playerSquad[3].currentActionPoints = restWords(%line);
			case "supportMaxActionPoints":
				$playerSquad[3].maxActionPoints = restWords(%line);
			case "supportOxygen":
				$playerSquad[3].oxygen = restWords(%line);
			case "supportSight":
				$playerSquad[3].sight = restWords(%line);
				
			case "supportPower":
				$playerSquad[3].power = restWords(%line);
			case "supportSpeed":
				$playerSquad[3].speed = restWords(%line);
			case "supportEndurance":
				$playerSquad[3].endurance = restWords(%line);
				
			case "supportBash":
				$playerSquad[3].bash = restWords(%line);
			case "supportDemolitions":
				$playerSquad[3].demolitions = restWords(%line);
			case "supportArms":
				$playerSquad[3].arms = restWords(%line);
			case "supportRetraining":
				$playerSquad[3].retraining = restWords(%line);
				
			case "supportWeapon":
				$playerSquad[3].weapon = createNewWeapon(restWords(%line));//restWords(%line);
			case "supportArmor":
				$playerSquad[3].armor = createNewArmor(restWords(%line));//restWords(%line);
			case "supportammo":
				$playerSquad[3].ammo = restWords(%line);
				
			case "supportKills":
				$playerSquad[3].kills = restWords(%line);
				
			case "supportEvasion":
				$playerSquad[3].evasion = restWords(%line);
					
			case "supportTalentPoints":
				$playerSquad[3].talentPoints = restWords(%line);
			case "supportStatPoints":
				$playerSquad[3].statPoints = restWords(%line);
			case "supportSkillPoints":
				$playerSquad[3].skillPoints = restWords(%line);
			case "supportTalents":
				$playerSquad[3].talents = restWords(%line);
			case "supportPerks":
				$playerSquad[3].perks = restWords(%line);
			case "supportWeaponAttachment":
				$supportWeaponAttachment = restWords(%line);
				
			case "supportVehicle":
				$playerSquad[3].vehicle = restWords(%line);
				setSquadMemberVehicleStatus(3);
			
			// NOTE: Statement "%item.setVisible(false);" will return unknown command for weapons and armor!
			//		 Benign, but should take into account weapon/armor object creation.
			//		 Also complains about lack of weapon/armor _h, _d, _i; these are benign warnings.
			case "InventoryItem1":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem2":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem3":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem4":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem5":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem6":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem7":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem8":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem9":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem10":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem11":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
			case "InventoryItem12":
				if (isObject($squadInventory))
				{
					%itemType = restWords(%line);
					%item = getItemFromSaveFile(%itemType, 0 SPC 0, 0, 0);
					//%item.setVisible(false);
					$squadInventory.add(%item);
				}
		}
	}
	
	// Close the save file.
	%saveFile.close();
}

// Loads the save game data into a new game.
//function LoadSaveGameData (%filePath)
function loadOnlySave ()
{//echo("loadOnlySave()");//echo("$NewGameStart =" SPC $NewGameStart);
	if (!checkSaveState())
	{
		playAudio("Audio:cantLoad", EffectsAudioVolume.value);
		return;
	}
	
	// Make sure to track this flag when loading a game!
	%generateNewLevel = $generateNewLevel;
	$generateNewLevelFromLoad = %generateNewLevel;		// $generateNewLevelFromLoad is used for loading certain data from save file!
	
	// Force new level generation when loading a save game flagged as a fresh New Game Plus.
	if ($NewGameStart)
	{
		$generateNewLevelFromLoad = true;	// For loading special data.
		$generateNewLevel = true;			// For generating a new level in function newGameButton().
		//$NewGameStart = 0;
		//echo("$NewGameStart =" SPC $NewGameStart);		// Don't do this here or fileManager.cs save file functions will flag incorrectly to file!
	}
	
	// Anti-save scummer alert! Save game if one is in progress!
	if ($gameInProgress)
	{
		// Save the current game.
		saveCurrentGame();
	}
	
	// Initialize global variables.
	initializeGlobals();
	
	// Set flag for function createNewSquad().
	$loadFromSave = true;
	
	// Need a game clear then launch the load state!
	// End the level.
	//sceneWindow2D.endLevel();
	destroyCurrentLevel();
	
	// Call this before or after file load? Should be after...
	// NOTE: This needs to know the status of $overworldLocation in the existing save file prior to executing!
	newGameButton(true);		// NOTE: Need to spawn monsters after code below that loads the dungeon level!
								// HACK
								//$generateNewLevel is set to false at the end of function newGamebutton()! Persist flag value in %generateNewLevel instead of $generateNewLevel!
								// END OF HACK
	
	// Persist squad inventory initialization!
	clearSquadInventory();
	createSquadInventory();
	
	// Load save data from file.
	loadSaveDataFromFile();
	
	// To hide monster HP/AP floating text!
	$fogOfWar.updateMonsterVisibility();
	
	// Flag all characters as not persistent - read from save file to determine their actual status!
	$currentSquadSize = $maxSquadSize;
	$activeCharacter = -1;
	if (!$leaderPersist)
	{//echo("Deleting Leader!");
		//$playerSquad[0].safeDelete();
		$playerSquad[0] = null;
		$currentSquadSize--;
		
		if ($activeCharacter == -1)			// Not necessary...
		{
			$activeCharacter = 1;
		}
	}
	else
	{
		$activeCharacter = 0;
	}
	if (!$scoutPersist)
	{//echo("Deleting Scout!");
		//$playerSquad[1].safeDelete();
		$playerSquad[1] = null;
		$currentSquadSize--;
		
		if ($activeCharacter == -1)
		{
			$activeCharacter = 2;
		}
	}
	else
	{
		if (!$leaderPersist)
		{
			$activeCharacter = 1;
		}
	}
	if (!$grenadierPersist)
	{//echo("Deleting Grenadier!");
		//$playerSquad[2].safeDelete();
		$playerSquad[2] = null;
		$currentSquadSize--;
		
		if ($activeCharacter == -1)
		{
			$activeCharacter = 3;
		}
	}
	else
	{
		if (!$scoutPersist)
		{
			$activeCharacter = 2;
		}
	}
	if (!$supportPersist)
	{//echo("Deleting Support!");
		//$playerSquad[3].safeDelete();
		$playerSquad[3] = null;
		$currentSquadSize--;
		
		if ($activeCharacter == -1)		// And this means an empty squad!
		{
			$activeCharacter = 0;
			
			// Should run clean main menu launch here!
			// Bad save state!
		}
	}
	else
	{
		if (!$grenadierPersist)
		{
			$activeCharacter = 3;
		}
	}
	
	// Mount squad weapons after reading from file.
	mountSquadWeapons();
	// Create lifted tile marker animations if required.
	if ($leaderPersist)
	{
		handleLiftedTileMarker($playerSquad[0]);
	}
	if ($scoutPersist)
	{
		handleLiftedTileMarker($playerSquad[1]);
	}
	if ($grenadierPersist)
	{
		handleLiftedTileMarker($playerSquad[2]);
	}
	if ($supportPersist)
	{
		handleLiftedTileMarker($playerSquad[3]);
	}
	// Updates the Squad Information Gui.
	updateSquadInfoGui();
	
	// We have a save state! Check $onOverworldMap!
	if ($onOverworldMap)
	{
		// Push the Overworld Map instead of loading a dungeon level.
		pushOverworld();
		return;
	}
	else
	{
		// Update portraits.
		updatePortraits();
	}
	
	// Start minimap.
	startMinimap();
	// Update talent bars.
	updateTalentBarIcons();
	// Enforce squad facings!
	enforceSquadFacing();
	// Update Guard Mode animations.
	updateGuardModeAnimations();
	
	// Move the squad if we're generating a new level - no good squad position data persists in save file!
	if (%generateNewLevel)
	{
		// Move squad to free area.
		moveSquadToFreeArea();
		// Initialize Mission Objectives.
		initializeMissionObjectives();
	}
	
	// Set active character.
	selectSquadMember($loadedActiveCharacter);
	// Properly orient weapon attachments.
	orientSquadMemberWeaponAttachments();
	// Enforce monster positions.
	enforceMonsterPositions();
	// Update mission objectives.
	updateMissionObjectivesText();
	// Set load flag to false.
	$loadFromSave = false;
	// Load all special data from save file!
	loadSpecialData();
	// Update monster health indicators.
	handleHealthIndicators();
	// Update monsters' floating text.
	updateMonsterFloatingText();
	// Attach all unit shadows.
	attachAllUnitShadows();
	// Update Deck Stats text.
	updateDeckStats();
	
	// Zoom to proper level!
	switch ($scaleLevel)
	{
		case 1:	schedule(150, 0, "setZoom1x");
		case 2:	schedule(150, 0, "setZoom2x");
		case 3:	schedule(150, 0, "setZoom3x");
	}
	
	// Updates sceneWindow2D position.
	updateCameraPosition();
	
	// Play level music.
	if ($overworldLocation $= "Command Deck"	&&			// Hulk encounter in progress!
		isHulkSpawned())
	{
		schedule(4500, 0, "playBGMOgg", "Audio:actionLoop", MusicAudioVolume.value);
	}
	else if ($overworldLocation $= "Engineering Deck"	&&	// Revenant encounter in progress!
			 isRevenantSpawned())
	{
		schedule(4500, 0, "playBGMOgg", "Audio:actionLoop", MusicAudioVolume.value);
	}
	else if ($overworldLocation $= "Medical Deck"	&&		// Brainien encounter in progress!
			 isBrainienSpawned())
	{
		schedule(4500, 0, "playBGMOgg", "Audio:actionLoop", MusicAudioVolume.value);
	}
	else if ($overworldLocation $= "Armory Deck"	&&		// Gunship encounter in progress!
			 isGunshipSpawned())
	{
		schedule(4500, 0, "playBGMOgg", "Audio:actionLoop", MusicAudioVolume.value);
	}
	else
	{
		playLevelMusic();
	}
	// Fade in music.
	fadeIn(0);
	
	// To hide monster HP/AP floating text!
	$fogOfWar.updateMonsterVisibility();
	
	// Updated elevator animation state!
	updateElevatorArrowAnimation();
	
	// Update Control Panel tooltips.
	updateControlPanelTooltips();
	
	// Update FirearmUI (weapon attachments).
	setLoadGameWeaponAttachmentUI();
	
	// Corrects any misplaced doors.
	correctDoors();
	
	// Fix save file writing non-idle animation!
	enforceMonsterPositions();
	
	// Full cover fog of war.
	$fogOfWar.fullCoverFog();
	// Flag as New Game Plus initiated!
	if ($NewGameStart)
	{
		//$fogOfWar.showFogOfWar();
		$NewGameStart = 0;
		executeNewGameDialogue();
		// Move squad to free area.
		moveSquadToFreeArea();
		// Refill squad AP.
		if ($leaderPersist)
		{
			$playerSquad[0].currentActionPoints = $playerSquad[0].maxActionPoints;
		}
		if ($scoutPersist)
		{
			$playerSquad[1].currentActionPoints = $playerSquad[1].maxActionPoints;
		}
		if ($grenaderPersist)
		{
			$playerSquad[2].currentActionPoints = $playerSquad[2].maxActionPoints;
		}
		if ($supportPersist)
		{
			$playerSquad[3].currentActionPoints = $playerSquad[3].maxActionPoints;
		}
	}
	// Force fog of war update when loading a save game flagged as a fresh New Game Plus.
	$fogOfWar.showFogOfWar();
	
	// Turn off physics!
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			if (isObject($mazeRoom[%i, %j]))
			{
				$mazeRoom[%i, %j].CollisionPhysicsReceieve = "0";
				$mazeRoom[%i, %j].CollisionPhysicsSend = "0";
			}
		}
	}
	
	// Load Preloaded.
	setPreloadedTilemap();
	
	// Save current game to avoid any middle-of-loading data persistence issues!
	saveCurrentGame();
	
	// Delay this!
	//pushDeckStatsText();	// Time to ambient music?
	schedule(1700, 0, "pushDeckStatsText");
}

// Loads special game data from save file.
function loadSpecialData ()
{//echo("loadSpecialData()");
	loadCurrentMonsterData();
	loadCurrentFogOfWarData();
	loadCurrentItemData();
	loadCurrentBarrelData();
	loadCurrentConsoleData();
	loadCurrentDispenserData();
	loadCurrentLightSwitchData();
	loadCurrentTileDestructionData();
	loadCurrentTreasureChestData();
	loadCurrentTrapData();
	loadCurrentGratingData();
	loadCurrentCryoTubeData();
	loadCurrentLockersData();
	loadCurrentCorpseData();
	loadCurrentTurretData();
	
	setElevatorTile();
	createElevatorArrowAnimation();
	if ($squadFoundStairs)
	{
		placeElevatorZone();
	}
	
	if ($ElevatorDisruptorXIndex != -1	&&
		$ElevatorDisruptorYIndex != -1)
	{//echo("create disruptor animation!");
		createDisruptorAnimation($ElevatorDisruptorXIndex, $ElevatorDisruptorYIndex);
	}
	
	// Only reset flags after loading all special data from save file!
	$generateNewLevelFromLoad = false;
	$generateNewLevel = false;
}

// Load persistent stat data.
function loadPersistentStats ()
{//echo("loadPersistentStats()");
	%userDirectory = $UserDirectory;
	//%savegameDirectory = %userDirectory @ "/Worthless Bums/Steam Marines/game/data/saves/";
	//%file = %savegameDirectory @ "stats" @ ".per";
	//%file = expandFilename(%file);
	%file = "../../../../stats.per";
	%perStatsFile = new fileobject();
	%ret = %perStatsFile.OpenForRead("stats" @ ".per");
	%line = %perStatsFile.readLine();
	%word = getWord(%line, 0);
	if (%word !$= "deathSlots")
	{
		%perStatsFile.close();
		return false;
	}
	$PersistentStats[10] = "";
	for (%i = 0; %i < 10; %i++)
	{
		%line = %perStatsFile.ReadLine();
		// This really should be outside the loop...
		if (getWord(%line, 0) $= "null")
		{
			$PersistentStats[%i] = "null";		// Kinda redundant for now, but possibly not later on!
		}
		else
		{
			$PersistentStats[%i] = %line;
		}
	}
	%perStatsFile.close();
}
function savePersistentStats ()
{//echo("savePersistentStats()");
	if ($LastMarineName !$= "")
	{
		%currentRecord = calculateCurrentPersistentRecord();
		insertPersistentStatsRecord(%currentRecord);
		$LastMarineName = "";
	}
	%userDirectory = $UserDirectory;
	%savegameDirectory = %userDirectory @ "/Worthless Bums/Steam Marines/game/data/saves/";
	%file = %savegameDirectory @ "stats" @ ".per";
	//%file = expandFilename(%file);
	%perStatsFile = new fileobject();
	%perStatsFile.OpenForWrite("stats" @ ".per");
	%perStatsFile.WriteLine("deathslots " @ $currentGameVersion);
	for (%i = 0; %i < 10; %i++)
	{
		if ($PersistentStats[%i] $= "")
		{
			%perStatsFile.WriteLine("null");
		}
		else
		{
			%perStatsFile.WriteLine($PersistentStats[%i]);
		}
	}
	%perStatsFile.close();
}
function calculateCurrentPersistentRecord ()
{//echo("calculateCurrentPersistentRecord()");
	%recordString = $LastMarineName		SPC
					$LastMarineClass	SPC
					$LastMarineRank		SPC
					$LastScore			SPC
					$LastDeck			SPC
					$LastLevel			SPC
					$LastTurn			SPC
					$LastThreat			SPC
					$LastDeaths			SPC
					$difficultyLevel	SPC
					$currentGameVersion;
	return %recordString;
}

/*function getCustomUserDataDirectory ()
{//echo("getCustomUserDataDirectory()");
	return getUserDataDirectory();		// Messing up some special character names/file paths?
}*/
function getSaveGameFilePath ()
{
	return getUserDataDirectory() @ "/Worthless Bums/Steam Marines/save.sav";
}
// Saves the current game to file.
function saveCurrentGame ()
{//echo("saveCurrentGame()");
	// Don't save in the tutorial level!
	if ($generateTutorialLevel	||
		!$gameInProgress)
	{
		return;
	}
	
	// Stop tracking game time.
	stopGameTimer();
	
	// Enforce squad persistence!
	enforceSquadPersistence();
	
	// Clear any current save game to prevent contamination!
	clearSaveFile();
	
	%file = getSaveGameFilePath();
	
	// Create the file object.
	%saveFile = new fileobject();
	
	// Open the file for writing.
	%saveFile.OpenForWrite(%file);
	
	//----------------------------------
	// Write save data.
	//----------------------------------
	// Steam Marines version.
	%saveFile.WriteLine("version " @ $currentGameVersion);
	
	// Difficulty level.
	%saveFile.WriteLine("difficultyLevel " @ $difficultyLevel);
	
	// New Game Plus counter.
	%saveFile.WriteLine("NewGamePlus " @ $NewGamePlus);
	// New Game Start flag.
	%saveFile.WriteLine("NewGameStart " @ $NewGameStart);
	
	// Save played time.
	%additionalPlayTime = getGamePlayedTime();
	//$gamePlayedTime += %additionalPlayTime;
	%saveFile.WriteLine("gamePlayedTime " @ $gamePlayedTime);
	
	// On Overworld Map.
	%saveFile.WriteLine("onOverworldMap " @ $onOverworldMap);
	// Overworld Location.
	%saveFile.WriteLine("overworldLocation " @ $overworldLocation);
	
	// Infection Discovered.
	%saveFile.WriteLine("infectionDiscovered " @ $infectionDiscovered);
	
	// (Current) Dungeon Level.
	%saveFile.WriteLine("dungeonLevel " @ $dungeonLevel);
	// Command Deck Dungeon Level.
	%saveFile.WriteLine("commandDeckLevel " @ $commandDeckLevel);
	// Engineering Deck Dungeon Level.
	%saveFile.WriteLine("engineeringDeckLevel " @ $engineeringDeckLevel);
	// Medical Deck Dungeon Level.
	%saveFile.WriteLine("medicalDeckLevel " @ $medicalDeckLevel);
	// Armory Deck Dungeon Level.
	%saveFile.WriteLine("armoryDeckLevel " @ $armoryDeckLevel);
	// Bridge Deck Dungeon Level.
	%saveFile.WriteLine("bridgeDeckLevel " @ $bridgeDeckLevel);
	// Alien Deck Dungeon Level.
	%saveFile.WriteLine("alienDeckLevel " @ $alienDeckLevel);
	
	// If the elevator is powered or not.
	%saveFile.WriteLine("elevatorPowered " @ $elevatorPowered);
	
	// Save active character.
	%saveFile.WriteLine("activeCharacter " @ $activeCharacter);
	
	// Save Mission Objective Data.
	%saveFile.WriteLine("primaryMissionID " @ $primaryMissionID);
	%saveFile.WriteLine("primaryObjectiveStatus " @ $primaryObjectiveStatus);
	%saveFile.WriteLine("secondaryMissionID " @ $secondaryMissionID);
	%saveFile.WriteLine("secondaryObjectiveStatus " @ $secondaryObjectiveStatus);
	
	// Squad State Flags.
	%saveFile.WriteLine("squadFoundStairs " @ $squadFoundStairs);
	%saveFile.WriteLine("merchantAccessed " @ $merchantAccessed);
	%saveFile.WriteLine("squadCredits " @ $squadCredits);
	
	// Disruptor Indices.
	if ($ElevatorDisruptorXIndex != -1	&&
		$ElevatorDisruptorYIndex != -1)
	{
		%saveFile.WriteLine("disruptorIndices " @ $ElevatorDisruptorXIndex SPC $ElevatorDisruptorYIndex);
	}
	
	// Multipass used flag.
	%saveFile.WriteLine("multipassUsed " @ $multipassUsed);
	
	// Merchants Met Flag.
	%saveFile.WriteLine("MerchantsMet " @ $MerchantsMet);
	
	// Gravity Well flag.
	%saveFile.WriteLine("GravityWellOn " @ $GravityWellOn);
	
	// Save Ship Object Data.
	// Command Deck
	%saveFile.WriteLine("commandDeckHostileControl " @ $ship.commandDeckHostileControl);
	%saveFile.WriteLine("commandDeckIntegrity " @ $ship.commandDeckIntegrity);
	%saveFile.WriteLine("commandDeckMaxIntegrity " @ $ship.commandDeckMaxIntegrity);
	%saveFile.WriteLine("commandDeckOxygen " @ $ship.commandDeckOxygen);
	%saveFile.WriteLine("commandDeckMaxOxygen " @ $ship.commandDeckMaxOxygen);
	%saveFile.WriteLine("commandDeckPower " @ $ship.commandDeckPower);
	%saveFile.WriteLine("commandDeckMaxPower " @ $ship.commandDeckMaxPower);
	%saveFile.WriteLine("commandDeckInfection " @ $ship.commandDeckInfection);
	%saveFile.WriteLine("commandDeckMaxInfection " @ $ship.commandDeckMaxInfection);
	%saveFile.WriteLine("commandDeckInvaded " @ $ship.commandDeckInvaded);
	// Engineering Deck
	%saveFile.WriteLine("engineeringDeckHostileControl " @ $ship.engineeringDeckHostileControl);
	%saveFile.WriteLine("engineeringDeckIntegrity " @ $ship.engineeringDeckIntegrity);
	%saveFile.WriteLine("engineeringDeckMaxIntegrity " @ $ship.engineeringDeckMaxIntegrity);
	%saveFile.WriteLine("engineeringDeckOxygen " @ $ship.engineeringDeckOxygen);
	%saveFile.WriteLine("engineeringDeckMaxOxygen " @ $ship.engineeringDeckMaxOxygen);
	%saveFile.WriteLine("engineeringDeckPower " @ $ship.engineeringDeckPower);
	%saveFile.WriteLine("engineeringDeckMaxPower " @ $ship.engineeringDeckMaxPower);
	%saveFile.WriteLine("engineeringDeckInfection " @ $ship.engineeringDeckInfection);
	%saveFile.WriteLine("engineeringDeckMaxInfection " @ $ship.engineeringDeckMaxInfection);
	%saveFile.WriteLine("engineeringDeckInvaded " @ $ship.engineeringDeckInvaded);
	// Medical Deck
	%saveFile.WriteLine("medicalDeckHostileControl " @ $ship.medicalDeckHostileControl);
	%saveFile.WriteLine("medicalDeckIntegrity " @ $ship.medicalDeckIntegrity);
	%saveFile.WriteLine("medicalDeckMaxIntegrity " @ $ship.medicalDeckMaxIntegrity);
	%saveFile.WriteLine("medicalDeckOxygen " @ $ship.medicalDeckOxygen);
	%saveFile.WriteLine("medicalDeckMaxOxygen " @ $ship.medicalDeckMaxOxygen);
	%saveFile.WriteLine("medicalDeckPower " @ $ship.medicalDeckPower);
	%saveFile.WriteLine("medicalDeckMaxPower " @ $ship.medicalDeckMaxPower);
	%saveFile.WriteLine("medicalDeckInfection " @ $ship.medicalDeckInfection);
	%saveFile.WriteLine("medicalDeckMaxInfection " @ $ship.medicalDeckMaxInfection);
	%saveFile.WriteLine("medicalDeckInvaded " @ $ship.medicalDeckInvaded);
	// Armory Deck
	%saveFile.WriteLine("armoryDeckHostileControl " @ $ship.armoryDeckHostileControl);
	%saveFile.WriteLine("armoryDeckIntegrity " @ $ship.armoryDeckIntegrity);
	%saveFile.WriteLine("armoryDeckMaxIntegrity " @ $ship.armoryDeckMaxIntegrity);
	%saveFile.WriteLine("armoryDeckOxygen " @ $ship.armoryDeckOxygen);
	%saveFile.WriteLine("armoryDeckMaxOxygen " @ $ship.armoryDeckMaxOxygen);
	%saveFile.WriteLine("armoryDeckPower " @ $ship.armoryDeckPower);
	%saveFile.WriteLine("armoryDeckMaxPower " @ $ship.armoryDeckMaxPower);
	%saveFile.WriteLine("armoryDeckInfection " @ $ship.armoryDeckInfection);
	%saveFile.WriteLine("armoryDeckMaxInfection " @ $ship.armoryDeckMaxInfection);
	%saveFile.WriteLine("armoryDeckInvaded " @ $ship.armoryDeckInvaded);
	// Bridge Deck
	%saveFile.WriteLine("bridgeDeckHostileControl " @ $ship.bridgeDeckHostileControl);
	%saveFile.WriteLine("bridgeDeckIntegrity " @ $ship.bridgeDeckIntegrity);
	%saveFile.WriteLine("bridgeDeckMaxIntegrity " @ $ship.bridgeDeckMaxIntegrity);
	%saveFile.WriteLine("bridgeDeckOxygen " @ $ship.bridgeDeckOxygen);
	%saveFile.WriteLine("bridgeDeckMaxOxygen " @ $ship.bridgeDeckMaxOxygen);
	%saveFile.WriteLine("bridgeDeckPower " @ $ship.bridgeDeckPower);
	%saveFile.WriteLine("bridgeDeckMaxPower " @ $ship.bridgeDeckMaxPower);
	%saveFile.WriteLine("bridgeDeckInfection " @ $ship.bridgeDeckInfection);
	%saveFile.WriteLine("bridgeDeckMaxInfection " @ $ship.bridgeDeckMaxInfection);
	%saveFile.WriteLine("bridgeDeckInvaded " @ $ship.bridgeDeckInvaded);
	// Alien Deck
	%saveFile.WriteLine("alienDeckHostileControl " @ $ship.alienDeckHostileControl);
	%saveFile.WriteLine("alienDeckIntegrity " @ $ship.alienDeckIntegrity);
	%saveFile.WriteLine("alienDeckMaxIntegrity " @ $ship.alienDeckMaxIntegrity);
	%saveFile.WriteLine("alienDeckOxygen " @ $ship.alienDeckOxygen);
	%saveFile.WriteLine("alienDeckMaxOxygen " @ $ship.alienDeckMaxOxygen);
	%saveFile.WriteLine("alienDeckPower " @ $ship.alienDeckPower);
	%saveFile.WriteLine("alienDeckMaxPower " @ $ship.alienDeckMaxPower);
	%saveFile.WriteLine("alienDeckInfection " @ $ship.alienDeckInfection);
	%saveFile.WriteLine("alienDeckMaxInfection " @ $ship.alienDeckMaxInfection);
	%saveFile.WriteLine("alienDeckInvaded " @ $ship.alienDeckInvaded);
	
	// Save Global Statistics.
	%saveFile.WriteLine("currentTurn " @ $GlobalStats.currentTurn);
	%saveFile.WriteLine("totalLevelsPassed " @ $GlobalStats.totalLevelsPassed);
	%saveFile.WriteLine("totalPrimaryMissionObjectivesCompleted " @ $GlobalStats.totalPrimaryMissionObjectivesCompleted);
	%saveFile.WriteLine("totalSecondaryMissionObjectivesCompleted " @ $GlobalStats.totalSecondaryMissionObjectivesCompleted);
	%saveFile.WriteLine("totalGuardModes " @ $GlobalStats.totalGuardModes);
	%saveFile.WriteLine("totalSquadMemberDeaths " @ $GlobalStats.totalSquadMemberDeaths);
	%saveFile.WriteLine("totalSurvivorsRecruited " @ $GlobalStats.totalSurvivorsRecruited);
	%saveFile.WriteLine("totalKills " @ $GlobalStats.totalKills);
	%saveFile.WriteLine("totalAmmunitionExpended " @ $GlobalStats.totalAmmunitionExpended);
	%saveFile.WriteLine("totalAmmunitionMassExpended " @ $GlobalStats.totalAmmunitionMassExpended);
	%saveFile.WriteLine("totalMeleeAttacks " @ $GlobalStats.totalMeleeAttacks);
	%saveFile.WriteLine("totalDamageDealt " @ $GlobalStats.totalDamageDealt);
	%saveFile.WriteLine("totalDamageTaken " @ $GlobalStats.totalDamageTaken);
	%saveFile.WriteLine("totalEnemiesKnockedIntoSpace " @ $GlobalStats.totalEnemiesKnockedIntoSpace);
	%saveFile.WriteLine("totalWallsSmashed " @ $GlobalStats.totalWallsSmashed);
	%saveFile.WriteLine("totalCratesSmashed " @ $GlobalStats.totalCratesSmashed);
	%saveFile.WriteLine("totalDispensersUsed " @ $GlobalStats.totalDispensersUsed);
	%saveFile.WriteLine("totalConsolesUsed " @ $GlobalStats.totalConsolesUsed);
	%saveFile.WriteLine("totalDoorsOpened " @ $GlobalStats.totalDoorsOpened);
	%saveFile.WriteLine("totalDoorsClosed " @ $GlobalStats.totalDoorsClosed);
	%saveFile.WriteLine("totalItemsGrabbed " @ $GlobalStats.totalItemsGrabbed);
	%saveFile.WriteLine("totalItemsUsed " @ $GlobalStats.totalItemsUsed);
	%saveFile.WriteLine("totalChestsOpened " @ $GlobalStats.totalChestsOpened);
	%saveFile.WriteLine("totalLightSwitchesUsed " @ $GlobalStats.totalLightSwitchesUsed);
	
	// Check if the Squad Leader is alive.
	if ($leaderPersist)//($playerSquad[0])
	{//echo("Squad Leader is alive!");
		// General information.
		%saveFile.WriteLine("leaderPersist " @ 1);
		%saveFile.WriteLine("leaderName " @ $playerSquad[0].name);
		%saveFile.WriteLine("leaderClass " @ $playerSquad[0].characterClass);
		%saveFile.WriteLine("leaderRank " @ $playerSquad[0].rank);
		%saveFile.WriteLine("leaderLevel " @ getLevelFromExperience($playerSquad[0].experience));
		%saveFile.WriteLine("leaderExperience " @ $playerSquad[0].experience);
		%saveFile.WriteLine("leaderGender " @ $playerSquad[0].gender);
		%saveFile.WriteLine("leaderImageMap " @ $playerSquad[0].imageMap);
		
		// Character position, location, and facing.
		%saveFile.WriteLine("leaderPosition " @ $playerSquad[0].getPosition());
		%saveFile.WriteLine("leaderXIndex " @ $playerSquad[0].xIndex);
		%saveFile.WriteLine("leaderYIndex " @ $playerSquad[0].yIndex);
		%saveFile.WriteLine("leaderFacing " @ $playerSquad[0].facing);
		
		// State.
		%saveFile.WriteLine("leaderGuardMode " @ $playerSquad[0].guardMode);
		
		// Character health, armor, action points, statistics, skills, and inventory!
		// Health, Armor, Action Points, and Oxygen:
		%saveFile.WriteLine("leaderCurrentHealth " @ $playerSquad[0].currentHealth);
		%saveFile.WriteLine("leaderMaxHealth " @ $playerSquad[0].maxHealth);
		%saveFile.WriteLine("leaderArmorRating " @ $playerSquad[0].armorRating);
		%saveFile.WriteLine("leaderCurrentActionPoints " @ $playerSquad[0].currentActionPoints);
		%saveFile.WriteLine("leaderMaxActionPoints " @ $playerSquad[0].maxActionPoints);
		%saveFile.WriteLine("leaderOxygen " @ $playerSquad[0].oxygen);
		%saveFile.WriteLine("leaderSight " @ $playerSquad[0].sight);
		// Statistics:
		%saveFile.WriteLine("leaderPower " @ $playerSquad[0].power);
		%saveFile.WriteLine("leaderSpeed " @ $playerSquad[0].speed);
		%saveFile.WriteLine("leaderEndurance " @ $playerSquad[0].endurance);
		// Skills:
		%saveFile.WriteLine("leaderBash " @ $playerSquad[0].bash);
		%saveFile.WriteLine("leaderDemolitions " @ $playerSquad[0].demolitions);
		%saveFile.WriteLine("leaderArms " @ $playerSquad[0].arms);
		// Retraining:
		%saveFile.WriteLine("leaderRetraining " @ $playerSquad[0].retraining);
		// Inventory:
		%saveFile.WriteLine("leaderWeapon " @ ($playerSquad[0].weapon).weaponType);
		%saveFile.WriteLine("leaderArmor " @ ($playerSquad[0].armor).armorType);
		%saveFile.WriteLine("leaderammo " @ $playerSquad[0].ammo);
		// Kills:
		%saveFile.WriteLine("leaderKills " @ $playerSquad[0].kills);
		// Evasion:
		%saveFile.WriteLine("leaderEvasion " @ $playerSquad[0].evasion);
		// Talents:
		%saveFile.WriteLine("leaderTalentPoints " @ $playerSquad[0].talentPoints);
		%saveFile.WriteLine("leaderStatPoints " @ $playerSquad[0].statPoints);
		%saveFile.WriteLine("leaderSkillPoints " @ $playerSquad[0].skillPoints);
		%saveFile.WriteLine("leaderTalents " @ $playerSquad[0].talents);
		%saveFile.WriteLine("leaderPerks " @ $playerSquad[0].perks);
		%saveFile.WriteLine("leaderWeaponAttachment " @ $leaderWeaponAttachment);
		// Vehicle Status:
		%saveFile.WriteLine("leaderVehicle " @ $playerSquad[0].vehicle);
	}
	else
	{//echo("Squad Leader is NOT alive!");
		$leaderPersist = false;
	}
	
	// Check if the Scout is alive.
	if ($scoutPersist)//($playerSquad[1])
	{//echo("Squad Scout is alive!");
		// General information.
		%saveFile.WriteLine("scoutPersist " @ 1);
		%saveFile.WriteLine("scoutName " @ $playerSquad[1].name);
		%saveFile.WriteLine("scoutClass " @ $playerSquad[1].characterClass);
		%saveFile.WriteLine("scoutRank " @ $playerSquad[1].rank);
		%saveFile.WriteLine("scoutLevel " @ getLevelFromExperience($playerSquad[1].experience));
		%saveFile.WriteLine("scoutExperience " @ $playerSquad[1].experience);
		%saveFile.WriteLine("scoutGender " @ $playerSquad[1].gender);
		%saveFile.WriteLine("scoutImageMap " @ $playerSquad[1].imageMap);
		
		// Character position, location, and facing.
		%saveFile.WriteLine("scoutPosition " @ $playerSquad[1].getPosition());
		%saveFile.WriteLine("scoutXIndex " @ $playerSquad[1].xIndex);
		%saveFile.WriteLine("scoutYIndex " @ $playerSquad[1].yIndex);
		%saveFile.WriteLine("scoutFacing " @ $playerSquad[1].facing);
		
		// State.
		%saveFile.WriteLine("scoutGuardMode " @ $playerSquad[1].guardMode);
		
		// Character health, armor, action points, statistics, skills, and inventory!
		// Health, Armor, Action Points, and Oxygen:
		%saveFile.WriteLine("scoutCurrentHealth " @ $playerSquad[1].currentHealth);
		%saveFile.WriteLine("scoutMaxHealth " @ $playerSquad[1].maxHealth);
		%saveFile.WriteLine("scoutArmorRating " @ $playerSquad[1].armorRating);
		%saveFile.WriteLine("scoutCurrentActionPoints " @ $playerSquad[1].currentActionPoints);
		%saveFile.WriteLine("scoutMaxActionPoints " @ $playerSquad[1].maxActionPoints);
		%saveFile.WriteLine("scoutOxygen " @ $playerSquad[1].oxygen);
		%saveFile.WriteLine("scoutSight " @ $playerSquad[1].sight);
		// Statistics:
		%saveFile.WriteLine("scoutPower " @ $playerSquad[1].power);
		%saveFile.WriteLine("scoutSpeed " @ $playerSquad[1].speed);
		%saveFile.WriteLine("scoutEndurance " @ $playerSquad[1].endurance);
		// Skills:
		%saveFile.WriteLine("scoutBash " @ $playerSquad[1].bash);
		%saveFile.WriteLine("scoutDemolitions " @ $playerSquad[1].demolitions);
		%saveFile.WriteLine("scoutArms " @ $playerSquad[1].arms);
		// Retraining:
		%saveFile.WriteLine("scoutRetraining " @ $playerSquad[1].retraining);
		// Inventory:
		%saveFile.WriteLine("scoutWeapon " @ ($playerSquad[1].weapon).weaponType);
		%saveFile.WriteLine("scoutArmor " @ ($playerSquad[1].armor).armorType);
		%saveFile.WriteLine("scoutammo " @ $playerSquad[1].ammo);
		// Kills:
		%saveFile.WriteLine("scoutKills " @ $playerSquad[1].kills);
		// Evasion:
		%saveFile.WriteLine("scoutEvasion " @ $playerSquad[1].evasion);
		// Talents:
		%saveFile.WriteLine("scoutTalentPoints " @ $playerSquad[1].talentPoints);
		%saveFile.WriteLine("scoutStatPoints " @ $playerSquad[1].statPoints);
		%saveFile.WriteLine("scoutSkillPoints " @ $playerSquad[1].skillPoints);
		%saveFile.WriteLine("scoutTalents " @ $playerSquad[1].talents);
		%saveFile.WriteLine("scoutPerks " @ $playerSquad[1].perks);
		%saveFile.WriteLine("scoutWeaponAttachment " @ $scoutWeaponAttachment);
		// Vehicle Status:
		%saveFile.WriteLine("scoutVehicle " @ $playerSquad[1].vehicle);
	}
	else
	{//echo("Squad Scout is NOT alive!");
		$scoutPersist = false;
	}
	
	// Check if the Grenadier is alive.
	if ($grenadierPersist)//($playerSquad[2])
	{//echo("Squad Grenadier is alive!");
		// General information.
		%saveFile.WriteLine("grenadierPersist " @ 1);
		%saveFile.WriteLine("grenadierName " @ $playerSquad[2].name);
		%saveFile.WriteLine("grenadierClass " @ $playerSquad[2].characterClass);
		%saveFile.WriteLine("grenadierRank " @ $playerSquad[2].rank);
		%saveFile.WriteLine("grenadierLevel " @ getLevelFromExperience($playerSquad[2].experience));
		%saveFile.WriteLine("grenadierExperience " @ $playerSquad[2].experience);
		%saveFile.WriteLine("grenadierGender " @ $playerSquad[2].gender);
		%saveFile.WriteLine("grenadierImageMap " @ $playerSquad[2].imageMap);
		
		// Character position, location, and facing.
		%saveFile.WriteLine("grenadierPosition " @ $playerSquad[2].getPosition());
		%saveFile.WriteLine("grenadierXIndex " @ $playerSquad[2].xIndex);
		%saveFile.WriteLine("grenadierYIndex " @ $playerSquad[2].yIndex);
		%saveFile.WriteLine("grenadierFacing " @ $playerSquad[2].facing);
		
		// State.
		%saveFile.WriteLine("grenadierGuardMode " @ $playerSquad[2].guardMode);
		
		// Character health, armor, action points, statistics, skills, and inventory!
		// Health, Armor, Action Points, and Oxygen:
		%saveFile.WriteLine("grenadierCurrentHealth " @ $playerSquad[2].currentHealth);
		%saveFile.WriteLine("grenadierMaxHealth " @ $playerSquad[2].maxHealth);
		%saveFile.WriteLine("grenadierArmorRating " @ $playerSquad[2].armorRating);
		%saveFile.WriteLine("grenadierCurrentActionPoints " @ $playerSquad[2].currentActionPoints);
		%saveFile.WriteLine("grenadierMaxActionPoints " @ $playerSquad[2].maxActionPoints);
		%saveFile.WriteLine("grenadierOxygen " @ $playerSquad[2].oxygen);
		%saveFile.WriteLine("grenadierSight " @ $playerSquad[2].sight);
		// Statistics:
		%saveFile.WriteLine("grenadierPower " @ $playerSquad[2].power);
		%saveFile.WriteLine("grenadierSpeed " @ $playerSquad[2].speed);
		%saveFile.WriteLine("grenadierEndurance " @ $playerSquad[2].endurance);
		// Skills:
		%saveFile.WriteLine("grenadierBash " @ $playerSquad[2].bash);
		%saveFile.WriteLine("grenadierDemolitions " @ $playerSquad[2].demolitions);
		%saveFile.WriteLine("grenadierArms " @ $playerSquad[2].arms);
		// Retraining:
		%saveFile.WriteLine("grenadierRetraining " @ $playerSquad[2].retraining);
		// Inventory:
		%saveFile.WriteLine("grenadierWeapon " @ ($playerSquad[2].weapon).weaponType);
		%saveFile.WriteLine("grenadierArmor " @ ($playerSquad[2].armor).armorType);
		%saveFile.WriteLine("grenadierammo " @ $playerSquad[2].ammo);
		// Kills:
		%saveFile.WriteLine("grenadierKills " @ $playerSquad[2].kills);
		// Evasion:
		%saveFile.WriteLine("grenadierEvasion " @ $playerSquad[2].evasion);
		// Talents:
		%saveFile.WriteLine("grenadierTalentPoints " @ $playerSquad[2].talentPoints);
		%saveFile.WriteLine("grenadierStatPoints " @ $playerSquad[2].statPoints);
		%saveFile.WriteLine("grenadierSkillPoints " @ $playerSquad[2].skillPoints);
		%saveFile.WriteLine("grenadierTalents " @ $playerSquad[2].talents);
		%saveFile.WriteLine("grenadierPerks " @ $playerSquad[2].perks);
		%saveFile.WriteLine("grenadierWeaponAttachment " @ $grenadierWeaponAttachment);
		// Vehicle Status:
		%saveFile.WriteLine("grenadierVehicle " @ $playerSquad[2].vehicle);
	}
	else
	{//echo("Squad Grenadier is NOT alive!");
		$grenadierPersist = false;
	}
	
	// Check if the Support is alive.
	if ($supportPersist)//($playerSquad[3])
	{//echo("Squad Support is alive!");
		// General information.
		%saveFile.WriteLine("supportPersist " @ 1);
		%saveFile.WriteLine("supportName " @ $playerSquad[3].name);
		%saveFile.WriteLine("supportClass " @ $playerSquad[3].characterClass);
		%saveFile.WriteLine("supportRank " @ $playerSquad[3].rank);
		%saveFile.WriteLine("supportLevel " @ getLevelFromExperience($playerSquad[3].experience));
		%saveFile.WriteLine("supportExperience " @ $playerSquad[3].experience);
		%saveFile.WriteLine("supportGender " @ $playerSquad[3].gender);
		%saveFile.WriteLine("supportImageMap " @ $playerSquad[3].imageMap);
		
		// Character position, location, and facing.
		%saveFile.WriteLine("supportPosition " @ $playerSquad[3].getPosition());
		%saveFile.WriteLine("supportXIndex " @ $playerSquad[3].xIndex);
		%saveFile.WriteLine("supportYIndex " @ $playerSquad[3].yIndex);
		%saveFile.WriteLine("supportFacing " @ $playerSquad[3].facing);
		
		// State.
		%saveFile.WriteLine("supportGuardMode " @ $playerSquad[3].guardMode);
		
		// Character health, armor, action points, statistics, skills, and inventory!
		// Health, Armor, Action Points, and Oxygen:
		%saveFile.WriteLine("supportCurrentHealth " @ $playerSquad[3].currentHealth);
		%saveFile.WriteLine("supportMaxHealth " @ $playerSquad[3].maxHealth);
		%saveFile.WriteLine("supportArmorRating " @ $playerSquad[3].armorRating);
		%saveFile.WriteLine("supportCurrentActionPoints " @ $playerSquad[3].currentActionPoints);
		%saveFile.WriteLine("supportMaxActionPoints " @ $playerSquad[3].maxActionPoints);
		%saveFile.WriteLine("supportOxygen " @ $playerSquad[3].oxygen);
		%saveFile.WriteLine("supportSight " @ $playerSquad[3].sight);
		// Statistics:
		%saveFile.WriteLine("supportPower " @ $playerSquad[3].power);
		%saveFile.WriteLine("supportSpeed " @ $playerSquad[3].speed);
		%saveFile.WriteLine("supportEndurance " @ $playerSquad[3].endurance);
		// Skills:
		%saveFile.WriteLine("supportBash " @ $playerSquad[3].bash);
		%saveFile.WriteLine("supportDemolitions " @ $playerSquad[3].demolitions);
		%saveFile.WriteLine("supportArms " @ $playerSquad[3].arms);
		// Retraining:
		%saveFile.WriteLine("supportRetraining " @ $playerSquad[3].retraining);
		// Inventory:
		%saveFile.WriteLine("supportWeapon " @ ($playerSquad[3].weapon).weaponType);
		%saveFile.WriteLine("supportArmor " @ ($playerSquad[3].armor).armorType);
		%saveFile.WriteLine("supportammo " @ $playerSquad[3].ammo);
		// Kills:
		%saveFile.WriteLine("supportKills " @ $playerSquad[3].kills);
		// Evasion:
		%saveFile.WriteLine("supportEvasion " @ $playerSquad[3].evasion);
		// Talents:
		%saveFile.WriteLine("supportTalentPoints " @ $playerSquad[3].talentPoints);
		%saveFile.WriteLine("supportStatPoints " @ $playerSquad[3].statPoints);
		%saveFile.WriteLine("supportSkillPoints " @ $playerSquad[3].skillPoints);
		%saveFile.WriteLine("supportTalents " @ $playerSquad[3].talents);
		%saveFile.WriteLine("supportPerks " @ $playerSquad[3].perks);
		%saveFile.WriteLine("supportWeaponAttachment " @ $supportWeaponAttachment);
		// Vehicle Status:
		%saveFile.WriteLine("supportVehicle " @ $playerSquad[3].vehicle);
	}
	else
	{//echo("Squad Support is NOT alive!");
		$supportPersist = false;
	}
	
	// Make sure the squad inventory exists prior to doing anything to it.
	if (isObject($squadInventory))
	{
		// Save squad inventory.
		for (%i = 1; %i <= $squadInventory.getCount(); %i++)
		{
			%saveFile.WriteLine(getItemCode($squadInventory.getObject(%i - 1), %i));
		}
	}
	
	// Pass the opened file handle to save level data.
	saveCurrentLevel(%saveFile);
	saveCurrentLiftedLevel(%saveFile);
	saveCurrentMonsterData(%saveFile);
	saveCurrentFogOfWarData(%saveFile);
	saveCurrentItemData(%saveFile);
	saveCurrentBarrelData(%saveFile);
	saveCurrentConsoleData(%saveFile);
	saveCurrentDispenserData(%saveFile);
	saveCurrentLightSwitchData(%saveFile);
	saveCurrentTileDestructionData(%saveFile);
	saveCurrentTreasureChestData(%saveFile);
	saveCurrentTrapData(%saveFile);
	saveCurrentGratingData(%saveFile);
	saveCurrentCryoTubeData(%saveFile);
	saveCurrentLockersData(%saveFile);
	saveCurrentCorpseData(%saveFile);
	saveCurrentTurretData(%saveFile);
	
	%saveFile.close();
	
	// Write encryption string.
	//createEncryptionStringForSave();		// Not working!
}

// Returns a properly formatted string for a weapon or armor object.
function getItemCode (%item, %inventorySlot)
{//echo("getItemCode()");
	if (%item.itemType == -1)		// Weapon.
	{
		return ("InventoryItem" @ %inventorySlot SPC -1 SPC %item.weaponType);
	}
	else if (%item.itemType == -2)	// Armor.
	{
		return ("InventoryItem" @ %inventorySlot SPC -2 SPC %item.armorType);
	}
	else
	{
		return ("InventoryItem" @ %inventorySlot SPC %item.itemType);
	}
}

// Returns a proper item object from the specified data.
// NOTE: %itemType holds the rest of the item data for a weapon or armor item!
function getItemFromSaveFile (%itemType, %position, %xIndex, %yIndex)
{//echo("getItemFromSaveFile()");
//echo("%itemType =" SPC %itemType);
	// Grab item index.
	%itemIndex = getWord(%itemType, 0);
	
	if (%itemIndex == -1)		// Weapon.
	{
		// Parse out data.
		// itemType is the first word, but we don't need it.
		%name = getWord(%itemType, 1);
		%squadMember = getWord(%itemType, 2);
		%damage = getWord(%itemType, 3);
		%range = getWord(%itemType, 4);
		%accuracy = getWord(%itemType, 5);
		%imageMap = getWord(%itemType, 6);
		%ammo = getWord(%weaponType, 7);
		%capacity = getWord(%itemType, 8);
		%damageRange = getWord(%itemType, 9);
		%currentAmmo = getWord(%itemType, 10);
		%reload = getWord(%itemType, 11);
		%fireCost = getWord(%itemType, 12);
		
		// Compose weapon code.
		%weaponCode = %name SPC %squadMember SPC %damage SPC %range SPC %accuracy SPC %imageMap SPC %ammo SPC %capacity SPC %damageRange SPC %currentAmmo SPC %reload SPC %fireCost;
		
		// Create new weapon.
		%weapon = createNewWeapon(%weaponCode);
		
		return %weapon;
	}
	else if (%itemIndex == -2)	// Armor.
	{
		// Parse out data.
		// itemType is the first word, but we don't need it.
		%name = getWord(%itemType, 1);
		%squadMember = getWord(%itemType, 2);
		%armorRating = getWord(%itemType, 3);
		%speed = getWord(%itemType, 4);
		%imageMap = getWord(%itemType, 5);
		%repair = getWord(%itemType, 6);
		%fireResistance = getWord(%itemType, 7);
		%frostResistance = getWord(%itemType, 8);
		%acidResistance = getWord(%itemType, 9);
		%explosiveResistance = getWord(%itemType, 10);
		%oxygen = getWord(%itemType, 11);
		
		// Compose armor code.
		%armorCode = %name SPC %squadMember SPC %armorRating SPC %speed SPC %imageMap SPC %repair SPC %fireResistance SPC %frostResistance SPC %acidResistance SPC %explosiveResistance SPC %oxygen;
		
		// Create new armor.
		%armor = createNewArmor(%armorCode);
		
		return %armor;
	}
	else
	{
		return createRandomItem(%itemType, %position, %xIndex, %yIndex);
	}
}